import json
import sys
import re
import urllib

from bs4 import BeautifulSoup

def contractAsJson(filename):
#yfs_l84_aapl
#span id="yfs_l84_aapl"
#98.94
    soup = BeautifulSoup (open(filename))

    keywords = soup.find("meta",{'name':'keywords'})
    content = keywords.attrs['content']
    symbolre = re.search(r'(\w+)',content)
    mysymbol = symbolre.group()
    priceLabel = "yfs_l84_" + mysymbol.lower()
    priceTag = soup.find('span', {'id': priceLabel})
    price = priceTag.contents[0]
    priceInt = float(price)

    overDict = {}
    overDict["currPrice"] = priceInt
    jsonObjen = json.dumps({"currPrice":priceInt})
    jsonObjde = json.loads(jsonObjen)

    expiration = soup.find_all("td")
    urlList =[]
    for td in expiration:
        view = td.next_element
        if(view == "View By Expiration: "):
            urls = td.findAll('a')

            for url in urls:
                if(url.find("strong",text='Expand to Straddle View...')):
                    urlList.append(url)
                for month in ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep', "Oct",'Nov','Dec']:
                    if(month in url.next_element):
                        urlList.append(url)
    hrefList = []
    for url in urlList:
        sub = url.attrs['href']
        index = sub.find('m=')
        sub = sub[:index] +'amp;' + sub[index:]
        hrefList.append("http://finance.yahoo.com" + sub)

    overDict["dateUrls"] = hrefList
    jsonObjen += json.dumps({"dateUrls":hrefList})
    x = 0
    table = soup.find("td",{'class': "yfnc_h"})
    tablep = table.parent
    tablepp = tablep.parent
    optList = []
    num = 0
    for child in tablepp.children:
        aOpt = optQ()
        num = 0
        # print child.name
        for td in child.children:
            if td.attrs["class"][0] == "yfnc_h" or td.attrs["class"][0] == "yfnc_tabledata1":
                # print td.name
                if num == 0:
                    a = td.next_element
                    strong = a.next_element
                    strike = strong.next_element
                    aOpt.Strike = strike
                elif num == 1:
                    a = td.next_element
                    content = a.next_element
                    search = re.search("(\d)",content)
                    group1 = search.group(1)
                    if group1 == "7":
                        search = re.search("([a-zA-z]+\d)",content)
                        aOpt.Symbol = search.group(1)
                    else:
                        search = re.search("([a-zA-z]+)",content)
                        aOpt.Symbol = search.group(1)
                    search = re.search("(\d)",content)
                    group1 = search.group(1)
                    if group1 == "7":
                        search = re.search("\d(\d+)",content)
                        date = search.group(1)
                    else:
                        search = re.search("(\d+)",content)
                        date = search.group(1)
                    aOpt.Date = date
                    search = re.search("[a-zA-z]+\d+([a-zA-Z])",content)
                    aOpt.Type = search.group(1)
                elif num == 2:
                    if(td.next_element == "N/A"):
                        aOpt.Last = td.next_element
                    else:
                        a = td.find("b")
                        aOpt.Last = a.next_element
                elif num == 3:
                    b = td.find("b")
                    aOpt.Change = " " + b.next_element
                elif num == 4:
                    aOpt.Bid = td.next_element
                elif num == 5:
                    aOpt.Ask = td.next_element
                elif num == 6:
                    aOpt.Vol = td.next_element
                elif num == 7:
                    aOpt.Open = td.next_element

                if num == 7:
                    optList.append(aOpt)
            num +=1

    table = soup.find_all("table",{"class":"yfnc_datamodoutline1"})
    tabled = table[1].find("td",{'class': "yfnc_tabledata1"})
    tablep = tabled.parent
    tablepp = tablep.parent

    num = 0
    for child in tablepp.children:
        aOpt = optQ()
        num = 0
        # print child.name
        for td in child.children:
            if td.attrs["class"][0] == "yfnc_h" or td.attrs["class"][0] == "yfnc_tabledata1":
                # print td.name
                if num == 0:
                    a = td.next_element
                    strong = a.next_element
                    strike = strong.next_element
                    aOpt.Strike = strike
                elif num == 1:
                    a = td.next_element
                    content = a.next_element
                    search = re.search("(\d)",content)
                    group1 = search.group(1)
                    if group1 == "7":
                        search = re.search("([a-zA-z]+\d)",content)
                        aOpt.Symbol = search.group(1)
                    else:
                        search = re.search("([a-zA-z]+)",content)
                        aOpt.Symbol = search.group(1)
                    search = re.search("(\d)",content)
                    group1 = search.group(1)
                    if group1 == "7":
                        search = re.search("\d(\d+)",content)
                        date = search.group(1)
                    else:
                        search = re.search("(\d+)",content)
                        date = search.group(1)
                    aOpt.Date = date
                    search = re.search("[a-zA-z]+\d+([a-zA-Z])",content)
                    aOpt.Type = search.group(1)
                elif num == 2:
                    if(td.next_element == "N/A"):
                        aOpt.Last = td.next_element
                    else:
                        a = td.find("b")
                        aOpt.Last = a.next_element
                elif num == 3:
                    b = td.find("b")
                    aOpt.Change = " " + b.next_element
                elif num == 4:
                    aOpt.Bid = td.next_element
                elif num == 5:
                    aOpt.Ask = td.next_element
                elif num == 6:
                    aOpt.Vol = td.next_element
                elif num == 7:
                    aOpt.Open = td.next_element

                if num == 7:
                    optList.append(aOpt)
            num +=1

    optList.sort(comparator)
    optDictList = []
    for opt in optList:
        dict = {}
        dict["Ask"] = opt.Ask
        dict["Bid"] = opt.Bid
        dict["Change"] = opt.Change
        dict["Date"] = opt.Date
        dict["Last"] = opt.Last
        dict["Open"] = opt.Open
        dict["Strike"] = opt.Strike
        dict["Symbol"] = opt.Symbol
        dict["Type"] = opt.Type
        dict["Vol"] = opt.Vol
        optDictList.append(dict)

    overDict["optionQuotes"] = optDictList
    jsonObjFinal = json.dumps(overDict,sort_keys=True,indent = 4)

    # jsonQuoteData = "[]"
    # return jsonQuoteData
    return jsonObjFinal

def comparator(x, y):
    openX = int(x.Open.replace(",",""))
    openY = int(y.Open.replace(",",""))
    return openY - openX

class optQ:

    def __init__(self):
        self.Ask = ""
        self.Bid = ""
        self.Change = ""
        self.Date = ""
        self.Last = ""
        self.Open = ""
        self.Strike = ""
        self.Symbol = ""
        self.Type = ""
        self.Vol = ""

    def toJson(self):
        return "Ask = " + self.Ask


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Deal with polynomials.
Comming soon:
    init by interpolation formula;
    Bernoulli summation algorithm - p.sum()
