# -*- coding: latin-1 -*-
from tkinter.filedialog import asksaveasfilename

from imports.guiutils import *
import re

# GUI de Gramatica Regular
class GrammarGLCGui(Hideble):
    # Construtor
    def __init__(self, grammar, master=None, topLevel=None, name="new-grammar"):
        super(GrammarGLCGui, self).__init__(master)

        self.topLevel = topLevel
        self.master = master
        self.name = name
        self.grammar = grammar

        self.container1 = Frame(self.frame)
        self.container1.pack()
        self.grammarframe = Frame(self.frame)
        self.grammarframe.pack()
        self.displaygrammar = Frame(self.frame)
        self.displaygrammar.pack()
        self.container2 = Frame(self.frame)
        self.container2.pack()
        self.container3 = Frame(self.frame)
        self.container3.pack()
        self.container4 = Frame(self.frame)
        self.container4.pack()
        self.container5 = Frame(self.frame)
        self.container5.pack()
        self.container6 = Frame(self.frame)
        self.container6.pack()
        self.container7 = Frame(self.frame)
        self.container7.pack()

        self.title = Label(self.container1, text=self.name)
        self.title["font"] = ("Roboto", "15", "bold")
        self.title.pack()

        self.updateProdGenDisplay()
        self.updateGrammarDisplay()

        self.addProd = Button(self.container2)
        self.addProd["text"] = "Adicionar producao"
        self.addProd["font"] = ("Roboto", "10")
        self.addProd["width"] = 20
        self.addProd.bind("<ButtonRelease-1>", self.createAddProductionFrame)
        self.addProd.pack(side=LEFT)

        self.removeProd = Button(self.container2)
        self.removeProd["text"] = "Remover producao"
        self.removeProd["font"] = ("Roboto", "10")
        self.removeProd["width"] = 20
        self.removeProd.bind("<ButtonRelease-1>", self.createRemoveProductionFrame)
        self.removeProd.pack(side=LEFT)

        self.setInitial = Button(self.container3)
        self.setInitial["text"] = "Alterar estado inicial"
        self.setInitial["font"] = ("Roboto", "10")
        self.setInitial["width"] = 20
        self.setInitial.bind("<ButtonRelease-1>",
                             lambda event, command=self.alterInitialState, label="Alterar": self.createStateSelect(
                                 command, label, "Nao Terminal"))
        self.setInitial.pack()

        self.chomsky = Button(self.container4)
        self.chomsky["text"] = "Forma normal de Chomsky"
        self.chomsky["font"] = ("Roboto", "10")
        self.chomsky["width"] = 20
        self.chomsky.bind("<ButtonRelease-1>",
                            lambda event, command=self.convertToChomsky, label="Sim": createConfimationBox(self.master,
                                                                                command,
                                                                                "Ao continuar, voce converter a gramatica atual para forma normal de chomsky. Deseja continuar?"))
        self.chomsky.pack()

        self.left_recursion_dir = Button(self.container4)
        self.left_recursion_dir["text"] = "Remover Req Esq Dir"
        self.left_recursion_dir["font"] = ("Roboto", "10")
        self.left_recursion_dir["width"] = 20
        self.left_recursion_dir.bind("<ButtonRelease-1>",
                          lambda event, command=self.removeLeftRecursionDir, label="Sim": createConfimationBox(self.master,
                                                                                command,
                                                                                "Ao continuar, voce ira remover a recursão a esquerda. Deseja continuar?"))
        self.left_recursion_dir.pack(side=LEFT)

        self.left_recursion_indir = Button(self.container4)
        self.left_recursion_indir["text"] = "Remover Req Esq Indir"
        self.left_recursion_indir["font"] = ("Roboto", "10")
        self.left_recursion_indir["width"] = 20
        self.left_recursion_indir.bind("<ButtonRelease-1>",
                                     lambda event, command=self.removeLeftRecursionIndir, label="Sim": createConfimationBox(
                                         self.master,
                                         command,
                                         "Ao continuar, voce ira remover a recursão a esquerda. Deseja continuar?"))
        self.left_recursion_indir.pack()

        self.fatoration_dir = Button(self.container5)
        self.fatoration_dir["text"] = "Fatoração Direta"
        self.fatoration_dir["font"] = ("Roboto", "10")
        self.fatoration_dir["width"] = 20
        self.fatoration_dir.bind("<ButtonRelease-1>",
                                 lambda event, command=self.factorization_direct, label="Sim": createConfimationBox(
                                     self.master,
                                     command,
                                     "Ao continuar, voce ira fatorar a gramatica. Deseja continuar?"))
        self.fatoration_dir.pack(side=LEFT)

        self.fatoration_dir = Button(self.container5)
        self.fatoration_dir["text"] = "Fatoração Indireta"
        self.fatoration_dir["font"] = ("Roboto", "10")
        self.fatoration_dir["width"] = 20
        self.fatoration_dir.bind("<ButtonRelease-1>",
                                 lambda event, command=self.factorization_indirect, label="Sim": createConfimationBox(
                                     self.master,
                                     command,
                                     "Ao continuar, voce ira fatorar a gramatica. Deseja continuar?"))
        self.fatoration_dir.pack()

        self.first = Button(self.container6)
        self.first["text"] = "First"
        self.first["font"] = ("Roboto", "10")
        self.first["width"] = 20
        self.first.bind("<ButtonRelease-1>",
                             lambda event, command=self.first_func, label="First": self.createFirstSelect(
                                 command, label, "First"))
        self.first.pack(side=LEFT)

        self.follow = Button(self.container6)
        self.follow["text"] = "Follow"
        self.follow["font"] = ("Roboto", "10")
        self.follow["width"] = 20
        self.follow.bind("<ButtonRelease-1>",
                             lambda event, command=self.follow_func, label="Follow": self.createFollowSelect(
                                 command, label, "Follow"))
        self.follow.pack()

        self.table = Button(self.container7)
        self.table["text"] = "Tabela de Análise"
        self.table["font"] = ("Roboto", "10")
        self.table["width"] = 20
        self.table.bind("<ButtonRelease-1>", self.show_table)
        self.table.pack()

        self.save = Button(self.container7)
        self.save["text"] = "Salvar"
        self.save["font"] = ("Roboto", "10")
        self.save["width"] = 20
        self.save.bind("<ButtonRelease-1>", self.file_save)
        self.save.pack()

        self.exit = Button(self.container7)
        self.exit["text"] = "Voltar"
        self.exit["font"] = ("Roboto", "10")
        self.exit["width"] = 20
        self.exit.bind("<ButtonRelease-1>", self.returnTop)
        self.exit.pack()

    # Frame de adicionar producao
    def createAddProductionFrame(self, event):
        window = Toplevel(self.master)
        container = Frame(window)
        container.pack()
        container2 = Frame(window)
        container2.pack()
        container3 = Frame(window)
        container3.pack()
        container4 = Frame(window)
        container4.pack()

        nomeLabel = Label(container, text="De", font="Roboto")
        nomeLabel.pack(side=LEFT)

        self.fromState = Entry(container)
        self.fromState["width"] = 10
        self.fromState["font"] = "Roboto"
        self.fromState.pack(side=LEFT)

        nomeLabel = Label(container2, text="Producao", font="Roboto")
        nomeLabel.pack(side=LEFT)

        self.newprod = Entry(container2)
        self.newprod["width"] = 10
        self.newprod["font"] = "Roboto"
        self.newprod.pack(side=LEFT)

        adicionar = Button(container4)
        adicionar["text"] = "Adicionar"
        adicionar["font"] = ("Roboto", "10")
        adicionar["width"] = 20
        adicionar["command"] = window.destroy
        adicionar.bind("<ButtonRelease-1>", self.addProduct)
        adicionar.pack(side=LEFT)

        exit = Button(container4)
        exit["text"] = "Cancelar"
        exit["font"] = ("Roboto", "10")
        exit["width"] = 20
        exit["command"] = window.destroy
        exit.pack(side=LEFT)

    # Frame de remover producao
    def createRemoveProductionFrame(self, event):
        window = Toplevel(self.master)
        for nt in self.grammar.productions:
            container = Frame(window)
            container.pack()
            l = Label(container, text=str(nt) + ": ")
            l["font"] = ("Roboto", "15", "bold")
            l.pack(side=LEFT)
            id = 0
            for x in self.grammar.productions[nt]:
                b = Button(container)
                b["text"] = x
                b["font"] = ("Roboto", "10")
                b["width"] = 4
                b.bind("<ButtonRelease-1>", lambda event, to=nt, term=x: self.removeProduct(to, term))
                b["command"] = window.destroy
                b.pack(side=LEFT)
                id += 1

    # Selecao de producao
    def createStateSelect(self, command, labelName, text):
        window = Toplevel(self.master)
        container = Frame(window)
        container.pack()
        for nt in self.grammar.productions:
            b = Button(container)
            b["text"] = str(nt)
            b["font"] = ("Roboto", "10")
            b["width"] = 5
            b["command"] = window.destroy
            b.bind("<ButtonRelease-1>", lambda event, a=str(nt): self.alterInitialState(a))
            b.pack(side=LEFT)

    # Selecao de first
    def createFirstSelect(self, command, labelName, text):
        window = Toplevel(self.master)
        container = Frame(window)
        container.pack()
        terminals = set()
        nonterminals = set(self.grammar.productions.keys())
        for nt in self.grammar.productions:
            for prod in self.grammar.productions[nt]:
                for curr_term in prod:
                    if curr_term not in nonterminals:
                        terminals.add(curr_term)
        terminals.update(nonterminals)
        for nt in terminals:
            b = Button(container)
            b["text"] = str(nt)
            b["font"] = ("Roboto", "10")
            b["width"] = 5
            b["command"] = window.destroy
            b.bind("<ButtonRelease-1>", lambda event, a=str(nt): self.first_func(a))
            b.pack(side=LEFT)

    # Selecao de follow
    def createFollowSelect(self, command, labelName, text):
        window = Toplevel(self.master)
        container = Frame(window)
        container.pack()
        nonterminals = set(self.grammar.productions.keys())
        for nt in nonterminals:
            b = Button(container)
            b["text"] = str(nt)
            b["font"] = ("Roboto", "10")
            b["width"] = 5
            b["command"] = window.destroy
            b.bind("<ButtonRelease-1>", lambda event, a=str(nt): self.follow_func(a))
            b.pack(side=LEFT)

    # Adicionar producao e update nos Displays
    def addProduct(self, event):
        if not self.fromState.get():
            displayBox(self.master, "Estado de inicio nao pode ser nulo")
            return
        if not self.newprod.get():
            displayBox(self.master, "Producao nao pode ser nulo")
            return
        elements = re.findall(r'("(.*?)"|.)', self.newprod.get())
        elements = [tuple(j for j in i if j)[-1] for i in elements]
        self.grammar.addProduction(self.fromState.get(), list(elements))
        self.updateProdGenDisplay()
        self.updateGrammarDisplay()

    # Remover producao e update nos Displays
    def removeProduct(self, to, prod):
        self.grammar.removeProduction(to, prod)
        self.updateProdGenDisplay()
        self.updateGrammarDisplay()

    # Atualizacao do display de gerador de palavras
    def updateProdGenDisplay(self):
        for widget in self.grammarframe.winfo_children():
            widget.destroy()

    # Atualizacao de display da gramatica
    def updateGrammarDisplay(self):
        for widget in self.displaygrammar.winfo_children():
            widget.destroy()
        for x in self.grammar.productions:
            prod_list = []
            for prod in self.grammar.productions[x]:
                prod_list.append(' '.join(prod))
            l = Label(self.displaygrammar, text=str(x) + ": " + str(' | '.join(prod_list)))
            l["font"] = ("Roboto", "15", "bold")
            l.pack()

    # Altera producao inicial
    def alterInitialState(self, id):
        self.grammar.setInitial(id)
        self.updateProdGenDisplay()

    # Altera producao inicial
    def first_func(self, id):
        first = self.grammar.first(id)
        displayBox(self.master, str(first))

    # Altera producao inicial
    def follow_func(self, id):
        follow = self.grammar.follow(id)
        displayBox(self.master, str(follow))

    # Altera producao inicial
    def convertToChomsky(self, event):
        self.grammar.convert_chomsky_normal_form()
        self.updateGrammarDisplay()

    def removeLeftRecursionDir(self, event):
        self.grammar.remove_left_recursion_direct()
        self.updateGrammarDisplay()

    def removeLeftRecursionIndir(self, event):
        self.grammar.remove_left_recursion_indirect()
        self.updateGrammarDisplay()

    def factorization_direct(self, event):
        self.grammar.factorization_direct()
        self.updateGrammarDisplay()

    def factorization_indirect(self, event):
        self.grammar.factorization_indirect()
        self.updateGrammarDisplay()

    def show_table(self, event):
        # try:
            table, list = self.grammar.generate_ll_1()
            window = Toplevel(self.master)
            container = Frame(window)
            container.pack()
            terminals = set()
            nonterminals = set(self.grammar.productions.keys())
            for nt in self.grammar.productions:
                for prod in self.grammar.productions[nt]:
                    for curr_term in prod:
                        if curr_term not in nonterminals:
                            terminals.add(curr_term)
            terminals.add('$')
            for widget in container.winfo_children():
                widget.destroy()
            col = 1
            chars = terminals
            for c in chars:
                l = Label(container, text=c, borderwidth=1, width=4, relief="solid")
                l["font"] = ("Roboto", "15", "bold")
                l.grid(row=0, column=col, sticky=W + E + N + S)
                col += 1
            ron = 1
            for state in nonterminals:
                labelStr = ""
                if self.grammar.isInitial(state):
                    labelStr += "*"
                labelStr += state
                l = Label(container, text=' ' + labelStr + ' ', borderwidth=1, relief="solid")
                l["font"] = ("Roboto", "15", "bold")
                l.grid(row=ron, column=0, sticky=W + E + N + S)
                container.columnconfigure(col, weight=1)
                col = 1
                for c in chars:
                    if c in table[state]:
                        if table[state][c]:
                            labelStr = str(table[state][c])
                        else:
                            labelStr = '-'
                    else:
                        labelStr = "-"
                    l = Label(container, text=' ' + labelStr + ' ', borderwidth=1, relief="solid")
                    l["font"] = ("Roboto", "15", "bold")
                    l.grid(row=ron, column=col, sticky=W + E + N + S)
                    col += 1
                ron += 1

        #
        # except:
        #     displayBox(self.master, "Linguagem não é LL(1)")

    # Salvar
    def file_save(self, event):
        f = asksaveasfilename(defaultextension=".glc",
                              filetypes=[('Arquivos de Gramatica Livre de Context', '.glc'),
                                         ('Todos os arquivos', '.*')])
        if not f:
            return
        self.grammar.save(f)
        self.title["text"] = f.split('/')[-1]
        displayBox(self.master, "Salvo com sucesso em " + f)

    # Retornar ao menu anterior
    def returnTop(self, event):
        self.hide()
        self.topLevel.show()


