# -*- coding:utf-8 -*-
from PySide2.QtCore import Signal
from PySide2.QtWidgets import QDialog
from core.options import MultiOption
from ui.base.constants import ITEM_SEPARATORS
from ui.base.ui_add_items import Ui_AddItemsDialog
# noinspection PyTypeChecker
from utils import warn, splitItems, isEmpty

# noinspection PyTypeChecker
class AddItemsDialog(QDialog, Ui_AddItemsDialog):
    ADD_EXCLUDE_MODULES = 0
    ADD_HIDDEN_IMPORTS = 1
    COLLECT_ALL_SUBMODULES = 3
    COLLECT_ALL_DATA = 4
    COLLECT_ALL_BINARIES = 5
    COLLECT_ALL = 6
    COPY_METADATA = 7
    DEEP_COPY_METADATA = 8

    DEFAULT_ITEMS_SEP = ";"

    itemsAdded = Signal(MultiOption, list)

    def __init__(self, parent):
        super().__init__(parent)
        self._action = -1
        self._option = None
        self.setupUi()

    def setupUi(self, _=None):
        super(AddItemsDialog, self).setupUi(self)
        self.multiItemSeparatorCombo.addItems(ITEM_SEPARATORS.keys())
        self.addButton.clicked.connect(self.onAddItem)

    def onAddItem(self):
        content = self.itemsEdit.toPlainText().replace("\n", "").replace("\r", "").strip()
        if isEmpty(content):
            warn(self, self.tr(u"Warning"), self.tr("Items cannot be empty!"))
            return
        content = content.replace("；", ";").replace("，", ",")
        sepKey = self.multiItemSeparatorCombo.currentText()
        items = splitItems(content, sepKey, self.DEFAULT_ITEMS_SEP)
        self.itemsAdded.emit(self._option, items)
        self.accept()

    def display(self, action, option):
        self._action = action
        self._option = option
        self.updateTitle()
        self.show()

    def updateTitle(self):
        if self._action == self.ADD_EXCLUDE_MODULES:
            self.setWindowTitle(self.tr("Add Exclude Modules"))
        elif self._action == self.ADD_HIDDEN_IMPORTS:
            self.setWindowTitle(self.tr("Add Hidden Imports"))
        elif self._action == self.COLLECT_ALL_SUBMODULES:
            self.setWindowTitle(self.tr("Collect all submodules from:"))
        elif self._action == self.COLLECT_ALL_DATA:
            self.setWindowTitle(self.tr("Collect all data from:"))
        elif self._action == self.COLLECT_ALL_BINARIES:
            self.setWindowTitle(self.tr("Collect all binaries from:"))
        elif self._action == self.COLLECT_ALL:
            self.setWindowTitle(self.tr("Collect all(submodules,data, bin...) from:"))
        elif self._action == self.COPY_METADATA:
            self.setWindowTitle(self.tr("Copy metadata for:"))
        elif self._action == self.DEEP_COPY_METADATA:
            self.setWindowTitle(self.tr("Copy metadata for(recursively):"))
        else:
            raise ValueError("unknown action")

    def hideEvent(self, event):
        super().hideEvent(event)
        self._action = -1
        self._option = None
        self.setWindowTitle("")
        self.itemsEdit.setText("")


import numpy as np
import scipy.ndimage
import scipy.misc
import glob
import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

def loadPsf(psftype, fileformat):
    path='/gdata/zhoutk/Deconv/'+psftype
    files=glob.glob(path+'/'+'*'+fileformat)
    length=len(files)
    if length==0:
        print(path+'/')
        print('invalid psf file path')
        return
    im0=scipy.misc.imread(files[0])
    shape=im0.shape
    psf=np.zeros((length, shape[0], shape[1]))
    files.sort()
    for i, file in enumerate(files):
        #print(file)
        psf[i,:,:]=scipy.misc.imread(file)
        #print(type(psf))
        #print(psf.shape)
    return psf

def convolvePsf3D(volumn, psf, psnr):
    ##normalize with its largest content
    psf=psf/np.sum(psf)
    #change from int8 to float64
    volumn=volumn.astype('float64')
    #convolve psf with volumn
    #print(volumn.shape)
    #print(psf.shape)
    print('max_volumn: ', np.max(volumn))
    #volumn=scipy.ndimage.zoom(volumn, 2.0)
    if torch.cuda.is_available():
        psf=psf[:99, :, :]
        for i in range(len(psf.shape)):
            psf=np.flip(psf, i)
        psf=torch.from_numpy(psf.copy()).unsqueeze(0).unsqueeze(0).type(torch.FloatTensor).cuda()
        psf=Variable(psf, requires_grad=False)
        volumn=torch.from_numpy(volumn.copy()).unsqueeze(0).unsqueeze(0).type(torch.FloatTensor).cuda()
        volumn=Variable(volumn, requires_grad=False)
        output=F.conv3d(volumn, psf, padding=(49, 12, 12))
        output=output.squeeze().cpu().data.numpy()
    else:
        output=scipy.ndimage.filters.convolve(volumn, psf, mode='constant')
    print('convolve output shape: ', output.shape)
    print('max_output: ', np.max(output))
    #noise level --- gaussian noise
    sigma=np.max(output)/np.power(10, psnr/20)
    print('gaussian noise level:', sigma)
    noise=np.random.normal(0, sigma, output.shape)
    #add noise to the output
    output=np.clip(output+noise, 0, np.max(output))
    #output=output[0:101,0:101,0:101]
    return output


def EatUp (n):
    if n > 1:
        EatUp(n-1)
        print("eat %d" %n)
    elif n == 1:
        print("eat 1")

def EatDown (n):
    if n > 1:
        print("eat %d" %n)
        EatDown(n-1)
    elif n == 1:
        print("eat 1")

def Fac(n):
    result = 1
    for i in range(2,n+1):
        print(i)
        result *= i
    return result

def Fac_Recursive(n):
    if n == 0 or n == 1:
        return 1
    else:
        return Fac_Recursive(n-1) * n

def summ(n, l):
    if n == 0:
        return 0
    elif n == 1:
        return l[0]
    else:
        return sum(n-1, l) + l[n-1]

def summ2(l, fromI, toI):
    if fromI > toI:
        return 0
    elif fromI == toI:
        return l[toI]
    else:
        return l[fromI] + summ2(l, fromI+1, toI)

def summ3(l):
    n = len(l)

    if n == 0:
        return 0
    elif n == 1:
        return l[0]
    else:
        return l[0] + summ3(l[1:])

def fibR(n):
    if n <= 1:
        return n
    else:
        return fibR(n-1) + fibR(n-2)

print(fibR(8))


from tkinter import *
import tkinter as tk
import tkinter.messagebox
from PIL import ImageTk, Image

HEIGHT = 500
WIDTH = 600
root = tk.Tk()

def restart():
    ans = tkinter.messagebox.askyesno('Starting New Game','Are you sure?')
    if ans:
        root.destroy()
        from BallShooterLimit import Limit
        Limit()
def history():
    hist = tkinter.messagebox.askyesno('View History','Are you sure you would like to view history?')
    if hist:
        root.destroy()

def exiting():
    exiting = tkinter.messagebox.askyesno('Exit','Are you sure you would like to exit?')
    if exiting:
        root.destroy()

def MainMenu():
  root.title("Main Menu Page GUI")
  canvas = tk.Canvas(root,height = HEIGHT, width = WIDTH)
  canvas.pack()

  #this label shows a header in the main menu
  headerLabel = tk.Label(root, text = "Choose any of the options below: ")
  headerLabel.place(relx = 0.1, rely =0.1, relwidth = 0.85, relheight = 0.1)

  #this frame is for the "StartNewGame" button
  restartframe = tk.Frame(root,bg = '#ff99cc',bd = 5)
  restartframe.place(relx = 0.5, rely = 0.25,relwidth = 0.3, relheight = 0.1,anchor = 'n')

  #this label is for the "StartNewGame" button
  restartlabel = tk.Label(restartframe)
  restartlabel.place(relx = 0.4, rely =0, relwidth = 0.5, relheight = 1)

  #this is the "StartnewGame" button
  restartbutton = tk.Button(restartframe,text = "Start New Game",font = 40,  fg =  'black', command = lambda: restart())
  restartbutton.place(relx = 0.5,rely = 0.5, relwidth = 0.9, relheight = 1, anchor = 'center')

  #this frame is for the "ViewHistory" button
  histframe = tk.Frame(root,bg = '#ff99cc',bd = 5)
  histframe.place(relx = 0.5, rely = 0.35,relwidth = 0.3, relheight = 0.1,anchor = 'n')

  #this label is for the "ViewHistory" button
  histlabel = tk.Label(histframe)
  histlabel.place(relx = 0.1, rely =0, relwidth = 0.8, relheight = 1)

  #this is the "ViewHistory" button
  histbutton = tk.Button(histframe,text = "View History",font = 40,  fg =  'black', command = lambda: history())
  histbutton.place(relx = 0.5,rely = 0.5, relwidth = 0.9, relheight = 1, anchor = 'center')

  #this frame is for the "ExitGame" button
  exitframe = tk.Frame(root,bg = '#ff99cc',bd = 5)
  exitframe.place(relx = 0.5, rely = 0.45,relwidth = 0.3, relheight = 0.1,anchor = 'n')

  #this label is for the "StartNewGame" button
  exitlabel = tk.Label(exitframe)
  exitlabel.place(relx = 0.4, rely =0, relwidth = 0.5, relheight = 1)

  #this is the "StartnewGame" button
  exitbutton = tk.Button(exitframe,text = "Exit Game",font = 40,  fg =  'black', command = lambda: exiting())
  exitbutton.place(relx = 0.5,rely = 0.5, relwidth = 0.9, relheight = 1, anchor = 'center')
  root.mainloop()


import time
import constants as cons
import matplotlib.pyplot as plt
from preprocessing.images_reader import ImagesReader

start_time = time.time()

print('reading images...')
reader = ImagesReader(cons.PREPROCESSED_DATASET_DIR)

train_images = reader.read_train_images()

classes = [None] * len(train_images)
samples = [None] * len(train_images)

for i, image_class in enumerate(train_images):
    classes[i] = image_class
    samples[i] = len(train_images[image_class])

plt.plot(classes, samples)
plt.show()

end_time = time.time()
print('done in {:.2f}s'.format(end_time - start_time))


import matplotlib.pyplot as plt
tiempo = [0,1,2,3,4,5]
sensor = [4,5,6,8,9, 10]
plt.plot(tiempo,sensor,'--,r')
plt.title('Grafico sensor contra el tiempo')
plt.xlabel('Tiempo(s)')
plt.ylabel('Voltaje(v)')
plt.savefig('sensor.png')
plt.show()

# Nota: se le puede poner el simbolo para que se grafique('--'), si no se pone nada se grafica como una linea recta

# DICCIONARIO
diccionario = {}
diccionario['NombresEstudiantes'] = ['Andrea', 'Nicolle', 'Isabel', 'Santiago']
diccionario['EdadEstudiantes'] = [18,20,19,15]
diccionario['Peso'] = [60,55,70,78]
print(diccionario)

print(diccionario['NombresEstudiantes'][-1],diccionario['EdadEstudiantes'][-1],diccionario['Peso'][-1])


# Licensed under a 3-clause BSD style license - see LICENSE
from __future__ import print_function, division

import Icarus
from Icarus.Utils.import_modules import *

##### Welcome message
print( "Analysing some mock data. It is recommended to run it within the `ipython --pylab' environment.\n" )

##### Loading the data
atmo_fln = 'atmo_models.txt'
data_fln = 'data.txt'
ndiv = 5
porb = 10 * 3600
x2sini = 1.1