"""

__author__ = 'Clarence Zhuo'

class Poly(object):
    """
    Doctest:

    >>> Poly(0)
    0
    >>> Poly()
    x
    >>> Poly(1,2,3)
    x^2 + 2x + 3
    >>> Poly(1,-1,-1)
    x^2 - x - 1
    >>> Poly(1,-4,-10)
    x^2 - 4x - 10
    >>> Poly(-1,-4,-10)
    -x^2 - 4x - 10
    >>> Poly(-1,-4,0)
    -x^2 - 4x
    >>> Poly(-1,0,-90)
    -x^2 - 90
    >>> Poly(lambda i: -i*i, 3)
    -9x^3 - 4x^2 - x

    >>> p = Poly(1,-2,3)
    >>> q = Poly(9,0,-1,3)
    >>> p+q
    9x^3 + x^2 - 3x + 6
    >>> p-q
    -9x^3 + x^2 - x

    >>> p = Poly(1,1)
    >>> p**2
    x^2 + 2x + 1
    >>> p
    x + 1
    >>> q = Poly(1,-1)
    >>> p*q
    x^2 - 1

    >>> p = Poly(1,-3,2)
    >>> p(5)
    12
    >>> p
    x^2 - 3x + 2
    >>> p(2)
    0
    >>> Poly(-1, 0, -2, 1).diff()
    -3x^2 - 2
    """
    def __init__(self, *args, sym='x', reverse=True):
        """
        Poly() -> polynomial x
        Poly(Poly p) -> a copy of p
        Poly(Iterable) -> init from Iterable
        Poly(callable f, n) -> f(n) x^n + ... + f(1) x + f(0)
        Poly(an, ..., a1, a0) -> an x^n + ... + a1 x + a0
        """
        from collections import Iterable
        self._sym = sym

        argc = len(args)
        if argc == 0:
            self._coef = [0, 1] # polynomial x
        elif argc == 1 and isinstance(args[0], Poly):
            self._coef = list(args[0]._coef)
        elif argc == 1 and isinstance(args[0], Iterable):
            self._coef = list(args[0])
        elif argc == 2 and callable(args[0]):
            if not isinstance(args[1], int) or args[1] < 0:
                raise TypeError('The 2nd argument (degree) '
                                'must be a non-negative int.')
            self._coef = [args[0](i) for i in range(args[1]+1)]
        else:
            if reverse:
                self._coef = list(reversed(args))
            else:
                self._coef = list(args)

        # invariant: len(self._coef) >= 1

        self.rmzero()

    # specials-------------------------------------------------

    def __getitem__(self, key):
        """
        Returns Cn, the coefficient of item x^n.
        """
        if not isinstance(key, int):
            raise TypeError('Key must be an int.')
        elif key < -len(self._coef):
            raise IndexError('Index out of range.')
        elif key > len(self._coef)-1:
            return 0 # higher degree coefficient == 0
        else:
            return self._coef[key]

    def __setitem__(self, key, value):
        if not isinstance(key, int):
            raise TypeError('Key must be an int.')
        elif key < -len(self._coef):
            raise IndexError('Index out of range.')

        while key > self.deg():
            self._coef.append(0)
        self._coef[key] = value

    def __str__(self):

        n = len(self._coef)-1
        ret = ''

        # reversed iteration
        for k in range(n, -1, -1):

            # ignore those with coef == 0
            # except for zero polynomial
            if self[k] == 0 and n != 0:
                continue

            # 'sign'
            # process highest degree item specially
            # self[k] is the kth degree coefficient
            if k == n:
                sign = '-' if self[k] < 0 else ''
            else:
                sign = ' - ' if self[k] < 0 else ' + '

            # 'coefficient'
            abs_coef = abs(self[k])
            if abs_coef == 1 and k != 0:
                coef = ''
            else:
                coef = str(abs_coef)

            # 'symbol and its exponent'
            if k == 0:
                expo = ''
            elif k == 1:
                expo = self._sym
            else:
                expo = self._sym + '^' + str(k)

            ret += sign + coef + expo

        return ret

    __repr__ = __str__

    def __call__(self, v):
        """
        Poly(v) -> result

        Assign a value to polynomial, using Horner's rule.
        """
        ret = self[-1]
        for c in self._coef[-2::-1]:
            ret = ret * v + c
        return ret

    def __eq__(self, other):
        try:
            other = Poly(other)
        except Exception:
            return False
        # list will compare lexicographically
        return self._coef == other._coef

    def __ne__(self, other):
        return not self == other

    def __pos__(self):
        return self

    def __neg__(self):
        return Poly(-c for c in self._coef)

    def __add__(self, other):
        return _do_operation(self, other, '+')

    def __radd__(self, other):
        return _do_operation(other, self, '+')

    def __sub__(self, other):
        return _do_operation(self, other, '-')

    def __rsub__(self, other):
        return _do_operation(other, self, '-')

    def __mul__(self, other):
        return _do_operation(self, other, '*')

    def __rmul__(self, other):
        return _do_operation(other, self, '*')

    def __divmod__(self, other):
        return _do_operation(self, other, '/%')

    def __floordiv__(self, other):
        return _do_operation(self, other, '//')

    def __mod__(self, other):
        return _do_operation(self, other, '%')

    def __pow__(self, other):
        if not isinstance(other, int) or other < 0:
            raise TypeError('arg2 for __pow__() must be '
                            'non-negative integer!')
        ret = Poly(1)
        for i in range(other):
            ret *= self
        return ret

    # other methods--------------------------------------------

    def deg(self):
        """
        Poly.deg() -> non-negative int

        Returns the degree of self. Degree of zero is -1.
        """
        if self.iszero():
            return -1
        else:
            return len(self._coef)-1

    def sym(self, c=None):
        """
        Poly.sym() -> str
        Poly.sym(c) -> None

        Reset the variable name for self.
        """
        if c == None:
            return self._sym
        self._sym = c

    def iszero(self):
        """Returns True iff self == zero polynomial."""
        return len(self._coef) == 1 and self[0] == 0

    def rmzero(self):
        """Remove extra zeros."""
        while len(self._coef) > 1 and self._coef[-1] == 0:
            self._coef.pop()

    def diff(self):
        """Derivate of polynomial."""
        if len(self._coef) == 1:
            return Poly(0)
        return Poly(self[i] * i for i in range(1, len(self._coef)))

# class ends---------------------------------------------------

def _do_operation(lhs, rhs, method):
    """helper function for method __add__, __radd__, __sub__ and so on"""
    try:
        if not isinstance(lhs, Poly):
            lhs = Poly(lhs)
        if not isinstance(rhs, Poly):
            rhs = Poly(rhs)
    except Exception:
        return NotImplemented

    if method == '+' or method == '-':
        if method == '+':
            func = lambda x,y: x+y
        else:
            func = lambda x,y: x-y
        length = max(len(lhs._coef), len(rhs._coef))
        return Poly(func(lhs[i], rhs[i]) for i in range(length))

    elif method == '*':
        if lhs.iszero() or rhs.iszero():
            return Poly(0)
        # 0 <= i < len(lhs._coef)
        # 0 <= j-i < len(rhs._coef) <---> j-len(rhs._coef) < i <= j
        # hence max(0, j-len(rhs)+1) <= i < min(j+1, len(lhs._coef))
        lenl, lenr = len(lhs._coef), len(rhs._coef)
        return Poly(sum(lhs[i] * rhs[j-i] for i in range(max(0, j-lenr+1),\
                min(j+1, lenl))) for j in range(lenl+lenr) )

    elif method == '/%':
        pass
    elif method == '//':
        pass
    elif method == '%':
        pass
    else:
        return NotImplemented

if __name__ == '__main__':
    import doctest
    doctest.testmod()


from __future__ import print_function
import argparse
import torch
import torch.utils.data
from torch import nn, optim
from torch.autograd import Variable
from torch.nn import functional as F
from torchvision import datasets, transforms
from torchvision.utils import save_image

import numpy as np

# parser = argparse.ArgumentParser(description='VAE MNIST Example')
# parser.add_argument('--batch-size', type=int, default=128, metavar='N',
#                     help='input batch size for training (default: 128)')
# parser.add_argument('--epochs', type=int, default=10, metavar='N',
#                     help='number of epochs to train (default: 10)')
# parser.add_argument('--no-cuda', action='store_true', default=False,
#                     help='enables CUDA training')
# parser.add_argument('--seed', type=int, default=1, metavar='S',
#                     help='random seed (default: 1)')
# parser.add_argument('--log-interval', type=int, default=10, metavar='N',
#                     help='how many batches to wait before logging training status')
# args = parser.parse_args()
# args.cuda = not args.no_cuda and torch.cuda.is_available()

# torch.manual_seed(args.seed)
# if args.cuda:
#     torch.cuda.manual_seed(args.seed)

# kwargs = {'num_workers': 1, 'pin_memory': False}
# train_loader = torch.utils.data.DataLoader(
#     datasets.MNIST('../data', train=True, download=True,
#                    transform=transforms.ToTensor()),
#     batch_size=32, shuffle=True, **kwargs)
# test_loader = torch.utils.data.DataLoader(
#     datasets.MNIST('../data', train=False, transform=transforms.ToTensor()),
#     batch_size=32, shuffle=True, **kwargs)

class VAE(nn.Module):
    def __init__(self, input_size, hidden_size=None, latent_variable_size=5,
                    log_interval=2, batch_size=32, epochs=3):
        super(VAE, self).__init__()

        self.input_size = input_size
        if hidden_size is None: self.hidden_size = (input_size + latent_variable_size) / 2
        else: self.hidden_size = hidden_size
        self.latent_variable_size = latent_variable_size

        self.log_interval = log_interval
        self.batch_size = batch_size
        self.epochs = epochs

        # self.fc1 = nn.Linear(784, 400)
        # self.fc21 = nn.Linear(400, 20)
        # self.fc22 = nn.Linear(400, 20)
        # self.fc3 = nn.Linear(20, 400)
        # self.fc4 = nn.Linear(400, 784)
        self.fc1 = nn.Linear(self.input_size, self.hidden_size)
        self.fc21 = nn.Linear(self.hidden_size, self.latent_variable_size)
        self.fc22 = nn.Linear(self.hidden_size, self.latent_variable_size)
        self.fc3 = nn.Linear(self.latent_variable_size, self.hidden_size)
        self.fc4 = nn.Linear(self.hidden_size, self.input_size)

        self.relu = nn.ReLU()
        self.tanh = nn.Tanh()
        self.sigmoid = nn.Sigmoid()

        self.optimizer = optim.Adam(self.parameters(), lr=1e-3)

        self.avg_loss_history = []

    def encode(self, x):
        h1 = self.relu(self.fc1(x))
        return self.fc21(h1), self.fc22(h1)

    def reparameterize(self, mu, logvar):
        if self.training:
            std = logvar.mul(0.5).exp_()
            eps = Variable(std.data.new(std.size()).normal_())
            return eps.mul(std).add_(mu)
        else:
            return mu

    def decode(self, z):
        h3 = self.relu(self.fc3(z))
        # return self.sigmoid(self.fc4(h3))
        return self.fc4(h3) # linear ouput for predicting dynamical data

    def forward(self, x):
        mu, logvar = self.encode(x.view(-1, self.input_size))
        z = self.reparameterize(mu, logvar)
        return self.decode(z), mu, logvar

    # Reconstruction + KL divergence losses summed over all elements and batch
    def loss_function(self, recon_x, x, mu, logvar):
        # BCE = F.binary_cross_entropy(recon_x, x.view(-1, self.input_size), size_average=False)
        BCE = F.mse_loss(recon_x, x.view(-1, self.input_size), size_average=False)

        # see Appendix B from VAE paper:
        # Kingma and Welling. Auto-Encoding Variational Bayes. ICLR, 2014
        # https://arxiv.org/abs/1312.6114
        # 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
        KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

        return BCE + KLD

    def train_one_epoch(self, epoch_idx, train_data, verbose=False):
        self.train()
        train_loss = 0
        # for batch_idx, data in enumerate(train_data):
        for batch_idx in range(0, len(train_data), self.batch_size):
            # data = Variable(data)
            data = Variable(train_data[batch_idx:(batch_idx+self.batch_size)])
            # if args.cuda:
            #     data = data.cuda()
            self.optimizer.zero_grad()
            recon_batch, mu, logvar = self(data)
            loss = self.loss_function(recon_batch, data, mu, logvar)
            loss.backward()
            train_loss += loss.data[0]
            self.optimizer.step()
            if batch_idx % self.log_interval == 0 and verbose:
                print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                    epoch_idx, batch_idx * len(data), len(train_data), #len(self.train_data.dataset),
                    100. * batch_idx / len(train_data),
                    loss.data[0] / len(data)))

        # print('====> Epoch: {} Average loss: {:.8f}'.format(
        #     epoch_idx, train_loss / len(train_data)))
            # epoch, train_loss / len(self.train_data.dataset)))
        self.avg_loss_history.append(train_loss / len(train_data))

    def test(self, epoch_idx, test_data):
        self.eval()
        test_loss = 0
        for i, data in enumerate(test_data):
            data = Variable(data, volatile=True)
            recon_batch, mu, logvar = self(data)
            test_loss += self.loss_function(recon_batch, data, mu, logvar).data[0]
            # if i == 0:
            #     n = min(data.size(0), 8)
            #     comparison = torch.cat([data[:n],
            #                         recon_batch.view(self.batch_size, 1, 28, 28)[:n]])
            #     save_image(comparison.data,
            #             'results/reconstruction_' + str(epoch_idx) + '.png', nrow=n)

        # test_loss /= len(self.test_data.dataset)
        test_loss /= len(test_data)
        # print('====> {} Test set loss: {:.4f}'.format(epoch_idx, test_loss))

    def train_full(self, train_data, test_data=None, verbose=False):
        # normalise the data before putting it into the ENCODER
        # _mean = train_data.mean()
        # _std = train_data.std()
        # train_data -= _mean
        # train_data /= _std.mean()
        # _std = train_data.std()
        # train_data -= _mean
        # train_data /= _std

        for epoch in range(1, self.epochs + 1):
            train_shuff = train_data[torch.randperm(train_data.shape[0]), :]
            # print(train_data[:5, :5])
            # print(train_shuff[:5, :5])

            self.train_one_epoch(epoch, train_shuff)
            if test_data is not None:
                self.test(epoch, test_data)
            self.sample()

    def sample(self):
        # print(torch.sort(torch.randn(200, self.latent_variable_size), dim=0))
        sample = Variable(torch.sort(torch.randn(200, self.latent_variable_size), dim=0)[0])
        sample = self.decode(sample)
        # print(sample)
        # print(sample.size())
        # save_image(sample.data.view(64, 1, 15, 20)*255,
        #         'sample_' + str(epoch) + '.png')
        return sample.data.numpy()

# model = VAE()
# if args.cuda:
#     model.cuda()
# optimizer = optim.Adam(model.parameters(), lr=1e-3)
# Reconstruction + KL divergence losses summed over all elements and batch
# def loss_function(recon_x, x, mu, logvar):
#     BCE = F.binary_cross_entropy(recon_x, x.view(-1, 784), size_average=False)

#     # see Appendix B from VAE paper:
#     # Kingma and Welling. Auto-Encoding Variational Bayes. ICLR, 2014
#     # https://arxiv.org/abs/1312.6114
#     # 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
#     KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

#     return BCE + KLD

# # Reconstruction + KL divergence losses summed over all elements and batch
# def loss_function(recon_x, x, mu, logvar):
#     BCE = F.binary_cross_entropy(recon_x, x.view(-1, 784), size_average=False)

#     # see Appendix B from VAE paper:
#     # Kingma and Welling. Auto-Encoding Variational Bayes. ICLR, 2014
#     # https://arxiv.org/abs/1312.6114
#     # 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
#     KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

#     return BCE + KLD

# def train(epoch, model, optimiser):
#     model.train()
#     train_loss = 0
#     for batch_idx, (data, _) in enumerate(train_loader):
#         data = Variable(data)
#         # if args.cuda:
#         #     data = data.cuda()
#         optimizer.zero_grad()
#         recon_batch, mu, logvar = model(data)
#         loss = loss_function(recon_batch, data, mu, logvar)
#         loss.backward()
#         train_loss += loss.data[0]
#         optimizer.step()
#         if batch_idx % model.log_interval == 0:
#             print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
#                 epoch, batch_idx * len(data), len(train_loader.dataset),
#                 100. * batch_idx / len(train_loader),
#                 loss.data[0] / len(data)))

#     print('====> Epoch: {} Average loss: {:.4f}'.format(
#           epoch, train_loss / len(train_loader.dataset)))

# def test(epoch, model):
#     model.eval()
#     test_loss = 0
#     for i, (data, _) in enumerate(test_loader):
#         data = Variable(data, volatile=True)
#         recon_batch, mu, logvar = model(data)
#         test_loss += loss_function(recon_batch, data, mu, logvar).data[0]
#         if i == 0:
#             n = min(data.size(0), 8)
#             comparison = torch.cat([data[:n],
#                                   recon_batch.view(model.batch_size, 1, 28, 28)[:n]])
#             save_image(comparison.data,
#                      'results/reconstruction_' + str(epoch) + '.png', nrow=n)

#     test_loss /= len(test_loader.dataset)
#     print('====> Test set loss: {:.4f}'.format(test_loss))

# model = VAE(784)
# model.train_full()
# optimizer = optim.Adam(model.parameters(), lr=1e-3)

# for epoch in range(1, model.epochs + 1):
#     train(epoch, model, optimizer)
#     test(epoch, model)
#     sample = Variable(torch.randn(64, 20))
#     sample = model.decode(sample)
#     save_image(sample.data.view(64, 1, 28, 28),
#                'results/sample_' + str(epoch) + '.png')


# -*- coding: utf-8 -*-
"""
Created on Sat Jan  6 15:47:40 2018