n = int(input())
l = list(map(int, input().split()))
length = len(l)
mx = 0

def dfs(result: int, cnt: int, visited: set):
    global mx

    for n in l:
        if n in visited:
            continue

        if cnt == length:
            result = result + (n * cnt)
            if (cnt % 2) == 0:
                result *= -1

            mx = max(mx, result)

        else:
            new_visited = set(visited)
            new_visited.add(n)

            value = n * cnt
            if (cnt % 2) == 0:
                value *= -1

            new_result = value + result

            dfs(new_result, cnt + 1, new_visited)

dfs(0, 1, set())

print(mx)


from pathlib import Path

import torch
import torch.nn as nn
from torch.nn import functional as F
from torch.optim import Adam
from torch.nn import CrossEntropyLoss
from torch.utils.data import DataLoader

from torchvision.transforms import ToTensor
from torchvision.datasets.mnist import MNIST
import os, sys
import cv2
import numpy as np

# An installation agnostic method to find and link to root of the package which is mlfactory
#==========================================================
import re
try: #testing the functions locally without pip install
  import __init__
  cimportpath = os.path.abspath(__init__.__file__)
  if 'extensions' in cimportpath:
    print("local testing ")
    import mlfactory
    cimportpath = os.path.abspath(mlfactory.__file__)

except: #testing while mlfactory is installed using pip
  print("Non local testing")
  import mlfactory
  cimportpath = os.path.abspath(mlfactory.__file__)

main_package_loc = cimportpath[:cimportpath.rfind('mlfactory')+len('mlfactory')]
print("got main package location ",main_package_loc)

os.environ['top'] = main_package_loc
sys.path.append(os.path.join(os.environ['top']))
#==========================================================

from models.pytorch.timesformer import TimeSformer
from datetime import datetime as dt
import cv2
from collections import deque

import mss.tools #for fast screenshots
import pyautogui
from datetime import datetime as dt
import time

pressed = []

def agent_action(pred): #maybe need to incorporate multinomial sampling
    global pressed

    if pressed!=[]:
        for p in pressed:
            pyautogui.keyUp(p)

    if pred==0:
        pyautogui.keyDown('w') # for example key = 'a'
        pressed = ['w']
    if pred==1:
        pyautogui.keyDown('a') # for example key = 'a'
        pressed = ['a']
    if pred==2:
        pyautogui.keyDown('s') # for example key = 'a'
        pressed = ['s']
    if pred==3:
        pyautogui.keyDown('d') # for example key = 'a'
        pressed = ['d']

    if pred==4:
        pyautogui.keyDown('w') # for example key = 'a'
        pyautogui.keyDown('a') # for example key = 'a'
        pressed = ['w','a']
    if pred==5:
        pyautogui.keyDown('w') # for example key = 'a'
        pyautogui.keyDown('d') # for example key = 'a'
        pressed = ['w','d']
    if pred==6:
        pyautogui.keyDown('s') # for example key = 'a'
        pyautogui.keyDown('a') # for example key = 'a'
        pressed = ['s','a']
    if pred==7:
        pyautogui.keyDown('s') # for example key = 'a'
        pyautogui.keyDown('d') # for example key = 'a'
        pressed = ['s','a']

def close_agent():
    global pressed

    if pressed!=[]:
        for p in pressed:
            pyautogui.keyUp(p)

def record_screen(rs):
    #im = pyautogui.screenshot(region=(823, 153, 997, 464)) #takes around 0.15 s
    #cv2.imwrite(folder+"/"+str(idx)+".png", np.array(im))

    with mss.mss() as sct:
        # The screen part to capture
        monitor = {"top": 191, "left": 373, "width": 1125, "height": 611}
        #output = "sct-{top}x{left}_{width}x{height}.png".format(**monitor)
        output = "temp.png"

        # Grab the data
        sct_img = sct.grab(monitor) #takes around 0.03 s

        # Save to the picture file
        mss.tools.to_png(sct_img.rgb, sct_img.size, output=output)
        #print(output)
    im = cv2.imread("temp.png", 0)
    im = cv2.resize(im, (rs,rs))
    return im

if __name__ == '__main__':
    print("loading timesformer ")
    num_prev_conditioning_frames = 10
    C,D = 1, 112 #input image properties, assuming H=W=D
    batch_size = 1
    n_class = 9
    num_batches = 500
    LR = 0.0003
    datafolder = 3 #each number stores a single run of a game

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    model = TimeSformer(
    dim = 256,
    image_size = D,
    patch_size = 8,
    channels = C,
    num_frames = num_prev_conditioning_frames,
    num_classes = n_class,
    depth = 8,
    heads = 8,
    dim_head =  64,
    attn_dropout = 0.1,
    ff_dropout = 0.1
    )

    if os.path.exists('weights.pt'):
        print("loading weights do far ")
        model = torch.load('weights.pt')

    print(sum(p.numel() for p in model.parameters())/1e6, 'M parameters')

    model.to(device)

    d = deque(maxlen=num_prev_conditioning_frames)

    time.sleep(5) #provide time for user to position the mouse cursor
    y = 8

    for _ in range(200): #try out 100 model actions
        x = record_screen(D)
        x = np.array(x/255.0, dtype = np.float32).reshape((1,D,D))

        if len(d)==num_prev_conditioning_frames: #now the agent can act upon sufficient history
            obs = np.array(d)
            inp = torch.from_numpy(obs).view((batch_size, num_prev_conditioning_frames, C, D, D)).to(device)
            out = model(inp)
            probs = F.softmax(out, dim=-1)

            act_idx = torch.argmax(probs)
            act_idx = torch.multinomial(probs, num_samples=1) # (B, 1)
            pred = act_idx.detach().cpu().numpy()[0][0] #should be a vector of length number of possible actions

            #pred = act_idx.detach().cpu().numpy() #should be a vector of length number of possible actions
            print("model pred ",pred)

            agent_action(pred)
            y = int(pred)

        #r = np.random.randint(0,9)
        #action_conditioning = (r/9.0)*np.ones((112,112), dtype = np.float32).reshape((1,D,D))
        #action_conditioning = np.random.sample((1,D,D)).astype(np.float32) #apply a random conditioning to each frame to help the network be able to think generatively

        #x = np.stack((x,action_conditioning)).reshape((2,D,D))
        #x = np.stack((x,x)).reshape((2,D,D))
        d.append(x)

    close_agent()


import BoltzmannMachine as bm
import QHO as qho
import numpy as np
import datetime
# Visualization imports
from IPython.display import clear_output
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['figure.dpi']=300
def sigmoid(x):
    return .5 * (1 + np.tanh(x / 2.))

# Set the quantum gas with N particles, a limit of 10 for the
# quantum numbers and default temperature and frequency
N = 10*10
gas = qho.QHOGas(N=N)
n_max = 10

training_size = 100000
# the amount of hidden units was set by trial and error
hidden_units = 70
# the recipe suggests to set the batchsize to 10, though it can range
# from 10 to 100
batchsize = 10
# the recipe suggests a learning rate that makes the weight updates about
# 1e-3 times the weights (to within an order of magnitude)
eta = 0.005
# the amount of steps was set by trial and error
nsteps = 300000

# define the validation set to be used in training_visualization
validation_set = gas.generate(amount=20)

def training_visualization(machine, current_step, total_steps, eta, a, b, w, da, db, dw):
    # Every now and then (every 50k steps), let us know that the training
    # is still running
    if current_step%50000 == 0:
        print("{:08d} / {:08d}".format(current_step, total_steps), end="   \r")

    # After 'checkpoint_steps', show the suggested plots
    checkpoint_steps = 10000
    if current_step%checkpoint_steps == 0 or current_step == total_steps-1:
        print(f"Showing at step {current_step}.")
        # Produce a sample starting from the validation set after 100 steps
        v_prime = machine.generate(validation_set, 100, a=a, b=b, w=w)
        # print useful plots for training
        plot_training(validation_set, v_prime, eta, a, b, w, da, db, dw)

def plot_training(v, v_prime, eta, a, b, w, da, db, dw):
    clear_output(wait=True)
    # Show how the weights light up for the state v
    hMean = sigmoid(np.dot(v, w) + b)
    image = Image.fromarray(hMean * 256).show()

    # Create the grid for all the other plots we want
    plt.rcParams.update({'font.size': 2})

    # plot histogram of initial vs generated
    n = np.arange(0,10)
    generated_quantum_numbers = np.rint(v_prime*10)
    plt.hist( generated_quantum_numbers.flatten(), bins=np.arange(0,10), density=True, label="Sampled" )
    plt.plot( n, gas.p_n(n), label="Theor." )
    plt.xlabel('n')
    plt.ylabel('P(n)')
    plt.legend()

    # plot histogram of visible, hidden, weights
    fig = plt.figure(constrained_layout=True)
    gs = fig.add_gridspec(ncols=3, nrows=2)
    def plotit(axis, values, title):
        axis.hist(values)
        axis.set_title(f"{title}: mm = {np.mean(np.fabs(values))}")
    plotit(fig.add_subplot(gs[0,0]), a, 'a')
    plotit(fig.add_subplot(gs[0,1]), w.flatten(), 'w')
    plotit(fig.add_subplot(gs[0,2]), b, 'b')
    # plot histogram of d_visible, d_hidden, d_weights
    plotit(fig.add_subplot(gs[1,0]), eta*da, 'da')
    plotit(fig.add_subplot(gs[1,1]), eta*dw.flatten(), 'dw')
    plotit(fig.add_subplot(gs[1,2]), eta*db, 'db')
    # show free energies of the average of samples
    x = lambda vv : b + np.dot(vv, w)
    free_training  = -np.dot(v, a) - np.sum( np.log(1 + np.exp(x(v))), axis=1)
    free_valdation = -np.dot(v_prime, a) - np.sum( np.log(1 + np.exp(x(v_prime))), axis=1)
    print(f"\nF_training={np.average(free_training)} vs F_validation={np.average(free_valdation)}\n")
    # Show.
    # CAUTION! This will freeze the execution
    plt.show()