print( "Loading the data into an Icarus.Photometry object (failure to do so is likely due to missing atmosphere models).\n" )
fit = Icarus.Photometry.Photometry(atmo_fln, data_fln, ndiv, porb, x2sini)

##### This is the list of true parameters for the stars, as per construction
incl = 75.*cts.degree
corotation = 1.
filling = 0.90
Tnight = 2500.
gravdark = 0.08
K = 300e3
Tday = 5000.
DM = 10.0
AJ = 0.02
par0 = np.r_[incl, corotation, filling, Tnight, gravdark, K, Tday, DM, AJ]

##### Fitting the data using a simple fmin algorithm from scipy
##### Here we make use of the Calc_chi2 function with offset_free = 1 in order to allow for a possible band calibration error, which we assume is 0.3 mag (see column 5 in data.txt).
##### We will also assume that corotation = 1, gravdark = 0.08 and K=300e3.
## Defining the func_par
func_par = lambda p: np.r_[p[0], 1., p[1], p[2], 0.08, 300e3, p[3], p[4], p[5]]
## Wrapper function for the figure of merit to optimize
def FoM(p):
    p = np.asarray(p)
    ## Return large value if parameters are out of bound
    if (p < np.r_[0.1, 0.1, 1500., p[2], 8., 0.]).any() or (p > np.r_[np.pi/2, 1.0, 8000., 8000., 12., 0.1]).any():
        #print( "out-of-bound" )
        return np.ones_like(fit.mag)*1e5
    else:
        chi2, extras = fit.Calc_chi2(p, offset_free=0, func_par=func_par, full_output=True, verbose=False)
        return extras['res']

## Initial guess
par_guess = [70*cts.degree, 0.95, 2000., 5500., 10.3, 0.01]

## Running the fit
print( "Performing a crude fit using the scipy.optimize.leastsq function.\n" )
print( "Beware that the fitting may not converge to the best-fit solution due to local minima. One should try to fit the data using diferent guess parameters or, even better, a more robust fitting algorithm.\n" )
print( "Also, do not expect the best-fit parameter to converge at the actual solution. The reason being that noise is added to the theoretical data when generating the mock data. Hence it might be that by sheer luck the mock data mimic a slightly different set of parameters. If one was to regenerate the mock data several times and rerun the fit, it would on average converge at the actual solution.\n" )
sol = scipy.optimize.leastsq(FoM, par_guess, full_output=True)
par = sol[0]
err = np.sqrt( sol[1].diagonal() )

##### Printing the results
print( "Results from the fitting:" )
print( "{:<28} {:>15}  {:>15}".format("Parameter", "Actual solution", "Fitted Solution") )
print( "{:<28} {:>15.3f}   {:>15.3f} +/- {:.3f}".format("inclination", incl/cts.degree, par[0]/cts.degree, err[0]/cts.degree) )
print( "{:<28} {:>15.3f}   {:>15.3f} +/- {:.3f}".format("filling factor", filling, par[1], err[1]) )
print( "{:<28} {:>15.1f}   {:>15.3f} +/- {:.3f}".format("Tnight", Tnight, par[2], err[2]) )
print( "{:<28} {:>15.1f}   {:>15.3f} +/- {:.3f}".format("Tday", Tday, par[3], err[3]) )
print( "{:<28} {:>15.2f}   {:>15.3f} +/- {:.3f}".format("DM", DM, par[4], err[4]) )
print( "{:<28} {:>15.3f}   {:>15.3f} +/- {:.3f}".format("AJ", AJ, par[5], err[5]) )
print( "" )

##### Plotting the data and model if possible
if pylab:
    print( "Plotting the data. If nothing shows up, try pylab.show()." )
    fig = pylab.figure()
    ax = fig.add_subplot(111)
    pl1 = ax.errorbar(np.r_[fit.data['phase'][0],fit.data['phase'][0]+1.], np.r_[fit.data['mag'][0],fit.data['mag'][0]], yerr=np.r_[fit.data['err'][0],fit.data['err'][0]], marker='s', mfc='red', mec='red', ms=3, ecolor='red', fmt='.')
    pl2 = ax.errorbar(np.r_[fit.data['phase'][1],fit.data['phase'][1]+1.], np.r_[fit.data['mag'][1],fit.data['mag'][1]], yerr=np.r_[fit.data['err'][1],fit.data['err'][1]], marker='s', mfc='blue', mec='blue', ms=3, ecolor='blue', fmt='.')
    phs = np.linspace(0, 2, 101)
    flux = fit.Get_flux_theoretical(par, [phs,phs], func_par=func_par)
    pl3 = ax.plot(phs, flux[0], 'r-')
    pl4 = ax.plot(phs, flux[1], 'b-')
    flux = fit.Get_flux_theoretical(par0, [phs,phs])
    pl5 = ax.plot(phs, flux[0], 'r:')
    pl6 = ax.plot(phs, flux[1], 'b:')
    leg = ax.legend([pl1[0],pl3[0],pl5[0],pl2[0],pl4[0],pl6[0]], ["i","Fit","Real","g","Fit","Real"], ncol=2, loc=0, numpoints=1, scatterpoints=1)
    ax.set_xlabel("Orbital Phase")
    ax.set_ylabel("Magnitude")
    ax.set_xlim([0.,2.])
    vals = np.r_[fit.data['mag'][0], fit.data['mag'][1]]
    ax.set_ylim([vals.max()+(vals.max()-vals.min())*0.1, vals.min()-(vals.max()-vals.min())*0.1])
    pylab.show()


def getLongestLine(img):
    longest = 0
    for i in range(0, len(img)):
        if len(img[i]) > longest:
            longest = len(img[i])
    return longest

def rotate(img):
    width = getLongestLine(img)
    height = len(img)
    longest = width
    answer = []
    if(width < height):
        longest = height
    for i in range(0, longest):
        answer.append([' '] * longest)
    for i in range(0, len(img)):
        for j in range(0, len(img[i])):
            try:
                print("Swapped at " + str(j) + " " + str(i))
                answer[j][i] = img[i][j]
            except:
                print("Entered a space")
                answer[j][i] = ' '
        print(answer[i])

lines = 1
while lines:
    lines = int(input())
    img = []
    for i in range(0, lines):
        line = input()
        img.append(list(line))
    rotate(img)
    print()


from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import pandas as pd

class Tabla:
    def __init__(self,root, dataFrame, anchos, fechas, bgColor, posX, posY):
        self.anchos = anchos
        self.fechas = fechas
        self.nuevoDatos = []
        self.componentes = []
        cont = 0
        self.df = dataFrame
        self.frm = ttk.Frame(root)
        for k in dataFrame:
            tmp = Entry(self.frm, width=anchos[cont], bg=bgColor, fg='black', font= ('Arial', 12),
                            highlightthickness=1, highlightbackground="#000000", highlightcolor="#000000")
            tmp.grid(row=0, column=cont)
            tmp.insert(INSERT, k)
            cont += 1
        self.lista = list(dataFrame.to_records(index=False))
        self.filas = len(self.lista)
        self.columnas = cont
        for i in range(self.filas):
            row = []
            for j in range(self.columnas):
                aux = Entry(self.frm, width=anchos[j], fg='black',
                               font=('Arial',12,), highlightthickness=1, highlightbackground="#000000", highlightcolor="#000000")
                aux.grid(row=i + 1, column=j)
                if len(fechas) == 0:
                    aux.insert(INSERT, self.lista[i][j])
                else:
                    if j in fechas:
                        aux.insert(INSERT, pd.to_datetime(self.lista[i][j]).date().strftime('%d/%m/%y'))
                    else:
                        aux.insert(INSERT, self.lista[i][j])
                aux.configure(state='readonly')
                row.append(aux)
            self.componentes.append(row)
        self.frm.pack()
        self.frm.place(x=posX, y=posY)

    def limpiar(self):
        for widget in self.frm.winfo_children():
            widget.destroy()

class EquiposFrame():
    def __init__(self, ventana):
        self.cantEquipos = tk.StringVar()
        self.retirados = tk.StringVar()
        self.inscritos = tk.StringVar()
        self.mostrarTabla(ventana)
        tk.Label(ventana, text='Equipos', font=('Arial Black', 12), bg="#3a7ff6", width=25).place(x=15, y=50)
        tk.Button(ventana, text='listar', font=('Arial', 12), width=8, height=2, highlightbackground = "black", borderwidth=5, bg="white", command= lambda: self.mostrarTabla(ventana)).place(x=40, y=120)
        tk.Button(ventana, text='borrar', font=('Arial', 12), width=8, height=2,  bg="white", borderwidth = 5, command=self.limpiarTabla).place(x=170, y=120)
        tk.Label(ventana, text='Cantidad de equipos', font=('Arial', 12), bg="white").place(x=25, y=220)
        tk.Label(ventana, text='Equipos retirados', font=('Arial', 12), bg="white").place(x=25, y=260)
        tk.Label(ventana, text='Equipos incritos', font=('Arial', 12), bg="white").place(x=25, y=300)
        tk.Button(ventana, textvariable=self.cantEquipos, font=('Arial', 12), state='disabled').place(x=300, y=210)
        tk.Button(ventana, textvariable=self.retirados, font=('Arial', 12), state='disabled').place(x=300, y=250)
        tk.Button(ventana, textvariable=self.inscritos, font=('Arial', 12), state='disabled').place(x=300, y=290)

    def mostrarTabla(self, ventana):
        archivo = pd.read_excel('Equipos.xlsx', sheet_name='Hoja1')
        self.cantEquipos.set(str(len(archivo['N°'])))
        self.retirados.set(list(archivo['Retirado']).count('Si'))
        self.inscritos.set(list(archivo['Retirado']).count('No'))
        # self.retirados.set(str(list(archivo['Retirado'].count('No'))))
        anchos = [5, 40, 20, 18, 10]
        fechas = []
        self.tabla = Tabla(ventana, archivo,anchos,fechas,'#3a7ff6', 50, 350)

    def limpiarTabla(self):
        self.tabla.limpiar()

class CampeonatoFrame():
    def __init__(self, ventana):
        self.temporada = tk.StringVar()
        self.inicio = tk.StringVar()
        self.fin = tk.StringVar()
        tk.Label(ventana, text='Campeonato', font=('Arial Black', 12), bg="#3a7ff6", width=25).place(x=15, y=50)
        tk.Label(ventana, text='Fecha de Inicio', font=('Arial', 12), bg="white").place(x=25, y=100)
        tk.Label(ventana, text='Fecha Final', font=('Arial', 12), bg="white").place(x=25, y=140)
        tk.Entry(ventana, bd=3, bg="#F6F7F9", highlightthickness=2,  font=("Arial", 11), textvariable=self.temporada).place(x=300, y=50, width=120.0, height=30)
        tk.Entry(ventana, bd=3, bg="#F6F7F9", highlightthickness=2,  font=("Arial", 11), textvariable=self.inicio).place(x=300, y=90, width=120.0, height=30)
        tk.Entry(ventana, bd=3, bg="#F6F7F9", highlightthickness=2,  font=("Arial", 11), textvariable=self.fin).place(x=300, y=130, width=120.0, height=30)
        tk.Button(ventana, text='GENERAR', wraplength=125, justify=tk.LEFT, relief='flat', font=('Arial', 16, "bold"), anchor="w", borderwidth = 0, highlightthickness = 15, compound = 'center', bg="#3a7ff6", fg="white", activebackground="#3a7ff6", command= lambda: self.mostrarTabla(ventana)).place(x=500, y=70)

    def mostrarTabla(self, ventana):
        archivo = pd.read_excel('Partidos.xlsx', sheet_name='Hoja1')
        anchos = [5, 10, 60]
        fechas = [1]
        self.tabla = Tabla(ventana, archivo,anchos,fechas,'#3a7ff6', 50, 350)