@author: mohammed-PC
"""
import cv2
import numpy as np
from matplotlib import pyplot as plt
from keras.models import load_model

#Input : RGB Image(Element of the Returned values of the dataSplit method)
#Return: String formatted Number
def getIDNumber(image_slice):
    classifier = load_model('ar_numbers_v2.h5')
    classifier.compile(loss= 'categorical_crossentropy', optimizer='adam')
    im = image_slice
    im = cv2.resize(im , (1742, 241))
    view =im
    color = im
    im = cv2.fastNlMeansDenoisingColored(im,None,10,10,7,21)
    im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(im, (55, 55), 2)
    '''low = np.array([0])
    upper = np.array([70])
    blurred = cv2.inRange(blurred ,low , upper )
    plt.imshow(blurred)'''
    im = cv2.adaptiveThreshold(blurred,100,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,39,5)
    hist,bins = np.histogram(im.flatten(),256,[0,256])
    cdf = hist.cumsum()
    cdf_normalized = cdf * hist.max()/ cdf.max()
    plt.hist(im.flatten(),256,[0,256], color = 'r')
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
    cl1 = clahe.apply(im)
    #cl1 = cv2.bitwise_not(cl1)
    low = np.array([0])
    upper = np.array([70])
    cl1 = cv2.inRange(cl1 ,low , upper )
    '''
    cv2.imshow("image",cl1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()'''

    image, contours, hierarchy = cv2.findContours(cl1,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    print (len(contours))

    space = 0
    lst = []

    for i in range(0,len(contours)):
        newview = view
        arr = [x,y,w,h] = cv2.boundingRect(contours[i])
        lst.append(arr)

    lst.sort()
    id_no = []
    for i in range(0,len(contours)) :
        y0 = lst[i][1] - space
        x0 = lst[i][0] - space
        yf0 = (lst[i][1] + lst[i][3] + space)
        xf0 = (lst[i][0] + lst[i][2] + space)
        slice_img = newview [y0:yf0 , x0:xf0 ]
        slice_img = cv2.resize(slice_img, (30, 30))
        slice_img = cv2.cvtColor(slice_img, cv2.COLOR_BGR2GRAY)
        (thresh, slice_img) = cv2.threshold(slice_img, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
        slice_img = cv2.cvtColor(slice_img,cv2.COLOR_GRAY2RGB)
        imresize = cv2.resize(slice_img, (32 , 32))
        imlist = np.array([imresize])
        classes =classifier.predict_classes(imlist)
        id_no.append(classes[0])

    plt.imshow(view)
    #print("ID:")
    final_no = str(id_no[0])+str(id_no[1])+str(id_no[2]) \
            +str(id_no[3])+str(id_no[4])+str(id_no[5]) \
            +str(id_no[6])+str(id_no[7])+str(id_no[8]) \
            +str(id_no[9])+str(id_no[10])+str(id_no[11]) \
            +str(id_no[12])+str(id_no[13])
    '''print(str(id_no[0])+str(id_no[1])+str(id_no[2])
            +str(id_no[3])+str(id_no[4])+str(id_no[5])
            +str(id_no[6])+str(id_no[7])+str(id_no[8])
            +str(id_no[9])+str(id_no[10])+str(id_no[11])
            +str(id_no[12])+str(id_no[13]))'''
    final_no_lst = id_no[1:7]
    return final_no , final_no_lst


from selenium import webdriver
from selenium.webdriver.common.by import By
from web_test_base import WebTestBase

class TestHomePage(WebTestBase):

    def test_button(self):
        driver = self.driver
        driver.get(self.WEBSITE_URL)

        # Attempts to navigate to content page with button
        masthead = driver.find_element(By.ID, "masthead")
        masthead_button = masthead.find_element(By.XPATH, "//a[@href='content.html']")
        masthead_button.click()

        # Asserts if the wrapper of content page is found
        self.assertIn("contentWrapper", driver.page_source)

    def test_masthead(self):
        driver = self.driver
        driver.get(self.WEBSITE_URL)

        # Finds the tags for masthead
        masthead = driver.find_element(By.ID, "masthead")
        masthead_h1 = masthead.find_element(By.TAG_NAME, "h1")
        masthead_h2 = masthead.find_element(By.TAG_NAME, "h2")

        # Asserts if the tags have specific text
        self.assertIn("Välkommen till APIskolan!", masthead_h1.text)
        self.assertIn("En svensk lärplattform för APIer", masthead_h2.text)

    def test_info_links(self):
        driver = self.driver
        driver.get(self.WEBSITE_URL)

        info_section = driver.find_element(By.ID, "info")
        link_elements = info_section.find_elements(By.TAG_NAME, "a")

        # Adds link names to array
        links = []
        for element in link_elements:
            links.append(element.get_attribute("href"))

        # Asserts if links are present in info
        self.assertIn("https://joakim2tusen.github.io/Portfolio/", links)
        self.assertIn("https://klado555.gitlab.io/portfolio/", links)
        self.assertIn("https://github.com/46elks/praktik-apiskolan/", links)


import os
from PIL import Image
from argparse import ArgumentParser

# torch
import torch
from torch import nn
import torch.nn.functional as F
from torch.utils.data import random_split,DataLoader
from torch.optim.lr_scheduler import ReduceLROnPlateau,CosineAnnealingLR,MultiplicativeLR

# lightning
import pytorch_lightning as pl
from pytorch_lightning import Trainer
from pytorch_lightning import loggers as pl_loggers
from pytorch_lightning.loggers import WandbLogger
from pytorch_lightning.callbacks import ModelCheckpoint,LearningRateMonitor

# utils
from .models import get_model
from .datasets import SIDDDataset,SIDDValidDataset
from .metrics import BatchPSNR,BatchSSIM,calc_batch_ssim

# wandb
import wandb

class LitDenoiser(pl.LightningModule):
    def __init__(self,args):
        super().__init__()
        self.model = get_model(args)
        self.psnr = BatchPSNR()
        self.save_hyperparameters()

    @staticmethod
    def add_model_specific_args(parent_parser):
        parser = ArgumentParser(parents=[parent_parser], add_help=False)
        parser.add_argument('--model',type=str,default='selfdncnn')
        parser.add_argument('--num_layers',type=int,default=17)
        parser.add_argument('--num_rrg', type=int, default=4//2)
        parser.add_argument('--num_dab', type=int, default=8//2)
        parser.add_argument('--nfeats', type=int, default=64)
        parser.add_argument('--batch_size', type=int,nargs=3,default=[4,4,16])
        parser.add_argument('--num_workers', type=int,default=4)
        parser.add_argument('--patch_size',type=int,default=80)
        parser.add_argument('--patches_per_image',type=int,default=512) # 512 => 160k training patches, 3200 => 1M training patches
        parser.add_argument('--patches_per_batch',type=int,default=32)
        parser.add_argument('--lr', type=float, default=0.001)
        parser.add_argument('--q', type=int, default=3)
        return parser

    def setup(self,stage):
        self.train_ds = SIDDDataset(
                path=self.hparams.args.data_path,
        		patches_per_batch = self.hparams.args.patches_per_batch,
        		patches_per_image = self.hparams.args.patches_per_image,
        		patch_size = self.hparams.args.patch_size
        	)
        train_len = round(len(self.train_ds)*0.9)
        val_len = len(self.train_ds)-train_len
        torch.manual_seed(27)
        self.train_ds,self.val_ds = random_split(self.train_ds,[train_len,val_len])
       	self.test_ds = SIDDValidDataset(path=self.hparams.args.data_path)
        print("Train:",train_len*self.hparams.args.patches_per_batch)
        print("Val:",val_len*self.hparams.args.patches_per_batch)
        print("Test:",len(self.test_ds))

        self.top_val = -1e9

    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(),lr=self.hparams.args.lr) #,momentum=0.9)
        lmbda = lambda epoch: 1.05
        scheduler = MultiplicativeLR(optimizer, lr_lambda=lmbda)
        return {
            'optimizer': optimizer,
            'lr_scheduler': scheduler
            #'monitor': 'train_loss'
        }

    def train_dataloader(self):
        num_workers = self.hparams.args.num_workers if self.hparams.args.overfit_batches==0 else 0
        return DataLoader(self.train_ds, batch_size=self.hparams.args.batch_size[0],pin_memory=True,num_workers=num_workers,shuffle=True)

    def val_dataloader(self):
        num_workers = self.hparams.args.num_workers if self.hparams.args.overfit_batches==0 else 0
        return DataLoader(self.val_ds, batch_size=self.hparams.args.batch_size[1],pin_memory=True,num_workers=num_workers)

    def test_dataloader(self):
        num_workers = self.hparams.args.num_workers if self.hparams.args.overfit_batches==0 else 0
        return DataLoader(self.test_ds, batch_size=self.hparams.args.batch_size[2],pin_memory=True,num_workers=num_workers)

    def forward(self, x): return self.model(x)

    def training_step(self, batch, batch_idx):
        noisy, clean = batch
        _, _, c, h, w = noisy.size()
        noisy = noisy.view(-1,c,h,w)
        clean = clean.view(-1,c,h,w)
        cleaned = self.model(noisy)
        loss = F.mse_loss(cleaned, clean,reduction='sum')
        return loss

    def training_epoch_end(self,losses):
        loss_epoch = torch.stack([x['loss'] for x in losses]).mean()
        if hasattr(self.logger.experiment,'log'): self.logger.experiment.log({
            'loss':loss_epoch,
            'epoch':self.current_epoch,
            'global_step':self.global_step
        })

    def validation_step(self, batch, batch_idx):
        noisy, clean = batch
        _, _, c, h, w = noisy.size()
        noisy = noisy.view(-1,c,h,w)
        clean = clean.view(-1,c,h,w)
        cleaned = self.model(noisy)
        self.psnr.update(cleaned,clean)

        cleaned_img = cleaned[0,...].permute(1,2,0).detach().cpu().numpy()
        return cleaned_img

    def validation_epoch_end(self, outs):
        # log epoch metric
        val_psnr = self.psnr.compute()
        self.top_val = max(val_psnr,self.top_val)
        self.log('val_psnr',val_psnr,prog_bar=True)
        if hasattr(self.logger.experiment,'log'):
            self.logger.experiment.log({
                'val_psnr':val_psnr,
                'epoch':self.current_epoch,
                'global_step':self.global_step,
                'best_val_psnr':self.top_val,
                #'examples': [wandb.Image(outs[0], caption="Cleaned")]
            })

        self.psnr.reset()

    def test_step(self,batch,batch_idx):
        noisy, clean = batch
        if noisy.dim()>4:
            _, _, c, h, w = noisy.size()
            noisy = noisy.view(-1,c,h,w)
            clean = clean.view(-1,c,h,w)

        cleaned = self.model(noisy)
        self.psnr.update(cleaned,clean)
        return calc_batch_ssim(cleaned,clean)

    def test_epoch_end(self,outs):
        test_psnr = self.psnr.compute()
        self.psnr.reset()
        correct = 0
        total = 0
        for (c,t) in outs: correct+=c; total+=t;
        print(test_psnr,correct/total)


"""Tests for Crossref.licenses"""
import os
import vcr
from habanero import Crossref

cr = Crossref()

@vcr.use_cassette("test/vcr_cassettes/licenses.yaml")
def test_licenses():
    "licenses - basic test"
    res = cr.licenses()
    assert dict == res.__class__
    assert 130 < len(res["message"]["items"])

@vcr.use_cassette("test/vcr_cassettes/licenses_query.yaml")
def test_licenses_query():
    "licenses - param: query - doesn't do anything without works"
    res = cr.licenses(query="aps")
    assert {u"search-terms": u"aps", u"start-index": 0} == res["message"]["query"]


import sys

import numpy as np
from skimage.transform import resize
import scipy
from PIL import ImageQt

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

from Src.CelebA.preserving_gan import *

class DragRegionLabel(QLabel):
    def __init__(self, parent):
        super().__init__(parent)

        self.enb = False
        self.rub = QRubberBand(QRubberBand.Rectangle, self)
        self.pt = QPoint()

        self.x = -1
        self.y = -1
        self.w = 0
        self.h = 0

    def mousePressEvent(self, event):
        if self.enb==True and event.button()==Qt.LeftButton:
            self.pt = QPoint(event.pos())
            self.rub.setGeometry(QRect(self.pt, QSize()))
            self.rub.show()

    def mouseMoveEvent(self, event):
        if self.enb==True and not self.pt.isNull():
            self.rub.setGeometry(QRect(self.pt, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if self.enb==True and event.button()==Qt.LeftButton:
            # (x, y) -> (y, x)
            self.x = self.rub.pos().y()
            self.y = self.rub.pos().x()
            self.h = self.rub.size().height()
            self.w = self.rub.size().width()

            self.enb = False

    def reset(self):
        self.enb = False

        self.rub.hide()

class GUI(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initResources()
        self.initUI()

    def initResources(self):
        self.pixfilenames = []
        self.pixmaps = []
        self.pixidx = 0

        self.selpixs = []
        self.regions = []

        self.drawpix = np.zeros((320, 320, 4), np.uint8)
        self.drawpix[:, :, 3] = 255

    def initUI(self):
        self.staBar = self.statusBar()
        self.staBar.showMessage('PreservingGAN Ready')

        self.impBtn = QPushButton('Import Image', self)
        self.impBtn.resize(120, 40)
        self.impBtn.move(10, 10)
        self.impBtn.clicked.connect(self.pressImpBtn)

        self.drawBtn = QPushButton('Draw', self)
        self.drawBtn.resize(80, 40)
        self.drawBtn.move(310, 10)
        self.drawBtn.clicked.connect(self.pressDrawBtn)

        self.prevBtn = QPushButton('<', self)
        self.prevBtn.resize(20, 20)
        self.prevBtn.move(10, 55)
        self.prevBtn.clicked.connect(self.pressPrevBtn)

        self.regBtn = QPushButton('O', self)
        self.regBtn.resize(20, 20)
        self.regBtn.move(40, 55)
        self.regBtn.clicked.connect(self.pressRegBtn)

        self.cclBtn = QPushButton('X', self)
        self.cclBtn.resize(20, 20)
        self.cclBtn.move(70, 55)
        self.cclBtn.clicked.connect(self.pressCclBtn)

        self.nextBtn = QPushButton('>', self)
        self.nextBtn.resize(20, 20)
        self.nextBtn.move(370, 55)
        self.nextBtn.clicked.connect(self.pressNextBtn)

        self.genBtn = QPushButton('Generate', self)
        self.genBtn.resize(100, 40)
        self.genBtn.move(680, 10)
        self.genBtn.clicked.connect(self.pressGenBtn)

        self.imgLbl = DragRegionLabel(self)
        self.imgLbl.resize(320, 320)
        self.imgLbl.move(40, 90)

        self.drawLbl = QLabel(self)
        self.drawLbl.resize(320, 320)
        self.drawLbl.move(440, 90)

        self.genpixs = []
        for i in range(9):
            self.genpixs.append(QLabel(self))
            self.genpixs[i].resize(120, 120)
            self.genpixs[i].move(800+(i//3)*120+(i//3)*10, 25+(i%3)*120+(i%3)*10)

        self.move(25, 25)
        self.setFixedSize(1200, 450)
        self.setWindowTitle('PreservingGAN - CelebA')

        self.show()

    def pressImpBtn(self):
        filename = QFileDialog.getOpenFileName()[0]
        if filename=='':
            return

        pix = QPixmap(filename)
        if pix.isNull()==True:
            return

        pix = pix.scaled(self.imgLbl.size())
        self.imgLbl.setPixmap(pix)

        self.pixfilenames.append(filename)
        self.pixmaps.append(pix)
        self.pixidx = len(self.pixmaps)-1

        self.imgLbl.reset()

    def pixmap2numpy(self, pix): # BGR->RGB
        w, h = 320, 320

        img = pix.toImage()
        s = img.bits().asstring(w*h*4)
        dat = np.fromstring(s, dtype=np.uint8).reshape((w, h, 4))
        dat = np.concatenate((dat[:, :, 2:3], dat[:, :, 1:2], dat[:, :, 0:1], dat[:, :, 3:4]), axis=2)

        return dat

    def numpy2pixmap(self, dat):
        pix = QPixmap.fromImage(ImageQt.ImageQt(scipy.misc.toimage(dat)))
        return pix

    def drawReg(self, dat, box):
        x, y, h, w = box

        for i in range(max(x, 0), min(x+h, 320)):
            for j in range(max(y, 0), min(y+w, 320)):
                self.drawpix[i, j, :] = dat[i, j, :]

    def pressDrawBtn(self):

        self.selpixs.append(self.pixmaps[self.pixidx])
        self.regions.append((self.imgLbl.x, self.imgLbl.y, self.imgLbl.h, self.imgLbl.w))

        dat = self.pixmap2numpy(self.pixmaps[self.pixidx])
        self.drawReg(dat, (self.imgLbl.x, self.imgLbl.y, self.imgLbl.h, self.imgLbl.w))
        pix = self.numpy2pixmap(self.drawpix)

        self.drawLbl.setPixmap(pix)

        self.imgLbl.reset()

    def pressPrevBtn(self):
        self.pixidx = (self.pixidx-1+len(self.pixmaps))%len(self.pixmaps)
        self.imgLbl.setPixmap(self.pixmaps[self.pixidx])

        self.imgLbl.reset()

    def pressNextBtn(self):
        self.pixidx = (self.pixidx+1+len(self.pixmaps))%len(self.pixmaps)
        self.imgLbl.setPixmap(self.pixmaps[self.pixidx])

        self.imgLbl.reset()

    def pressGenBtn(self):
        self.staBar.showMessage('Press Generation Button')

        img_cont = cv2.resize(self.drawpix, (64, 64))
        mask_pix = np.zeros((320, 320), np.float32)

        for reg in self.regions:
            x, y, h, w = reg

            for i in range(x, x+h):
                for j in range(y, y+w):
                    mask_pix[i][j] = 1

        mask_pix = cv2.resize(mask_pix, (64, 64))
        mask_lat = cv2.resize(mask_pix, (8, 8))

        out = produce(img_cont[:, :, :3], mask_pix, mask_lat)

        for i in range(9):
            dat = out[i]*255
            dat = dat.astype(np.uint8)
            tmp = np.ones((64, 64, 4), np.uint8)*255
            for x in range(64):
                for y in range(64):
                    tmp[x, y, :3] = dat[x][y]
            dat = tmp
            pix = self.numpy2pixmap(dat).scaled(120, 120)

            self.genpixs[i].setPixmap(pix)

    def pressRegBtn(self):
        self.imgLbl.reset()

        self.imgLbl.enb = True

    def pressCclBtn(self):
        self.imgLbl.reset()

if __name__=='__main__':
    app = QApplication(sys.argv)
    gui = GUI()

    sys.exit(app.exec_())


"""
Author: Sam McGrath
Class: CS 450
Instructor: Br. Burton
"""
import numpy as np
import pandas as pd
from scipy import stats

def get_iris():
    headers = [
        'sepal length',
        'sepal width',
        'petal length',
        'petal width',
        'class'
    ]

    classObj = {
        'Iris-setosa': 1,
        'Iris-versicolor': 2,
        'Iris-virginica': 3
    }

    df = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data",
                    header=None, names=headers)

    df.replace(classObj, inplace=True)

    return stats.zscore(df.as_matrix(columns=headers[:-1])), \
            df.as_matrix(columns=headers[-1:]), \
            ["Iris-setosa", "Iris-versicolor", "Iris-virginica"]


# -*- coding: utf-8 -*-
# /***************************************************************************/
# * __________________________________
# * METIS CYBERSPACE TECHNOLOGY S.A.
# * www.metis.tech
# * __________________________________
# * [2019] All Rights Reserved.
# *
# * NOTICE:  All information contained herein is, and remains
# * the property of Metis CyberSpace Technology and its suppliers,
# * if any.  The intellectual and technical concepts contained
# * herein are proprietary to METIS CYBERSPACE TECHNOLOGY
# * and its suppliers and may be covered by European and Foreign Patents,
# * patents in process, and are protected by trade secret or copyright law.
# * Dissemination of this information or reproduction of this material
# * is strictly forbidden unless prior written permission is obtained
# * from Metis Cyberspace Technology.
#
# /***************************************************************************/
#
# Created Date: Friday April 5th 2019
# Author: Vassilis Lemonidis
"""Module that holds class that fixes document orientation
"""

import cv2
import numpy as np
from ImageProcessing import IMPROC_CONFIG
from ImageProcessing import DEBUG_CONFIG
import ImageProcessing.Debugging.operations as dbg
from ImageProcessing.GeometricalTransformations.operations import rotate
from Model.BasicObjects import GrayscaleGraphic

class RotationCanceller:
    '''
    Fixes given image rotation
    '''

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.min_angle = IMPROC_CONFIG['min_accepted_angle']

    def run(self, struct):  # @IgnorePep8 pylint: disable=unused-argument
        '''
        Rotates image based on each contents orientation
        '''
        _, contours, _ = cv2.findContours(struct.binary.any.astype(np.uint8),
                                          cv2.RETR_EXTERNAL,
                                          cv2.CHAIN_APPROX_SIMPLE)
        if not contours:
            return struct.img, 0
        massive_contour = np.array([point for contour in contours for
                                    point in contour])
        hull = cv2.convexHull(massive_contour)
        rect = cv2.minAreaRect(
            hull)
        (p_x, p_y), _, angle = rect
        if DEBUG_CONFIG.visualize_rotation_canceller:
            img = np.zeros_like(struct.binary.any).astype(np.uint8)
            cv2.drawContours(img, [hull], 0, 1, 3)

            box = cv2.boxPoints(rect)
            box = np.int0(box)
            box_img = np.zeros_like(struct.binary.any).astype(np.uint8)
            cv2.drawContours(box_img, [box],0, 1 , 3)
            dbg.imshow(np.concatenate((struct.binary.any.astype(np.uint8)[:, :, None],
                                       img[:, :, None],
                                       box_img[:, :, None]), axis=2),
                                       'Image with convex hull used to cancel rotation')

        if angle < -45:
            angle = 90 + angle
        elif angle > 45:
            angle = angle - 90
        if abs(angle) < self.min_angle:
            return struct.img, 0
        return GrayscaleGraphic(rotate(struct.binary.all, angle, (p_x, p_y))), angle


import numpy as np
import gym
import os

enviroment = 'CartPole-v1'
env = gym.make(enviroment)
Q = np.zeros((1, 1))
states = []

for i_episode in range(200):
    observation = env.reset()
    reward = 0
    done = False
    steps = 0
    while not done:
        env.render()
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)

        if not any((observation == x).all() for x in states):
            states.append(observation)

        os.system('clear')
        print(f'Reward: {reward}')
        print(f'Episode: {i_episode}')
        print(f'Done: {done}')
        print(f'Steps: {steps}')
        steps += 1

print(f"Number of states: {len(states)}")
print()

env.close()


"""alphastoka URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from mgmt import views
from datetime import datetime
from django.template.defaulttags import register

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^mgmt/create', views.mgmt_create),
    url(r'^mgmt/murder/([^\s]+)', views.mgmt_murder),
    url(r'^mgmt/jail/([^\s]+)', views.mgmt_jail),
    url(r'^mgmt/release/([^\s]+)', views.mgmt_release),
    url(r'^results/export', views.results_export),
    url(r'^results', views.results),
    url(r'^categorization', views.categorization),
    url(r'^processors', views.processors),
    # default first view
    url(r'^$', views.index)
]