# Init the boltzmann machine and train it while visualizing the suggested plots
training_set = gas.generate(amount=training_size, n_max=n_max)
m = bm.BoltzmannMachine(num_hidden=hidden_units)
a,b,w = m.train(training_set, batchsize=batchsize, eta=eta, nsteps=nsteps, do_while_training=None)
# Store in a file
run_id = int(datetime.datetime.now().timestamp())
np.savetxt(f"a_{run_id}.csv", a, delimiter=',')
np.savetxt(f"b_{run_id}.csv", b, delimiter=',')
np.savetxt(f"w_{run_id}.csv", w, delimiter=',')


import socket

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('en.wikipedia.org', 80))
command = 'GET http://en.wikipedia.org/wiki/A HTTP/1.0\n\n'.encode()
mysock.send(command)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())
mysock.close()


import matplotlib.pyplot as plt
import pyspark
from pyspark import SparkContext
from pyspark.sql import SparkSession, SQLContext, HiveContext
from pyspark.sql.functions import *
from fpdf import FPDF
from PIL import Image
import glob
import matplotlib.cm as cm
import numpy as np

import pymongo
import pandas as pd
import json

WIDTH = 210
HEIGHT = 297

#HELPER FUNCTIONS
def read_from_database(mongo_ip):
    iris = sqlC.read.format("com.mongodb.spark.sql.DefaultSource").option("uri", mongo_ip + "Iris").load()
    iris.createOrReplaceTempView("iris")
    iris = sqlC.sql("SELECT * FROM iris")
    #iris = iris.withColumn("Processor", iris["Processor"].cast("string"))
    return iris

def load_to_database(path_to_xlsx, database_name):
    client = pymongo.MongoClient("mongodb://localhost:27017") #connect to local server
    df = pd.read_excel(path_to_xlsx) #read from xlsx file
    data = df.to_dict(orient = "records") #insert data into a dictionary and choose the type of values as records
    db = client[database_name] #construct db
    db.Iris.insert_many(data) #insert data into db

#by creating RDD's manually, optimize the memory used and shorten execution time.
def create_partition(dataframe, sparkcontext):
    dataframe.repartition(6).createOrReplaceTempView('sf_view')
    sparkcontext.catalog.cacheTable('sf_view')
    dataframe = sparkcontext.table('sf_view')
    return dataframe

#Extract a dataframe for every client using _Total values for Processor
def extract_dataframes(dataframe):
    clients = dataframe.withColumn('Server_Name', dataframe['Server_Name'].substr(0, 3)).select('Server_Name').distinct().toPandas()["Server_Name"].values.tolist()
    client_dataframes = {}
    for client in clients:
        client_dataframes[client] = dataframe.filter(dataframe.Server_Name.contains(client) & dataframe.Processor.contains('_Total')) #take every row for a client which includes total processor usage data.
    return clients, client_dataframes

class Client:
    def __init__(self, client_dataframe, sparkcontext, client_name):
        self.client_dataframe = client_dataframe
        self.sparkcontext = sparkcontext

        self.client_name = client_name
        self.hostnames = self.client_dataframe.withColumn('Server_Name', self.client_dataframe['Server_Name'].substr(5, 1)).select('Server_Name').distinct().toPandas()["Server_Name"].values.tolist()
        self.hostnames = sorted(self.hostnames) #sort hostnames alphabetically

        self.hosts_dataframes = {} #Holds dataframes for every host of a client. Keys are hostnames.

        for host in self.hostnames:
            self.hosts_dataframes[host] = self.client_dataframe.filter(self.client_dataframe.Server_Name.contains(host)) #take every row includes the name of the host

        #mesaj gidiyo motor donmuyo hero kodu degmis olabilir

#Report template for CPU usage
class ClientReport:
    def __init__(self, client):

        #client object will be passed and graphs related to that client will be printed as a seperate pdf.
        self.client = client

        self.chart_row = 1
        self.figure_num = 0
        self.page_num = 1
        self.minus = 0
        self.figure_per_page_num = 0

        self.create_pdf()

    def add_figure(self, path, pdf, width, is_last):

        if(self.figure_num % 2 == 0 or width > WIDTH/2-5):

            if(width > WIDTH/2-5):
                pdf.image(path, 40, 80*self.chart_row-self.minus, width)
                self.figure_num += 2
                self.figure_per_page_num +=2
            else:
                pdf.image(path, 5, 80*self.chart_row-self.minus, width)
                self.figure_per_page_num += 1
                self.figure_num += 1
            #self.y = 80*chart_row-minus
            #self.x = WIDTH/2+5
        else:
            pdf.image(path, WIDTH/2+5, 80*self.chart_row-self.minus, width)
            self.figure_per_page_num +=1
            self.chart_row += 1
            self.figure_num += 1
            #self.y = 80*self.chart_row-self.minus
            #self.x = 5

        if (not is_last):
            if(self.page_num > 1 and self.figure_per_page_num == 6):
                pdf.add_page()
                self.footer(pdf)
                self.line_header(pdf)
                self.figure_per_page_num = 0
                self.chart_row = 1
                self.page_num += 1

            elif(self.page_num == 1 and self.figure_per_page_num == 4):
                pdf.add_page()
                self.footer(pdf)
                self.line_header(pdf)
                self.figure_per_page_num = 0
                self.chart_row = 1
                self.page_num += 1
                self.minus = 50

    def usage_for_every_host(self, pdf):
        i = 0
        is_last = False
        for host in self.client.hostnames:
            i+=1
            if(i == len(self.client.hostnames)):
                is_last == True
            # if(self.page_num == 1):
            #     offset = self.chart_row*50
            # else:
            offset = 75
            if(self.figure_per_page_num==0 and self.page_num > 1):
                offset = 23
            elif(self.figure_per_page_num != 0):
                offset += 7

            #pdf.cell(w=0, txt = "Charts for host "+host, ln = 1, align = 'L')
            pdf.ln(offset)
            pdf.set_font('Arial', '',10)
            pdf.write(3,"            Charts for host "+host);
            title = "Hourly CPU Usage for " + self.client.client_name + " with host " + host
            title2 = "Weekly CPU Usage for " + self.client.client_name + " with host " + host
            self.hourly_line_chart(title, self.client.hosts_dataframes[host], host, self.client.client_name)
            self.weekly_bar_chart(title2, self.client.hosts_dataframes[host], host, self.client.client_name)
            path = "/home/basan/internship-codes/charts/"+self.client.client_name+host+'.jpg'
            path2 = "/home/basan/internship-codes/charts/weekly"+self.client.client_name+host+'.jpg'
            width = WIDTH/2-5
            self.add_figure(path, pdf, width, is_last)
            self.add_figure(path2, pdf, width, is_last)

    #function for PDF output.
    def traingle_header(self, pdf, day):
        pdf.image("/home/basan/internship-codes/letterhead.png",0,0,WIDTH)
        pdf.image("/home/basan/internship-codes/ibmlogo.png", 170, 20, 25)
        pdf.set_font("Arial", size = 24)
        pdf.ln(35)
        pdf.cell(w=0, txt = "CPU Report", ln = 5, align = 'L')
        pdf.set_font("Arial", size = 15)
        pdf.ln(10)
        pdf.cell(w=0, txt = f'{day}', ln = 4, align = 'L')
        #pdf.cell(200, 30, txt = "Report Example 1", ln = 1, align = 'C')

    def line_header(self, pdf):
        #pdf.image("/home/basan/internship-codes/arkaheader.png",0,0,WIDTH)
        pdf.image("/home/basan/internship-codes/ibmlogo.png", 183, 20, 15)

    def footer(self, pdf):
        pdf.image("/home/basan/internship-codes/altheader.png", 0, 285, WIDTH)
        pdf.set_margins(0,0,0)
        pdf.set_y(-8.3)
        pdf.cell(w= 0, h=0, txt = str(pdf.page_no()) + '        ', ln = 3, align = 'R')
        pdf.set_y(0)

    def create_pdf(self):

        pdf = FPDF()
        pdf.set_auto_page_break(False, 0)
        pdf.add_page()
        pdf.set_margins(13,0,0)
        day = "01/09/2021"
        self.traingle_header(pdf, day)
        self.footer(pdf)
        #pdf.set_auto_page_break(True)
        self.usage_for_every_host(pdf)
        path, width = self.all_hosts_pie_chart(pdf)
        self.add_figure(path, pdf, width, True)

        pdf.output("cpu-reports/" + self.client.client_name+"-example1.pdf")

    #a chart that shows weekly CPU usage for an host of a single client. (7 days)
    #Hangi gunler daha cok kullanilmis
    def weekly_bar_chart(self, title, df, hostname, clientname):
        plt.clf()
        client_days = df.select(dayofweek('HR_Time')).distinct().orderBy('dayofweek(HR_Time)')
        #empty arrays to be filled (will be used in matplotlib graphs)
        labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
        x =[]
        y = []
        temp = []
        weeks = 4*24

        for aday in client_days.collect():
            x.append(aday[0])
            #her saat icin avg processor time columni topla
            df_for_day = df.filter(dayofweek('HR_Time') == lit(aday[0])).groupBy().sum('AVG_%_Processor_Time')
            temp.append(df_for_day.toPandas()["sum(AVG_%_Processor_Time)"].values.tolist())

        for i in range(0,len(temp)):
            y.append(temp[i][0])

        y1 = [value / weeks for value in y]

        plt.rcParams['axes.edgecolor']='#333F4B'
        plt.rcParams['axes.linewidth']=0.8
        plt.rcParams['xtick.color']='#333F4B'
        plt.rcParams['ytick.color']='#333F4B'

        plt.xticks(x, labels)
        plt.title(title)
        plt.bar(x,y1,color=(0.2, 0.4, 0.6, 0.6))
        #ax = sns.barplot(y= "Deaths", x = "Causes", data = deaths_pd, palette=("Blues_d"))
        #sns.set_context("poster")
        plt.savefig('./charts/weekly'+clientname+hostname+'.jpg')

    #a chart that shows hourly CPU usage for an host of a single client (24 hours).
    #Hangi saatler daha cok kullanilmis
    def hourly_line_chart(self, title, df, hostname, clientname):
        plt.clf()
        client_hours = df.select(hour('HR_Time')).distinct().orderBy('hour(HR_Time)')
        #empty arrays to be filled (will be used in matplotlib graphs)
        x = []
        y = []
        temp = []
        days = 31

        for anhour in client_hours.collect():
            x.append(anhour[0]) #insert hour names into array to be used in x axis
            #her saat icin avg processor time columni topla
            df_for_hour = df.filter(hour('HR_Time') == lit(anhour[0])).groupBy().sum('AVG_%_Processor_Time')
            temp.append(df_for_hour.toPandas()["sum(AVG_%_Processor_Time)"].values.tolist())

        for i in range(0,len(temp)):
            y.append(temp[i][0])

        y1 = [value / days for value in y]

        plt.rcParams['axes.edgecolor']='#333F4B'
        plt.rcParams['axes.linewidth']=0.8
        plt.rcParams['xtick.color']='#333F4B'
        plt.rcParams['ytick.color']='#333F4B'

        plt.xticks(x)
        plt.title(title)
        plt.plot(x,y1)
        plt.grid(True)
        plt.savefig('./charts/'+clientname+hostname+'.jpg')

    #a chart that shows total percentage usage of CPU of every host
    #Hangi host daha cok kullanmis
    def all_hosts_pie_chart(self, pdf):
        plt.clf()
        labels = self.client.hostnames
        sizes = []
        d2_sizes = []
        for host in self.client.hostnames:
            df = self.client.hosts_dataframes[host].select('AVG_%_Processor_Time').groupBy().sum()
            d2_sizes.append(df.toPandas()["sum(AVG_%_Processor_Time)"].values.tolist())

        for i in range(0,len(d2_sizes)):
            sizes.append(d2_sizes[i][0])

        #fig1, ax1 = plt.subplots(figsize=(3, 3))
        #fig1, ax1 = plt.subplots()
        #fig1.subplots_adjust(0.1,0,1,1)

        colors = cm.rainbow(np.linspace(0, 1, len(sizes)))
        plt.gca().axis("equal")
        plt.pie(sizes, labels=labels, colors=colors, autopct = '%1.1f%%', pctdistance=1.25, labeldistance=0.9, textprops={'fontsize': 8})
        plt.title("Total Percentage Usage per Host in 1 month")
        path = "/home/basan/internship-codes/charts/"+self.client.client_name+'allhosts.jpg'
        #legend_labels = ['%s, %1.1f %%' % (l, s) for l, s in zip(labels, sizes)]
        #plt.legend(pie[0], labels=labels, bbox_to_anchor=(0.5,0.5), loc='center right', fontsize=8)
        #plt.subplots_adjust(left=0.1, bottom=0.1, right=0.11)
        plt.savefig(path)
        width = 3*WIDTH/5
        return path, width