class ListaRegistroFrame():
    def __init__(self, ventana):
        self.equipo = tk.StringVar()
        self.representante = tk.StringVar()
        self.jugadores = tk.StringVar()
        self.mostrarTabla(ventana)
        tk.Label(ventana, text='Lista de Registro', font=('Arial Black', 12), bg="#3a7ff6", width=25).place(x=15, y=50)
        tk.Label(ventana, text='Nombre del Equipo', font=('Arial', 12), bg="white").place(x=25, y=100)
        tk.Label(ventana, text='Representante', font=('Arial', 12), bg="white").place(x=25, y=140)
        tk.Label(ventana, text='Cantidad de Jugadores', font=('Arial', 12), bg="white").place(x=25, y=180)
        tk.Entry(ventana, bd=1, bg="#F6F7F9", highlightthickness=2,  font=("Arial", 11), textvariable=self.equipo).place(x=320, y=90, width=220.0, height=30)
        tk.Entry(ventana, bd=1, bg="#F6F7F9", highlightthickness=2,  font=("Arial", 11), textvariable=self.representante).place(x=320, y=130, width=220.0, height=30)
        tk.Entry(ventana, bd=1, bg="#F6F7F9", highlightthickness=2,  font=("Arial", 11), textvariable=self.jugadores).place(x=320, y=170, width=220.0, height=30)
        tk.Button(ventana, text='AGREGAR', wraplength=125, justify=tk.LEFT, relief='flat', font=('Arial', 16, "bold"), anchor="w", borderwidth = 0, highlightthickness = 15, compound = 'center', bg="#3a7ff6", fg="white", activebackground="#3a7ff6", command= lambda:self.agregarEquipo(ventana)).place(x=580, y=115)

    def mostrarTabla(self, ventana):
        archivo = pd.read_excel('Equipos.xlsx', sheet_name='Hoja1')
        anchos = [5, 40, 20, 18, 10]
        fechas = []
        self.tabla = Tabla(ventana, archivo,anchos,fechas,'#3a7ff6', 50, 350)

    def agregarEquipo(self, ventana):
        mensajes = ''
        if self.equipo.get() == "":
            mensajes += 'Debe ingresar el nombre del equipo\n'
        if self.jugadores.get().isnumeric() is False:
            mensajes += 'La cantidad de jugadores debe de ser un numero.\n'
        if self.representante.get() == "":
            mensajes += 'Debe ingresar el nombre del representante.\n'
        if len(mensajes) > 0:
            messagebox.showerror(title='ERROR', message=mensajes)
            return
        archivo = pd.read_excel('Equipos.xlsx', sheet_name='Hoja1')
        archivo.loc[archivo.shape[0]] = [len(archivo['N°']) + 1, self.equipo.get(), self.representante.get(), int(self.jugadores.get()), 'No']
        archivo.to_excel('Equipos.xlsx', sheet_name='Hoja1', index=False)
        self.jugadores.set('')
        self.equipo.set('')
        self.representante.set('')
        self.mostrarTabla(ventana)

class ReportesProblemasFrame():
    def __init__(self, ventana):
        tk.Label(ventana, text='Reporte de Problema', font=('Arial Black', 12), bg="#3a7ff6", width=25).place(x=15, y=50)
        tk.Label(ventana, text='Informar Incidencias', font=('Arial', 12), bg="white").place(x=25, y=100)
        tk.Label(ventana, text='Describa su inconveniente', font=('Arial', 12), bg="#3a7ff6").place(x=50, y=180)
        self.texto = tk.Text(ventana, font=('Arial', 12), width=50, height=12)
        self.texto.place(x=50, y=200)
        tk.Button(ventana, text='ENVIAR', wraplength=125, justify=tk.LEFT, relief='flat', font=('Arial', 16, "bold"), anchor="w", borderwidth = 0, highlightthickness = 0, compound = 'center', bg="#3a7ff6", fg="white", activebackground="#3a7ff6", command=self.reportar).place(x=300, y=450)
        tk.Button(ventana, text='BORRADOR', wraplength=125, justify=tk.LEFT, relief='flat', font=('Arial', 16, "bold"), anchor="w", borderwidth = 0, highlightthickness = 0, compound = 'center', bg="#3a7ff6", fg="white", activebackground="#3a7ff6", command=self.borrador).place(x=450, y=450)

    def reportar(self):
        archivo = pd.read_excel('Problemas.xlsx', sheet_name='Hoja1')
        archivo.loc[archivo.shape[0]] = [len(archivo['Codigo']) + 1, self.texto.get("1.0","end-1c")]
        archivo.to_excel('Problemas.xlsx', sheet_name='Hoja1', index=False)
        self.texto.delete(1.0,END)
        messagebox.showinfo(title='EXITOSO', message='El problema se ha reportado satisfactoriamente')

    def borrador(self):
        self.texto.delete(1.0,END)

class GestionEquipos():
    def __init__(self):
        self.main_window = tk.Tk()
        w = 1000
        h = 650
        screen_width = self.main_window.winfo_screenwidth()
        screen_height = self.main_window.winfo_screenheight()
        x = (screen_width/2) - (w/2)
        y = (screen_height/2) - (h/2)
        self.main_window.geometry('%dx%d+%d+%d' % (w, h, x, y))
        self.formActual = EquiposFrame(self.main_window)
        self.agregarBotonesPrincipales()

        self.main_window.mainloop()

    def agregarBotonesPrincipales(self):
        tk.Button(self.main_window, text='Equipos', command=self.abrirEquiposFrm).place(x=0, y=0)
        tk.Button(self.main_window, text='Campeonato', command=self.abrirCampeonatoFrm).place(x=52, y=0)
        tk.Button(self.main_window, text='Lista de Registro', command=self.abrirListaRegistroFrm).place(x=131, y=0)
        tk.Button(self.main_window, text='Reporte de Problemas', command=self.abrirReporteProblemaFrm).place(x=227, y=0)

    def limpiarVentana(self):
        for widget in self.main_window.winfo_children():
            widget.destroy()

    def abrirEquiposFrm(self):
        self.limpiarVentana()
        self.agregarBotonesPrincipales()
        self.formActual = EquiposFrame(self.main_window)

    def abrirCampeonatoFrm(self):
        self.limpiarVentana()
        self.agregarBotonesPrincipales()
        self.formActual = CampeonatoFrame(self.main_window)

    def abrirListaRegistroFrm(self):
        self.limpiarVentana()
        self.agregarBotonesPrincipales()
        self.formActual = ListaRegistroFrame(self.main_window)

    def abrirReporteProblemaFrm(self):
        self.limpiarVentana()
        self.agregarBotonesPrincipales()
        self.formActual = ReportesProblemasFrame(self.main_window)

programa = GestionEquipos()


import json as js
import csv
import sys
import jinja2
import os
from datetime import datetime
# import smtplib

# read customers file to get information about customers
def get_customers(customers_file, error):
    TITLE = []
    FIRST_NAME = []
    LAST_NAME = []
    EMAIL = []

    with open(customers_file, mode='r') as csv_file:
        customers = csv.DictReader(csv_file, delimiter=',')
        errorData = []
        for customer in customers:
            if customer["EMAIL"] != '':
                TITLE.append(customer["TITLE"])
                FIRST_NAME.append(customer["FIRST_NAME"])
                LAST_NAME.append(customer["LAST_NAME"])
                EMAIL.append(customer["EMAIL"])
            else:
                errorData.append([customer["TITLE"], customer["FIRST_NAME"], customer["LAST_NAME"], customer["EMAIL"]])
        with open(error, mode='w', newline='') as f:
            errorCustomer = csv.writer(f)
            errorCustomer.writerow(['TITLE','FIRST_NAME','LAST_NAME','EMAIL'])
            for customer in errorData:
                errorCustomer.writerow(customer)

    return TITLE, FIRST_NAME, LAST_NAME, EMAIL

def read_template(email_template_file):
    with open(email_template_file, mode='r') as email_template:
        template = js.load(email_template)
    return template

# Can use CLI Python Library to parse agv from CMD such as argparse, getopt,...
def main(email_template, customers, path_output_emails, error):
    # how to use smtp send email
    # s = smtplib.SMTP(host='host_address', port=port)
    # s.starttls()
    # s.login(MY_ADDRESS, PASSWORD)
    TITLE, FIRST_NAME, LAST_NAME, EMAIL = get_customers(customers, error)
    template = read_template(email_template)
    if os.path.isdir(path_output_emails):
        os.chdir(path_output_emails)
    else:
        os.mkdir(path_output_emails)
        os.chdir(path_output_emails)

    now = datetime.now()
    env = jinja2.Environment()
    outputJsonFile = open("output.json", "w")
    resultData = []
    for title, first_name, last_name, email in zip(TITLE, FIRST_NAME, LAST_NAME, EMAIL):
        data = {}
        body_template = env.from_string(template["body"])
        data["from"] = template["from"]
        data["to"] = email
        data["subject"] = template["subject"]
        data["mineType"] = template["mineType"]
        data["body"] = body_template.render(TITLE=title, FIRST_NAME=first_name, LAST_NAME=last_name, TODAY=now.strftime('%d %b %Y'))
        resultData.append(data)
        # s.send_message(data)
        # del data
    output = js.dumps(resultData, indent=4)
    outputJsonFile.write(output)
    outputJsonFile.close()

if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])


import sys
import glob
from log.logdb import LogDb
from log.loader import LogLoader
from gcp.storage import LogStorage
from log.timeutil import timestamp

class DbLoader:
    def __init__(self):
        self.book_last_time = 0
        self.funding_last_time = 0
        self.trade_last_time = 0
        self.log_db = None
        self.log_loader = LogLoader(self.order_book_tick,  self.trade_tick, self.funding_tick)

    def open_db(self, db_file=None):
        self.log_db = LogDb(db_file)
        self.log_db.connect()
        self.log_db.create_cursor()
        self.log_db.create()

    def close_db(self):
        self.log_db.close()

    def get_db(self):
        return self.log_db

    def load_line(self, line):
        self.log_loader.load_line(line)

    def load_lines(self, lines):
        for line in lines:
            self.log_loader.load_line(line)

    def load_file(self, log_file):
        print('Processs ' + log_file, end='')
        try:
            self.log_loader.load(log_file)
        except EOFError as e:
            print('error to process fileError EOF', e)
        except Exception as e:
            print('File process error SKIP', e)

    def load_dir(self, log_dir ='/tmp'):
        log_files = sorted(glob.glob(log_dir + '/' + '*.log'))
        for file in log_files:
            self.log_db.create_cursor()
            self.load_file(file)
            self.log_db.commit()

        log_files = sorted(glob.glob(log_dir + '/' + '*.log.gz'))
        for file in log_files:
            self.log_db.create_cursor()
            self.load_file(file)
            self.log_db.commit()

    def load_from_blobs(self, path=''):
        log_storage = LogStorage()

        log_storage.process_blob_dir(path, self.load_file)

    def load_from_blob_by_date(self, year, month, day):
        log_storage = LogStorage()

        log_storage.process_blob_date_with_padding(year, month, day, self.load_file)

    def order_book_tick(self, time_stamp, order_book):
        if self.book_last_time != time_stamp:
            self.log_db.insert_order_book_message(time_stamp, order_book)
        self.book_last_time = time_stamp

    def funding_tick(self, time_stamp, funding):
        self.log_db.insert_funding(time_stamp, funding)

    def trade_tick(self, time_stamp, buy_trade, sell_trade):
        for price in buy_trade.keys():
            self.log_db.insert_buy_trade(time_stamp, price, buy_trade[price])

        for price in sell_trade.keys():
            self.log_db.insert_sell_trade(time_stamp, price, sell_trade[price])