@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

@register.filter
def add_int(v, b):
    return int(v) + int(b)

@register.filter
def unixtime(intTime):
    that = datetime.fromtimestamp(int(intTime))
    total_time=(datetime.now() - that)

    return str(total_time).split(".")[0]


from nsepy import get_history
from datetime import date, timedelta
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import nsepy
from matplotlib import style
style.use('fivethirtyeight')

#TICKER NAME
ticker = "SBIN"
#TIME PERIOD, 15 days in this case
end_day = date.today()
start_day = end_day - timedelta(200)

#Fetch ticker data from nsepy
df = get_history(symbol=ticker, start=start_day, end=end_day)
data=df[['Open', 'High', 'Low', 'Close', 'Volume']]
data['15d']= np.round(data['Close'].rolling(window=15).mean(),2)
data['40d']= np.round(data['Close'].rolling(window=40).mean(),2)

data[['Close','15d','40d']].plot(grid=True, figsize=(30,30))
# plt.show()

data['15d-40d']=data['15d']-data['40d']
x=30
data['Stance']=np.where(data['15d-40d']>x,1,0)
data['Stance']=np.where(data['15d-40d']<x,-1,data['Stance'])
# print(data['Stance'].value_counts())
data['Stance'].value_counts()
data['Stance'].plot(lw=2,ylim=[-1.1,1.1])
plt.show()