class OverallReport:
    def __init__(self, dataframe):
        self.dataframe = dataframe

    def client_usage(self):
        client_hours = []
        cli = []
        client_dataframes = []

        for i in self.clients:
            client_dataframes.append(self.dataframe.filter(self.dataframe.Server_Name.contains(i) & self.dataframe.Processor.contains('_Total')))

        for client in client_dataframes:
            df = client.select('AVG_%_Processor_Time').groupBy().sum()
            client_hours.append(df.toPandas()["sum(AVG_%_Processor_Time)"].values.tolist())

        for c in client_hours:
            cli.append(c[0])

        sizes = cli
        labels = ['aig', 'eti', 'tuv', 'aho', 'zor']

        fig1, ax1 = plt.subplots(figsize=(3, 3))
        fig1.subplots_adjust(0.1,0,1,1)

        theme = plt.get_cmap('flag')
        ax1.set_prop_cycle("color", [theme(1. * i / len(sizes)) for i in range(len(sizes))])

        ax1.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90, radius=100)
        ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
        plt.title("Total Client Usage")
        plt.savefig('client_usage.jpg')

if __name__ == "__main__":
    conf = pyspark.SparkConf().set("spark.jars.packages", "org.mongodb.spark:mongo-spark-connector_2.12:3.0.1").setMaster("local").setAppName("newApp").setAll([("spark.driver.memory", "15g"), ("spark.executer.memory", "20g")])
    sc = SparkContext(conf=conf)

    sqlC = SQLContext(sc)

    spark = SparkSession.builder \
    .master('local[*]') \
    .config("spark.driver.memory", "15g") \
    .appName('newApp') \
    .getOrCreate()

    mongo_ip = "mongodb://localhost:27017/basanto."
    iris = read_from_database(mongo_ip)
    dataframe = create_partition(iris, spark)

    clients = [] #names of clients
    client_dataframes = {} #dataframes of clients
    clients, client_dataframes = extract_dataframes(dataframe)
    client_objects = {} #dictionary of client objects

    for client in clients:
        client_objects[client] = Client(client_dataframes[client], spark, client)
        print(client)
        ClientReport(client_objects[client])

    OverallReport(dataframe)


import torch
import torch.nn as nn

from models.world_model import WorldModel

def expand_world_model_embedding(world_model: WorldModel) -> None:
    # we need to modify the Embedder of the world model, because
    # now the there are two more actions added.
    config = world_model.config

    embedding_tables = world_model.embedder.embedding_tables
    act_vocab_size, obs_vocab_size = (
        embedding_tables[0].weight.shape[0],
        embedding_tables[1].weight.shape[0]
    )

    assert act_vocab_size == world_model.act_vocab_size

    vocab_embedding = nn.Embedding(act_vocab_size + 2, config.embed_dim)
    vocab_embedding.weight.data[:act_vocab_size] = world_model.embedder.embedding_tables[0].weight.data

    new_embedding_tables = nn.ModuleList([
        vocab_embedding,
        embedding_tables[1]
    ]).to(next(world_model.parameters()).device)

    world_model.embedder.embedding_tables = new_embedding_tables


# -*- coding: utf-8 -*-

from __future__ import annotations

import logging
import os
import sys
from collections.abc import Mapping
from typing import Optional, Union

def _setup_handlers(logger, handlers=None, reset=True):
    if reset:
        for handler in logger.handlers[:]:
            logger.removeHandler(handler)
            handler.close()

    if handlers:
        for handler in handlers:
            logger.addHandler(handler)

def _setup_formaters(logger, format_):
    for handler in logger.handlers:
        handler.setFormatter(logging.Formatter(format_))

def _setup_logger(logger, level, format_, handlers):
    logger.setLevel(level)
    _setup_handlers(logger, handlers, reset=True)
    _setup_formaters(logger, format_)

#  pylint: disable=redefined-builtin
def setup_logger(
    logger: Optional[logging.Logger] = None,
    level: Optional[Union[int, str]] = logging.INFO,
    format: str = "%(asctime)s %(name)s %(levelname)s: %(message)s",
    force: bool = True,
    stream: bool = True,
    filename: Optional[Union[str, bytes, os.PathLike]] = None,
    **kwargs,
) -> None:
    handlers = []
    if stream:
        handlers += [logging.StreamHandler()]

    if filename:
        handlers += [logging.FileHandler(filename)]

    if logger is not None:
        _setup_logger(logger, level, format, handlers)
        return

    kwargs = {"level": level, "format": format, "handlers": handlers}
    if force:
        if sys.version_info < (3, 8):
            _setup_handlers(logging.root, reset=True)
        else:
            kwargs["force"] = force

    logging.basicConfig(**kwargs)

def log_dict(_logger: logging.Logger, d: Mapping, sep: str = " = ") -> None:
    for key, value in d.items():
        _logger.info(f"{key}{sep}{value}")


from PyQt5 import QtCore, QtGui, QtWidgets