if __name__ == '__main__':
    log_dir = '/tmp'
    db_file = '/tmp/bitlog.db'

    if len(sys.argv) == 2:
        log_dir = sys.argv[0]
        db_file = sys.argv[1]

        print(log_dir, db_file)

    db_loader = DbLoader()
    db_loader.open_db()
    db_loader.load_dir(log_dir)
    db_loader.close_db()


import boto3
import logging
import os
import json
import time
from datetime import datetime
from jsonpath_ng.ext import parse
import helpers

logger = logging.getLogger()
logger.setLevel(logging.INFO)

utl = helpers.Utils()
dyn = helpers.Dyn()

ssm = boto3.client('ssm')
ec2 = boto3.client('ec2')
appValue = os.getenv('TAG_APP_VALUE')
appName = os.getenv('APP_NAME')

def getNicInformation(instance):
    logger.info(instance + "- getNicInformation")

    ssm_rsp = ssm.send_command(
            InstanceIds=[instance],
            DocumentName='AWS-RunShellScript',
            TimeoutSeconds=30,
            Parameters={
                'commands':[
                     "NIC=$(ifconfig -a | grep UP,BROADCAST | awk '{print substr($1, 1, length($1)-1)}');aws ssm put-parameter --name '/amplify/minecraftserverdashboard/" + instance + "/nic' --type 'String' --value $NIC"
                ]
            },
        )
    resp = checkExecutionLoop(instance,ssm_rsp["Command"]["CommandId"])
    logger.info(resp)

def minecraftInit(instance):
    logger.info(instance + " - minecraftInit")
    instanceInfo = dyn.GetInstanceAttr(instance)
    logger.info(instanceInfo)

    if instanceInfo['code'] != 200:
        logger.warning("Instance data does not exist")
        return False

    if 'runCommand' in instanceInfo['msg'] and 'workingDir' in instanceInfo['msg']:
        script = os.path.join(instanceInfo['msg']['workingDir'],instanceInfo['msg']['runCommand'])
        #script = instanceInfo['msg']['runCommand']

        ssm_rsp = ssm.send_command(
            InstanceIds=[instance],
            DocumentName='AWS-RunShellScript',
            TimeoutSeconds=30,
            Parameters={
                'commands':[
                     script
                ],
                'workingDirectory':[
                    instanceInfo['msg']['workingDir']
                ],
            },
        )
        logger.info(ssm_rsp)

    else:
        logger.warning("RunCommand or Working Directories are not defined")
        return False

def cwAgentStatusCheck(instance):
    logger.info(instance + " - cwAgentStatusCheck")
    ssmAgentStatus = ssmExecCommands(instance,"AmazonCloudWatch-ManageAgent",{"action": ["status"],"mode": ["ec2"]})
    #logger.info(ssmAgentStatus)

    # Checking Agent Status if Success. Failed messages occurs when the CloudWatch Agent is not installed.
    if ssmAgentStatus["Status"] == "Success":
        agentDetails=""
        jpexpr = parse("$.pluginsDetails[?(@.Name[:] == 'ControlCloudWatchAgentLinux')].Output")
        for i in jpexpr.find(ssmAgentStatus):
            agentDetails = i.value

        if len(agentDetails) > 5:
            agentDetailsJson = json.loads(agentDetails)
            if agentDetailsJson["status"] == "running":
                logger.info("Agent is already running. Version :" + agentDetailsJson["version"])
                # AmazonCloudWatch Agent configuration
                logger.info("Configuring agent")
                ssmAgentConfig = ssmExecCommands(instance,"AmazonCloudWatch-ManageAgent",{"action": ["configure"],"mode": ["ec2"],"optionalConfigurationLocation": ["/amplify/minecraftserverdashboard/amazoncloudwatch-linux"],"optionalConfigurationSource": ["ssm"],"optionalRestart": ["yes"]})
                logger.info(ssmAgentConfig)
                return { "code": 200, "msg": "Agent is already running. Version :" + agentDetailsJson["version"] }
            else:
                logger.info("Agent Status: " + agentDetailsJson["status"] + " - configuration Status: " + agentDetailsJson["configstatus"])
                return { "code": 400, "msg":"Agent Status: " + agentDetailsJson["status"] + " - configuration Status: " + agentDetailsJson["configstatus"] }
        else:
            logger.warning(agentDetailsJson)
            return { "code": 500, "msg": "Detailed information not available"}
    else:
        return { "code": 500, "msg": "Failed" }

def cwAgentInstall(instance):
    ssmInstallAgent = ssmExecCommands(instance,"AWS-ConfigureAWSPackage",{"action": ["Install"],"name": ["AmazonCloudWatchAgent"]})
    #logger.info(ssmInstallAgent)

    # Checking Agent Status if Success. Failed messages occurs when the CloudWatch Agent is not installed.
    if ssmInstallAgent["Status"] == "Success":
        # AmazonCloudWatch Agent installation
        jpexpr = parse("$.pluginsDetails[?(@.Name[:] == 'configurePackage')].Output")
        for i in jpexpr.find(ssmInstallAgent):
            agentDetails = i.value
            logger.info(agentDetails)
        # AmazonCloudWatch Agent configuration
        logger.info("Configuring agent")
        ssmAgentConfig = ssmExecCommands(instance,"AmazonCloudWatch-ManageAgent",{"action": ["configure"],"mode": ["ec2"],"optionalConfigurationLocation": ["/amplify/minecraftserverdashboard/amazoncloudwatch-linux"],"optionalConfigurationSource": ["ssm"],"optionalRestart": ["yes"]})
        logger.info(ssmAgentConfig)

def scriptExec(instance):
    ssmRunScript = ssmExecCommands(instance,"AWS-RunRemoteScript",{"sourceType": ["GitHub"],"sourceInfo": ["{\"owner\":\"arturlr\", \"repository\": \"minecraft-server-dashboard\", \"path\": \"scripts/adding_cron.sh\", \"getOptions\": \"branch:dev\" }"],"commandLine": ["bash adding_cron.sh"]})
    logger.info(ssmRunScript)

def sendCommand(instance, param, docName):
    ssm_rsp = ssm.send_command(
                InstanceIds=[instance],
                DocumentName=docName,
                TimeoutSeconds=30,
                Parameters=param
            )

    # logger.info("sendCommand " + instance + " - " + ssm_rsp["Command"]["Status"])
    return { "CommandId": ssm_rsp["Command"]["CommandId"], "Status": ssm_rsp["Command"]["Status"] }

def listCommand(instance, commandId):
    ssm_rsp = ssm.list_commands(
            CommandId=commandId,
            InstanceId=instance,
    )

    logger.info("listCommand " + instance + " - " + ssm_rsp["Commands"][0]["Status"])
    return { "Status": ssm_rsp["Commands"][0]["Status"] }

def getCommandDetails(instance, commandId):
    ssm_rsp = ssm.list_command_invocations(
            CommandId=commandId,
            InstanceId=instance,
            Details=True
    )

    if 'CommandPlugins' in  ssm_rsp["CommandInvocations"][0]:
        pluginsDetails = ssm_rsp["CommandInvocations"][0]["CommandPlugins"]

    logger.info("getCommandDetails " + instance + " - " + ssm_rsp["CommandInvocations"][0]["Status"])
    return { "Status": ssm_rsp["CommandInvocations"][0]["Status"], "pluginsDetails": pluginsDetails }

def checkExecutionLoop(instanceId, commandId, sleepTime=5):

    loopCount = 0

    while True:
        checkStatusCommand = listCommand(instanceId, commandId)
        logger.info(instanceId + " - " + commandId + " - " + checkStatusCommand["Status"])
        if checkStatusCommand["Status"] == "Success":
            getStatusDetails = getCommandDetails(instanceId, commandId)
            return getStatusDetails
        elif checkStatusCommand["Status"] == "Failed":
            return "Failed"
        elif loopCount > 5:
            logger.error("Timeout - Cancelling the Command")
            logger.error(checkStatusCommand)
            ssm.cancel_command(
                CommandId=commandId,
                InstanceIds=[instanceId]
            )
            return "Cancelled"
        else:
            loopCount = loopCount + 1
            time.sleep(sleepTime)

def ssmExecCommands(instanceId, docName, params):
    logger.info("ssmExecCommands " + instanceId + " - " + docName)

    command = sendCommand(instanceId, params, docName)
    response = checkExecutionLoop(instanceId,command["CommandId"])

    return response

def handler(event, context):
    try:
        instanceId = event["instanceId"]

        # Execute minecraft initialization
        minecraftInit(instanceId)

        # Nic Value
        getNicInformation(instanceId)

        ## CloudWatch Agent Steps
        cwAgentStatus = cwAgentStatusCheck(instanceId)
        if cwAgentStatus['code'] != 200:
            cwAgentInstall(instanceId)
            scriptExec(instanceId)
            return { "code": 200, "msg": "CW Agent installed and Script executed"}
        else:
            return cwAgentStatus

    except Exception as e:
        logger.error('Something went wrong: ' + str(e))
        return { "code": 500, "msg": str(e) }


from flask import Response
import json

from presentation.contracts import HttpController, HttpRequest

def adapt_route(flask_request, controller: HttpController):
    request = HttpRequest(
        params=flask_request.args,
        body=flask_request.json
    )
    data = controller.handle(request)
    return Response(
        json.dumps(data.body),
        status=data.status,
        mimetype='application/json'
    )
    try:
        request = HttpRequest(
            params=flask_request.args,
            body=flask_request.json
        )
        data = controller.handle(request)
        return Response(
            json.dumps(data.body),
            status=data.status,
            mimetype='application/json'
        )
    except Exception as e:
        return Response(
            json.dumps({"error": "Internal server error"}),
            status=500,
            mimetype='application/json'
        )


from typing import *

# class Solution:
#     def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
#         n_str = str(n)
#         k = len(n_str)

#         res = 0
#         for i in range(1, k):
#             res += len(digits) ** i

#         def dfs(cur, pos, res):
#             # base case
#             if pos == k:
#                 res += 1
#                 return res

#             for d in digits:
#                 if d < n_str[pos]:
#                     res += len(digits) ** (k-1-pos)
#                 elif d == n_str[pos]:
#                     res = dfs(cur*10 + int(d), pos+1, res)

#             return res

#         res = dfs(0, 0, res)
#         return res

class Solution:
    def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
        n_str = str(n)
        k = len(n_str)

        # NOTE, need to use global
        global res
        res = 0
        for i in range(1, k):
            res += len(digits) ** i

        def dfs(cur, pos):
            global res
            # base case
            if pos == k:
                res += 1
                return

            for d in digits:
                if d < n_str[pos]:
                    res += len(digits) ** (k-1-pos)
                elif d == n_str[pos]:
                    dfs(cur*10 + int(d), pos+1)

        dfs(0, 0)
        return res

if __name__ == "__main__":
    s = Solution()

    digits = ["7"]
    n = 8
    assert s.atMostNGivenDigitSet(digits, n) == 1

    digits = ["1","3","5","7"]
    n = 100
    assert s.atMostNGivenDigitSet(digits, n) == 20


# -*- coding: utf-8 -*-
"""
Created on Wed Sep  6 11:55:47 2023

@author: Gilberto
"""

import pandas as pd
from datetime import datetime, timedelta