data['Stock_Returns']=np.log(data['Close']/data['Close'].shift(1))
data['SMAC_Strategy']=data['Stock_Returns']*data['Stance'].shift(1)
data[['Stock_Returns','SMAC_Strategy']].plot(grid=True,figsize=(10,6))
plt.show()

# check for SettingWithCopyWarning. https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy


from flask import Flask, request, abort, jsonify
from linebot import (LineBotApi, WebhookHandler)
from linebot.exceptions import (InvalidSignatureError)
from linebot.models import (MessageEvent, TextMessage, TextSendMessage,)
from flask.logging import create_logger
import requests
import json
import datetime, pytz
tz = pytz.timezone('Asia/Bangkok')

app = Flask(__name__)
LOG = create_logger(app)

line_bot_api = LineBotApi('THIS IS A SECRET')
handler = WebhookHandler('THIS IS A SECRET')

@app.route("/")
def hello():
    return "Hello World"

def date_now():
    now1 = datetime.datetime.now(tz)
    month_name = 'x มกราคม กุมภาพันธ์ มีนาคม เมษายน พฤษภาคม มิถุนายน กรกฎาคม สิงหาคม กันยายน ตุลาคม พฤศจิกายน ธันวาคม'.split()[now1.month]
    thai_year = now1.year + 543
    time_str = now1.strftime('%H:%M:%S')
    return "%d %s %d %s"%(now1.day, month_name, thai_year, time_str) # 30 ตุลาคม 2560 20:45:30

# for test
@app.route("/test")
def test():
    r = requests.get(
      'https://bx.in.th/api/')
    data = r.json()
    command = "acn"
    today = date_now()
    message = "ข้อมูลปัจจุบัน ณ เวลา " + today + "\n"
    if command == "tcn":
        filterData = [v for v in data.values() if "THB" in v.values()]
        for value in sorted(filterData, key = lambda name: name['pairing_id']):
            message += str(value['pairing_id']) + ": " + value['primary_currency'] + " to " + value['secondary_currency'] + " = " + str(value['last_price']) + "\n"
    elif command == "acn":
        for value in sorted(data.values(), key = lambda name: name['pairing_id']):
            message += str(value['pairing_id']) + ": " + value['primary_currency'] + " to " + value['secondary_currency'] + " = " + str(value['last_price']) + "\n"
    # for key, value in sort_data:
    # return jsonify(r.json())
    print(message)
    return "ok"

@app.route("/webhook", methods=['POST'])
def webhook():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    LOG.debug("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    r = requests.get(
      'https://bx.in.th/api/')
    data = r.json()
    command = event.message.text
    today = date_now()
    message = "ข้อมูลปัจจุบัน ณ เวลา " + today + "\n"
    if command == "tcn":
        filterData = [v for v in data.values() if "THB" in v.values()]
        for value in sorted(filterData, key = lambda name: name['pairing_id']):
            message += str(value['pairing_id']) + ": " + value['primary_currency'] + " to " + value['secondary_currency'] + " = " + str(value['last_price']) + "\n"
    elif command == "acn":
        for value in sorted(data.values(), key = lambda name: name['pairing_id']):
            message += str(value['pairing_id']) + ": " + value['primary_currency'] + " to " + value['secondary_currency'] + " = " + str(value['last_price']) + "\n"
    elif command == "รักเค้าไหม":
        message = "รักดิมากด้วย <3"
    elif command == "ตอแหลไหม":
        message = "มากที่สุดเหมือนกัน :)"
    else:
        message = "ไม่มีคำสั่งที่คุณพิมพ์มาตอนนี้เรามีแค่\n1.acn (all crypto now)\n2.tcn(thai crypto now)"
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=message))

if __name__ == "__main__":
    app.run()


import numpy as np
import matplotlib.pyplot as plt
import utils

def computeGaussian(value, mean, var):
    """This function is compute log of Gaussian distribution, because original multiply values will become smaller and smaller."""
    return np.log(1.0 / (np.sqrt(2.0 * np.pi * var))) - ((value - mean) ** 2.0 / (2.0 * var))

def checkResult(prediction, answer):
    # prediction = np.argmin(probability)
    # print("Prediction: ", prediction, ", Ans: ", answer)
    if prediction == answer:
        return 0
    else:
        return 1

def normalization(probability, class_num):
    """This function is used to normalize the probability."""
    temp = 0
    for j in range(class_num):
        temp += probability[j]
    for j in range(class_num):
        probability[j] /= temp
    return probability

def train(train_x, train_y, class_num):
    """This function is training stage of naive-bayes classifier."""
    # print("train x shape : {}".format(train_x.shape))
    # print("train y shape : {}".format(train_y.shape))
    prior = np.zeros((class_num), dtype = float)
    train_square = np.zeros((class_num, train_x.shape[1]), dtype = float)
    train_mean = np.zeros((class_num, train_x.shape[1]), dtype = float)
    train_var = np.zeros((class_num, train_x.shape[1]), dtype = float)

    for data_idx in range(train_x.shape[0]):
        label = train_y[data_idx]
        prior[label] += 1
        for feature_idx in range(train_x.shape[1]):
            train_square[label][feature_idx] += (train_x[data_idx][feature_idx] ** 2)
            train_mean[label][feature_idx] += train_x[data_idx][feature_idx]
    #Calculate mean and standard deviation
    for label in range(class_num):
        for feature_idx in range(train_x.shape[1]):
            train_mean[label][feature_idx] = float(train_mean[label][feature_idx] / prior[label])
            train_var[label][feature_idx] = float(train_square[label][feature_idx] / prior[label]) - float(train_mean[label][feature_idx] ** 2)
            # psuedo count for variance
            if train_var[label][feature_idx] == 0:
                train_var[label][feature_idx] = 1e-6
    prior = prior / train_x.shape[0]
    prior = np.log(prior)
    return prior, train_mean, train_var