class AddAuthorUI(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(656, 157)
        self.authorEdit = QtWidgets.QLineEdit(Form)
        self.authorEdit.setGeometry(QtCore.QRect(30, 40, 581, 22))
        self.authorEdit.setReadOnly(False)
        self.authorEdit.setObjectName("authorEdit")
        self.addAuthorButton = QtWidgets.QPushButton(Form)
        self.addAuthorButton.setGeometry(QtCore.QRect(30, 110, 581, 28))
        self.addAuthorButton.setObjectName("addAuthorButton")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.authorEdit.setPlaceholderText(_translate("Form", "Автор"))
        self.addAuthorButton.setText(_translate("Form", "Добавить автора"))


from pathlib import Path
import math

def parse_input(path: str):
    return Path(path).read_text().split("\n")

def get_sounding_heights(x: int, y: int, floor_map: list):
    try:
        right = int(floor_map[y][x + 1])
    except IndexError:
        right = 9
    try:
        left = int(floor_map[y][x - 1]) if 0 <= x - 1 else 9
    except IndexError:
        left = 9
    try:
        up = int(floor_map[y - 1][x]) if 0 <= y - 1 else 9
    except IndexError:
        up = 9
    try:
        down = int(floor_map[y + 1][x])
    except IndexError:
        down = 9
    return int(right), int(left), int(up), int(down)

def find_basin(x: int, y: int, floor_map: list, included_positions):

    included_positions.add((x, y))
    right, left, up, down = get_sounding_heights(x, y, floor_map)

    if right != 9 and (x + 1, y) not in included_positions:
        included_positions.union(find_basin(x + 1, y, floor_map, included_positions))
    if left != 9 and (x - 1, y) not in included_positions:
        included_positions.union(find_basin(x - 1, y, floor_map, included_positions))
    if up != 9 and (x, y - 1) not in included_positions:
        included_positions.union(find_basin(x, y - 1, floor_map, included_positions))
    if down != 9 and (x, y + 1) not in included_positions:
        included_positions.union(find_basin(x, y + 1, floor_map, included_positions))
    return included_positions

def main():
    floor_map = parse_input("advent_of_code/2021/advent_of_code_day9/input.txt")
    total_risk = 0
    basins = []
    basin_sizes = []
    for y in range(len(floor_map)):
        for x in range(len(floor_map[0])):
            right, left, up, down = get_sounding_heights(x, y, floor_map)
            current_pos_height = int(floor_map[y][x])
            if (
                current_pos_height < right
                and current_pos_height < left
                and current_pos_height < up
                and current_pos_height < down
            ):
                total_risk += current_pos_height + 1
                basin = find_basin(x, y, floor_map, set())
                basin_sizes.append(len(basin))
                basins.append(basin)

    print(f"Part 1: {total_risk}")

    basin_sizes.sort()
    print(f"Part 2: {math.prod(basin_sizes[-3:])}")

    symbols = "#?*.-&%|<>!'"
    for i, basin in enumerate(basins):
        for x, y in basin:
            floor_map[y] = (
                floor_map[y][:x] + symbols[i % len(symbols)] + floor_map[y][x + 1 :]
            )
    with open("advent_of_code/2021/advent_of_code_day9/output.txt", "w") as out_file:
        for row in floor_map:
            out_file.write(row.replace("9", " ") + "\n")

if __name__ == "__main__":
    main()


from django.urls import path
from . import views
from django.conf.urls import url
from users.views import DependantListAPIView

urlpatterns = [
    path('dependants/', views.DependantListAPIView.as_view(),
         name=views.DependantListAPIView.name),
    path('dependants/<uuid:pk>/', views.DependantDetailAPIView.as_view(),
         name=views.DependantDetailAPIView.name),
    path('dependants/<uuid:pk>/prescription', views.PrescriptionCreate.as_view(),
         name=views.PrescriptionCreate.name),
    path('prescriptions/', views.PrescriptionList.as_view(),
         name=views.PrescriptionList.name),
    path('prescriptions/<uuid:pk>', views.PrescriptionDetail.as_view(),
         name=views.PrescriptionDetail.name),
    path('prescriptions/<uuid:pk>/', views.PrescriptionUpdate.as_view(),
         name=views.PrescriptionUpdate.name),

    path('prescriptions/<uuid:pk>/item', views.PrescriptionItemCreate.as_view(),
         name=views.PrescriptionItemCreate.name),
    path('prescription-items/', views.PrescriptionItemList.as_view(),
         name=views.PrescriptionItemList.name),
    path('prescription-items/<uuid:pk>', views.PrescriptionItemDetail.as_view(),
         name=views.PrescriptionItemDetail.name),
    # path('prescription-items/<uuid:pk>/', views.PrescriptionItemUpdate.as_view(),
    #      name=views.PrescriptionItemUpdate.name),

]


import json;
import vilo; app = vilo.buildApp(); wsgi = app.wsgi;

pasteMap = {};  # In-memory paste storage.

@app.route("GET", "/")
def get_homepage (req, res):
    return vilo.escfmt("""

TestBin: In-Memory Pastebin

            Visit /compose to compose a new paste.

            Go to /paste/{Paste-ID-here} to view a paste.

Paste IDs: %s

    """, json.dumps(list(pasteMap.keys()), indent=4));

@app.route("GET", "/compose")
def get_compose (req, res):
    return """

Compose Paste:

        <form method="POST" style="max-width: 500px;">
            <input type="text" name="title" placeholder="Title" style="width: 100%;">

            <textarea name="body" placeholder="Body ..." rows="10" style="width: 100%;"></textarea>

            <button>Submit</button>
        </form>

< Home

    """;

@app.route("POST", "/compose")
def post_compose (req, res):
    title = req.fdata.get("title") or "(Blank Title)";
    body = req.fdata.get("body") or "(Blank Body)";
    pasteId = len(pasteMap) + 1;
    pasteMap[pasteId] = vilo.dotsi.fy({
        "id": pasteId, "title": title, "body": body,
    });
    assert len(pasteMap) == pasteId;
    return vilo.escfmt("""

Paste Created!

            Visit /paste/%s to view your paste,
            or /compose to compose another.

< Home

    """, [pasteId, pasteId]);

@app.route("GET", "/paste/*")
def get_paste (req, res):
    pid = req.wildcards[0];
    if not (pid.isdigit() and int(pid) in pasteMap):
        raise vilo.error("
No such paste.
", 404);
    paste = pasteMap[int(pid)];
    return vilo.escfmt("""

Paste ID: %(id)s

%(title)s

%(body)s

< Home

    """, paste);

# Error related: :::::::::::::::::::::::::::::::::::::::::::

@app.frameworkError("route_not_found")
def error_routeNotFound (req, res, err):
    return "That route couldn't be found.";

@app.route("GET", "/static/**")
def get_static (req, res):
    relpath = req.wildcards[0];
    return res.staticFile("./static/no.such.path/" + relpath);

@app.frameworkError("file_not_found")
def error_fileNotFound (req, res, err):
    return "No such file.";

@app.route("GET", "/500")
def get_500 (req, res):
    1/0;
    assert False;

@app.frameworkError("unexpected_error")
def error_unexpected (req, res, err):
    return "Something broke.";

@app.route("GET", "/foo/*")
def get_foo (req, res):
    return vilo.escfmt("%s", repr(req.wildcards[0]));

@app.route("GET", "/redirect-home")
def get_redirHome (req, res):
    return res.redirect("/");


import pytest
import nvme as d

import time
import logging

rand = True
seq = False
TEST_SCALE = 100    #100, 10

def do_fill_drive(rand, nvme0n1, region_end, nvme0):
    io_size = 8 if rand else 128
    ns_size = nvme0n1.id_data(7, 0)
    io_count = ns_size//io_size
    io_per_second = []

    w = nvme0n1.ioworker(io_size=io_size, lba_align=io_size,
                     lba_random=rand, qdepth=512,
                     region_end=region_end,
                     io_count=io_count, read_percentage=0,
                     output_io_per_second=io_per_second).start()
    while w.running:
        nvme0.getfeatures(7).waitdone()
        time.sleep(1)
    r = w.close()
    logging.info(io_per_second)

# full drive seq write
def test_clean_and_fill_drive(nvme0, nvme0n1):
    nvme0n1.format(512)
    do_fill_drive(seq, nvme0n1, nvme0n1.id_data(7, 0), nvme0)

# random write 20% region to steady
def test_random_write_small_region(nvme0, nvme0n1):
    do_fill_drive(rand, nvme0n1, nvme0n1.id_data(7, 0)//5, nvme0)

# iops: read/write/mixed
# latency: read/write/mixed
@pytest.mark.parametrize("readp", [100, 90, 67, 50, 33, 10, 0])
def test_steady_iops_latency(nvme0, nvme0n1, readp):
    percentile_latency = dict.fromkeys([50, 90, 99, 99.9, 99.999])
    io_per_second = []

    w = nvme0n1.ioworker(io_size=8, lba_align=8,
                         lba_random=rand, qdepth=64,
                         region_end=nvme0n1.id_data(7, 0)//5,
                         time=TEST_SCALE, read_percentage=readp,
                         output_percentile_latency=percentile_latency,
                         output_io_per_second=io_per_second).start()
    while w.running:
        nvme0.getfeatures(7).waitdone()
        time.sleep(1)
    r = w.close()
    logging.info(io_per_second)
    consistency = w.iops_consistency(90)
    logging.info(percentile_latency)
    max_iops = (r.io_count_read+r.io_count_nonread)*1000//r.mseconds
    logging.info(max_iops)

    with open("report.csv", "a") as f:
        f.write('%d\n' % readp)
        f.write('%.2f\n' % (consistency/100))
        f.write('%d\n' % percentile_latency[99.9])
        f.write('%d\n' % max_iops)

    # latency against iops
    for iops_percentage in [20, 40, 60, 80, 100]:
        iops = max_iops*iops_percentage//100
        w = nvme0n1.ioworker(io_size=8, lba_align=8,
                             lba_random=rand, qdepth=64,
                             iops=iops,
                             region_end=nvme0n1.id_data(7, 0)//5,
                             time=TEST_SCALE, read_percentage=readp,
                             output_percentile_latency=percentile_latency).start()
        while w.running:
            nvme0.getfeatures(7).waitdone()
            time.sleep(1)
        r = w.close()
        logging.info("iops %d, latency %dus" % (iops, r.latency_average_us))

        # write to report
        with open("report.csv", "a") as f:
            f.write('%d\n' % iops)
            f.write('%d\n' % r.latency_average_us)


class node:
    def __init__(self,data,next):
        self.data = data
        self.next = next

class Linked_List:
    def __init__(self):
        self.head = None

    def insert_node_begin(self,data):
        self.head = node(data,self.head)

    def print(self):
        temp = self.head
        x = ""
        while temp:
            x += str(temp.data)+"->"
            temp = temp.next
        print(x)

if __name__ == '__main__':
    sike = Linked_List()
    sike.insert_node_begin(5)
    sike.insert_node_begin(7)
    sike.print()


from colorama import Fore
from tictactoe import TicTacToe
from Board import Board
import random

initialBoard = Board()
print("The initial state of board is as follow- ")
initialBoard.printBoard()
print("\t1) Tiles numbered in color white are empty spaces.")
print("\t2) Tiles numbered in color green are filled by user.")
print("\t3) And the Tiles numbered in red are filled by the computer(AI).")

game = TicTacToe(initialBoard)
state = random.randrange(0, 2)
while(True):
    if state:
        game.startUserMove()
        game.startComputerMove()
    else:
        game.startComputerMove()
        game.startUserMove()


from typing import Optional, List

from fastapi import APIRouter, Depends

from helpers.auth import oauth2_scheme, is_admin
from helpers.users import UserHelper
from models import RoleTypes
from schemas.responses.users import UserOut

router = APIRouter(tags=["Users"])

@router.get(
    "/users/users/",
    dependencies=[Depends(oauth2_scheme), Depends(is_admin)],
    response_model=List[UserOut],
)
async def get_users(username: Optional[str] = None):
    if username:
        return await UserHelper.get_user_by_username(username=username)
    return await UserHelper.get_all_users()

@router.put(
    "/users/{user_id}/make-admin",
    dependencies=[Depends(oauth2_scheme), Depends(is_admin)],
    status_code=204,
)
async def make_admin(user_id: int):
    await UserHelper.change_role(RoleTypes.admin, user_id)
    return {"success": True}

@router.put(
    "/users/{user_id}/make-scraper",
    dependencies=[Depends(oauth2_scheme), Depends(is_admin)],
    status_code=204,
)
async def make_scraper(user_id: int):
    await UserHelper.change_role(RoleTypes.scraper, user_id)
    return {"success": True}


import pandas as pd
import numpy as np
from rdkit import Chem
from rdkit.Chem import rdMolDescriptors,Draw,AllChem
from rdkit.Chem.Draw import IPythonConsole
from IPython.display import SVG, display
import urllib.request
import requests
import os
import csv
from pprint import pprint
import re
import itertools
#import util
#sys.setrecursionlimit(10000)
from type_conversion import smarts_to_smiles, circular_fingerprints, similarity_check, running_through_all_reaction_templates
from rdkit import DataStructs
from rdkit import RDLogger
from type_conversion import moltosmiles
import numpy as np
import rdkit.Chem.Descriptors as Descriptors
import rdkit.Chem.rdMolDescriptors as rdMolDescriptors
import rdkit.Chem.EState as EState
import rdkit.Chem.rdPartialCharges as rdPartialCharges
import rdkit.Chem.rdChemReactions as rdRxns
import rdkit.Chem.rdChemReactions as ReactionFromSmarts
from rdkit.Chem import rdChemReactions
from chemical_module import Chemical
from reaction import Reaction
from rdkit.Chem import rdMolDescriptors,Draw,AllChem
from rdkit.Chem.Draw import IPythonConsole
from IPython.display import SVG, display

att_dtype = np.float32
RDLogger.DisableLog('rdApp.*')

def kegg_data():
    kegg_reactions = pd.read_csv("ATLAS_Curated_KEGG_Reactions.csv")

def reaction_rules():
    return pd.read_csv("retrorules_rr02_rp2_flat_retro.csv")

def SMILE_rxn_rules():
    return pd.read_csv("SMILE_reaction_rules.csv")

def breaking(string):
    """We have long kegg ID strings but since we know that they can be only of length 6 we
    are splitting them into parts of 6."""
    return [string[start:start+6] for start in range(0, len(string), 6)]

def conversion(data):
    """
    Kegg reactions are not directly writing molecular compounds but they reference each compound by
    using something called kegg ID, which is unique for each compound.
    """
    temp= []
    for i in range(0,data.shape[0]):
        temp.append((data.REACTION[i]).split(" "))
    su = ""
    for i in range(0,len(data.REACTION)):
        su +=str(data.REACTION[i])
    import re
    res = re.sub('\(.*?\)','', su).split(" ")
    temp = []
    for i in range(0,len(res)):
        if "C" in res[i]:
            temp.append(res[i])
    stage2 = ""
    for i in range(0,len(temp)):
        stage2 +=str(temp[i])
    stage3 = []
    stage3 = stage2.split("+")
    stage4 = []
    for i in range(0,len(stage3)):
        if len(stage3[i])==6:
            stage4.append(stage3[i])
        if len(stage3[i])> 6:
            stage4.extend(breaking(stage3[i]))
    return list(set(stage4))

def collecting_reactions_kegg(data):
    """
    Objective:- This function makes a call to the kegg api makes a list of lists with index 1 returning the Kegg ID and second index
    being the kegg compund formula.
    Input:- I have made a function call within this function which already does that,
    NOT NEEDED(please input a list containing the kegg id which you wish to query, these need to input one at a time
    without any seperator or plus, stoichometric coefficeints).
    Output:- [kegg ID, corresponding SMILES string]
    Return Type : Lists of lists
    """
    def ses(url_t):
        with urllib.request.urlopen(url_t) as kegg:
            data = kegg.read()

        try:
            textfile = open('demo20.txt', 'wb')
            textfile.write(data)
            textfile.close()
            demo = Chem.MolFromMolFile('demo20.txt')
            return Chem.MolToSmiles(demo)

        except:
            os.remove('demo20.txt')

    list_url = []
    stage4 = conversion(data)
    unprocessed = []
    print(stage4[0:10])
    for i in range(0,len(stage4)):
        url_t = 'http://rest.kegg.jp/get/%s/mol'%(stage4[i])
        if i != 17:
            try:
                list_url.append([stage4[i],ses(url_t)])
                print(len(list_url))
            except :  # This is the correct syntax
                unprocessed.append(stage4[i])
                pass
    return list_url, unprocessed

print("this is working")

def split_into_reactions_products(string):
    """
    Input:-  would be a string which will check the position of <=> special character and based on that split the
    data into reactents and products. Another issue which we did not want to run into was dealing with spacing
    stoichometric coefficients, so this function would also be removing them as well.

    Output:- 2 strings, first one would be the reactent and other one would be product.
    """
    reactent,product = [],[]
    #string = string.split(" ")
    index = string.index("<=>")
    reactent.append(string[:index -1])
    product.append(string[index+3:])
    reactent, product =  re.sub(r'\([^)]*\)', '',reactent[0]), re.sub(r'\([^)]*\)', '',product[0])
    return " ".join(reactent.split()), " ".join(product.split())

def smiles(kegg_id,dictionary):
    """
    Input :
        1. Kegg ID
        2. Dictionary with the kegg-smiles conversion already defined
    Output:-
        Return type : SMILE string
    """
    return dictionary[kegg_id]

def kegg_dictionary():
    """
    Input : The location of this smiles file with only 2 columns,
    Column 1: Name of the kegg Compound
    Column 2: Corresponding SMILE String

    Output : Format Dictionary
        1. keys are the names of compounds,
        2. values are the SMILE strings

    """

    class ListDict(dict):
        """ Dictionary who's values are lists. """
        def __missing__(self, key):
            value = self[key] = []
            return value

    filename = 'keggsmiles.csv'

    lstdct = ListDict()
    with open(filename, "rt") as csvfile:
        for row in csv.reader(csvfile, delimiter=','):
            key, value = row[:2]
            lstdct[key].append(value)
    return lstdct

def dictionary_mapping(lis,dictionary):
    """
    Input: String Format

    The input must either be the the whole of reactents and whole of products, which must be in string format
    seperated by + sign without having stoichometric coefficients"""
    #my_string = ""
    my_string = []
    plus = lis.split("+")
    for i in range(0,len(plus)):
        #my_string += str(smiles(plus[i],dictionary))
        my_string.append(smiles(plus[i],dictionary))
    return my_string

def original_kegg_reactions(kegg_reactions,converting_dictionary):
    """
    MAIN function:- Kegg Datset
    This function should be able to generate the smiles of the origial kegg
    Return type: List 1: Reactents, List 2: Products
    """
    #oro = unconverted_kegg_reactions()
    lstdct = converting_dictionary()
    REA, PRO = [],[]
    for i in range(0,kegg_reactions.REACTION.shape[0]):
        #print(i)
        r, p = split_into_reactions_products(kegg_reactions.REACTION[i])
        #print(p)
        REA.append(dictionary_mapping(r,lstdct))
        PRO.append(dictionary_mapping(p,lstdct))
    return REA, PRO

def reducing_reaction_rules(data,cutoff = 50):
    """
    Input: Extracted reaction rules which should have 2 columns one with smarts format and more
    importantly a smile format with column name "SMILES".,
    optional argument: Cutoff value for how many times should that rule at least occur in the reactions
    database.
    Output: reduced set of reaction rules
    Example :-
    SMILE_rxn_rules = pd.read_csv("/Users/aasimwani/Downloads/MS research/extractedData/SMILE_reaction_rules.csv")
    reducing_reaction_rules(SMILE_rxn_rules,cutoff = 100)
    """
    #SMILE_rxn_rules = pd.read_csv("/Users/aasimwani/Downloads/MS research/extractedData/SMILE_reaction_rules.csv")
    number_list = np.array(data["REACTION_RULES"])
    (unique, counts) = np.unique(number_list, return_counts=True)
    frequencies = np.asarray((unique, counts)).T
    bot = pd.DataFrame(frequencies,columns = ["strings","counts"])
    counted = bot.sort_values(by ='counts',ascending = False )
    total = np.sum(counted["counts"])
    return counted.loc[counted["counts"]> cutoff]

def classififes_negative_reaction():
    """
    This self contained function should be converting the kegg reactions smiles and using more then one product to create;
    this function would sort the list of products based on the length of the smile string. The first one would be classified as the
    more important string classified as positive strings and others which are smaller in length strings would be classifies as negative
    strings. There exist multiple null reactions in the datacase wich will also need to be removed.
    """
    REA, PRO = original_kegg_reactions(kegg_reactions(),converting_dictionary=kegg_dictionary())
    temp = []
    for i in range(0,len(PRO)):
        current_length = len(PRO[i])
        if current_length >1:
            sorted_product = list(reversed(sorted(PRO[i], key=len)))
            for j in range(0,current_length):
                if sorted_product[j]:
                    if j == 0 :
                        temp.append([REA[i],sorted_product[j],"Positive"])
                    else:
                        temp.append([REA[i],sorted_product[j],"Negative"])
                else:
                    pass
        else:
            temp.append([REA[i],PRO[i],"Positive"])
    df = pd.DataFrame(temp)
    df.columns = ["Reactent","Product","Type"]
    return df

def generating_reaction_fingerprints():
    def circular_fingerprint(smile_string):
        mol = Chem.MolFromSmiles(smile_string)
        bi = {}
        fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, bitInfo=bi)
        return fp.ToBitString()

    def encoding(current_element):
        return [int(item) for item in circular_fingerprint(current_element)]

    def making_product_reactents_morgan_fingerprints(a_a):
        merging_element_df = []
        temporary_merging_element = np.zeros((1,2048))
        for i in range(0,len(a_a)):
            for j in range(0,len(a_a[i])):
                item = a_a[i][j]
                if item != []:
                    temporary_merging_element+=encoding(item[0])
                #print(len(merging_element_df))
                temporary_merging_element = np.zeros((1,2048))
            merging_element_df.append(temporary_merging_element)
        return merging_element_df

    REA, PRO = original_kegg_reactions(kegg_reactions,converting_dictionary=kegg_dictionary)
    a  = making_product_reactents_morgan_fingerprints(REA)
    reactent_fingerprints = pd.DataFrame([item[0] for item in a])
    b  = making_product_reactents_morgan_fingerprints(PRO)
    product_fingerprints = pd.DataFrame([item[0] for item in b])
    reaction_fingerprints = np.add(reactent_fingerprints,product_fingerprints)
    return reaction_fingerprints

def generating_products_from_reaction_rules(molefile,cutoff):
    """
    Input - Molefile of the
    Number_of_rules - number of reaction rules which you want to generate reactents
    """
    #morphine = Chem.MolFromMolFile("/Users/aasimwani/Downloads/MolData/morphine.mol")
    ruleDF = pd.read_csv("retrorules_rr02_rp2_flat_retro.csv")
    SMILE_rxn_rules = pd.read_csv("SMILE_reaction_rules.csv")
    extracted_reaction_rules = reducing_reaction_rules(SMILE_rxn_rules,cutoff)
    rules = pd.DataFrame(pd.merge(extracted_reaction_rules.reset_index(),ruleDF.reset_index(),how = "inner",on = "index")["Rule"])
    item = []
    negative_reactions = []
    for i in range(0,rules.shape[0]):
        from rdkit.Chem import rdChemReactions
        rxn = rdChemReactions.ReactionFromSmarts(rules["Rule"][i])
        reacts = Chem.AddHs(Chem.MolFromSmiles(molefile))
        products = rxn.RunReactants((reacts,))
        item.append(products)
        if products == ():
            negative_reactions.append([molefile,rdChemReactions.ReactionFromSmarts(rules['Rule'][i])])
    formatted = list(itertools.chain(*item))
    let = []
    for i in range(0,len(formatted)):
        let.append(Chem.MolToSmiles(formatted[i][0]))
    a = pd.DataFrame(let)
    a.columns = ["ar1"]
    only_uniques = a["ar1"].unique()
    return only_uniques, negative_reactions

def please_work(initial,target,cutoff):
    def reaction_rules_final(cutoff):
        data = pd.read_csv("retrorules_rr02_rp3_nohs/retrorules_rr02_flat_all.tsv",sep='\t')
        number_list = np.array(data["Rule_SMARTS"])
        (unique, counts) = np.unique(number_list, return_counts=True)
        frequencies = np.asarray((unique, counts)).T
        bot = pd.DataFrame(frequencies,columns = ["strings","counts"])
        counted = bot.sort_values(by ='counts',ascending = False )
        unique_strings = np.array(counted.loc[counted["counts"]> cutoff]["strings"])
        return unique_strings

    def state_space_generation(molefile,unique_strings):
        item = []
        from rdkit.Chem import rdChemReactions
        molefile = morphine()
        for i in range(0,len(unique_strings)):
            rxn = rdChemReactions.ReactionFromSmarts(unique_strings[i])
            reacts = Chem.MolFromSmiles(molefile)
            products = rxn.RunReactants((reacts,))
            if products != ():
                item.append(products)
        formatted = list(itertools.chain(*item))
        print("Number of Possible poducts generated are", len(formatted))
        string_for_morphine = [Chem.MolToSmiles(item[0]) for item in formatted]
        return string_for_morphine

    def searching_state_space_for_desired_product(possible_reactants,pattern):
        totalParts = []
        for item in possible_reactants:
            subparts = (item.split("."))
            totalParts.append(subparts)
        found_it = []
        positions = []
        for i in range(0,len(totalParts)):
            m = Chem.MolFromSmiles(pattern)
            patt = Chem.MolFromSmiles(totalParts[i][0])
            if patt.HasSubstructMatch(m) and m.HasSubstructMatch(patt):
            #if patt.HasSubstructMatch(m):
                found_it.append(Chem.MolFromSmiles(totalParts[i][0]))
                positions.append(i)
        return found_it, positions

    r1 = reaction_rules_final(49)
    possible_products = state_space_generation(initial,r1)
    r3,r4 = searching_state_space_for_desired_product(possible_products,target)
    return ("Index position where target molecule is found in state space:",r4 )

def get_hydrogen_atoms(my_mol):
    my_mol = Chem.MolFromSmiles(moltosmiles(my_mol))
    my_mol_with_explicit_h = Chem.AddHs(my_mol)
    return my_mol_with_explicit_h.GetNumAtoms() - my_mol_with_explicit_h.GetNumHeavyAtoms()

def reversing_smarts():
    data = pd.read_csv("retrorules_rr02_rp3_nohs/retrorules_rr02_flat_all.tsv",sep='\t')
    number_list = np.array(data["Rule_SMARTS"])
    reversed_strings = []
    for i in range(0,len(number_list)):
        reaction_smarts_retro = number_list[i].split(">>")[1] + ">>" + number_list[i].split(">>")[0]
        reversed_strings.append(str(reaction_smarts_retro))
    return reversed_strings
"""
    all_values = []
    current_max = []
    for i in range(0,len(REA)):
        for item in REA[i]:
            if item != []:
                temp = get_hydrogen_atoms(item[0])
            current_max.append(temp)
        all_values.append(max(current_max))

    Y = pd.DataFrame(all_values)
    salutaridine =  "COC1=C[C@]23CCN(C)[C@H](Cc4ccc(OC)c(O)c24)C3=CC1=O"
r_reticulene = "CN1CCC2=CC(=C(C=C2[C@@H]1CC3=CC(=C(C=C3)OC)O)O)OC"
s_reticulene = "COc1ccc(C[C@@H]2N(C)CCc3cc(OC)c(O)cc23)cc1O"
s_n_methyl_coculaurine = "COc1cc2CCN(C)[C@@H](Cc3ccc(O)cc3)c2cc1O"
#s_coculaurine = "COc1cc2CCN[C@@H](Cc3ccc(O)cc3)c2cc1O"
s_coculaurine= "COc1cc2c(cc1O)[C@H](Cc1ccc(O)cc1)NCC2"
#COC1=C(C=C2C(NCCC2=C1)CC3=CC=C(C=C3)O)O
#norococulaurine = "Oc1ccc(C[C@@H]2NCCc3cc(O)c(O)cc23)cc1"
norococulaurine = "Oc1ccc(CC2NCCc3cc(O)c(O)cc32)cc1"

s3_hydroxy_methylcoclaurine = "COc1cc2CCN(C)[C@@H](Cc3ccc(O)c(O)c3)c2cc1O"
salutaridnal = "COC1=C[C@]23CCN(C)[C@H](Cc4ccc(OC)c(O)c42)C3=C[C@@H]1O"

thebaine = "COC1=CC=C2[C@H]3Cc4ccc(OC)c5O[C@@H]1[C@]2(CCN3C)c45"

glucose = "OC[C@H]1O[C@@H](O)[C@H](O)[C@@H](O)[C@@H]1O"
glucose_6p = "O[C@@H]1O[C@H](COP(O)(O)=O)[C@@H](O)[C@H](O)[C@H]1O"

    """

def pushing_through_reaction_for_reaction_centers(status,reactent=None,product = None):
    def extracting(reactant,product):
        R2 = "*"
        temp_reactant, temp_product = [],[]
        for reactant_index in range(0,len(reactant)):
            try:
                if reactant[reactant_index] != []:
                    m = Chem.MolFromSmiles(reactant[reactant_index][0][0])
                    if m is not None:
                        reactant_smarts = Chem.MolToSmarts(m,isomericSmiles=True)
                        temp_reactant.append(reactant_smarts.format(R2))
                    else:
                        pass
            except:
                IndexError
        part1 = ".".join(temp_reactant)
        print(index)
        for product_index in range(0,len(product)):
            try:
                if product[product_index] != []:
                    m = Chem.MolFromSmiles(product[product_index][0][0])
                    if m is not None:
                        product_smarts = Chem.MolToSmarts(m,isomericSmiles=True)
                        temp_product.append(product_smarts.format(R2))
                    if m is None:
                        pass
            except:
                IndexError
        part2 = ".".join(temp_product)
        #print(part2)
        return '>>'.join([part2,part1])

    if status == "training":
        REA, PRO = original_kegg_reactions(kegg_reactions,converting_dictionary=kegg_dictionary)
        extracting_reaction_core_smarts = []
        for index in range(0,len(REA)):
            r_part = ".".join([item[0] for item in REA[index] if item != []])
            p_part = ".".join([item[0] for item in PRO[index] if item != []])
            r_part = str(r_part).replace('*', "C")
            p_part = str(p_part).replace('*', "C")
            extracting_reaction_core_smarts.append(extracting(r_part,p_part))
    if status == "testing":
        extracting_reaction_core_smarts = []
        r_part = ".".join([item[0] for item in reactent if item != []])
        p_part = ".".join([item[0] for item in product if item != []])
        r_part = str(r_part).replace('*', "C")
        p_part = str(p_part).replace('*', "C")
        extracting_reaction_core_smarts.append(extracting(r_part,p_part))

    return extracting_reaction_core_smarts

def getting_reaction_cores():
    REA, PRO = original_kegg_reactions(kegg_reactions,converting_dictionary=kegg_dictionary)
    extracting_reaction_core_smarts = pushing_through_reaction_for_reaction_centers(REA,PRO)
    import os
    from chemical_module import Chemical
    from reaction import Reaction
    from rdkit.Chem import rdChemReactions
    list_of_cores = []
    for i in range(0,len(extracting_reaction_core_smarts)):
        rxn = rdChemReactions.ReactionFromSmarts(extracting_reaction_core_smarts[i])
        rxn_smiles = AllChem.ReactionToSmiles(rxn)
        rxn = Reaction(rxn_smiles, verbose=True)
        core = rxn.find_core()
        list_of_cores.append(core)
    return list_of_cores

def mol_level_descriptors(mol):
	'''
	Given an RDKit mol, returns a list of molecule-level descriptors
	and their names
	returns: (labels, attributes)
	'''

	labels = [label for (label, f) in Descriptors._descList]
	attributes = [f(mol) for (label, f) in Descriptors._descList]

	return (labels, attributes)

def atom_level_descriptors(mol, include = ['functional'], asOneHot = False, ORIGINAL_VERSION = False):
	'''
	Given an RDKit mol, returns an N_atom-long list of lists,
	each of which contains atom-level descriptors and their names
	returns: (label, attributes)
	'''

	attributes = [[] for i in mol.GetAtoms()]
	labels = []
	if 'functional' in include:

		[attributes[i].append(x[0]) \
			for (i, x) in enumerate(rdMolDescriptors._CalcCrippenContribs(mol))]
		labels.append('Crippen contribution to logp')

		[attributes[i].append(x[1]) \
			for (i, x) in enumerate(rdMolDescriptors._CalcCrippenContribs(mol))]
		labels.append('Crippen contribution to mr')

		[attributes[i].append(x) \
			for (i, x) in enumerate(rdMolDescriptors._CalcTPSAContribs(mol))]
		labels.append('TPSA contribution')

		[attributes[i].append(x) \
			for (i, x) in enumerate(rdMolDescriptors._CalcLabuteASAContribs(mol)[0])]
		labels.append('Labute ASA contribution')

		[attributes[i].append(x) \
			for (i, x) in enumerate(EState.EStateIndices(mol))]
		labels.append('EState Index')

		rdPartialCharges.ComputeGasteigerCharges(mol)
		[attributes[i].append(float(a.GetProp('_GasteigerCharge'))) \
			for (i, a) in enumerate(mol.GetAtoms())]
		labels.append('Gasteiger partial charge')

		# Gasteiger partial charges sometimes gives NaN
		for i in range(len(attributes)):
			if np.isnan(attributes[i][-1]):
				attributes[i][-1] = 0.0

		[attributes[i].append(float(a.GetProp('_GasteigerHCharge'))) \
			for (i, a) in enumerate(mol.GetAtoms())]
		labels.append('Gasteiger hydrogen partial charge')

		# Gasteiger partial charges sometimes gives NaN
		for i in range(len(attributes)):
			if np.isnan(attributes[i][-1]):
				attributes[i][-1] = 0.0

	if 'structural' in include:
		[attributes[i].extend(atom_structural(mol.GetAtomWithIdx(i), asOneHot = asOneHot, ORIGINAL_VERSION = ORIGINAL_VERSION)) \
			for i in range(len(attributes))]
		labels.append('--many structural--')

	return (labels, attributes)

def pushing_through_reaction_for_reaction_centers(REA,PRO):
    def extracting(reactant,product):
        R2 = "*"
        temp_reactant, temp_product = [],[]
        for reactant_index in range(0,len(reactant)):
            try:
                if reactant[reactant_index] != []:
                    m = Chem.MolFromSmiles(reactant[reactant_index][0][0])
                    if m is not None:
                        reactant_smarts = Chem.MolToSmarts(m,isomericSmiles=True)
                        temp_reactant.append(reactant_smarts.format(R2))
                    else:
                        pass
            except:
                IndexError
        part1 = ".".join(temp_reactant)
        print(index)
        for product_index in range(0,len(product)):
            try:
                if product[product_index] != []:
                    m = Chem.MolFromSmiles(product[product_index][0][0])
                    if m is not None:
                        product_smarts = Chem.MolToSmarts(m,isomericSmiles=True)
                        temp_product.append(product_smarts.format(R2))
                    if m is None:
                        pass
            except:
                IndexError
        part2 = ".".join(temp_product)
        #print(part2)
        return '>>'.join([part2,part1])
    extracting_reaction_core_smarts = []
    for index in range(0,len(REA)):
        extracting_reaction_core_smarts.append(extracting(REA[index],PRO[index]))
    return extracting_reaction_core_smarts

def training_dataset_features():
    def getting_reaction_cores():
        REA, PRO = original_kegg_reactions(kegg_reactions,converting_dictionary=kegg_dictionary)
        extracting_reaction_core_smarts = pushing_through_reaction_for_reaction_centers(REA,PRO)
        import os
        from chemical_module import Chemical
        from reaction import Reaction
        from rdkit.Chem import rdChemReactions
        list_of_cores = []
        for i in range(0,len(extracting_reaction_core_smarts)):
            rxn = rdChemReactions.ReactionFromSmarts(extracting_reaction_core_smarts[i])
            rxn_smiles = AllChem.ReactionToSmiles(rxn)
            rxn = Reaction(rxn_smiles, verbose=True)
            core = rxn.find_core()
            list_of_cores.append(core)
        return list_of_cores

    def generating_product_reactant_features():
        list_of_cores = getting_reaction_cores()
        product_array = []
        reactant_array = []
        for iteration in range(0,len(list_of_cores)):
            pro_nju = atom_level_descriptors(Chem.MolFromSmiles(list_of_cores[iteration].split(">>")[0]))
            rea_nju = atom_level_descriptors(Chem.MolFromSmiles(list_of_cores[iteration].split(">>")[1]))
            index = 0
            product_addition = np.zeros((1,7))
            reactant_addition = np.zeros((1,7))
            for i in range(0,len(pro_nju[1])):
                product_addition = np.add(product_addition,pro_nju[1][i])
            product_array.append(product_addition)
            for j in range(0,len(rea_nju[1])):
                reactant_addition = np.add(reactant_addition,rea_nju[1][j])
            reactant_array.append(reactant_addition)
        return reactant_array,product_array

    reactent_features, product_features = generating_product_reactant_features()
    reactant_array = [item[0] for item in reactent_features]
    product_array = [item[0] for item in product_features]
    reactant_features = pd.DataFrame(reactant_array)
    product_features = pd.DataFrame(product_array)
    reactant_columns = ['reactant_Crippen contribution to logp',
                        'reactant_Crippen contribution to mr',
                        'reactant_TPSA contribution',
                        'Labute ASA contribution',
                        'reactant_EState Index',
                        'reactant_Gasteiger partial charge',
                        'reactant_Gasteiger hydrogen partial charge']
    product_columns = ['product_Crippen contribution to logp',
                        'product_Crippen contribution to mr',
                        'product_TPSA contribution',
                        'product_Labute ASA contribution',
                        'product_EState Index',
                        'product_Gasteiger partial charge',
                        'product_Gasteiger hydrogen partial charge']
    reactant_features.columns = reactant_columns
    product_features.columns = product_columns
    merged_features = pd.concat([reactant_features,product_features],axis =1)
    #merged_features.drop(columns = ["reactant_EState Index","product_EState Index"],inplace = True)
    return merged_features

"""
path = [morphine, morphinone,oripavine, thebaine, salutaridnol,salutaridine,
        r_reticuline,s_reticulene,s3_hydroxy_methylcoclaurine,s_n_methyl_coculaurine,
       s_coculaurine,norococulaurine, dopamine, tyramine, l_tyrosine]
"""

def generating_product_rxn_templates(rxn,second_product):
    """
    This function will take in a reaction rule and add a product to the existing product
    Example

    rxn rule :
        '([#8&v2&H1:1]-[#8&v2&H1:2])>>([#8&v2&H0:1]=[#8&v2&H0:2])'

    smile form of rxn rule:
        '[OH:1][OH:2]>>[O:1]=[O:2]'

    second_product : morphine molecule "CN1CC[C@]23C4=C5C=CC(O)"

    generating_product_rxn_templates(rxn_rule , morphine)

    Output:
    '[OH:1][OH:2].CN1CC[C@]23C4=C5C=CC(O)=C4O[C@H]2[C@@H](O)C=C[C@H]3[C@H]1C5>>[O:1]=[O:2]'

    """
    if type(second_product) != str:
        return "Type error, the second_product needs to be in smiles format"
    else:
        #Since the reaction is initially in smarts format it needs to be read into reaction format
        rxn_smiles = rdChemReactions.ReactionFromSmarts(rxn)
        #The reaction format is not directly useful we will convert into smiles fromat
        reaction_smiles = AllChem.ReactionToSmiles(rxn_smiles)
        #We want to split smiles strings into reaction/product becuase we wanted to add a new product to
        # existing product
        initial_product, reactant = reaction_smiles.split(">>")
        product = ".".join([initial_product,second_product])
        return ">>".join([product,reactant])

def setting_reaction_rules():
    data = pd.read_csv("retrorules_rr02_rp3_nohs/retrorules_rr02_flat_all.tsv",sep='\t')
    r_50 = reaction_rules_final(data,50)
    r_49 = reaction_rules_final(data,49)
    r_1 = reaction_rules_final(data,1)
    r_0 = reaction_rules_final(data,0)
    r_30 = reaction_rules_final(data,30)
    r_20 = reaction_rules_final(data,20)
    r_10 = reaction_rules_final(data,10)
    return r_50, r_49, r_30, r_20, r_10, r_1, r_0

def one_generate_features(current_rule):
    rxn = rdChemReactions.ReactionFromSmarts(current_rule)
    rxn_smiles = AllChem.ReactionToSmiles(rxn)
    rxn = Reaction(rxn_smiles, verbose=True)
    core = rxn.find_core()
    return core

def model_development():
    def get_hydrogen_atoms(my_mol):
        my_mol = Chem.MolFromSmiles(moltosmiles(my_mol))
        my_mol_with_explicit_h = Chem.AddHs(my_mol)
        return my_mol_with_explicit_h.GetNumAtoms() - my_mol_with_explicit_h.GetNumHeavyAtoms()

    all_values = []
    current_max = []
    for i in range(0,len(REA)):
        for item in REA[i]:
            if item != []:
                temp = get_hydrogen_atoms(item[0])
            current_max.append(temp)
        all_values.append(max(current_max))

    merged_features = training_dataset_features()
    X = pd.concat([reactent_fingerprints,merged_features],axis =1)
    Y = pd.DataFrame(all_values)
    from keras.models import Sequential
    from keras.layers import Dense
    model = Sequential()
    model.add(Dense(1, input_dim=2060, activation='sigmoid'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    hist = model.fit(X.values,Y.values, epochs=2, batch_size=20,verbose=1,
                    validation_data=(X.values,Y.values), shuffle=True)

def generating_atomic_features(extracting_reaction_core_smarts):
    import os
    from chemical_module import Chemical
    from reaction import Reaction
    from rdkit.Chem import rdChemReactions
    list_of_cores = []
    rxn = rdChemReactions.ReactionFromSmarts(extracting_reaction_core_smarts)
    rxn_smiles = AllChem.ReactionToSmiles(rxn)
    rxn = Reaction(rxn_smiles, verbose=True)
    core = rxn.find_core()
    list_of_cores.append(core)
    return list_of_cores

def testing_atomic_features(smile_string_list):
    temp = []
    current_sum = np.zeros((1,7))
    for i in range(0,len(smile_string_list)):
        for j in range(0,len(smile_string_list[i])):
            atom_level = pd.DataFrame(np.array(atom_level_descriptors(smile_string_list[i]),asOneHot=True)[1])
            sum_values =  atom_level.sum()
            current_sum = np.sum(current_sum,sum_values)
    return current_sum

def getting_reaction_cores(reaction):
    extracting_reaction_core_smarts = pushing_through_reaction_for_reaction_centers(reaction.split(">>")[1],reaction.split(">>")[0])
    import os
    from chemical_module import Chemical
    from reaction import Reaction
    from rdkit.Chem import rdChemReactions
    list_of_cores = []
    for i in range(0,len(extracting_reaction_core_smarts)):
        rxn = rdChemReactions.ReactionFromSmarts(extracting_reaction_core_smarts[i])
        rxn_smiles = AllChem.ReactionToSmiles(rxn)
        rxn = Reaction(rxn_smiles, verbose=True)
        core = rxn.find_core()
        list_of_cores.append(core)
    return list_of_cores
def one_generate_features(current_rule):
    rxn = rdChemReactions.ReactionFromSmarts(current_rule)
    rxn_smiles = AllChem.ReactionToSmiles(rxn)
    rxn = Reaction(rxn_smiles, verbose=True)
    core = rxn.find_core()
    return core

def testing_atomic_features(cores):
    product_addition = np.zeros((1,7))
    reactant_addition = np.zeros((1,7))
    pro_nju = atom_level_descriptors(Chem.MolFromSmiles(cores.split(">>")[0]))
    rea_nju = atom_level_descriptors(Chem.MolFromSmiles(cores.split(">>")[1]))
    for i in range(0,len(pro_nju[1])):
        product_addition = np.add(product_addition,pro_nju[1][i])
    for j in range(0,len(rea_nju[1])):
        reactant_addition = np.add(reactant_addition,rea_nju[1][j])
    P2_removing_e_state_index = np.concatenate([product_addition[0][0:3],product_addition[0][4:]])
    P1_removing_e_state_index = np.concatenate([reactant_addition[0][0:3],reactant_addition[0][4:]])
    return np.concatenate([P1_removing_e_state_index,P2_removing_e_state_index])

def mol_level_descriptors(mol):
    '''
    Given an RDKit mol, returns a list of molecule-level descriptors
    and their names
    returns: (labels, attributes)
    '''

    labels = [label for (label, f) in Descriptors._descList]
    attributes = [f(mol) for (label, f) in Descriptors._descList]

    return (labels, attributes)

def atom_level_descriptors(mol, include = ['functional'], asOneHot = False, ORIGINAL_VERSION = False):
    '''
    Given an RDKit mol, returns an N_atom-long list of lists,
    each of which contains atom-level descriptors and their names
    returns: (label, attributes)
    '''

    attributes = [[] for i in mol.GetAtoms()]
    labels = []
    if 'functional' in include:

        [attributes[i].append(x[0]) \
            for (i, x) in enumerate(rdMolDescriptors._CalcCrippenContribs(mol))]
        labels.append('Crippen contribution to logp')

        [attributes[i].append(x[1]) \
            for (i, x) in enumerate(rdMolDescriptors._CalcCrippenContribs(mol))]
        labels.append('Crippen contribution to mr')

        [attributes[i].append(x) \
            for (i, x) in enumerate(rdMolDescriptors._CalcTPSAContribs(mol))]
        labels.append('TPSA contribution')

        [attributes[i].append(x) \
            for (i, x) in enumerate(rdMolDescriptors._CalcLabuteASAContribs(mol)[0])]
        labels.append('Labute ASA contribution')

        [attributes[i].append(x) \
            for (i, x) in enumerate(EState.EStateIndices(mol))]
        labels.append('EState Index')

        rdPartialCharges.ComputeGasteigerCharges(mol)
        [attributes[i].append(float(a.GetProp('_GasteigerCharge'))) \
            for (i, a) in enumerate(mol.GetAtoms())]
        labels.append('Gasteiger partial charge')

        # Gasteiger partial charges sometimes gives NaN
        for i in range(len(attributes)):
            if np.isnan(attributes[i][-1]):
                attributes[i][-1] = 0.0

        [attributes[i].append(float(a.GetProp('_GasteigerHCharge'))) \
            for (i, a) in enumerate(mol.GetAtoms())]
        labels.append('Gasteiger hydrogen partial charge')

        # Gasteiger partial charges sometimes gives NaN
        for i in range(len(attributes)):
            if np.isnan(attributes[i][-1]):
                attributes[i][-1] = 0.0

    if 'structural' in include:
        [attributes[i].extend(atom_structural(mol.GetAtomWithIdx(i), asOneHot = asOneHot, ORIGINAL_VERSION = ORIGINAL_VERSION)) \
            for i in range(len(attributes))]
        labels.append('--many structural--')

    return (labels, attributes)

def circular_fingerprint(smile_string):
    mol = Chem.MolFromSmiles(smile_string)
    bi = {}
    fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=3, bitInfo=bi)
    return fp.ToBitString()

def encoding(current_element):
    return [int(item) for item in circular_fingerprint(current_element)]


import spacy
nlp = spacy.load("en_core_web_sm")
third_person_prons = ["he", "she", "it", "they", "him", "her", "them", "his", "her", "its", "their"]

def create_doc(utt):
    return nlp(utt)

def _rewrite_utt(doc, first_topic="", previous_topic="",
                 context_list=None, trailing=False):
        new_utt = ""
        for token in doc:
            if (token.tag_ == "PRP" or token.tag_ == "PRP$") \
                    and token.text in third_person_prons:
                if previous_topic != "":
                    new_utt += previous_topic + " "
                if first_topic != "":
                    new_utt += first_topic + " "
            else:
                new_utt += token.text + " "

        # TRAILING THE TOPIC
        if trailing:
            if previous_topic.lower() not in new_utt.lower():
                new_utt += previous_topic + " "
            if first_topic.lower() not in new_utt.lower():
                new_utt += first_topic

        # TRAILING THE CONTEXT
        if context_list is not None:
            new_utt += " ".join(context_list)

        return new_utt

def _find_cue_topic(doc):
    cue_phrases = ["tell me more about", "tell me about"]
    third_person_prons = ["he", "she", "it", "they", "him", "her", "them",
                          "his", "her", "its", "their"]

    current_topic = ""
    pron = False
    for cue in cue_phrases:
        if cue in str(doc).lower():
            # check if pron:
            for token in doc:
                if (token.tag_ == "PRP" or token.tag_ == "PRP$") and \
                        token.text in third_person_prons:
                    pron = True
            if not pron:
                current_topic = str(doc).lower().replace(cue, "").replace(".","")
    return current_topic

def _find_topic(doc):
    """
    We remove if "chunk.root.dep_ in pos_list" for GT and winning method to avoid problems from spacy, when it cannot
    analyse the phrase.
    """
    pos_list = ["nsubj", "dobj", "pobj"]
    topic = ""

    # NEW FEATURE
    # check if it's a cue topic first
    cue_topic = _find_cue_topic(doc)
    if cue_topic != "":
        return cue_topic

    # GET the first topic
    for chunk in doc.noun_chunks:
        # if chunk.root.dep_ in pos_list:
            if chunk.root.pos_ != "PRON":
                topic += " " + chunk.text

    # NO FIRST TOPIC - trick for "Describe Uranus."
    if topic == "":
        for token in doc:
            if token.pos_ not in ["VERB", "PUNCT"]:
                topic += token.text + " "

    return topic

def _find_topic_all(doc):
    pos_list = ["nsubj", "dobj", "pobj"]
    topic = ""

    # NEW FEATURE
    # check if it's a cue topic first
    cue_topic = _find_cue_topic(doc)
    if cue_topic != "":
        return cue_topic

    # GET the first topic
    for chunk in doc.noun_chunks:
        if chunk.root.pos_ != "PRON":
            topic += " " + chunk.text

    # NO FIRST TOPIC - trick for "Describe Uranus."
    if topic == "":
        for token in doc:
            if token.pos_ not in ["VERB", "PUNCT"]:
                topic += token.text + " "

    return topic


# - async I/O
#	- non-blocking sockets
#	- callbacks (not elegant, replace with coroutines)
#	- event loop
#	- efficiency! (single-threaded concurrency)

# - coroutines
#	- Future
#	- generators
#	- Task

import socket
import time
from selectors import DefaultSelector, EVENT_WRITE, EVENT_READ

PORT = 80
BUF_SIZE = 1000

selector = DefaultSelector()

start = time.time()

n_job = 0

class Future:
	def __init__(self):
		self.callbacks = []

	def resolve(self):
		for fn in self.callbacks:
			fn()

def get(path):
	global n_job
	n_job += 1
	s = socket.socket()
	s.setblocking(False)	# non blocking socket, never waits till succeed
	try:
		s.connect(('www.hdwallpapers.in', PORT))
	except BlockingIOError:
		pass

	callback = lambda: connected(s, path)
	f = Future()
	f.callbacks.append(callback)
	# fileobj, events, data
	selector.register(s.fileno(), EVENT_WRITE, f)

def connected(s, path):
	selector.unregister(s.fileno())
	request = 'GET %s HTTP/1.0\r\n\r\n' % path
	s.send(request.encode())

	buf = []
	callback = lambda: readable(s, buf)
	f = Future()
	f.callbacks.append(callback)
	selector.register(s.fileno(), EVENT_READ, f)

def readable(s, buf):
	global n_job
	selector.unregister(s.fileno())
	chunk = s.recv(BUF_SIZE)
	if chunk:
		buf.append(chunk)
		callback = lambda: readable(s, buf)
		f = Future()
		f.callbacks.append(callback)
		selector.register(s.fileno(), EVENT_READ, f)
	else:
		res = (b''.join(buf)).decode()
		print(res.split('\n')[0])
		n_job -= 1

get('/walls/huge_tiger_ride-wide.jpg')
get('/walls/huge_tiger_ride-wide.jpg')

# event loop
while n_job:
	events = selector.select()
	# key, mask = event (EVENT_WRITE)
	for key, mask in events:
		future = key.data
		future.resolve()

print('%.2f seconds' % (time.time() - start))


from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path

from .views import (
    custom_bad_request_view,
    custom_permission_denied_view,
    custom_page_not_found_view,
    custom_server_error_view,
)

urlpatterns = [
    path("admin/", admin.site.urls),
    path("accounts/", include("allauth.urls")),
    path("", include("home.urls")),
    path("products/", include("inventorize.urls")),
    path("products/", include("products.urls")),
    path('bag/', include('bag.urls')),
    path('checkout/', include('checkout.urls')),
    path('profile/', include('profiles.urls')),
    path('wishlist/', include('wishlist.urls')),
    #  allows to serve media files in development
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

handler400 = custom_bad_request_view
handler403 = custom_permission_denied_view
handler404 = custom_page_not_found_view
handler500 = custom_server_error_view


"""

Given a list of non negative integers, arrange them such that they form the largest number.

For example:

Given [3, 30, 34, 5, 9], the largest formed number is 9534330.

Note: The result may be very large, so you need to return a string instead of an integer.

QUESTIONS YOU SHOULD ASK:
+ Is the input always going to be valid? Yes.
+ Can I get zeroes in the list? Yes.
+ Should I form the largest number with them or try to ignore them from the function? Use them to form it.

"""
from fractions import Fraction

"""

Since sorting in descending order doesn't work (because 34 > 9 but 9 appears first in the finished number), we need to
sort on a custom comparison A or B.

A) Given numbers X and Y, we append to form XY and YX, and then we compare. If XY > YX, then X should come first,
   otherwise Y should come first.

B) Given a number X, we calculate it's fraction in relation to the number of digits it has. For example, if X=3, then
   the fraction is 3/10^1 = 3/10. If X=30, the fraction is 30/10^2 = 30/100. In order to make 3 come before 30 as we
   need, we subtract 1 from the denominator. That makes X=3 --> 3/9 and X=30 --> 30/99, such as 3/9 > 30/99. This
   subtraction of 1 makes sure that all the cases of 3 vs 30 or 30 vs 300 always prioritize the number with the least
   digit count.
    It also makes the cases of 3 vs 31 or 3 vs 3i, with i > 3 favor the case of 3i as it should be. For example,
    X=3 --> 3/9 and X=34 --> 34/99 such that 3/9 < 34/99. Of course this also means that 3 vs 3i will favor 3 with
    i < 3. With i == 3 it doesn't matter, since they are "the same".

"""

def largest_number(numbers):
    # Sort by the fraction method B)
    numbers = sorted(numbers, key=lambda n: Fraction(n, (10 ** len(str(n)))-1), reverse=True)
    i = 0
    # This while is in place in case the array is full of zeroes. It will make answer just a '0' which is the
    # largest number.
    while i < len(numbers) - 1:
        if numbers[i] != 0:
            break
        else:
            i += 1
    answer = ''.join(str(digit) for digit in numbers[i:])
    return answer