class StraightLineAmortization:
    def __init__(self, settlement_date, maturity_date, first_payment_date, notional_amount, rate, basis_numerator, basis_denominator, amortization_years, payment_frequency):
        self.settlement_date = datetime.strptime(settlement_date, "%m/%d/%Y") if isinstance(settlement_date, str) else settlement_date
        self.maturity_date = datetime.strptime(maturity_date, "%m/%d/%Y") if isinstance(maturity_date, str) else maturity_date
        self.first_payment_date = datetime.strptime(first_payment_date, "%m/%d/%Y") if isinstance(first_payment_date, str) else first_payment_date
        self.notional_amount = notional_amount
        self.rate = rate/100
        self.basis_numerator = basis_numerator
        self.basis_denominator = basis_denominator
        self.amortization_years = amortization_years
        # Add the payment_frequency variable
        self.payment_frequency = payment_frequency
        # Adjust the num_periods and monthly_principal_payment based on payment_frequency
        if self.payment_frequency == "1M":
            self.num_periods = self.amortization_years * 12
        elif self.payment_frequency == "3M":
            self.num_periods = self.amortization_years * 4
        elif self.payment_frequency == "6M":
            self.num_periods = self.amortization_years * 2
        self.period_principal_payment = self.notional_amount / self.num_periods

    def compute_days(self, start_date, end_date):
        if self.basis_numerator == "ACT":
            days = (end_date - start_date).days
        else:
            days = 30  # assuming each month has 30 days
        if self.basis_denominator == 360:
            return days
        else:
            return days / 365.0 * 360.0

    def get_next_dates(self, current_date):
        if current_date == self.settlement_date:
            return self.first_payment_date, self.first_payment_date

        # Calculate next_month and next_year based on payment_frequency
        if self.payment_frequency == "1M":
            months_increment = 1
        elif self.payment_frequency == "3M":
            months_increment = 3
        elif self.payment_frequency == "6M":
            months_increment = 6

        next_month = (current_date.month + months_increment - 1) % 12 + 1
        next_year = current_date.year + (current_date.month - 1 + months_increment) // 12

        period_end_date = current_date.replace(year=next_year, month=next_month, day=self.first_payment_date.day)

        payment_date = period_end_date
        # If it's a weekend, move to the next business day for payment date
        while payment_date.weekday() >= 5:
            payment_date += timedelta(days=1)

        return period_end_date, payment_date

    def generate_schedule(self):
        data = []
        current_date = self.settlement_date
        payment_number = 1
        notional_amount = self.notional_amount

        while current_date < self.maturity_date and payment_number <= self.num_periods:
            period_start_date = current_date
            period_end_date, payment_date = self.get_next_dates(current_date)
            days_in_period = self.compute_days(period_start_date, period_end_date)
            actual_days_in_period = (period_end_date - period_start_date).days
            interest_for_period = (notional_amount * self.rate * days_in_period) / self.basis_denominator
            period_payment = round(interest_for_period + self.period_principal_payment,2)
            notional_amount -= self.period_principal_payment

            data.append([period_start_date, period_end_date, payment_date, payment_number, notional_amount + self.period_principal_payment, period_payment, self.period_principal_payment, actual_days_in_period])

            current_date = period_end_date # Start next period the same day as the previous period's end date
            payment_number += 1

        df = pd.DataFrame(data, columns=['Period Start Date', 'Period End Date', 'Payment Date', 'Payment Number', 'Outstanding Balance', 'Period Payment', 'Principal Payment', 'Actual Days in Period'])
        return df

# Usage
sla = StraightLineAmortization("8/1/2022", "8/1/2032", "9/1/2022", 600000, 7.03, "ACT", 360, 25, "3M")
amortization_schedule = sla.generate_schedule()
print(amortization_schedule)


# Establish the Python Logger
import logging # built in python library that does not need to be installed
import time
from datetime import datetime
import os
import talking_code as tc
speaking_log = False
speaking_steps = False

def set_speaking_log(on_off_setting = False):
    global speaking_log
    speaking_log = on_off_setting

def get_speaking_log():
    return speaking_log

def set_speaking_steps(on_off_setting = False):
    global speaking_steps
    speaking_steps = on_off_setting

def get_speaking_steps():
    return speaking_steps

def talk(speech):
    tc.say(speech)
    return

def set_start_time():
    start_time = time.time()
    return(start_time)

def create_logger_Start(solution_name, start_time):
    logging.basicConfig(level=logging.INFO, filename=solution_name + '.log',
                    filemode='w', format='%(asctime)s - %(levelname)s - %(message)s')
    process_start_time_stamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'[:-3])
    logging.info(f'START {solution_name} ' + ('=' * 45) )
    logging.info(f'START {solution_name} Start Time = {process_start_time_stamp}')
    logging.info(f'{solution_name} Step 0 - Initialize the configuration file parser')
#     return f'logger_started for {solution_name} at {process_start_time_stamp}'
    return logging

def create_logger_start(solution_name, start_time):
    logging.basicConfig(level=logging.INFO, filename=solution_name + '.log',
                    filemode='w', format='%(asctime)s - %(levelname)s - %(message)s')
    process_start_time_stamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'[:-3])
    logging.info(f'START {solution_name} ' + ('=' * 45) )
    logging.info(f'START {solution_name} Start Time = {process_start_time_stamp}')
    logging.info(f'{solution_name} Step 0 - Initialize the configuration file parser')
#     return f'logger_started for {solution_name} at {process_start_time_stamp}'
    return logging

def append_log_file(solution_name):
    log_filename=solution_name + '.log'
    historical_log_filename=solution_name + '_history.log'

    with open(log_filename) as log_file:
        log_content = log_file.read()

    with open(historical_log_filename,'a') as historical_log_file:
        print(120*' ', file=historical_log_file)
        print(120*'>', file=historical_log_file)
        print(log_content, file=historical_log_file)
        print(120*'<', file=historical_log_file)
        print(120*' ', file=historical_log_file)
    return(log_content)

def calculate_process_performance(solution_name, process_start_time):
    import time
    stop_time = time.time() # establish the stop time of the overall process.
    process_duration = stop_time - process_start_time
    process_stop_time_stamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'[:-3])

    logging.info(f'PERFORMANCE {solution_name} The total process duration was:{process_duration:.2f}')
    logging.info(f'PERFORMANCE {solution_name} Stop Time = {process_stop_time_stamp}')
    status = f'END   {solution_name} Duration Classification Error - Process Duration UNKNOWN'
    if process_duration > 600.0:
        logging.info(f'PERFORMANCE {solution_name} LONG process duration greater than 10 Minutes:{process_duration:.2f}')
        logging.info(f'PERFORMANCE {solution_name} Performance optimization is required')
    elif process_duration > 120.0:
        logging.info(f'PERFORMANCE {solution_name} Medium process duration greater than 3 minutes:{process_duration:.2f}')
        logging.info(f'PERFORMANCE {solution_name} Performance optimization is optional')
    elif process_duration > 3.0:
        logging.info(f'PERFORMANCE {solution_name} Low process duration less than 3 minutes:{process_duration:.2f}')
        logging.info(f'PERFORMANCE {solution_name} Performance optimization is optional')
    elif process_duration < 3.0:
        logging.info(f'PERFORMANCE {solution_name} Short process duration less than 3 Seconds:{process_duration:.2f}')
        logging.info(f'PERFORMANCE {solution_name} Performance optimization is not reccomended')
    else:
        status = f'PERFORMANCE {solution_name} Duration Classification Error - Process Duration UNKNOWN'

    logging.info(f'END {solution_name} ' + ('=' * 45) )
    return(status)

def set_start_time():
    start_time = time.time()
    return(start_time)

def pvlog(log_level, log_string):
    global speaking_log
    global speaking_steps

    print(log_string)
    if speaking_log:
        tc.say(log_string)

    if speaking_steps:
        if log_string.find("Step") > -1:
            tc.say(log_string)

    if log_level == 'debug':
        logging.debug(log_string)
    if log_level == 'info':
        logging.info(log_string)
    if log_level == 'warn':
        logging.warn(log_string)
    if log_level == 'error':
        logging.error(log_string)
    if log_level == 'critical':
        logging.critical(log_string)


import os
import sys
import csv
from collections import Counter, defaultdict

import pandas as pd
from statsmodels.stats.inter_rater import aggregate_raters, fleiss_kappa
#from pptx import Presentation

# configure Django so we can use models from the annotate app
sys.path.append('/home/nejl/Dropbox/projects/tator/repo/tator')
os.environ['DJANGO_SETTINGS_MODULE'] = 'tagit.settings'
import django
django.setup()

from django.contrib.auth.models import User

from annotate.models import Query, Annotation, UserResponse
from templates import slide_template

# TODO: need to add sampling method that samples equally from dividing the
# probability mass of the distribution into thirds: top most frequent, middle,
# and bottom.

# TODO: fix analysis to have a global collection filter and then make sure adding
# annotations to queries in a different collection does not change the results

def split_data_frame_by_prob(df, column, nbins):
    # splits a dataframe into 'nbins' of equal probability mass
    # using column specified by 'coilumn'

    df = df.sort_values(column, ascending=False)
    values = df[column]

    bin_probability = 1/nbins
    total = sum(values)
    cutoffs = []
    cumulative_total = 0
    next_bin_probability = bin_probability

    for i, count in enumerate(values):
        cumulative_total += count

        if cumulative_total/total < next_bin_probability:
            continue

        cutoffs.append(i)
        next_bin_probability += bin_probability

    start = 0
    new_dfs = []
    while cutoffs:
        cutoff = cutoffs.pop(0)
        if len(cutoffs) == 0:
            # last item; get the rest
            new_dfs.append(df[start:])
        else:
            new_dfs.append(df[start:cutoff])
        start = cutoff

    return new_dfs

def load_queries(path):
    with open(path) as csvfile:
        df = pd.read_csv(csvfile, delimiter=';')
    return df

def clean_queries(df):
    """Returns the input DataFrame of queries cleaned"""
    # filter out queries with length less than 2 characters long
    df = df[df['querystring'].str.len() > 1]
    return df

def split_num(num, splits):
    """Returns the number 'num' divided into a list of numbers of size 'splits' """
    splits = [int(num/splits)+1]*(num%splits) + [int(num/splits)]*(splits-num%splits)
    assert sum(splits) == num
    return splits

def import_queries(path, collection, sample='first', limit=None, allow_dupes=False):
    df = load_queries(path)
    df = clean_queries(df)

    if not allow_dupes:
        # remove existing queries from candidate queries to sample
        existing = [query.text for query in Query.objects.all()]
        df = df[~df['querystring'].isin(existing)]

    if limit is not None:
        if sample == 'first':
            df = df[:limit]
        elif sample == 'random':
            df = df.sample(limit)
        elif sample == 'proportional':
            df = df.sample(limit, weights='countqstring')
        elif sample == 'split':
            split_size = 3
            splits = split_data_frame_by_prob(df, 'countqstring', split_size)
            sizes = split_num(limit, split_size)
            sub_samples = []
            for size, split_df in zip(sizes, splits):
                sub_samples.append(split_df.sample(size, weights='countqstring'))
            df = pd.concat(sub_samples)
            assert len(df) == limit
        else:
            print('Unknown sampling method')
            return

    for i, values in enumerate(df.values.tolist()):
         text, count = values
         Query.objects.create(text=text, count=count, collection=collection)

    print("Added {} queries to the database.\n".format(i+1))
    print(df.describe())

def pretty_print_counter(counter, reverse=False):
    lines = []
    for key, value in sorted(counter.items(), reverse=reverse):
        lines.append("{}: {}".format(key, value))
    return "\n".join(lines)