def test(test_x, test_y, prior, train_mean, train_var, class_num, filename, model_name, testing=False):
    """This function is testing stage of naive-bayes classifier."""
    # print("test_x shape : {}".format(test_x.shape))
    # print("test_y shape : {}".format(test_y.shape))
    error = 0
    predict_list = []
    total_probability = [0 for _ in range(test_x.shape[0])]
    multi_class = []
    for data_idx in range(test_x.shape[0]):
        probability = np.zeros((class_num), dtype = float)
        for label in range(class_num):
            probability[label] += prior[label]
            for feature_idx in range(test_x.shape[1]):
                predict_value = computeGaussian(test_x[data_idx][feature_idx], train_mean[label][feature_idx], train_var[label][feature_idx])
                probability[label] += predict_value
        probability = normalization(probability, class_num)
        total_probability[data_idx] = probability[1]            # Select class 1
        multi_class.append(probability)
        prediction = np.argmin(probability)
        predict_list.append(prediction)
        error += checkResult(prediction, test_y[data_idx])
    accuracy = (test_x.shape[0] - error) / test_x.shape[0]
    print("Error : {}. Accuracy {}".format(error, accuracy))

    #Plot ROC curve
    FA_PD = []
    if class_num == 2:
        slices = 50
        low = min(total_probability)
        high = max(total_probability)
        step = (abs(low) + abs(high)) / slices
        thresholds = np.arange(low-step, high+step, step)
        for threshold in thresholds:
            FA_PD.append(utils.computeConfusionMatrix(total_probability, test_y, class_num, model_name, threshold))
        FA = [row[0] for row in FA_PD]
        PD = [row[1] for row in FA_PD]
        FA_x = np.linspace(0.0, 1.0, slices)
        PD_interp = np.interp(FA_x, FA, PD)
        # Plot ROC curve of testing data
        if testing is True:
            utils.computeConfusionMatrix(multi_class, test_y, class_num, model_name)
            fig = plt.figure()
            plt.plot(FA_x, PD_interp)
            plt.xlabel('FA')
            plt.ylabel('PD')
            fig.savefig('plotting/' + filename + '_' + model_name + '_roc_testing.png')
        return accuracy, FA_x, PD_interp
    else:
        utils.computeConfusionMatrix(multi_class, test_y, class_num, model_name)
        return accuracy


#importing data sets

#This file does two tasks
"""
1. Given humidity predict temperature
2. Given humidity predict apparent temperature
"""
import numpy as np;
import matplotlib.pyplot as plt;
import pandas as pd;

#impoting dataset
dataset=pd.read_csv('weatherHistory.csv')
humidity=dataset.iloc[0:10000,5:6].values
temperature=dataset.iloc[0:10000:,3:4].values
apparentTemperature=dataset.iloc[0:10000:,4:5].values

#replace missing data with mean using imputer library
from sklearn.preprocessing import Imputer
imputerHumidity=Imputer(missing_values='NaN',strategy='mean',axis=0)
imputerHumidity=imputerHumidity.fit(humidity)
humidity=imputerHumidity.transform(humidity)

imputerTemperature=Imputer(missing_values='NaN',strategy='mean',axis=0)
imputerTemperature=imputerTemperature.fit(temperature)
temperature=imputerTemperature.transform(temperature)

imputerappTemp=Imputer(missing_values='NaN',strategy='mean',axis=0)
imputerappTemp=imputerappTemp.fit(apparentTemperature)
apparentTemperature=imputerappTemp.transform(apparentTemperature)

#split the data into training and testing
from sklearn.cross_validation import train_test_split
humidity_train,humidity_test,temperature_train,temperature_test=train_test_split(humidity,temperature,test_size=0.3,random_state=0)
humidity_train,humidity_test,apptemp_train,apptemp_test=train_test_split(humidity,apparentTemperature,test_size=0.3,random_state=0)
humidity_train=humidity_train
humidity_test=humidity_test
temperature_train=temperature_train.flatten()
temperature_test=temperature_test.flatten()
apptemp_train=apptemp_train.flatten()
apptemp_test=apptemp_test.flatten()

#Task 1 To predict Temperature given Humidity
from LinearRegression import LinearRegression
lr1=LinearRegression(humidity_train,temperature_train)
print(lr1.computeCostFunction())
theta1=lr1.returnTheta()
theta1,cost_history1,theta_history1=lr1.performGradientDescent(10000,0.01)
temperature_predict,temperature_error=lr1.predict(humidity_test,temperature_test)
temperature_pred_normal,error_temp_normal=lr1.predictUsingNormalEquation(humidity_test,temperature_test)

plt.scatter(humidity_test,temperature_test)
plt.plot(humidity_test,temperature_pred_normal,'r')
plt.title('Humidity vs Temperature using normal equation')
plt.xlabel('Humidity')
plt.ylabel('Temperature')
plt.show()

plt.scatter(humidity_test,temperature_test)
plt.plot(humidity_test,temperature_predict,'r')
plt.title('Humidity vs Temperature using gradient descent')
plt.xlabel('Humidity')
plt.ylabel('Temperature')
plt.show()

lr2=LinearRegression(humidity_train,apptemp_train)
print(lr2.computeCostFunction())
theta2=lr2.returnTheta()
theta2,cost_history2,theta_history2=lr2.performGradientDescent(100000,0.01)
apptemp_predict,apptemp_error=lr2.predict(humidity_test,apptemp_test)
apptemp_pred_normal,error_apptemp_normal=lr2.predictUsingNormalEquation(humidity_test,apptemp_test)

plt.scatter(humidity_test,apptemp_test)
plt.plot(humidity_test,apptemp_pred_normal,'r')
plt.title('Humidity vs Apparent Temperature using normal equation')
plt.xlabel('Humidity')
plt.ylabel('Apparent Temperature')
plt.show()

plt.scatter(humidity_test,temperature_test)
plt.plot(humidity_test,temperature_predict,'r')
plt.title('Humidity vs Apparent Temperature using gradient descent')
plt.xlabel('Humidity')
plt.ylabel('Apparent Temperature')
plt.show()


from conans import ConanFile

class CctoolsTestConan(ConanFile):
    requires = 'llvm/5.0.2-1@vuo/stable'

    def imports(self):
        self.copy('*', dst='bin', src='bin')

    def test(self):
        self.run('bin/codesign_allocate -i bin/codesign_allocate -r -o codesign_allocate2')
        self.run('ls -l bin/codesign_allocate codesign_allocate2')
        self.run('file codesign_allocate2')
        self.run('./codesign_allocate2 -i codesign_allocate2 -r -o codesign_allocate3')
        self.run('ls -l codesign_allocate3')
        self.run('file codesign_allocate3')

        self.run('bin/lipo -info bin/lipo')

        self.run('bin/install_name_tool -add_rpath test codesign_allocate3')


#!/usr/bin/env python
import sys
import json
import uuid
import logging
import asyncio
import traceback
from typing import Any
from typing import Dict
from typing import Tuple

__all__ = ['Server', 'Client', 'Crate']

logging.basicConfig(
    level=logging.DEBUG,
    format='[%(levelname)-5s][%(asctime)s][crate] %(message)s',
    stream=sys.stderr)

class Server(asyncio.Protocol):
    def __init__(self, app, loop):
        self.app = app
        self.loop = loop

        self.log = logging.getLogger('server')

        super().__init__()

    def _jsonify(self, **kwargs):
        return json.dumps(kwargs).encode('utf-8')

    def connection_made(self, transport):
        self.transport = transport
        self.address = transport.get_extra_info('peername')
        self.log.debug(
            'Connection accepted from {}:{}'.format(*self.address))

    def data_received(self, data):
        message = json.loads(data.decode())
        task_name = message.get('task')
        task_args = message.get('args', [])
        task_kwargs = message.get('kwargs', {})

        # If data received contains a task name
        if task_name:
            # Retrieve task method in registrar
            task_func = self.app._registrar.get(task_name)

            # If no method has been retrieved, this is an unregistered task
            if not task_func:
                self.log.info(
                    'Unregistered "{}" task received'.format(task_name))
                self.transport.write(self._jsonify(
                    success=False, message='Unregistered task.'))
                return

            task_uuid = str(uuid.uuid4())
            self.log.info('(task:{}) Running task...'.format(task_uuid))

            try:
                # Send task coroutine to loop
                self.loop.create_task(task_func(*task_args, **task_kwargs))
                self.log.info('(task:{}) Task sent.'.format(task_uuid))
                # Send to client task uuid
                self.transport.write(
                    self._jsonify(success=True, message=task_uuid))
            except Exception as err:
                self.log.info(
                    '(task:{}) Error while running task...\n{}'.format(
                        task_uuid, traceback.format_exc()))
                # Send to client task uuid and traceback
                self.transport.write(
                    self._jsonify(
                        success=False, error=str(err),
                        message=task_uuid, traceback=traceback.format_exc()))
        else:
            self.log.info('Invalid message received: {}'.format(data))

class Client(asyncio.Protocol):
    def __init__(self, message: Dict, loop: asyncio.AbstractEventLoop):
        super().__init__()
        self.message = message
        self.loop = loop
        self.result = {}

        self.log = logging.getLogger('client')

    def connection_made(self, transport):
        self.transport = transport
        self.address = transport.get_extra_info('peername')
        self.log.debug('Connecting to {}:{}'.format(*self.address))

        data = json.dumps(self.message)
        transport.write(data.encode('utf-8'))

        self.log.debug('Sending {!r}'.format(data))
        if transport.can_write_eof():
            transport.write_eof()

    def data_received(self, data):
        self.log.debug('Received {!r}'.format(data))
        self.result = json.loads(data.decode('utf-8'))

    def connection_lost(self, exc):
        self.log.debug('Server closed connection')
        self.transport.close()
        self.loop.stop()
        super().connection_lost(exc)

class Crate:
    def __init__(self, host: str = 'localhost', port: int = 6666):
        self.host = host
        self.port = port
        self.log = logging.getLogger('crate')

        self._registrar = {}
        self._loop = asyncio.get_event_loop()

    def __del__(self):
        if self._loop:
            self._loop.close()

    def run(self):
        self.log.info('Listening on {}:{}...'.format(self.host, self.port))

        factory = self._loop.create_server(
            lambda: Server(self, self._loop), self.host, self.port)
        server = self._loop.run_until_complete(factory)
        try:
            self._loop.run_forever()
        finally:
            self.log.info('Closing server')
            server.close()
            self._loop.run_until_complete(server.wait_closed())
            self.log.debug('Closing event loop')
            self._loop.close()

    def task(self, *args: Any, **kwargs: Any):
        def delay(app, name, *args, **kwargs):
            return app.send_task(name, args, kwargs)

        method = args[0]
        method.delay = lambda *args, **kwargs: delay(
            self, method.__name__, *args, **kwargs)
        self._registrar[method.__name__] = method

        return method

    def send_task(
            self, name: str, args: Tuple = tuple(), kwargs: Dict = {}) -> Dict:

        coroutine = self._loop.create_connection(lambda: Client(
            {'task': name, 'args': args, 'kwargs': kwargs}, self._loop),
            self.host, self.port)

        transport, client = self._loop.run_until_complete(coroutine)
        self._loop.run_forever()

        return client.result


# Image Process

try:
    import boto3
    from botocore.exceptions import ClientError
    import botocore
    import os
    import sys
    import json
except Exception as e:
    print(e)
import time
import logging
import PIL.Image
from logging.handlers import RotatingFileHandler

# Variable global pour les noms des queues d'entrée et de sortie.
AWS_SQS_QUEUE_NAME_INPUT = "Inbox"
AWS_SQS_QUEUE_NAME_OUTPUT = "Outbox"
AWS_S3_BUCKET ="mybucket307991"

#Class de type Client.
class client(object):

    def __init__(self):
        self.flag=0
        try:
            # Create the queue. This returns an SQS.Queue instance
            self.inputqueue = sqs.create_queue(QueueName=AWS_SQS_QUEUE_NAME_INPUT)
            self.receivedKeyName = None  #The key Name of the processed Image
        except Exception:
            print("Connexion Failed !")

        # Get the queue
        self.inputqueue = sqs.get_queue_by_name(QueueName=AWS_SQS_QUEUE_NAME_INPUT)
        print("You are connected to the SQS service ...")

    def upload_image(Self, file_name, bucket, key_name):
        s3 = boto3.client('s3')
        s3.upload_file(file_name, bucket, key_name)

        # Upload the image
        try:
        	response = s3.upload_file(file_name, bucket, key_name)
        	print("The image is sent !!")
        except ClientError as e:
            logging.error(e)
        # return False

	#Download the image
    def download_image(self, bucket, key_name, local_name):
        s3 = boto3.resource('s3')
        try:
            s3.Bucket(bucket).download_file(key_name,local_name)
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] == "404":
                print("The object does not exist.")
            else:
                raise
    #Send message
    def send(self, message=None):
        # Create a new message
        response = self.inputqueue.send_message(MessageBody=message)
        print("The Key of your image is sent !!")
        return response

    # Receive the Key Name of the processed Image from the sqs (OutboxQueue)
    def receive(self):
        try:
            self.queue = sqs.get_queue_by_name(QueueName=AWS_SQS_QUEUE_NAME_OUTPUT)
            for message in self.queue.receive_messages():
                data = message.body
                print("Here is the name of your processed image : ",str(data),".jpg, check the directory from where you started your client program :)\n")
                self.receivedKeyName = str(data)
                #Download the processed Image by his Key Name
                self.download_image(AWS_S3_BUCKET, str(q.receivedKeyName), str(q.receivedKeyName)+".jpg")
                processedImageDisplay = PIL.Image.open(str(data)+".jpg")
                processedImageDisplay.show()
                message.delete()

                self.flag=1
        except Exception:

            return []

if __name__ == "__main__":
    # Get the service resource
    sqs = boto3.resource('sqs')
    print("You are connected to the AWS service ...")
    flag = 0
    q = client()
    while True:
        if flag == 0 :
            command = int(input("Hi, Dear Client choose one option Tap : \n"
                         "1) For sending the key of your image that you want to proccess \n"
                         "2) To exit\n"))
            flag=flag+1

        else :
            command = int(input("Hi again, Dear Client choose one option Tap : \n"
                         "1) For sending the key of your image that you want to proccess \n"
                         "2) To exit\n"))

        if command == 1 :
            ImageName = input("Enter your image name (that exist in same directory of the program) : ")
            keyName = input("Enter your key image (that exist in same directory of the program) : ")
            q.upload_image( ImageName, AWS_S3_BUCKET, keyName)
            response = q.send(message=keyName)
            while q.flag==0:
                time.sleep(0.5)
                print("Waiting for the processed Image ...")
                #Receive the Key name of the Key Name from Outbox Queue and saved in "q.receivedKeyName" self variable .
                q.receive()
            q.flag=0
        elif command == 2:
            print("See you, Bye!")
            exit()


from flask import Flask, render_template, request, jsonify
from textblob import TextBlob
from textblob import Word
from spell import correction, words, candidates
import random
import nltk
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
#import json
import os
#synonym checking implemented
#sentiment analysis implemented
#POS tagging implemented - synergizes with sentiment analysis
#REFERENCES: https://stevenloria.com/wordnet-tutorial/
#https://medium.com/@gianpaul.r/tokenization-and-parts-of-speech-pos-tagging-in-pythons-nltk-library-2d30f70af13b
#https://www.geeksforgeeks.org/part-speech-tagging-stop-words-using-nltk-python/
#https://www.geeksforgeeks.org/twitter-sentiment-analysis-using-python/

os.environ['NLTK_DATA'] = '~/nltk_data'
GREETING_KEYWORDS = ("yo", "hey", "hello", "hi", "greetings", "sup", "what's up", "hi there", "good evening", "wuzzup my homie")
GREETING_RESPONSES = ["What can I get you?", "Hello stranger, what can I serve up for you?", "Hey there! Need a drink?", "Hi, hope you're thirsty. What can I get you?", "Welcome! What'll it be today?"]
GOODBYE_KEYWORDS = ("bye", "good bye", "goodbye", "see ya")
GOODBYE_RESPONSES = ["Have a good night", "Drive safe!", "Until next time"]
MEALS = ["steak", "hamburger", "fish and chips", "blt", "spaghetti", "hot dog", ]
HEDGE_RESPONSES = ["I have no idea what you're asking", "I'm not sure", "Can you re-phrase that?", "Pardon?", "Sorry I can't do that", "I'm confused"]
DRINKS = ("vodka", "beer", "whiskey", "wine", "sex on the beach", "screwdriver", "green fairy", "whiskey", "absinthe", "acapulco gold", "amaretto", "bacardi", "baileys" "budweiser", "champagne", "daiquiri", "goldschlager" "guinness", "grey goose", "hootch", "jack daniels", "jagermeister", "limoncello", "mezcal", "moonshine", "martini", "pina colada", "tequila", "vodka", "zinfandel", "raki", "long island iced tea"  )
DRINKSTYLE = ("on the rocks", "neat")#ask this after they request a drink
YES_KEYWORDS = ("good", "yes", "that's good", "yeah", "certainly", "true", "yep", "yea", "okay", "exactly", "gladly")
YES_RESPONSES = ["Okay", "Sounds good", "I like it", "Thats great!", "Exciting!"]
NO_KEYWORDS = ("no", "nah", "negative", "not really", "never", "false", "nope")
NO_RESPONSES = ["That's too bad", "Suit yourself", "If you say so", "I insist"]
chat_log = {}
GRATITUDE = ["thanks", "thank you", "much obliged", "thanks a bunch"]

#testing section for determining synonyms
#synonym tested words are: grub, alcohol, booze, nothing, dandy, goodbye, hello all at [0]
# testword = Word("milk")
# bev = testword.synsets[0]
print(candidates("grub"))
# print(bev.lemma_names())

def createMessage(input):
    '''Takes json facebook input and creates the message to return to facebook'''
    #input_msg = TextBlob(input['text'])

    spellingcheck = str(input).split()
    counter = 0
    for x in spellingcheck:

        if x not in candidates(x) and x not in Word("grub").synsets[0].lemma_names() and x not in Word("booze").synsets[0].lemma_names() and x not in MEALS and x not in DRINKS:
            spellingcheck[counter] = correction(x)
            print(spellingcheck[counter])
        counter += 1
    spell_checked_word = " ".join(spellingcheck)
    print(spell_checked_word)
    input_msg = TextBlob(spell_checked_word)

    senderId = 0
    data = buildMessage(input_msg, senderId)

    return str(data)  #this will return the wanted message back out to messenger

def checkForFeedback(words): #for checking sentiment behind response
    analysis = TextBlob(str(words))
    if analysis.sentiment.polarity > 0:
        return 'positive'
    elif analysis.sentiment.polarity == 0:
        return 'neutral'
    else:
        return 'negative'

def buildMessage(input_msg, senderId):
    '''Core Logic to build the message.
    If unsure how to reply, will respond with a hedge'''
    tokenform = nltk.word_tokenize(str(input_msg)) #pos tagging form of sentence
    #initializes switch for feedback

    if tokenform[0] in GRATITUDE:
        return "You're welcome!"

    # Clears the user session to start over new
    if input_msg.lower() == 'clear':
        clearSession(senderId)
        return "Session cleared"

    times_con = howManyMessages(senderId)
    # If the user is greeting, respond with a greeting
    if CheckForGreeting(input_msg):
        return random.choice(GREETING_RESPONSES)

    # If the user is greeting, respond with a greeting
    if CheckForGoodbye(input_msg):

        #the user will give an impression with their farewell which the bartender will respond to
        #setGoodByeTrue()
        if checkForFeedback(tokenform) == 'positive':
            clearSession(senderId)

            return "Happy to hear that!  " + random.choice(GOODBYE_RESPONSES)
        elif checkForFeedback(tokenform) == 'negative':
            clearSession(senderId)

            return "I'm sorry to hear that. " + random.choice(GOODBYE_RESPONSES)
        else:
            clearSession(senderId)

            return random.choice(GOODBYE_RESPONSES)

    # Break the message into parts
    pronoun, noun, adjective, verb = getSpeechParts(input_msg)
    num_drinks = chat_log[senderId]['drinks_served']

    # Search for a drink in the user input and respond as well as we can
    drink = noun #pass the noun through spell check
    if noun not in DRINKS:
        drink = searchForDrink(input_msg)
    if len(input_msg.words) == 1:
        drink = input_msg
    if drink in DRINKS:
        if tokenform[0] == 'can' or tokenform[0] == 'may': #pos tagging to specify
            return "you sure "+ tokenform[0] + "! here's your {0}".format(drink)
        if num_drinks == 1:

            return "Here's your {0}. How are you enjoying your drink so far?"
        if num_drinks > 3:
            return "You are too drunk I am unable to serve you any more drinks. You can type 'clear' to tell me that you're sober again"
        #increment drink counter
        chat_log[senderId]['drinks_served'] = num_drinks + 1
        if num_drinks <= 1:
            return "One {0} coming right up!".format(drink)
        if num_drinks == 2:
            return "{0} for you, enjoy.".format(drink)
        else:
            return "Here is your {0}! Wow you've already had {1} drinks!".format(drink, num_drinks)

    # Look for yes or no responses and respond with a weak hedge
    if checkForYes(input_msg):
        return random.choice(YES_RESPONSES)
    if checkForNo(input_msg):
        return random.choice(NO_RESPONSES)

    # If someone doesn't want anything
    if noun == Word("nothing").synsets[0].lemma_names():
        return "There isn't anything I can get for you? I have a vast knowledge of drinks. I'm sure you'll like something we have in stock."
    # If the noun is a meal:
    meal = noun
    if noun not in MEALS:
        meal = searchForMeal(input_msg)
    if len(input_msg.words) == 1:
        meal = input_msg
    if meal in MEALS:
        if tokenform[0] == 'can' or tokenform[0] == 'may': #pos tagging to specify
            return "you sure "+ tokenform[0] + "! here's your {0}".format(meal)
        if num_drinks == 1:

            return "Here's your {0}. How are you enjoying your food so far?".format(meal)
        else:
            return "Alright, here's your {0}, bon appetite".format(meal)
    #If we have a noun but no drink, we don't know what they want, so we answer with a question
    for x in tokenform:
        print(str(x))
        if str(x) in Word("grub").synsets[0].lemma_names():
            return "Sounds good. What would you like to eat?"
    for x in tokenform:
        print(str(x))
        if str(x) == "drink" or x in Word("booze").synsets[0].lemma_names():
            return "One drink coming up. What's your fancy?"
    if noun:
        if checkForFeedback(tokenform) == 'positive':
            return "Happy to hear that!  "
        elif checkForFeedback(tokenform) == 'negative':
            return "Oh that's no good. I'm sure we can fix that"
        else:
            return "well, can't say I understood that, I'll assume it was positive!"
    #If nothing caught, return a hedge
    return random.choice(HEDGE_RESPONSES)