def get_user_results(username, collection=None):
    # for each user, display the number of results
    # user
    lines = ["*** Annotator: {} ***".format(username)]
    lines.append("===================================\n")
    responses = UserResponse.objects.filter(user__username=username)

    if collection is not None:
        responses = responses.filter(query__collection=collection)

    annotations = [r for r in responses if r.annotation]
    skipped = [r for r in responses if r.skipped]

    lines.append("{} Skipped Queries:\n".format(len(skipped)))
    for response in skipped:
        line ='    "{}"\n    --- "{}"'.format(response.query.text,
                                              response.skipped.description)
        lines.append(line)

    lines.append("\n{} Annotations:\n".format(len(annotations)))

    lines.append(Annotation._meta.get_field('is_geo').verbose_name)
    q1 = Counter(r.annotation.is_geo for r in annotations)
    lines.append(pretty_print_counter(q1, reverse=True))

    lines.append("")

    lines.append(Annotation._meta.get_field('loc_type').verbose_name)
    q2 = Counter(r.annotation.loc_type for r in annotations)
    lines.append(pretty_print_counter(q2, reverse=True))

    lines.append("")

    lines.append(Annotation._meta.get_field('query_type').verbose_name)
    q3 = Counter(r.annotation.query_type for r in annotations)
    lines.append(pretty_print_counter(q3))

    return "\n".join(lines)

def do_iaa_pairs(user_pairs, questions=(1,2,3), collection=None, level='fine'):
    results = defaultdict(list)
    for question in questions:
        for users in user_pairs:
            kappa = get_iaa(question, users=users, collection=collection, level=level)
            results[question].append(kappa)
    return results

def print_iaa_pairs(results, user_pairs):
    print('    '+'   '.join(', '.join(user) for user in user_pairs))
    for question, kappas in results.items():
        ks = ''.join("{:0<5.3}                    ".format(k) for k in kappas)
        print("Q{}: {}".format(question, ks))

def get_iaa(question_num, queries=None, users=None, collection=None, level='fine'):
    data  = get_annotations(question_num, queries=queries, users=users, level=level, collection=collection)
    #n_cat = Annotation.get_num_categories(question_num)
    results = aggregate_raters(data, n_cat=None)
    kappa = fleiss_kappa(results[0])
    return kappa

def get_annotations(question_num, queries=None, users=None, level='fine', collection=None):
    assert level in ('fine', 'coarse')

    queries = Query.objects.exclude(responses__skipped__isnull=False).distinct()

    if collection is not None:
        queries = queries.filter(collection=collection)

    if queries is not None:
        queries = queries.filter(pk__in=queries)

    data = []
    for query in queries:
        # get all non-skipped results
        responses = query.responses.exclude(skipped__isnull=False)

        if users is not None:
            # restrict annotations to supplied users
            responses = responses.filter(user__username__in=users)

        results = [r.annotation.get_question(question_num) for r in responses]

        if question_num in (2,3) and level == 'coarse':
            # use course grained agreement
            results = [r[0] for r in results]

        if results:
            data.append(results)
    return data

def show_agreement(question_num, users, collection=None, skip_agree=True):
    lines = []
    queries = Query.objects.exclude(responses__skipped__isnull=False).distinct()

    if collection is not None:
        queries = queries.filter(collection=collection)

    queries = sorted(queries, key=lambda x:x.pk)
    users.sort()
    col_width = max(len(u) for u in users) + 2

    lines.append("".join("{u:{width}}".format(u=u, width=col_width)
                         for u in users))
    agree = 0
    disagree = 0

    for query in queries:
        responses  = query.responses.order_by('user__username')
        answers = [r.annotation.get_question(question_num) for r in responses]
        if skip_agree and len(set(answers)) <= 1:
            # all annotators agree, skip
            agree += 1
            continue
        disagree += 1
        line = "".join("{a:<{width}}".format(a=a, width=col_width)
                       for a in answers) + query.text
        lines.append(line)

    start = [
        "Question {}:".format(question_num),
        "Number all agree: {}".format(agree),
        "Number with some disagreement: {}".format(disagree),
        ""
    ]

    return "\n".join(start + lines)

def get_results(users):
    queries = Query.objects.exclude(responses__skipped__isnull=False).distinct()
    queries = sorted(queries, key=lambda x:x.pk)
    users.sort()

    rest_cols = ["Q{}_{}".format(num, user) for user in users for num in (1,2,3)]
    header = ['id', 'query'] + rest_cols
    rows = [header]

    for query in queries:
        row = [query.pk, query.text]
        responses = query.responses.order_by('user__username')
        for response in responses:
            row.append(response.annotation.get_question(1))
            row.append(response.annotation.get_question(2))
            row.append(response.annotation.get_question(3))
        rows.append(row)
    return rows

def export_results_csv(users, outfile='annotations.csv'):
    results = get_results(users)
    with open(outfile, 'w', encoding='utf8', newline='') as csvfile:
        writer = csv.writer(csvfile, delimiter=',')
        writer.writerows(results)

def make_slides_latex(users, csv=None, outfile='slides/slides.tex'):
    if csv is None:
        results = get_results(users)
    else:
        with open(csv, encoding='utf8') as csvfile:
            results = list(csv.reader(csvfile))

    lines = []
    header = results[0]
    for i, query in enumerate(results[1:]):
        row1 = r"Q1 & {} & {} & {}\\".format(query[2], query[5], query[8])
        row2 = r"Q2 & {} & {} & {}\\".format(query[3], query[6], query[9])
        row3 = r"Q3 & {} & {} & {}\\".format(query[4], query[7], query[10])
        rows = "\n".join([row1, row2, row3])
        title = "Query {}".format(i+1)
        slide = slide_template.format(title=title, query=query[1], rows=rows)
        lines.append(slide)

    with open(outfile, 'w', encoding='utf8') as texfile:
        texfile.write('\n'.join(lines))

def make_slides_pptx(users, csv=None):
    """Not finished. Used latex instead"""
    if csv is None:
        results = get_results(users)
    else:
        with open(csv, encoding='utf8') as csvfile:
            results = list(csv.reader(csvfile))

    header = results[0]

    prs = Presentation()
    slide_layout = prs.slide_layouts[1]

    for i, query in enumerate(results[1:]):
        slide = prs.slides.add_slide(slide_layout)
        slide.shapes.title.text = 'Query {}'.format(i+1)

        body_shape = slide.shapes.placeholders[1]
        tf = body_shape.text_frame

        p = tf.paragraphs[0]
        p.text = query[1]
        p.level = 0

    prs.save('test.pptx')


# -*- coding: utf-8 -*-
import time, functools

def metric(fn):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args,**kw):
            print(fn) if fn.__str__()==fn else print('no metric args')
            start_time=time.time()
            return (func(*args,**kw),print('%s executed in %s ms' % (func.__name__, time.time()-start_time)))[0]
        return wrapper
    return decorator if fn.__str__()==fn else decorator(fn)

@metric
def fast(x, y):
    time.sleep(0.0012)
    return x + y;

@metric('test')
def slow(x, y, z):
    time.sleep(0.1234)
    return x * y * z;

f = fast(11, 22)
s = slow(11, 22, 33)
if f != 33:
    print('测试失败!')
elif s != 7986:
    print('测试失败!')
else:
    print('测试成功!')


import os
from collections import deque
from typing import Dict, List, Optional, Any
import langchain
import openai
import pinecone
from langchain.chains import LLMChain
from langchain.chains.base import Chain
from langchain.agents import AgentType, ZeroShotAgent, Tool, AgentExecutor, initialize_agent
from langchain.llms import OpenAI, LlamaCpp, BaseLLM
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory, ReadOnlySharedMemory
from langchain.utilities import GoogleSearchAPIWrapper
from langchain.vectorstores.base import VectorStore
from pydantic import BaseModel, Field
from langchain.embeddings import OpenAIEmbeddings
import faiss
from langchain.vectorstores import FAISS
from langchain.docstore import InMemoryDocstore

# Define your embedding model
embeddings_model = OpenAIEmbeddings()

# Initialize the vectorstore as empty
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})

# Initialize our LLM
llm = OpenAI(temperature=0)