def createChatLog(senderId):
    '''Keeps track of each session ID in a dictionary'''
    log = {'times_contacted': 1, 'context': None, 'drinks_served': 0}
    chat_log[senderId] = log

def howManyMessages(senderId):
    '''Check the chat log for number of messages and increment accordinly.'''
    if senderId not in chat_log:
        createChatLog(senderId)
        #return value is number of messages received
        return 1
    else:
        times_con = chat_log[senderId]['times_contacted'] + 1
        chat_log[senderId]['times_contacted'] = times_con
        return times_con

def clearSession(senderId):
    '''Delete any data from the user session log'''
    chat_log[senderId]['times_contacted'] = 0
    chat_log[senderId]['drinks_served'] = 0

def CheckForGreeting(sentence):
    '''Return boolean if the user sentence contains a greeting'''
    for word in sentence.words:
        if word.lower() in GREETING_KEYWORDS or word.lower() in Word("hello").synsets[0].lemma_names():
            return True
    return False

def CheckForGoodbye(sentence):
    '''Return boolean if the user wants to leave/end the sesion'''
    for word in sentence.words:
        if word.lower() in GOODBYE_KEYWORDS or word.lower() in Word("goodbye").synsets[0].lemma_names():
            return True
    return False

def checkForYes(sentence):
    '''Return boolean if the user indicated a yes/true reply'''
    for word in sentence.words:
        if word.lower() in YES_KEYWORDS or word.lower() in Word("yes").synsets[0].lemma_names():
            return True
    return False

def checkForNo(sentence):
    '''Return boolean if the user indicated a no/false reply'''
    for word in sentence.words:
        if word.lower() in NO_KEYWORDS or word.lower() in Word("no").synsets[0].lemma_names():
            return True
    return False

def searchForDrink(sentence):
    '''Return boolean if the user sentence contains a drink'''
    for word in sentence.words:
        if word.lower() in DRINKS: #or word.lower in Word(word).synsets[0].lemma_names():
            return word
    return None

def searchForMeal(sentence):
    '''Return boolean if the user sentence contains a drink'''
    for word in sentence.words:
        if word.lower() in MEALS: # or word.lower in Word(word).synsets[0].lemma_names():
            return word
    return None

def getSpeechParts(input_msg):
    '''Use natural language processing to find and categorize each part of the sentance'''
    pronoun = None
    noun = None
    adjective = None
    verb = None
    for s in input_msg.sentences:
        pronoun = findPronoun(s)
        noun = findNoun(s)
        adjective = findAdjective(s)
        verb = findVerb(s)
    return pronoun, noun, adjective, verb

def findPronoun(sent):
    '''Return pronoun (I or You). Determins if the user is talking about
    themselves or the bot.
    Pronoun is represented as PRP in NLTK'''
    pronoun = None
    for word, part_of_speech in sent.pos_tags:
        if part_of_speech == 'PRP' and word.lower() == 'you':
            pronoun = 'I'
        elif part_of_speech == 'PRP' and word == 'I' or word == 'i':
            pronoun = 'You'
    return pronoun

def findVerb(sent):
    '''Return verb represended as VB in NLTK'''
    verb = None
    pos = None
    for word, part_of_speech in sent.pos_tags:
        if part_of_speech.startswith('VB'):  # This is a verb
            verb = word
            pos = part_of_speech
            break
    return verb, pos

def findNoun(sent):
    '''Return noun represended as NN in NLTK'''
    noun = None
    if not noun:
        for w, p in sent.pos_tags:
            if p == 'NN' and w != 'i':  # This is a noun
                #textblob detecting 'i' as a noun
                noun = w
                break
    return noun

def findAdjective(sent):
    '''Return adjective represended as JJ in NLTK'''
    adj = None
    for w, p in sent.pos_tags:
        if p == 'JJ':  # This is an adjective
            adj = w
            break
    return adj

def startsWithVowel(word):
    '''Used to check if a noun starts with a vowel
    then we can assign the proper pronoun'''
    return True if word[0] in 'aeiou' else False

#all code above this created API
app = Flask(__name__) #create the app server to recieve json
@app.route("/")
def root():
    return render_template('chat.html')

@app.route("/chat", methods=['POST','GET'])
def chat():
    content = str(request.form['chatmessage'])
    if content == "quit":
        exit()
        return jsonify({"status":"ok", "answer":"exit Thank You"})
    else:
        message = createMessage(content)
        return jsonify({'status':'OK','answer':message})

app.run(host = '127.0.0.1', port = 8090)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Articulossegunda',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('art_nombre', models.CharField(max_length=30, verbose_name='Nombre:')),
                ('art_precio', models.FloatField(verbose_name='Precio:')),
                ('art_cantidad', models.IntegerField(verbose_name='Cantidad')),
                ('art_serie', models.CharField(max_length=50, verbose_name='Serie')),
                ('art_estado', models.CharField(default='D', verbose_name='Estado', max_length=1, editable=False)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Categoria',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('mar_nombre', models.CharField(max_length=30)),
                ('mar_descripcion', models.CharField(max_length=75)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Ciudad',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('ciu_nombre', models.CharField(max_length=30)),
                ('ciu_descripcion', models.CharField(max_length=70)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Clientes',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('cli_cedula', models.CharField(max_length=10)),
                ('cli_nombre', models.CharField(max_length=30)),
                ('cli_apellido', models.CharField(max_length=30)),
                ('cli_telefono', models.CharField(max_length=10, blank=True)),
                ('cli_direccion', models.CharField(max_length=75)),
                ('cli_email', models.CharField(max_length=75)),
                ('cli_estado', models.CharField(max_length=1)),
                ('ciu', models.ForeignKey(blank=True, to='sistema.Ciudad', null=True)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Factura',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('fac_subtotal', models.FloatField()),
                ('fac_iva', models.FloatField()),
                ('fac_descuento', models.FloatField(verbose_name='Ingrese descuento')),
                ('fac_total', models.FloatField()),
                ('fac_fecha', models.DateField()),
                ('fac_estado', models.CharField(max_length=1)),
                ('cli', models.ForeignKey(blank=True, to='sistema.Clientes', null=True)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Facturadetalle',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('det_cantiadd', models.IntegerField()),
                ('det_preciou', models.FloatField()),
                ('det_preciot', models.FloatField()),
                ('fac', models.ForeignKey(blank=True, to='sistema.Factura', null=True)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Facturadetallemantenimiento',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('fad_preciou', models.FloatField()),
                ('fad_preciot', models.FloatField()),
                ('fac', models.ForeignKey(to='sistema.Factura')),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Mantenimiento',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('man_fecha', models.DateField()),
                ('man_garantia', models.IntegerField()),
                ('man_informe', models.TextField(max_length=300)),
                ('man_fechaentrega', models.DateField()),
                ('man_estado', models.CharField(max_length=1, blank=True)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Mensajeria',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('men_asunto', models.CharField(max_length=30)),
                ('men_descripcion', models.CharField(max_length=500)),
                ('cli', models.ForeignKey(to='sistema.Clientes')),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Modelo',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('mod_nombre', models.CharField(max_length=30)),
                ('mod_descripcion', models.CharField(max_length=75)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='OrdenDeCompra',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('ord_subtotal', models.FloatField()),
                ('ord_iva', models.FloatField()),
                ('ord_descuento', models.FloatField()),
                ('ord_total', models.FloatField()),
                ('ord_fecha', models.DateField()),
                ('ord_estado', models.CharField(max_length=1)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Productos',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('pro_nombre', models.CharField(max_length=30, verbose_name='Nombre:')),
                ('pro_cantidad', models.IntegerField(verbose_name='Nombre:')),
                ('pro_precio', models.FloatField(verbose_name='Nombre:')),
                ('pro_ecg', models.CharField(max_length=75, verbose_name='Nombre:', blank=True)),
                ('pro_tarifa_iva', models.FloatField(verbose_name='Nombre:')),
                ('pro_ex', models.IntegerField(verbose_name='Nombre:')),
                ('pro_pvp', models.FloatField(verbose_name='Nombre:')),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Detalleproveedor',
            fields=[
                ('pro', models.ForeignKey(primary_key=True, serialize=False, to='sistema.Productos')),
                ('kar_precio_proveedor', models.FloatField(db_column='kar_Precio_proveedor')),
                ('kar_entra', models.IntegerField()),
                ('kar_sald', models.IntegerField()),
                ('kar_fecha', models.DateTimeField()),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Proveedor',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('prov_ruc', models.CharField(max_length=13, verbose_name='RUC')),
                ('prov_cedula', models.CharField(max_length=10, verbose_name='CEDULA')),
                ('prov_nombre', models.CharField(max_length=30, verbose_name='NOMBRE')),
                ('prov_representante', models.CharField(max_length=50, verbose_name='REPRESENTANTE')),
                ('prov_direccion', models.CharField(max_length=80, verbose_name='DIRECCI\xd3N')),
                ('prov_telefono', models.CharField(max_length=10, verbose_name='TELEFONO', blank=True)),
                ('prov_estado', models.CharField(max_length=1, verbose_name='ESTADO', blank=True)),
                ('ciu', models.ForeignKey(verbose_name='CIUDAD', blank=True, to='sistema.Ciudad', null=True)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Repuestos',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('rep_cantidad', models.IntegerField()),
                ('man', models.ForeignKey(to='sistema.Mantenimiento')),
                ('pro', models.ForeignKey(to='sistema.Productos')),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Solicitudmantenimiento',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('solm_fecha', models.DateField(verbose_name='Fecha')),
                ('solm_falla', models.CharField(max_length=100, verbose_name='Falla')),
                ('solm_observaciones', models.CharField(max_length=100, verbose_name='Observacion', blank=True)),
                ('solm_abono', models.FloatField(verbose_name='Abono')),
                ('solm_saldo', models.FloatField(verbose_name='Saldo')),
                ('solm_total', models.FloatField(verbose_name='Total')),
                ('solm_estado', models.CharField(max_length=1, verbose_name='Estado', blank=True)),
                ('art', models.ForeignKey(to='sistema.Articulossegunda')),
                ('cli', models.ForeignKey(blank=True, to='sistema.Clientes', null=True)),
            ],
            options={
                'ordering': ['id'],
            },
            bases=(models.Model,),
        ),
        migrations.AddField(
            model_name='productos',
            name='mar',
            field=models.ForeignKey(verbose_name='Nombre:', blank=True, to='sistema.Categoria', null=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='ordendecompra',
            name='prov',
            field=models.ForeignKey(to='sistema.Proveedor'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='mantenimiento',
            name='solm',
            field=models.ForeignKey(to='sistema.Solicitudmantenimiento'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='facturadetallemantenimiento',
            name='solm',
            field=models.ForeignKey(to='sistema.Solicitudmantenimiento'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='facturadetalle',
            name='pro',
            field=models.ForeignKey(blank=True, to='sistema.Productos', null=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='detalleproveedor',
            name='ord',
            field=models.ForeignKey(blank=True, to='sistema.OrdenDeCompra', null=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='articulossegunda',
            name='mar',
            field=models.ForeignKey(verbose_name='Marca', blank=True, to='sistema.Categoria', null=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='articulossegunda',
            name='mod',
            field=models.ForeignKey(verbose_name='Modelo', blank=True, to='sistema.Modelo', null=True),
            preserve_default=True,
        ),
    ]