class TaskCreationChain(LLMChain):
    """Chain to generates tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        task_creation_template = (
            "You are a task creation AI that uses the result of an execution agent"
            " to create new tasks with the following objective: {objective},"
            " The last completed task has the result: {result}."
            " This result was based on this task description: {task_description}."
            " These are incomplete tasks: {incomplete_tasks}."
            " Based on the result, create new tasks to be completed"
            " by the AI system that do not overlap with incomplete tasks."
            " Return the tasks as an array."
        )
        prompt = PromptTemplate(
            template=task_creation_template,
            input_variables=[
                "result",
                "task_description",
                "incomplete_tasks",
                "objective",
            ],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

class TaskPrioritizationChain(LLMChain):
    """Chain to prioritize tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        task_prioritization_template = (
            "You are a task prioritization AI tasked with cleaning the formatting of and reprioritizing"
            " the following tasks: {task_names}."
            " Consider the ultimate objective of your team: {objective}."
            " Do not remove any tasks. Return the result as a numbered list, like:"
            " #. First task"
            " #. Second task"
            " Start the task list with number {next_task_id}."
        )
        prompt = PromptTemplate(
            template=task_prioritization_template,
            input_variables=["task_names", "next_task_id", "objective"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

class ExecutionChain(AgentExecutor):
    """Chain to execute tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> AgentExecutor:
        """Get the response parser."""

        template = """This is a conversation between a human and a bot:

            {chat_history}

            Write a summary of the conversation for {input}:
        """
        prompt = PromptTemplate(template=template, input_variables=["chat_history", "input"])
        memory = ConversationBufferMemory(memory_key="chat_history")
        read_memory = ReadOnlySharedMemory(memory=memory)
        summary_chain = LLMChain(memory=read_memory, prompt=prompt, llm=llm, verbose=True)
        search = GoogleSearchAPIWrapper()
        tools = [
            Tool(
                name = "Search",
                func=search.run,
                description="useful for when you need to answer questions about current events"
            ),
            Tool(
                name = "Summary",
                func=summary_chain.run,
                description="useful for when you summarize a conversation. The input to this tool should be a string, representing who will read this summary."
            )
        ]
        prefix = """
            You are an AI who performs one task based on the following objective: {objective}.
            Take into account these previously completed tasks: {context}.
        """
        suffix = """
             Your task: {task}.
             Response:
             {agent_scratchpad}
        """
        prompt = ZeroShotAgent.create_prompt(
            tools,
            prefix=prefix,
            suffix=suffix,
            input_variables=["objective", "context", "task", "agent_scratchpad"],
        )
        llm_chain = LLMChain(llm=llm, prompt=prompt)
        agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=verbose)
        return cls.from_agent_and_tools(agent=agent, tools=tools, verbose=verbose, memory=memory)

todo_template = """
    You are an expert in walking through your thoughts. You are able to take the main objective, as well as the tasks, and create step by step observations. Here is the objective: {objective}
"""
todo_prompt = PromptTemplate(template=todo_template, input_variables=["objective"])
todo_chain = LLMChain(llm=OpenAI(temperature=0), prompt=todo_prompt)
search = GoogleSearchAPIWrapper()
tools = [
    Tool(
        name="Search",
        func=search.run,
        description="useful for when you need to answer questions about current events",
    ),
    Tool(
        name="TODO",
        func=todo_chain.run,
        description="useful for when you need to come up brainstorming for the current task at hand. Input: an objective to create a todo list for as well as the task. Output: a rational thought process behind the objective and task, enough to help you craft a perfect response.",
    ),
]

prefix = """You are an AI who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}."""
suffix = """Question: {task}
{agent_scratchpad}"""
zeroshot_prompt = ZeroShotAgent.create_prompt(
    tools,
    prefix=prefix,
    suffix=suffix,
    input_variables=["objective", "task", "context", "agent_scratchpad"],
)

def get_next_task(
    task_creation_chain: LLMChain,
    result: Dict,
    task_description: str,
    task_list: List[str],
    objective: str,
) -> List[Dict]:
    """Get the next task."""
    incomplete_tasks = ", ".join(task_list)
    response = task_creation_chain.run(
        result=result,
        task_description=task_description,
        incomplete_tasks=incomplete_tasks,
        objective=objective,
    )
    new_tasks = response.split("\n")
    return [{"task_name": task_name} for task_name in new_tasks if task_name.strip()]

def prioritize_tasks(
    task_prioritization_chain: LLMChain,
    this_task_id: int,
    task_list: List[Dict],
    objective: str,
) -> List[Dict]:
    """Prioritize tasks."""
    task_names = [t["task_name"] for t in task_list]
    next_task_id = int(this_task_id) + 1
    response = task_prioritization_chain.run(
        task_names=task_names, next_task_id=next_task_id, objective=objective
    )
    new_tasks = response.split("\n")
    prioritized_task_list = []
    for task_string in new_tasks:
        if not task_string.strip():
            continue
        task_parts = task_string.strip().split(".", 1)
        if len(task_parts) == 2:
            task_id = task_parts[0].strip()
            task_name = task_parts[1].strip()
            prioritized_task_list.append({"task_id": task_id, "task_name": task_name})
    return prioritized_task_list

def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]:
    """Get the top k tasks based on the query."""
    results = vectorstore.similarity_search_with_score(query, k=k)
    if not results:
        return []
    sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))
    return [str(item.metadata["task"]) for item in sorted_results]

def execute_task(
    vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5
) -> str:
    """Execute a task."""
    context = _get_top_tasks(vectorstore, query=objective, k=k)
    return execution_chain.run(objective=objective, context=context, task=task)

class BabyAGI(Chain, BaseModel):
    """Controller model for the BabyAGI agent."""

    task_list: deque = Field(default_factory=deque)
    task_creation_chain: TaskCreationChain = Field(...)
    task_prioritization_chain: TaskPrioritizationChain = Field(...)
    execution_chain: ExecutionChain = Field(...)
    task_id_counter: int = Field(1)
    vectorstore: VectorStore = Field(init=False)
    max_iterations: Optional[int] = None

    class Config:
        """Configuration for this pydantic object."""

        arbitrary_types_allowed = True

    def add_task(self, task: Dict):
        self.task_list.append(task)

    def print_task_list(self):
        print("\033[95m\033[1m" + "\n*****TASK LIST*****\n" + "\033[0m\033[0m")
        for t in self.task_list:
            print(str(t["task_id"]) + ": " + t["task_name"])

    def print_next_task(self, task: Dict):
        print("\033[92m\033[1m" + "\n*****NEXT TASK*****\n" + "\033[0m\033[0m")
        print(str(task["task_id"]) + ": " + task["task_name"])

    def print_task_result(self, result: str):
        print("\033[93m\033[1m" + "\n*****TASK RESULT*****\n" + "\033[0m\033[0m")
        print(result)

    @property
    def input_keys(self) -> List[str]:
        return ["objective"]

    @property
    def output_keys(self) -> List[str]:
        return []

    def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
        """Run the agent."""
        objective = inputs["objective"]
        first_task = inputs.get("first_task", "Make a todo list")
        self.add_task({"task_id": 1, "task_name": first_task})
        num_iters = 0
        while True:
            if self.task_list:
                self.print_task_list()

                # Step 1: Pull the first task
                task = self.task_list.popleft()
                self.print_next_task(task)

                # Step 2: Execute the task
                result = execute_task(
                    self.vectorstore, self.execution_chain, objective, task["task_name"]
                )
                this_task_id = int(task["task_id"])
                self.print_task_result(result)

                # Step 3: Store the result in Pinecone
                result_id = f"result_{task['task_id']}"
                self.vectorstore.add_texts(
                    texts=[result],
                    metadatas=[{"task": task["task_name"]}],
                    ids=[result_id],
                )

                # Step 4: Create new tasks and reprioritize task list
                new_tasks = get_next_task(
                    self.task_creation_chain,
                    result,
                    task["task_name"],
                    [t["task_name"] for t in self.task_list],
                    objective,
                )
                for new_task in new_tasks:
                    self.task_id_counter += 1
                    new_task.update({"task_id": self.task_id_counter})
                    self.add_task(new_task)
                self.task_list = deque(
                    prioritize_tasks(
                        self.task_prioritization_chain,
                        this_task_id,
                        list(self.task_list),
                        objective,
                    )
                )
            num_iters += 1
            if self.max_iterations is not None and num_iters == self.max_iterations:
                print(
                    "\033[91m\033[1m" + "\n*****TASK ENDING*****\n" + "\033[0m\033[0m"
                )
                break
        return {}

    @classmethod
    def from_llm(
        cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs
    ) -> "BabyAGI":
        """Initialize the BabyAGI Controller."""
        task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)
        task_prioritization_chain = TaskPrioritizationChain.from_llm(llm, verbose=verbose)
        llm_chain = LLMChain(llm=llm, prompt=zeroshot_prompt)
        tool_names = [tool.name for tool in tools]
        agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names)
        agent_executor = AgentExecutor.from_agent_and_tools(
            agent=agent, tools=tools, verbose=True
        )

        return cls(
            task_creation_chain=task_creation_chain,
            task_prioritization_chain=task_prioritization_chain,
            execution_chain=agent_executor,
            vectorstore=vectorstore,
            **kwargs,
        )

# Logging of LLMChains
verbose = False
# If None, will keep on going forever
max_iterations: Optional[int] = None

baby_agi = BabyAGI.from_llm(
    llm=llm, vectorstore=vectorstore, verbose=verbose, max_iterations=max_iterations
)

baby_agi({"objective": 'Write a cohesive and articulated story about a man named Jack who conquers the world.'})


import fileinput
import sys
from collections import deque, defaultdict, Counter
from functools import lru_cache
from itertools import permutations, combinations, combinations_with_replacement, product
sys.setrecursionlimit(10000000)
dd = defaultdict(lambda: 0)
dx = [0, 0, -1, 1]  # NSWE
dy = [-1, 1, 0, 0]  # NSWE

p1 = 6
p2 = 10

def part1(p1, p2):
    die = 1
    score1 = score2 = 0
    turn = True
    rolled = 0
    while (score1 < 1000 and score2 < 1000):

        d1 = die
        die = die % 100 + 1
        d2 = die
        die = die % 100 + 1
        d3 = die
        die = die % 100 + 1
        rolled += 3
        roll = d1+d2+d3
        if turn:
            p1 = (p1 - 1 + roll) % 10 + 1
            score1 += p1
        else:
            p2 = (p2 - 1 + roll) % 10 + 1
            score2 += p2
        turn = not turn
    return min(score1, score2) * rolled

@lru_cache(maxsize=None)
def old_dp(p1, p2, score1, score2, turn):
    if score1 >= 21:
        return Counter({"p1": 1})
    elif score2 >= 21:
        return Counter({"p2": 1})
    s = Counter()
    for i, j, k in product([1, 2, 3], repeat=3):
        if turn:
            z = (p1 - 1 + i+j+k) % 10 + 1
            s += old_dp(z, p2, score1 + z, score2, not turn)
        else:
            z = (p2 - 1 + i+j+k) % 10 + 1
            s += old_dp(p1, z, score1, score2+z, not turn)
    return s

dices = []
for i, j, k in product([1, 2, 3], repeat=3):
    dices.append(i+j+k)
dices = Counter(dices)

@lru_cache(maxsize=None)
def dp(p1, p2, score1, score2):
    if score1 >= 21:
        return (1,0)
    elif score2 >= 21:
        return (0,1)
    a = b = 0
    for k,times in dices.items():
        z = (p1 - 1 + k) % 10 + 1
        x,y = dp(p2, z, score2, score1 + z)
        a+=times * x
        b+=times * y
    return (b,a)

# print(part1(p1, p2), max(old_dp(p1, p2, 0, 0, True)))
print(part1(p1, p2), max(dp(p1, p2, 0, 0)))


import sys, json
from urllib.request import urlopen
from collections import OrderedDict

list_host = 'http://localhost:5000'
list_url = list_host + '/api/3/action/organization_list'
get_url = list_host + '/api/3/action/organization_show'

contents = urlopen(list_url)
org_list =  json.load(contents)['result']

for org_name in org_list:

    org_url = get_url + "?id=" + org_name
    print("=== Loading " +org_name + " from " + org_url)

    org_content = urlopen(org_url)
    org_obj = json.load(org_content)['result']

    org = OrderedDict()
    for key in ('name', 'title', 'description', 'site', 'email', 'region', 'identifier'):
        if key in org_obj and org_obj[key]:
            org[key] = org_obj[key]

    org_filename = "orgs/"+org_name+".json"
    with open(org_filename,"w+") as f:
        f.write(json.dumps(org, indent=4))

    print("=== Saved in "+org_filename+"\n")


# https://leetcode.com/problems/rotting-oranges/
"""
Time complexity:- O(N)
Space Complexity:- O(N)
"""

"""
Intuition:

The algorithm uses Breadth-First Search (BFS) to simulate the rotting process, starting from initially rotten oranges.
The queue (q) is used to keep track of the rotten oranges and their coordinates.
The process continues until either all fresh oranges are rotten or there are no more rotten oranges.
The time variable keeps track of the minutes passed during the rotting process.
If there are still fresh oranges after the simulation, it means some oranges cannot be rotten, and -1 is returned.
The algorithm follows a simple and intuitive approach of simulating the rotting process through BFS traversal.
"""
import collections
from typing import List

class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        q = collections.deque()  # Using deque for efficient pop and append operations
        fresh = 0  # Counter for fresh oranges
        time = 0  # Variable to track time (minutes)

        # Iterate through the grid to identify fresh and rotten oranges
        for r in range(len(grid)):
            for c in range(len(grid[0])):
                if grid[r][c] == 1:
                    fresh += 1
                if grid[r][c] == 2:
                    q.append((r, c))  # Add coordinates of rotten oranges to the queue

        # Directions to check neighboring cells (up, down, left, right)
        directions = [[0, 1], [0, -1], [1, 0], [-1, 0]]

        # BFS traversal to simulate rotting process
        while fresh > 0 and q:
            length = len(q)
            for i in range(length):
                r, c = q.popleft()  # Pop the front of the queue

                for dr, dc in directions:
                    row, col = r + dr, c + dc
                    # Check if the neighboring cell is in bounds and contains a fresh orange
                    if (
                        row in range(len(grid))
                        and col in range(len(grid[0]))
                        and grid[row][col] == 1
                    ):
                        grid[row][col] = 2  # Mark the orange as rotten
                        q.append((row, col))  # Add the coordinates to the queue
                        fresh -= 1  # Decrease the count of fresh oranges

            time += 1  # Increment time after processing each minute

        # Return the time required if all fresh oranges are rotten, otherwise return -1
        return time if fresh == 0 else -1


import socket
host = "192.168.0.1"
port = 80
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
buf = b'-' * 30
s.send(b'GET /HTTP/1.1\r\n\r\n')
resp = s.recv(2048)
print("Number of bytes",len(resp))
print(buf.decode())
s.close()


import os
import sys
import signal
import threading
import multiprocessing
import atexit
import time
from ctypes import c_bool

from .module import StateIO
from .config import Config

class Controller:
    def __init__(self, config: Config) -> None:

        args, self.cfg = config.load()
        self.pidfile_path = '/tmp/controller.pids' # should be config ?

        # make sure self.on_exist is always called
        atexit.register(self.on_shutdown)

        self.procmem = {"StateIO": multiprocessing.Array(StateIO, 1)}
        self.threads = {}
        self.processes = {}

        # parse config and import modules classes
        self.modules_classes = {}
        self.args_import(args)

        # initialize all modules
        self.modules_instances = [None]*99
        self.modules_init()

    def _module_init(self, mtype):

        mclass = self.modules_classes[mtype]["ModuleName"]
        args = self.modules_classes[mtype]["Attributes"]
        init_order = self.modules_classes[mtype]["RunPriority"]
        in_list = self.modules_classes[mtype]["InputMem"]
        out_list = self.modules_classes[mtype]["OutputMem"]

        # initialize BaseModule class
        module = mclass(args, self.procmem, in_list, out_list)
        module.INIT_NAME = mtype
        module.INIT_ORDER = init_order
        module.SHUTDOWN = multiprocessing.Value(c_bool, False)
        # TODO tick_delta should be here with info msg if it is here

        run_type = self.modules_classes[mtype]["RunType"]
        if run_type == 0:
            module.IS_MAIN = True
        elif run_type == 1:
            module.IS_THREAD = True
        elif run_type == 2:
            module.IS_PROCESS = True
        else:
            print("fatal error: incorect RunType config at:\n module: {0}".format(module.INIT_NAME))
            sys.exit(1)

        if self.modules_instances[init_order]:
            _name = self.modules_instances[init_order].INIT_NAME
            print("fatal error: equal RunPriority config at modules:\n"
                  "module{0}\nmodule: {1}".format(_name, module.INIT_NAME))
            sys.exit(1)

        self.modules_instances.pop(init_order)
        self.modules_instances.insert(init_order, module)

        print(" {0} initilized".format(module.INIT_NAME))

    def modules_init(self):

        for key in self.modules_classes:

            asycn_init = self.modules_classes[key]["AsyncInit"]

            if asycn_init:
                thread = threading.Thread(
                    target=self._module_init,
                    args=([key])
                    )
                thread.daemon = True
                thread.start()

            else:
                self._module_init(key)

        self.modules_instances = [ inst for inst in self.modules_instances if inst is not None ]
        index = list(range(len(self.modules_instances)))
        for instance, n in zip(self.modules_instances, index):
            instance.INIT_ORDER = n

    def start(self):

        self.kill_processes() # FIXME make sure only one instance is running

        # save main pid
        with open(self.pidfile_path, "w") as pidfile:
            pid0 = str(os.getpid())
            pidfile.write("%s\n" % (pid0))
            print(" controller started with PID(s):", pid0)

        tmp = []
        while not self.procmem["StateIO"][0].shutdown:
            # TODO test if class_import works here (hot reload), should be async call when updating instances
            # TODO add nice arg to processes
            # FIXME on_start is out of order

            for instance in self.modules_instances:

                # print("tick:",instance.INIT_NAME)
                shutdown = instance.SHUTDOWN.value

                if not instance.IS_RUNNING:
                    if instance.IS_PROCESS and not shutdown:
                        instance.IS_RUNNING = True
                        proc = multiprocessing.Process(target=instance._tick)
                        proc.name = instance.INIT_NAME
                        self.processes[proc.name] = proc
                        proc.start()
                        # TODO should save here process pids

                    elif instance.IS_THREAD and not shutdown:
                        instance.IS_RUNNING = True
                        thread = threading.Thread(target=instance._tick)
                        thread.name = instance.INIT_NAME
                        thread.daemon = True
                        self.threads[thread.name] = thread
                        thread.start()

                    elif not instance.IS_MAIN and not shutdown:
                        instance.IS_RUNNING = True
                        instance._start()

                if instance.IS_MAIN and not shutdown:
                    try:
                        instance.on_tick()
                    except Exception as e:
                        # TODO error reporing format
                        print(instance.INIT_NAME)
                        print(e)

                if shutdown:
                    tmp.append(instance.INIT_ORDER)
                    # FIXME process is still be visible in top with 0 mem, when it is shutdown

            tmp.reverse()
            for n in tmp:

                name = self.modules_instances[n].INIT_NAME

                if self.modules_instances[n].IS_PROCESS:
                    self.processes[name].kill()
                    self.processes[name].join(timeout=0.001)
                    self.processes[name].close()
                    del self.processes[name]

                elif self.modules_instances[n].IS_THREAD:
                    del self.threads[name]

                elif self.modules_instances[n].IS_MAIN:
                    self.modules_instances[n]._stop()

                self.modules_instances.remove(self.modules_instances[n])
                print(" {0} is removed".format(name))

            tmp.clear()

            # t_instances = len(self.modules_instances) + 1
            # t_threads = len(self.threads)
            # t_processes = len(self.processes)
            # t_main = t_instances - t_threads - t_processes

            # print(" main process instence(s): {0}\n"
            #       " thread instance(s):       {1}\n"
            #       " subprocess instance(s):   {2}\n"
            #       " total running instances:  {3}"\
            #         .format(t_main,
            #                 t_threads,
            #                 t_processes,
            #                 t_instances
            #                 ))

            time.sleep(1)

    def on_shutdown(self):
        """
            Called each time application is exiting throught atexit
        """
        # FIXME will error on joystick
        # TODO make sure threads are exited correctly
        # TODO wait for processes to exit, check for zombie processes
        pass

    def shutdown(self):
        self.procmem["StateIO"][0].shutdown = True

    def kill_processes(self):
        pid = None
        if os.path.exists(self.pidfile_path):
            with open(self.pidfile_path, "r") as pidfile:
                pids = pidfile.readlines()
                pidfile.close()

            for _pid in pids[::-1]:

                pid = _pid[:-1]

                while True:
                    if os.path.exists("/proc/" + pid):
                        print("Attempting to shutdown existing controller:", pid)
                        # FIXME hcitool will hangd when sending SIGINT
                        os.kill(int(pid), signal.SIGINT)
                        continue
                    break

    def class_import(self, mtype, arg, mname=None):
        # TODO check if configs class(s) is already imported in config
        try:
            print(mtype, arg, mname)
            class_cfg = self.cfg[mtype][mname][arg]
            module_name = class_cfg["ModuleName"]
            cls_name = mtype[:3] + ":" + arg[:3] + ":" + mname + ":" + module_name

        except KeyError:
            print("import error: unknown module class name:", arg)
            sys.exit(1)

        self.modules_classes[cls_name] = class_cfg

        try:

            if module_name != 'BaseModule':
                folder_name = mtype[:-1]
                module_path = 'modules.'+ module_name + '.' + folder_name
                class_name = folder_name.capitalize()
                module = __import__(module_path, fromlist=[class_name])
                self.modules_classes[cls_name]["ModuleName"] = getattr(module, class_name)
            else:
                # used for testing
                module_path = 'controller'
                module = __import__(module_path, fromlist=['BaseModule'])
                self.modules_classes[cls_name]["ModuleName"] = getattr(module, 'BaseModule')

        except AttributeError:
            print("import error: failed to import class:", cls_name, 'modules.'+ module_name + '.' + mtype[:-1])
            sys.exit(1)

        try:
            for m in self.modules_classes[cls_name]['InputMem']:
                if not m in self.procmem:
                    module = __import__('modules.structures', fromlist=[m])
                    mem = getattr(module, m)
                    self.procmem[m] = multiprocessing.Array(mem, 1)
                    print(" shared memory {0} intialized".format(m))

        except AttributeError:
            print("import error: failed to import input shared memory class:", m)
            sys.exit(1)

        try:
            for m in self.modules_classes[cls_name]['OutputMem']:
                if not m in self.procmem:
                    module = __import__('modules.structures', fromlist=[m])
                    mem = getattr(module, m)
                    # mem = getattr(self.imported, m)
                    self.procmem[m] = multiprocessing.Array(mem, 1)
                    print(" shared memory {0} intialized".format(m))

        except AttributeError:
            print("import error: failed to import output shared memory class:", m)
            sys.exit(1)

    def _parse_module_args(self, const):
        if const != 'default':
            args = const.split(":")
            return args[0], args[1]
        else:
            return const, const

    def args_import(self, args):
        if len(sys.argv) == 1:
            # TODO add default args, when no argements provided
            print("default args are not implemented!")
            sys.exit(1)

        if args.stop:
            self.kill_processes()
            sys.exit(0)

        # reset sys args to avoid interference with other modules
        sys.argv = [sys.argv[0]]

        if args.hardware_only:
            self.class_import("interfaces", args.hardware_only, "hardware")
            return

        if args.display_only:
            interface, controller = self._parse_module_args(args.display_only)
            self.class_import("interfaces",  interface, "display")
            self.class_import("controllers", controller, "display")
            return

        if args.sound_only:
            interface, controller = self._parse_module_args(args.sound_only)
            self.class_import("interfaces", interface, "speaker")
            self.class_import("controllers", controller, "speaker")
            return

        if not args.no_hardware:
            self.class_import("interfaces", 'default', "hardware")

        # must below hardware, to support no-hardware flag
        if args.actuators_only:
            interface, controller = self._parse_module_args(args.actuators_only)
            self.class_import("interfaces", interface, "actuators")
            self.class_import("controllers", controller, "actuators")
            return

        if not args.actuators_only:
            self.class_import("interfaces", 'default', "actuators")
            self.class_import("controllers", 'default', "actuators")

        if not args.no_display:
            self.class_import("interfaces", 'default', "display")
            self.class_import("controllers",'default', "display")

        if not args.no_sound:
            self.class_import("interfaces", 'default', "speaker")
            self.class_import("controllers", 'default', "speaker")

        if args.keyboard:
            self.class_import("interfaces", args.keyboard, "keyboard")

        if args.joystick:
            self.class_import("interfaces", args.joystick, "joystick")


n = input().split()

def with_c(c):
    temp = []
    for i in n:
        if c in i:
            temp.append(i)
    return temp

def vowel_count(pairs):
    for i in pairs:
        i = i.lower()
        if i.count('a') + i.count('e') + i.count('i') + i.count('o') + i.count('u') != 2:
            return False
    else:
        return True

main = []

for word in n:
    for letter in word:
        pairs = with_c(letter)

        if vowel_count(pairs) and len(pairs) == 2:
            main.append(pairs)
        else:
            break
    else:
        print(word)


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import NoSuchElementException
import logging

def has_booking_started(url: str) -> bool:
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_experimental_option('excludeSwitches', ['enable-logging'])
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
    driver.implicitly_wait(0.5)
    driver.get(url)
    try:
        if driver.find_elements(By.XPATH, '//button[@data-name="get-tickets"]'):
            logging.info("Ticket booking has started")
            return True
        else:
            logging.info("Ticket booking hasn't started yet")
            return False
    except NoSuchElementException:
        logging.info("Ticket booking hasn't started yet")
        return False
    finally:
        driver.close()


# Clase 1
import machine, time
from machine import ADC

# file=open("data.csv","w")	# creation and opening of a CSV file in Write mode
# # Type Program Logic Here
# file.write(str(value)+",")	# Writing data in the opened file
# # file.flush()			# Internal buffer is flushed (not necessary if close() function is used)
# file.close()			# The file is closed

rtc = machine.RTC()
#rtc.datetime((2020, 1, 21, 2, 10, 32, 36, 0))
print(rtc.datetime())

value_ad = ADC(26)

print("Starting...")
file = open("data/data.txt","w") # creation and opening of a CSV file in Write mode
led = machine.Pin(25, machine.Pin.OUT)

while True:
    n = value_ad.read_u16()
    print(n)
    file.write(str(n)+",") # Writing data in the opened file
    file.flush() # Internal buffer is flushed (not necessary if close() function is used)
    time.sleep(1)
file.close()			# The file is closed


from kingadmin.admin_base import BaseKingAdmin

class AdminSite():
    """用于注册用的类"""
    def __init__(self):
        self.enabled_admins = {}

    def register(self, model_class, admin_class = None):
        """注册admin表"""
        app_name = model_class._meta.app_label
        model_name = model_class._meta.model_name
        if not admin_class:#为了避免多个model共享一个BaseKingAdmin内存对象
            admin_class = BaseKingAdmin()
        else:
            admin_class = admin_class()

        admin_class.model = model_class #把model_class赋值给了admin_class

        if app_name not in self.enabled_admins:
            self.enabled_admins[app_name] = {}
        self.enabled_admins[app_name][model_name] = admin_class

site = AdminSite()