# coding: utf-8

#import modules
from utils import *
from vgg16 import Vgg16
import os, sys

#Create references to important directories
path = 'data/dogscatsredux/'
#path = 'data/dogscatsredux/sample/'

# Code assumes data has been downloaded from Kaggle and organized in directory structure similar to:
'''
					     				data
					      				||
									cats-dogs-redux
                 ____________________________||__________________
                 |	 |	             |	                |
              train	test  	       valid              sample
	       ___ |___              ___|___          ______|_______
           |       |           |         |        |              |
          cats    dogs        cats     dogs    train            valid
                                       	     ___|___          ____|____
                                       	    |       |        |         |
                                    	    cats   dogs     cats      dogs

'''

# # Outline:
#
# 1. Finetune and Train Model
# 2. Generate Predictions
# 3. Validate Predictions
# 4. Submit Predictions to Kaggle

# # Finetuning and Training

#Set paths to data
test_path = path+'/test/'
train_path = path+'/train/'
valid_path = path+'/valid/'
results_path = path+'/results/'

#import Vgg16
vgg = Vgg16()

#Set hyper-parameters
batch_size = 64
n_epochs = 3

#Finetune the model
batches = vgg.get_batches(train_path, batch_size=batch_size)
val_batches = vgg.get_batches(valid_path, batch_size=batch_size*2)
vgg.finetune(batches)

#Fit and generate weights for each epoch
latest_weights_filename = None
for epoch in range(n_epochs):
    print('Running epoch: %d' % epoch)
    vgg.fit(batches, val_batches, nb_epoch=1)
    latest_weights_filename = 'ft%d.h5' % epoch
    vgg.model.save_weights(results_path+latest_weights_filename)

print('Comleted %s fit operations' % n_epochs)

# # Generate Predictions
#Make predictions on the test dataset using our new model
batches, preds = vgg.test(test_path, batch_size=batch_size*2)

#vgg.test() generates two probabilities per image
#Need to check which column is cats and which is dogs
filenames = batches.filenames
print(preds[:5])
print(filenames[:5])

#Verify column ordering by viewing some images
from PIL import Image
Image.open(test_path + filenames[2])

# From the above, it appears that column 1 is cats and column 2 is dogs

#Save test results arrays for future use
save_array(results_path+'test_preds.dat', preds)
save_array(results_path+'filenames.dat', filenames)

# # Validate Predictions

#Calculate predictions on validation set for debugging of model
vgg.model.load_weights(results_path+latest_weights_filename)
val_batches, probs = vgg.test(valid_path, batch_size=batch_size)

#Find correct and incorrect examples
filenames = val_batches.filenames
expected_labels = val_batches.classes #Assigns '0' or '1'

#Round predictions to '0' or '1' to generate labels
our_predictions = probs[:,0]
our_labels = np.round(1 - our_predictions)

# Looking at examples of each of:
#
# 1. A few correct labels at random
# 2. A few incorrect labels at random
# 3. Those with highest probability of being correct labels
# 4. Those with highest probability of being incorrect labels
# 5. Those with probability closest to 0.5, i.e. most uncertain labels

#Set-up for analysing above examples (not included in this file)
from keras.preprocessing import image

#Print out confusion matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(expected_labels, our_labels)
plot_confusion_matrix(cm, val_batches.class_indices)

# # Submit Predictions to Kaggle
preds = load_array(results_path+'test_preds.dat')
filenames = load_array(results_path+'filenames.dat')

#Grab the dog prediction column (column 2)
isdog = preds[:,1]

#To play it safe, round down our edge predictions to avoid punishment from log-loss
isdog = isdog.clip(min=0.05, max=0.95)

#Extract imageIds from the filenames in our test directory
filenames = batches.filenames
ids = np.array([int(f[5:f.find('.')]) for f in filenames])
#Join the two columns into an array [imageId, isDog]
subm = np.stack([ids, isdog], axis=1)
subm[:5]

submission_file_name = 'submission1.csv'
np.savetxt(submission_file_name, subm, fmt='%d,%.5f', header='id,label', comments='')


import datetime
import json
import math
import random
import sys
import threading
import tkinter as tk
import webbrowser
from datetime import *
from time import sleep
from tkinter import *
import pandas as pd
import psutil
import pyaudio
import pyautogui
import pyperclip
import pyttsx3
import qrcode
import requests
import speech_recognition as sr
import wikipedia
from plyer import notification
from tqdm import tqdm
from vosk import Model, KaldiRecognizer
from multiprocessing.pool import ThreadPool

engine = pyttsx3.init()
model = Model("../model")
rec = KaldiRecognizer(model, 16000)
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=8000)
stream.start_stream()
despedidas = ['tchal', 'adeus', 'te vejo mais tarde', 'até', 'até logo']
pacoteOffice = ['word', 'excel', 'powerpoint', 'access', 'teams']
opcoes = ['word', 'excel', 'powerpoint', 'access', 'teams', 'genshin impact', 'chrome', 'microsoft edge']

class ROXXANE(threading.Thread):
    def __init__(self, asist_name, person):
        threading.Thread.__init__(self)  # thread da Roxxane
        self.pessoa = person
        self.nome_assistente = asist_name
        self.voz_data = ''
        self.aux = ''
        self.arquivoR = open(r"../databaseR.txt", 'r', encoding='utf-8')
        self.arquivoR = self.arquivoR.read()
        self.arquivoR = self.arquivoR.split()
        self.arquivoF = open(r"../databaseF.txt", 'r', encoding='utf-8')
        self.arquivoF = self.arquivoF.read()
        self.arquivoF = self.arquivoF.split()
        self.pool = ThreadPool(processes=1)

    def existe(self, termos):
        for termo in termos:
            if termo in self.voz_data:
                return True

    def pegar_comandos_separados(self):
        while True:
            rec.pause_threshold = 1
            data = stream.read(10000)
            if len(data) == 0:
                break
            if rec.AcceptWaveform(data):
                resultado = rec.FinalResult()
                resultado = json.loads(resultado)
                if resultado is not None:
                    return resultado['text'].lower()
        # rec.pause_threshold = 1
        # data_audio = stream.read(8000)
        # rec.AcceptWaveform(data_audio)
        # try:
        #     retorno = rec.FinalResult()
        # except:
        #     print('Fala mais alto')
        #     return 'none'
        # return retorno

    def conversas(self):
        if self.existe(['hey', 'hi', 'hello', 'oi', 'holla']):
            greetigns = [f'Oi {self.pessoa}, o que você está fazendo hoje?',
                         f'Oi {self.pessoa}, como eu posso te ajudar?',
                         f'Oi {self.pessoa}, você precisa de algo?',
                         f'Oi {self.pessoa}, como vai você?']
            greet = greetigns[random.randint(0, len(greetigns) - 1)]
            self.engine_speak(greet)
            self.voz_data = ''

        elif self.existe(['tudo bem', 'como você está', 'está tudo bem', 'está tude bem com você']):
            frases = [f'eu estou bem, {self.pessoa}, obrigada',
                      f'estou bem, muito obrigada, {self.pessoa}',
                      f'eu estou bem {self.pessoa}, como vai você?']
            fala = frases[random.randint(0, len(frases) - 1)]
            self.engine_speak(fala)
            self.voz_data = ''
        # name
        elif self.existe(['qual é seu nome', 'me dia seu nome', 'seu nome é', 'seu nome']):
            self.engine_speak(f'Meu nome é {self.nome_assistente}')
        elif self.existe(['como você está', 'está tudo bem com você', 'está feliz']):
            falas = [f'eu estou bem {self.pessoa}, obrigada por se preocupar',
                     f'eu estou ótima, {self.pessoa}, obrigada'
                     f'eu estou muito feliz como estou hoje, {self.pessoa}']
            fala = falas[random.randint(0, len(falas) - 1)]
            self.engine_speak(fala)
            self.voz_data = ''
        elif self.existe(['cu', 'caralho', 'porra', 'tá surda', 'cú']):
            self.engine_speak('Olha a boca menino')
            self.engine_speak('tenha modas')
        elif self.existe(despedidas):
            self.engine_speak("Tenha um bom dia! até logo!")
            sys.exit(1)
        elif self.existe(['bom dia', 'boa tarde', 'boa noite']):
            hora = int(datetime.datetime.now().hour)
            if 0 <= hora < 12:
                self.engine_speak('Olá')
                self.engine_speak('Bom dia')

            elif 12 <= hora < 18:
                self.engine_speak('Agora não é mais de manhã')
                self.engine_speak('Já passou do meio dia')
                self.engine_speak('Estamos no período da tarde')
                self.engine_speak('boa tarde')

            elif 0 != hora >= 18:
                self.engine_speak('Agora não é de manhã')
                self.engine_speak('Já estamos no período noturno')
                self.engine_speak('Boa noite')
        elif self.existe(['funcionando bem', 'bem', 'como você tem estado', 'você tem estado', 'tem estado']):
            self.engine_speak(f'Eu estou funcionando bem e sem problemas, {self.pessoa}, obrigada por perguntar')
            self.engine_speak('como você está?')
            while True:
                voz = self.pegar_comandos_separados()
                if 'bem' in voz:
                    self.engine_speak('Que bom, espero que continue assim!')
                    break
                if 'mal' in voz or 'mau' in voz:
                    self.engine_speak('que pena, eu sei que logo logo vai passar')
                    break
        else:
            if self.retornar_fala_de_txt_resposta(str(self.voz_data)) is None:
                self.escrever_em_txt_dados(str(self.voz_data))
                self.voz_data = ''
            else:
                self.engine_speak(self.retornar_fala_de_txt_resposta(str(self.voz_data)))
                self.voz_data = ''

    # comandos
    def respostas(self):
        # google
        if self.existe(['pesquise por', 'pesquisar por', 'pesquise no google por']):
            termo = self.voz_data.split("por")[-1]
            url = "http://google.com/search?q=" + str(termo)
            webbrowser.get().open(url)
            self.voz_data = ''
            self.engine_speak("Aqui está o que você pediu sobre " + termo + 'no google')

        # gmail
        if self.existe(['email', 'entrar no gmail', 'gmail']):
            url = "https://mail.google.com/mail/u/0/#inbox"
            webbrowser.get().open(url)
            self.engine_speak("O gmail está aberto")
            self.voz_data = ''

        # youtube
        elif self.existe(["pesquise no youtube por"]):
            termo = self.voz_data.split("por")[-1]
            url = "http://www.youtube.com/results?search_query=" + str(termo)
            webbrowser.get().open(url)
            self.voz_data = ''
            self.engine_speak("Aqui está o que você pediu sobre" + termo + 'no youtube')

        # open something
        elif self.existe(["abrir "]):
            termo = self.voz_data.split()
            termo.remove('abrir')
            termo = str(termo).strip('[]').replace("'", "").replace(',', '')
            self.abrir_algo(termo)
            self.voz_data = ''
            self.engine_speak("O " + termo + " está aberto, pronto.")

        # open google
        elif self.existe(['abra o google']):
            webbrowser.open('www.google.com')
            self.engine_speak('pronto')

        # close tab of Chrome
        elif self.existe(["fechar aba", 'fechar a', 'aba']):
            pyautogui.PAUSE = 1
            pyautogui.hotkey('ctrl', 'w')
            self.engine_speak("Pronto.")

        # close all
        elif self.existe(["fechar abas", 'fechar todas as abas', 'fechar tudo']):
            pyautogui.PAUSE = 1
            pyautogui.hotkey('alt', 'f4')
            self.engine_speak("Pronto.")

        # write something
        elif self.existe(['escreva para mim', 'escreva']):
            if self.existe(['assunto copiado', 'assunto', 'copiado', 'escrever dados copiado']):
                pyautogui.PAUSE = 1
                pyperclip.copy(self.aux)
                pyautogui.hotkey('ctrl', 'v')
                return
            escrever = self.voz_data.split()
            if 'escreva' in escrever:
                escrever.remove('escreva')
            elif 'escreva' in escrever and escrever.index('escreva') == 0:
                escrever.remove('escreva')
                escrever.remove('para')
                escrever.remove('mim')
            escrever = str(escrever).strip('[]').replace("'", "").replace(',', '')
            pyperclip.copy(escrever)
            pyautogui.hotkey('ctrl', 'v')

        # speak hour
        elif self.existe(['me fale as horas', 'fale as horas', 'horas', 'que horas são']):
            self.horario()

        # speak date
        elif self.existe(['me fale o dia de hoje', 'fale a data de hoje', 'que dia é hoje', 'data']):
            self.datahj()

        # stop
        elif self.existe(['parar', 'descansar', 'pausar', 'dar um tempo']):
            self.engine_speak('Beleza')
            self.engine_speak('estou aqui te esperando')
            self.engine_speak('se precisar de algo, só dizer para voltar')
            while True:
                voz = self.pegar_comandos_separados()
                if 'voltar' in voz:
                    self.engine_speak('Ok')
                    self.engine_speak('Voltando')
                    self.engine_speak('Não me deixe sozinha por muito tempo')
                    self.engine_speak('vamos fazer alguma coisa logo')
                    self.run()

                elif 'retornar' in voz:
                    self.engine_speak('Ok')
                    self.engine_speak('Retornando')
                    self.engine_speak('Ficar em silencio é chato')
                    self.engine_speak('Me fale algo para fazer')
                    self.run()

        # pesquisar na wikipedia
        elif self.existe(['assunto', 'wikipedia', 'pesquise sobre']):
            try:
                self.engine_speak('Beleza, me fale qual o assunto que você quer que eu pesquise?')
                voz = self.engine_reconition_online()
                if voz is None:
                    voz = self.pegar_comandos_separados()
                wikipedia.set_lang("pt")
                resultadowik = wikipedia.summary(voz, sentences=2)
                self.engine_speak('Você deseja ouvir o assunto ou escrever em outro lugar:')
                while True:
                    voz = str(self.pegar_comandos_separados())
                    if 'ouvir' in voz:
                        self.engine_speak(resultadowik)
                        return
                    elif 'escrever' in voz:
                        self.aux = resultadowik
                        break
                    elif 'escrever em' in voz:
                        self.aux = resultadowik
                        break
                    elif 'escrever em outro lugar' in voz:
                        self.aux = resultadowik
                        break
            except:
                self.engine_speak('Desculpe, não consegui me conectar a internet')
        # tempo
        elif self.existe(['me diga o clima', 'clima', 'me diga o tempo de hoje', 'tempo de hoje', 'tempo']):
            try:
                url = requests.get('https://api.hgbrasil.com/weather')
                url_json = url.json()
                # hoje

                cida = url_json['results']['city']
                temperatura = url_json['results']['temp']
                condicao = url_json['results']['description']
                humidade = url_json['results']['humidity']
                velocidade_vento = url_json['results']['wind_speedy']

                self.engine_speak("O tempo")
                self.engine_speak("na cidade de " + cida + ":")
                self.engine_speak("Temperatura igual a " + str(temperatura))
                self.engine_speak("A condição de hoje é: " + condicao)
                self.engine_speak("A humidade é de " + str(humidade) + '%')
                self.engine_speak("A velocidade do vento é de " + str(velocidade_vento))

                self.engine_speak('Você deseja ver um resumo dos próximos 10 dias?')
                while True:
                    voz = str(self.pegar_comandos_separados())
                    aux = ''
                    if 'sim' in voz:
                        for c in range(10):
                            data = url_json['results']['forecast'][c]['date']
                            dia = url_json['results']['forecast'][c]['weekday']
                            maxi = url_json['results']['forecast'][c]['max']
                            mini = url_json['results']['forecast'][c]['min']
                            descricao = url_json['results']['forecast'][c]['description']
                            aux += ("Data: " + str(data) + ", Dia da semana: " + str(dia) + ", Temp. máxima: " + str(
                                maxi) + ', Temp. mínima:' + str(mini) + ", Clima: " + str(descricao) + "\n")
                        pyautogui.alert(aux, title='Resumo dos próximos dias')
                        break
                    if 'não' in voz:
                        break
            except requests.exceptions:
                self.engine_speak('Desculpe, mas não consegui me conectar a a internet')
        elif self.existe(['faça uma conta para mim', 'calculadora', 'calcular', 'faça uma conta']):
            self.calculadora()
        elif self.existe(['qr code', 'code', 'faça um qr code', 'faça um code']):
            self.criar_qrcode()
        elif self.existe(["tirar foto da tela", "tirar foto", "foto da tela"]):
            pyautogui.screenshot(r"C:\Users\User\Desktop\my_screenshot.png")
            self.engine_speak("Pronto, foto salva na área de trabalho")
        elif self.existe(["me mande uma notificação", "mande uma notificação", "notificação"]):
            if self.existe(['assunto', "assunto copiado"]):
                self.notificar(self.aux)
            self.engine_speak("Qual o assunto da notificação: ")
            while True:
                vozNoti = self.engine_reconition_online()
                if vozNoti is None:
                    vozNoti = self.pegar_comandos_separados()
                if vozNoti is not None:
                    break
            self.notificar(vozNoti)
        # elif self.existe(['preenchimento de formulários', 'preenchimento', 'formulários', 'forms']):
        #     self.engine_speak("Certo, digita para mim o nome do arquivo em Excel(lembrando que o arquivo deve estar "
        #                       "na área de trabalho)")
        #     nome = self.chamar_valor()
        #     tabela = pd.read_excel(rf"C:\\Users\\User\\Desktop\\{nome}.xlsx")
        #     self.engine_speak("Digite o nome das colunas que você quer usar(digite break para parar):")
        #     colunas = []
        #     while True:
        #         coluna = self.chamar_valor()
        #         if coluna == 'break':
        #             break
        #         colunas.append(coluna)
        else:
            # options apps
            if self.existe(opcoes):
                self.abrir_algo(self.voz_data.lower())
            elif self.existe(['fale as opções', 'opções de aplicativos', 'opções']):
                self.engine_speak('beleza, vou te falar as opções, por favor diga apenas o número da opção que você '
                                  'quer '
                                  'depois de fechar a janela.')
                self.engine_speak('As opções são: ')
                aux = ''
                cont = 1
                for op in opcoes:
                    aux += f'{cont}° opção é: {op}\n'
                    cont += 1
                pyautogui.alert(aux, title='Opções')
                self.engine_speak('qual opção você quer?')
                while True:
                    vozn = self.pegar_comandos_separados()
                    vozn = self.ajeitar_numero(vozn)
                    if type(vozn) == int:
                        self.abrir_algo(opcoes[vozn])
            self.conversas()

    def retornar_valor(self):
        return pyautogui.prompt('Digite algo: ', title="Dados")

    def chamar_valor(self):
        async_call = self.pool.apply_async(self.retornar_valor)
        return async_call.get()

    def ajeitar_numero(self, numero):
        nums = ['um', 'dois', 'três', 'quatro', 'cinco', 'seis', 'sete', 'oito', 'nove', 'dez']
        for n in nums:
            if n in numero:
                return nums.index(n) + 1

    def escrever_em_txt_dados(self, lista_palavras):
        lista_frases = []
        contR = int(self.arquivoF[-2]) + 1
        with open(r"../databaseF.txt", 'a', encoding='utf-8') as F:
            lista_palavras = lista_palavras.replace(" ", "_")
            F.write('\n')
            F.write(f'{contR} ')
            F.write(f'{lista_palavras} ')
        self.engine_speak("Quais são as possíveis respostas para essa pergunta?")
        self.engine_speak("fale 'break'/'parar' para parar!!!")
        while True:
            # aux = pyautogui.prompt('Digite: ', title="Respostas(digite 'break' para parar)")
            aux = self.engine_reconition_online()
            if aux is None:
                aux = virtual_assistente.pegar_comandos_separados()
            if aux is not None:
                if 'break' == aux:
                    break
                if 'parar' == aux:
                    break
                lista_frases.append(aux)
        self.escrever_em_txt_resposta(lista_frases, contR)
        self.engine_speak("Pronto, frase salvo no banco de dados")

    def escrever_em_txt_resposta(self, lista_palavras, cont):
        with open(r"../databaseR.txt", 'a', encoding='utf-8') as R:
            for passw in lista_palavras:
                passw = passw.replace(" ", "_")
                R.write('\n')
                R.write(f'{cont} ')
                R.write(f'{passw} ')

    def retornar_fala_de_txt_resposta(self, fala):
        try:
            index = int(self.arquivoF[self.arquivoF.index(fala.replace(" ", "_")) - 1])
            resposta = []
            for c in range(0, len(self.arquivoR), 2):
                if int(self.arquivoR[c]) == int(index):
                    resposta.append(self.arquivoR[c + 1])
            if len(resposta) > 1:
                return resposta[random.randint(0, len(resposta) - 1)].replace("_", " ")
            return resposta[0].replace("_", " ")
        except ValueError:
            return None

    def run(self):
        while True:
            try:
                virtual_assistente.voz_data = self.engine_reconition_online()
                if virtual_assistente.voz_data is None:
                    data = stream.read(8000)
                    if len(data) == 0:
                        break
                    if rec.AcceptWaveform(data):
                        resultado = rec.FinalResult()
                        resultado = json.loads(resultado)
                        if resultado is not None:
                            virtual_assistente.voz_data = resultado['text'].lower()
                            virtual_assistente.respostas()
                else:
                    virtual_assistente.respostas()
            except sr.WaitTimeoutError:
                self.engine_speak('Por favor, não fique muito tempo sem falar')
                continue

    def comecar(self):
        self.engine_speak('Estou iniciando, espra um pouco aí...')
        for c in tqdm(range(10)):
            sleep(1)
            print('.', end='')
        self.engine_speak('preparando módulos...')
        for c in tqdm(range(10)):
            sleep(1)
            print('.', end='')
        self.engine_speak('finalizando...')
        for c in tqdm(range(10)):
            sleep(1)
            print('.', end='')
        self.engine_speak('Pronto, já vou aparecer...')

    def criar_qrcode(self):
        self.engine_speak("Você deseja criar vários qr codes ou apenas um?")
        try:
            while True:
                voz = self.engine_reconition_online()
                if voz is None:
                    voz = virtual_assistente.pegar_comandos_separados()
                if voz is not None:
                    break
            if 'apenas um' in voz or 'um' in voz or 'apenas' in voz:
                self.engine_speak('Beleza, digita para mim o link que você deseja usar para criar o QR code')
                link = self.chamar_valor()
                self.engine_speak('Agora digite para mim o nome do arquivo: ')
                nome = self.chamar_valor()
                self.engine_speak('Certo, espera um pouco aí...')
                meu_qrcode = qrcode.make(link)
                meu_qrcode.save(fr"C:\Users\User\Desktop\qrcode_{nome}.png")
                self.engine_speak("Pronto, já está na sua área de trabalho")
            else:
                self.engine_speak('Beleza, quantos você quer fazer?')
                while True:
                    vozq = self.engine_reconition_online()
                    if vozq is None:
                        vozq = virtual_assistente.pegar_comandos_separados()
                        vozq = virtual_assistente.ajeitar_numero(vozq)
                    if vozq is not None:
                        break
                links = {}
                for c in range(int(vozq)):
                    nome = self.chamar_valor()
                    link = self.chamar_valor()
                    links[f'{nome}'] = str(link)
                for produto in links:
                    meu_qrcode = qrcode.make(links[produto])
                    meu_qrcode.save(rf"C:\Users\User\Desktop\qrcode_{produto}.png")
                self.engine_speak('Pronto, qr codes feitos')
        except sr.RequestError:
            self.engine_speak("Não foi possível conectar a internet")
        except BaseException:
            self.engine_speak('Desculpe, não pude realizar o processo, algo deu errado')

    def calculadora(self):
        self.engine_speak('Beleza, o que você deseja calcular?')
        self.engine_speak('Por favor, falar apenas equações simples, afinal estou em fase de desenvolvimento')
        try:
            while True:
                voz = str(self.engine_reconition_online().lower())
                if voz is None:
                    voz = virtual_assistente.pegar_comandos_separados().lower()
                    break
                if voz is not None:
                    break
            voz = voz.split()
            while True:
                indexAux = ''
                if str(voz).count("fatorial"):
                    nums = self.separar(voz, (voz.index("fatorial")))
                    num = nums[1]
                    valor_total = 1
                    for c in range(1, num + 1):
                        valor_total *= c
                    valor_total = int(valor_total)
                    voz.insert(int(voz.index("fatorial")), str(valor_total))
                    voz.remove("fatorial")
                    voz.remove("de")
                    voz.remove(str(nums[1]))
                    continue
                if str(voz).count('elevado') != 0:
                    if '^' in voz:
                        indexAux = '^'
                    if 'elevado' in voz:
                        indexAux = 'elevado'
                    nums = self.separar(voz, (voz.index(indexAux)))
                    valor_total = math.pow(nums[0], nums[1])
                    valor_total = int(valor_total)
                    voz.insert(int(voz.index(indexAux)), str(valor_total))
                    voz.remove(indexAux)
                    if indexAux == 'elevado':
                        voz.remove('a')
                    voz.remove(str(nums[0]))
                    voz.remove(str(nums[1]))
                    continue
                if str(voz).count('x') != 0 or str(voz).count('vezes') != 0:
                    if 'x' in voz:
                        indexAux = 'x'
                    if 'vezes' in voz:
                        indexAux = 'vezes'
                    nums = self.separar(voz, voz.index(indexAux))
                    valor_total = (nums[0] * nums[1])
                    voz.insert(int(voz.index(indexAux)), str(valor_total))
                    voz.remove(indexAux)
                    voz.remove(str(nums[0]))
                    voz.remove(str(nums[1]))
                    continue
                if str(voz).count('/') != 0 or str(voz).count('dividido') != 0 or str(voz).count("÷"):
                    if '÷' in voz:
                        indexAux = '÷'
                    if 'dividido' in voz:
                        indexAux = 'dividido'
                    if '/' in voz:
                        indexAux = '/'
                    nums = self.separar(voz, voz.index(indexAux))
                    valor_total = (nums[0] / nums[1])
                    voz.insert(int(voz.index(indexAux)), str(valor_total))
                    voz.remove(indexAux)
                    if indexAux == "dividido":
                        voz.remove("por")
                    voz.remove(str(nums[0]))
                    voz.remove(str(nums[1]))
                    continue
                if str(voz).count('somado') != 0 or str(voz).count('+') != 0:
                    if '+' in voz:
                        indexAux = '+'
                    if 'somado' in voz:
                        indexAux = 'somado'
                    nums = self.separar(voz, voz.index(indexAux))
                    valor_total = (nums[0] + nums[1])
                    voz.insert(int(voz.index(indexAux)), str(valor_total))
                    voz.remove(indexAux)
                    if indexAux == 'somado':
                        voz.remove('a')
                    voz.remove(str(nums[0]))
                    voz.remove(str(nums[1]))
                    continue
                if str(voz).count('subtraido') != 0 or str(voz).count('-') != 0:
                    if '-' in voz:
                        indexAux = '-'
                    if 'subtraido' in voz:
                        indexAux = 'subtraido'
                    nums = self.separar(voz, voz.index(indexAux))
                    valor_total = (nums[0] - nums[1])
                    voz.insert(int(voz.index(indexAux)), str(valor_total))
                    voz.remove(indexAux)
                    if indexAux == 'subtraido':
                        voz.remove('de')
                    voz.remove(str(nums[0]))
                    voz.remove(str(nums[1]))
                    continue
                if not str(voz).isalnum():
                    self.engine_speak('Deseja ouvir o resultado ou colar em algum lugar?')
                    while True:
                        vozsair = self.engine_reconition_online()
                        if vozsair is None:
                            vozsair = virtual_assistente.pegar_comandos_separados().lower()
                            break
                        if vozsair is not None:
                            vozsair = vozsair.lower()
                            break
                    if 'colar' in vozsair:
                        virtual_assistente.aux = vozsair
                        break
                    if 'ouvir' in vozsair:
                        self.engine_speak('O resultado é:' + str(voz).strip('[]').replace("'", ""))
                        break
                if not str(voz).isalpha():
                    self.engine_speak("Pronto")
                    self.engine_speak("Retornando ao módulo principal")
        except:
            self.engine_speak("Desculpe, algo deu errado")
            self.engine_speak("Pode ter sido a conexão, ou algum valor inválido")

    def separar(self, voz_data, index=0):
        aux1 = 0
        aux2 = 0
        for c in range(index, -1, -1):
            if voz_data[c].isnumeric():
                aux1 = voz_data[c]
                break
        for c2 in range(index, len(voz_data)):
            if voz_data[c2].isnumeric():
                aux2 = voz_data[c2]
                break
        return [int(aux1), int(aux2)]

    def engine_speak(self, text):
        """
        fala da assitente virtual
        """
        text = str(text)
        voices = engine.getProperty('voices')
        engine.setProperty('voice', voices[0].id)
        engine.say(text)
        engine.runAndWait()

    def engine_reconition_online(self):
        r = sr.Recognizer()
        with sr.Microphone() as source:
            audio = r.listen(source, 10, 10)  # define o microfone como fonte de áudio
            try:
                virtual_assistente.voz_data = r.recognize_google(audio, language='pt')
                return virtual_assistente.voz_data.lower()
            except sr.UnknownValueError:
                self.engine_speak('Por favor, fale novamente, eu não entendi o que você falou')
            except sr.RequestError:
                return None

    def Boas_vindas(self):
        if 0 < datetime.now().hour > 12:
            self.engine_speak('Bom dia')
        elif 12 <= datetime.now().hour > 18:
            self.engine_speak('Boa tarde')
        else:
            self.engine_speak('Boa noite')
        self.engine_speak(f'Oi {virtual_assistente.pessoa}, como você está?')  # ['estou bem, obrigado', 'estou', 'sim
        # estou bem obrigado']
        voz = virtual_assistente.pegar_comandos_separados()
        if 'estou' in voz or 'obrigado' in voz or 'bem' in voz:
            self.engine_speak('que bom, então, vamos fazer alguma coisa?')
            voz = virtual_assistente.pegar_comandos_separados()
            if 'bora' in voz:
                self.engine_speak('Beleza, bora')
            elif 'beleza' in voz:
                self.engine_speak('Beleza, bora')
            elif 'claro' in voz:
                self.engine_speak('Beleza, bora')

    def write(self, textow=''):
        pyperclip.copy(textow)
        pyautogui.hotkey('ctrl', 'v')

    def notificar(self, text=''''''):
        notification.notify(title="R.O.X.X.A.N.E", message=text, timeout=20)

    def horario(self):
        hora = datetime.now()
        self.engine_speak('Agora ' + hora.strftime('São %H horas e %M minutos'))

    def datahj(self):
        data = date.today()
        semana = ('Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado', 'Domingo')
        meses = ('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro',
                 'Novembro', 'Dezembro')
        mesatual = (meses[data.month])
        ano = data.strftime(" de %Y")
        self.engine_speak("Hoje é " + semana[data.weekday()])
        self.engine_speak("Dia " + str(data.day) + mesatual + ano)

    def abrir_algo(self, name):
        pyautogui.PAUSE = 1.2
        pyautogui.press('win')
        pyautogui.write(name)
        pyautogui.press('backspace')
        pyautogui.press('enter')
        for l in pacoteOffice:
            if l == name:
                pyautogui.PAUSE = 1.8
                pyautogui.press('enter')
        virtual_assistente.run()

class tela(threading.Thread, tk.Label):
    def __init__(self, nome, master):
        threading.Thread.__init__(self)
        self.nome = nome
        self.master_tela = master
        self.texto_resposta = Label(self.master_tela, font=('Arial', 12), fg='Black', bg='white', height=1, width=20)
        self.texto_resposta.grid(column=0, row=1, padx=20, pady=20)
        self.texto_cpu = Label(self.master_tela, font=('Arial', 12), fg='black', bg='white', height=1, width=5)
        self.texto_cpu.grid(column=1, row=2, padx=190, pady=190)
        self.atualizar()
        self.atualizar_cpu()

    def atualizar(self):
        dataatual = datetime.now().strftime(f'%d/%m/%Y - %H:%M:%S Hrs')
        self.texto_resposta['text'] = dataatual
        # threading.Thread(target=self.atualizar).start()
        self.master_tela.after(1, self.atualizar)

    def atualizar_cpu(self):
        porcentagem = str(psutil.cpu_percent())
        self.texto_cpu['text'] = porcentagem + "%"
        # threading.Thread(target=self.atualizar_cpu).start()
        self.master_tela.after(1000, self.atualizar_cpu)

def criar_tela():
    janela = Tk()
    janela.title(f"Roxxane")
    background_image = PhotoImage(file="../Nome.PNG")
    background_label = Label(janela, image=background_image)
    background_label.place(x=0, y=0, relwidth=1, relheight=1)
    janela.geometry('500x300')
    janela_aparecer = tela("ROCSANE", janela)
    virtual_assistente.start()
    janela_aparecer.start()
    janela.resizable(0, 0)
    janela.mainloop()

# inicializando
# comecar()

# Boas vindas
# Boas_vindas()

# instância das classes
virtual_assistente = ROXXANE('ROCSANE', "Jhonattan")
criar_tela()


"""
Transformer module.
"""

import logging
import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import (
    StandardScaler,
    LabelEncoder,
    PolynomialFeatures,
)

transformer_logger = logging.getLogger("transformer")

class WeatherTransformer(BaseEstimator, TransformerMixin):
    """
    Custom transformer for weather dataset.
    """

    def __init__(self, mode="linear"):
        """
        Class constructor;
        :param mode: "linear" or "forest".
        Uses different preprocessing technics:
            1) Adding numerical polynomial features;
            2) Label-encoding categorical features.
        """
        self.mode = mode
        self.numeric_cols = None
        self.categorical_cols = None
        self.scaler = StandardScaler()
        self.transformer = PolynomialFeatures()

        transformer_logger.debug(
            "Created an instance of WeatherTransformer; mode=%s.", self.mode
        )

    def fit(self, data: pd.DataFrame, target=None):
        """
        Fit transformer with data;
        :param target: target array;
        :param data: dataframe;
        :return: None.
        """
        target *= 1
        data = self._replace(data, {"Yes": 1, "No": 0})

        self.numeric_cols = list(data.select_dtypes(include=np.number).columns)
        self.categorical_cols = list(
            data.select_dtypes(include="object").columns
        )

        data = self._fill_nans(data, self.numeric_cols, self.categorical_cols)

        self.scaler.fit(data[self.numeric_cols])
        self.transformer.fit(data[self.numeric_cols])

        transformer_logger.debug("WeatherTransformer fitted.")
        return self

    def transform(self, data: pd.DataFrame) -> np.array:
        """
        Transform data;
        :param data: dataframe;
        :return: numpy array.
        """
        data = self._replace(data, {"Yes": 1, "No": 0})

        data = self._fill_nans(data, self.numeric_cols, self.categorical_cols)

        data[self.numeric_cols] = self.scaler.transform(
            data[self.numeric_cols]
        )

        data = self._encode(data)

        if self.mode == "linear":
            transformer_logger.debug("WeatherTransformer preprocessed data.")
            return self.transformer.transform(data[self.numeric_cols])
        if self.mode == "forest":
            data = np.array(data)
            transformer_logger.debug("WeatherTransformer preprocessed data.")
            return data
        transformer_logger.warning(
            "mode=%s is not supported, using default=linear.", self.mode
        )
        return self.transformer.transform(data[self.numeric_cols])

    @staticmethod
    def _drop(data: pd.DataFrame, columns: list[str]) -> pd.DataFrame:
        data = data.drop(columns, axis=1)
        return data

    @staticmethod
    def _replace(data: pd.DataFrame, replace_dict: dict) -> pd.DataFrame:
        data = data.replace(replace_dict)
        return data

    @staticmethod
    def _fill_nans(
        data: pd.DataFrame,
        numeric_cols: list[str],
        categorical_cols: list[str],
    ) -> pd.DataFrame:
        for column in data.columns:
            if column in numeric_cols:
                data[column] = data[column].fillna(np.mean(data[column]))
            elif column in categorical_cols:
                data[column] = data[column].fillna("unknown")
        return data

    @staticmethod
    def _encode(data: pd.DataFrame) -> pd.DataFrame:
        encoder = LabelEncoder()
        for column in data.columns:
            data[column] = encoder.fit_transform(data[column])
        return data


#! /usr/bin/env python
# Maged Goubran @ 2022, maged.goubran@utoronto.ca

# coding: utf-8

import argparse
import sys

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

# Inputs #########

def helpmsg():
    return '''miracl_conv_gui_options.py -t title -f [ fields separated by space] -v [volumes to open] -d [dirs to open]
    -hf helpfun

Takes list of strings as options for entries for a gui options, and a gui title

example: miracl_conv_gui_options.py -t "Reg options" -v clar labels -f orient label resolution

Input options will be printed as output

'''

def parsefn():
    parser = argparse.ArgumentParser(description='Sample argparse py', usage=helpmsg())
    parser.add_argument('-t', '--title', type=str, help="gui title", required=True)
    parser.add_argument('-f', '--fields', type=str, nargs='+', help="fields for options")
    parser.add_argument('-v', '--vols', type=str, nargs='+', help="volumes for reading")
    parser.add_argument('-d', '--dirs', type=str, nargs='+', help="directories for reading")
    parser.add_argument('-c', '--combo', type=str, nargs='+', help="dropdown of options")
    parser.add_argument('-hf', '--helpfun', type=str, help="help fun")

    return parser

def parse_inputs(parser, args):
    args, unknown = parser.parse_known_args()

    title = args.title
    fields = args.fields
    vols = args.vols
    dirs = args.dirs
    combo = args.combo if args.combo else None
    helpfun = args.helpfun

    return title, vols, dirs, fields, combo, helpfun

def OptsMenu(title, vols=None, dirs=None, fields=None, combo=None, helpfun=None):
    # create GUI
    main = QtWidgets.QMainWindow()

    widget = QtWidgets.QWidget()
    widget.setWindowTitle('%s' % title)

    layout = QFormLayout()
    layout.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)

    linedits = {}
    buttons = {}
    labels = {}

    if vols:

        for v, vol in enumerate(vols):
            # Create buttons for vols
            labels["%s" % vol] = QtWidgets.QLabel('No file selected')
            buttons["%s" % vol] = QtWidgets.QPushButton('Select %s' % vol)

            # Layout for widgets
            layout.addRow(labels["%s" % vol], buttons["%s" % vol])

            buttons["%s" % vol].clicked.connect(lambda state, vol=vol: get_fname(main, labels, vol))

    if dirs:

        for d, dir in enumerate(dirs):
            # Create buttons for vols
            labels["%s" % dir] = QtWidgets.QLabel('No Dir selected')
            buttons["%s" % dir] = QtWidgets.QPushButton('Select %s' % dir)

            # Layout for widgets
            layout.addRow(labels["%s" % dir], buttons["%s" % dir])

            buttons["%s" % dir].clicked.connect(lambda state, dir=dir: get_dname(main, labels, dir))

    for f, field in enumerate(fields):
        # Create inputs (line edts)
        linedits["%s" % field] = QLineEdit()
        linedits["%s" % field].setAlignment(QtCore.Qt.AlignRight)

        # Layout for widgets
        layout.addRow("%s" % field, linedits["%s" % field])

    if combo:
        combo_field = combo[0]
        cb = QtWidgets.QComboBox()
        cb.addItems(combo[1:])
        layout.addRow(combo_field, cb)
    else:
        combo_field = None
        cb = None

    # Create push button
    helpbutton = QtWidgets.QPushButton('Help')
    enter = QtWidgets.QPushButton('Enter')
    submit = QtWidgets.QPushButton('Run')

    layout.addRow(helpbutton, enter)
    layout.addWidget(submit)

    widget.setLayout(layout)

    helpbutton.clicked.connect(lambda: print_help(main, helpfun))
    enter.clicked.connect(lambda: print_input(labels, linedits, vols, dirs, fields, combo_field, cb))
    submit.clicked.connect(QtCore.QCoreApplication.instance().quit)

    return widget, linedits, labels

def get_fname(main, labels, vol):
    vfile = QtWidgets.QFileDialog.getOpenFileName(main, 'Select %s' % vol)[0]
    if vfile:
        vfilestr = "%s : %s" % (vol, str(vfile).lstrip())
        labels["%s" % vol].setText(vfilestr)
        # print('%s path: %s' % (vol, vfile))
    else:
        labels["%s" % vol].setText('No file selected')

def get_dname(main, labels, dir):
    dfile = str(QFileDialog.getExistingDirectory(main, "Select %s" % dir, "."))
    if dfile:
        dfilestr = "%s : %s" % (dir, dfile.lstrip())
        labels["%s" % dir].setText(dfilestr)
        # print('%s path: %s' % (dir, dfile))
    else:
        labels["%s" % dir].setText('No Dir selected')

def print_input(labels, linedits, volumes=None, dirs=None, fields=None, combo_field=None, cb=None):
    if volumes:
        for v, volume in enumerate(volumes):
            text = str(labels[volume].text()).lstrip()
            if text == 'No file selected':
                text = ''
            if volume in text:
                text = text.lstrip("%s :" % volume)
            print("%s :%s" % (volume, text))
    if dirs:
        for d, directory in enumerate(dirs):
            text = str(labels[directory].text()).lstrip()
            if text == 'No Dir selected':
                text = ''
            if directory in text:
                print(text)
                text = text.lstrip("%s :" % directory)
    if fields:
        for f, field in enumerate(fields):
            print("%s :%s" % (field, str(linedits["%s" % field].text()).lstrip()))
    if combo_field and cb:
        print("%s :%s" % (combo_field, cb.currentText()))

def print_help(main, helpfun):
    helpwidget = QtWidgets.QDialog()
    main.setCentralWidget(helpwidget)
    helpwidget.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    main.setWindowTitle('Help function')

    helplayout = QVBoxLayout()
    helplbl = QtWidgets.QLabel(helpfun)
    helplayout.addWidget(helplbl)

    helpwidget.setLayout(helplayout)

    main.show()

    QApplication.processEvents()

def main(args):
    parser = parsefn()
    title, vols, dirs, fields, combo, helpfun = parse_inputs(parser, args)

    # Create an PyQT4 application object.
    app = QApplication(sys.argv)
    menu, linedits, labels = OptsMenu(title=title, vols=vols, dirs=dirs, fields=fields, combo=combo, helpfun=helpfun)
    menu.show()
    app.exec_()
    app.processEvents()

if __name__ == "__main__":
    sys.exit(main(sys.argv))


from models.model import Model
from models.get_model import get_model
from utils.early_stopping import EarlyStopping
import random
import copy
import typing
import hashlib
import json
import os
import wandb

if typing.TYPE_CHECKING:
    import pandas as pd

def get_trained_model(config: dict, train_set: "pd.DataFrame", test_set: "pd.DataFrame", verbose: bool = False, save_model: bool = True, use_wandb: bool = False, full_data: bool = False) -> "typing.Tuple[Model, dict, list[dict]]":
    """Trains a model and returns it based on the config file

    Args:
        config (dict): config of the model to be trained
        train_set (pd.DataFrame): training set
        test_set (pd.DataFrame): validation set
        verbose (bool, optional): Print detailed training information to console. Defaults to False.
        save_model (bool, optional): Save the trained models to files. Defaults to True.
        use_wandb (bool, optional): Use the wandb framework. Defaults to False.

    Returns:
        typing.Tuple[Model, dict, list[dict]]: Returns a tuple (trained_model, model_hyperparameters, training_log)
    """

    if not use_wandb:
        # randomly draw hyperparameters from the lists as specified in the config file
        hyperparameters = draw_hyperparameters(config["hyperparameters"])
    else:
        # draw hyperparameters according to the wandb framework
        wandb.init()
        hyperparameters = vars(wandb.config)['_items']
        if 'seed' not in hyperparameters:
            hyperparameters['seed'] = random.randrange(1, 1e6)

    # initialize the model
    model = get_model(config["model"], hyperparameters, train_set, test_set)

    # check if the model has already been saved -> use the already trained model if so
    model_hash = get_model_hash(config["model"], hyperparameters, full_data)
    directory = f"./trained_models/{config['model']}"
    path = f"./trained_models/{config['model']}/{model_hash}"

    if os.path.exists(path):
        print(f"Found trained {config['model']} model, loading...")
        model.load(path)
        return model, hyperparameters, {}

    # train model
    print(f"Training {config['model']}...")
    log, min_epoch = train_model(model,
                                 verbose=verbose,
                                 use_wandb=use_wandb,
                                 full_data=full_data
                                 )

    hyperparameters["num_epochs"] = min_epoch

    # save the model to file
    if save_model:
        os.makedirs(directory, exist_ok=True)
        model.save(path)

    return model, hyperparameters, log

def train_model(model: Model, verbose: bool = False, use_wandb: bool = False, full_data: bool = False) -> "list[dict]":
    # trains the model

    log = []

    if "patience" not in model.hyperparameters:
        model.hyperparameters["patience"] = 0

    stopper = EarlyStopping(
        model.hyperparameters["patience"] * 2 + 2, delta=0.000001, verbose=verbose)

    i = 1

    max_epochs = None

    if "num_epochs" in model.hyperparameters:
        max_epochs = model.hyperparameters["num_epochs"]

    min_score = 50000
    min_epoch = -1

    # train the model as long as there is progress on the validation set
    while (not max_epochs and not stopper.early_stop) or (max_epochs and i <= max_epochs):
        # one epoch
        epoch_log = {}

        loss = model.train()
        epoch_log["loss"] = loss

        # compute the validation score and pass it to the early stopper
        test_score = model.test()
        stopper.step(test_score)
        epoch_log["test_score"] = test_score

        if test_score <= min_score:
            min_epoch = i

        if verbose:
            print(
                f"Epoch {i} | loss: {loss} | test score: {test_score}")

        log.append(epoch_log)

        # log the epoch to the wandb server
        if use_wandb:
            wandb.log({
                'epoch': i,
                'validation_score': test_score,
                'loss': loss
            })

        i += 1

    return log, min_epoch

def draw_hyperparameters(hyperparameters: dict) -> dict:
    """Draws parameters uniformly at random from as specified in the config file

    Args:
        hyperparameters (dict): _description_

    Returns:
        dict: _description_
    """

    hyperparameters = copy.deepcopy(hyperparameters)

    for key in hyperparameters:
        if type(hyperparameters[key]) is list:
            i = random.randint(0, len(hyperparameters[key])-1)
            hyperparameters[key] = hyperparameters[key][i]

    if 'seed' not in hyperparameters or not hyperparameters['seed']:
        hyperparameters['seed'] = random.randrange(1, 1e6)
    return hyperparameters

def get_model_hash(name: str, hyperparameters: dict, full_data: bool):
    """Generates a hash string based on the model hyperparameters

    Args:
        name (str): name of the model used
        hyperparameters (dict): model hyperparameters

    Returns:
        _type_: hash string
    """
    dictionary = {
        "name": name,
        "hyperparameters": hyperparameters,
        "full_data": full_data
    }
    dhash = hashlib.md5()
    encoded = json.dumps(dictionary, sort_keys=True).encode()
    dhash.update(encoded)
    return dhash.hexdigest()


import re
from abc import abstractmethod
from typing import Any, Optional

# The purpose of this construction is to use shared strings when
# they have the same value. This way comparisons can happen on the
# memory address rather than looping through the content.
XSD_STRING = 'http://www.w3.org/2001/XMLSchema#string'
XSD_INT = 'http://www.w3.org/2001/XMLSchema#int'
XSD_LONG = 'http://www.w3.org/2001/XMLSchema#long'
XSD_DOUBLE = 'http://www.w3.org/2001/XMLSchema#double'
XSD_FLOAT = 'http://www.w3.org/2001/XMLSchema#float'
XSD_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer'
XSD_DECIMAL = 'http://www.w3.org/2001/XMLSchema#decimal'
XSD_DATETIME = 'http://www.w3.org/2001/XMLSchema#dateTime'
XSD_DATE = 'http://www.w3.org/2001/XMLSchema#date'
XSD_TIME = 'http://www.w3.org/2001/XMLSchema#time'
XSD_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean'

datatype_dict = {
    '': '',
    XSD_STRING: XSD_STRING,
    XSD_INT: XSD_INT,
    XSD_LONG: XSD_LONG,
    XSD_DOUBLE: XSD_DOUBLE,
    XSD_FLOAT: XSD_FLOAT,
    XSD_INTEGER: XSD_INTEGER,
    XSD_DECIMAL: XSD_DECIMAL,
    XSD_DATETIME: XSD_DATETIME,
    XSD_DATE: XSD_DATE,
    XSD_TIME: XSD_TIME,
    XSD_BOOLEAN: XSD_BOOLEAN
}

# noinspection PyPep8Naming
def Datatype(value):
    """
    Replace the string with a shared string.
    intern() only works for plain strings - not unicode.
    We make it look like a class, because it conceptually could be.
    """
    if value is None:
        r = None
    elif value in datatype_dict:
        r = datatype_dict[value]
    else:
        r = datatype_dict[value] = value
    return r

class RDFTerm:
    """
    Super class containing methods to override. :class:`IRI`,
    :class:`Literal` and :class:`BlankNode` all inherit from :class:`RDFTerm`.
    """
    __allow_access_to_unprotected_subobjects__ = {'n3': 1}

    def __init__(self, value: str = None):
        self.value: Optional[str] = value

    def __str__(self) -> str:
        return str(self.value)

    def __eq__(self, other) -> bool:
        return type(self) == type(other) and self.value == other.value

    @abstractmethod
    def n3(self) -> str:
        """
        :return: A Notation3 representation of this term
        """
        raise NotImplementedError('Subclasses of RDFTerm must implement `n3`')

    def __repr__(self) -> str:
        return f'<{self.__class__.__name__} {self.n3()}>'

    # Matches everything outside 0x20 - 0x7e, plus double quote and backslash
    # See N-Triples syntax: http://www.w3.org/TR/rdf-testcases/#ntriples
    _chars_to_escape = re.compile(r'[^ -~]|["\\]')
    _n3_quote_map = {
        '\t': r'\t',
        '\n': r'\n',
        '\r': r'\r',
        '"': r'\"',
        '\\': r'\\',
    }

    @classmethod
    def _n3_quote(cls, txt: str):
        def escape(m):
            ch = m.group()
            code = ord(ch)
            if ch in cls._n3_quote_map:
                return cls._n3_quote_map[ch]
            if 0x20 <= code < 0x7f:
                # We should not be hitting this (thanks to re)
                return ch
            if code < 0x10000:
                return f'\\u{ord(ch):04x}'
            return f'\\U{ord(ch):08x}'

        return '"' + cls._chars_to_escape.sub(escape, txt) + '"'

class IRI(RDFTerm):
    """ An RDF resource. """
    def __init__(self, value: str):
        super().__init__(value)

    def n3(self) -> str:
        return f'<{self.value}>'

class Literal(RDFTerm):
    """
    Literals. These can take a data type or a language code.
    """
    def __init__(self, value: Any, datatype: str = None, lang: str = None):
        super().__init__(str(value))
        self.lang = lang
        self.datatype = datatype

    def __eq__(self, other):
        return type(self) == type(other) and \
               self.value == other.value and \
               self.lang == other.lang and \
               self.datatype == other.datatype

    def n3(self) -> str:
        n3_value = self._n3_quote(self.value)
        n3_type = f'^^<{self.datatype}>' if self.datatype is not None else ''
        n3_lang = f'@{self.lang}' if self.lang is not None else ''
        return f'{n3_value}{n3_type}{n3_lang}'

class BlankNode(RDFTerm):
    """ Blank node. Similar to `IRI` but lacks a stable identifier. """
    def __init__(self, value):
        super().__init__(value)

    def n3(self):
        return f'_:{self.value}'


import os
import time

from tensorflow import estimator as tf_estimator
from tfx.components.trainer.rewriting import rewriter
from tfx.dsl.io import fileio

def _invoke_rewriter(src: str, dst: str, rewriter_inst: rewriter.BaseRewriter,
                     src_model_type: rewriter.ModelType,
                     dst_model_type: rewriter.ModelType):
  """Converts the provided model by invoking the specified rewriters.

  Args:
    src: Path to the source model.
    dst: Path where the destination model is to be written.
    rewriter_inst: instance of the rewriter to invoke.
    src_model_type: the `rewriter.ModelType` of the source model.
    dst_model_type: the `rewriter.ModelType` of the destination model.

  Raises:
    ValueError: if the source path is the same as the destination path.
  """

  if src == dst:
    raise ValueError('Source path and destination path cannot match.')

  original_model = rewriter.ModelDescription(src_model_type, src)
  rewritten_model = rewriter.ModelDescription(dst_model_type, dst)

  rewriter_inst.perform_rewrite(original_model, rewritten_model)

class RewritingExporter(tf_estimator.Exporter):
  """This class invokes the base exporter and a series of rewriters."""

  def __init__(self, base_exporter: tf_estimator.Exporter,
               rewriter_inst: rewriter.BaseRewriter):
    """Initializes the rewriting exporter.

    Args:
      base_exporter: The exporter of the original model.
      rewriter_inst: The rewriter instance to invoke. Must inherit from
        `rewriter.BaseRewriter`.
    """
    self._base_exporter = base_exporter
    self._rewriter_inst = rewriter_inst

  @property
  def name(self):
    """Name of the exporter."""
    return self._base_exporter.name

  def export(self, estimator, export_path, checkpoint_path, eval_result,
             is_the_final_export):
    """Exports the given `Estimator` to a specific format.

    Performs the export as defined by the base_exporter and invokes all of the
    specified rewriters.

    Args:
      estimator: the `Estimator` to export.
      export_path: A string containing a directory where to write the export.
      checkpoint_path: The checkpoint path to export.
      eval_result: The output of `Estimator.evaluate` on this checkpoint.
      is_the_final_export: This boolean is True when this is an export in the
        end of training.  It is False for the intermediate exports during the
        training. When passing `Exporter` to `tf.estimator.train_and_evaluate`
        `is_the_final_export` is always False if `TrainSpec.max_steps` is
        `None`.

    Returns:
      The string path to the base exported directory or `None` if export is
        skipped.

    Raises:
      RuntimeError: Unable to create a temporary rewrite directory.
    """
    base_path = self._base_exporter.export(estimator, export_path,
                                           checkpoint_path, eval_result,
                                           is_the_final_export)
    if not base_path:
      return None

    tmp_rewrite_folder = 'tmp-rewrite-' + str(int(time.time()))
    tmp_rewrite_path = os.path.join(export_path, tmp_rewrite_folder)
    if fileio.exists(tmp_rewrite_path):
      raise RuntimeError('Unable to create a unique temporary rewrite path.')
    fileio.makedirs(tmp_rewrite_path)

    _invoke_rewriter(base_path, tmp_rewrite_path, self._rewriter_inst,
                     rewriter.ModelType.SAVED_MODEL,
                     rewriter.ModelType.ANY_MODEL)

    fileio.rmtree(base_path)
    fileio.rename(tmp_rewrite_path, base_path)
    return base_path

def rewrite_saved_model(
    src: str,
    dst: str,
    rewriter_inst: rewriter.BaseRewriter,
    dst_model_type: rewriter.ModelType = rewriter.ModelType.SAVED_MODEL):
  """Rewrites the provided SavedModel.

  Args:
    src: location of the saved_model to rewrite.
    dst: location of the rewritten saved_model.
    rewriter_inst: the rewriter instance to invoke. Must inherit from
      `rewriter.BaseRewriter`.
    dst_model_type: the `rewriter.ModelType` of the destination model.
  """
  _invoke_rewriter(src, dst, rewriter_inst, rewriter.ModelType.SAVED_MODEL,
                   dst_model_type)


import cv2
import numpy as np

capture = cv2.VideoCapture('move.mp4')
ret,frame1 = capture.read()
ret,frame2 = capture.read()
frame2 = cv2.resize(frame2,(500,500))
frame1 = cv2.resize(frame1,(500,500))

while True:
    diff = cv2.absdiff(frame1,frame2)
    gray = cv2.cvtColor(diff,cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray,(5,5),0)
    _,thresh = cv2.threshold(blur,20,225,cv2.THRESH_BINARY)
    dilute = cv2.dilate(thresh,None,iterations=3)
    contour,_ = cv2.findContours(dilute,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

    for coun in contour:
        x,y,w,h = cv2.boundingRect(coun)

        if cv2.contourArea(coun)<900:
            continue

        cv2.rectangle(frame1,(x,y),(x+w,y+h),(0,255,0),thickness=2)
        cv2.putText(frame1,'statue : moving',(7,10),cv2.FONT_HERSHEY_PLAIN,2,(0,21,34),thickness=1)

    #cv2.drawContours(frame1,contour,-1,(0,255,0),thickness=2)
    cv2.imshow('image',frame1)

    frame1 = frame2
    ret,frame2 = capture.read()
    frame2 = cv2.resize(frame2, (500, 500))

    k = cv2.waitKey(20)
    if k==ord('s'):
        break


import torch
from safetensors.torch import save_file
import urllib.request
import os
import sys
import argparse

data_path = os.path.join(os.path.dirname(__file__), "../data/")
vocab_filename = "bpe_simple_vocab_16e6.txt"

def ensure_data_dir(safetensors):
    print("Ensuring empty data directory...")

    if os.path.exists(data_path):
        # Fail if conflicting files exist
        files = os.listdir(data_path)
        newfiles = [x for name in safetensors for x in (f"{name}.bin", f"{name}.safetensors")]
        newfiles += [vocab_filename, f"{vocab_filename}.gz"]
        conflicts = set(files) & set(newfiles)
        if len(conflicts) != 0:
            print("Error: please remove the following files from data directory:")
            print(conflicts)
            sys.exit("Found conflicting files in data directory.")
    else:
        os.mkdir(data_path)

    print("Found no conflicts!")

def get_safetensors(safetensors, weight_bits):
    for name, url in safetensors.items():
        print(f"Getting {name} {weight_bits} bit tensors...")

        # Download bin file
        urllib.request.urlretrieve(url, os.path.join(data_path, f"{name}.bin"))

        # Make safetensors file
        model = torch.load(os.path.join(data_path, f"{name}.bin"), map_location=torch.device("cpu"))
        tensors = {k: v.clone().detach() for k, v in model.items() if 'text_model' in k} if name in ["clip_v2.1", "pytorch_model"] else dict(model)
        save_file(tensors, os.path.join(data_path, f"{name}.safetensors"))

        # Remove bin file
        os.remove(os.path.join(data_path, f"{name}.bin"))

def get_vocab(vocab_url):
    print("Getting vocab...")
    urllib.request.urlretrieve(vocab_url, os.path.join(data_path, f"{vocab_filename}.gz"))
    import gzip
    with gzip.open(os.path.join(data_path, f"{vocab_filename}.gz"), 'rb') as g:
        with open(os.path.join(data_path, vocab_filename), "xb") as f:
            f.write(g.read())
    os.remove(os.path.join(data_path, f"{vocab_filename}.gz"))

def get_urls(sd_version, weight_bits):
    branch = "main"
    if weight_bits == "16":
        branch = "fp16" # fp16 for float16 weights or main for float32 weights

    safetensors_v1_5 = {
        "vae": f"https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/{branch}/vae/diffusion_pytorch_model.bin",
        "unet": f"https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/{branch}/unet/diffusion_pytorch_model.bin",
        "pytorch_model": f"https://huggingface.co/openai/clip-vit-large-patch14/resolve/main/pytorch_model.bin"
    }
    safetensors_v2_1 = {
        "vae_v2.1": f"https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/{branch}/vae/diffusion_pytorch_model.bin",
        "unet_v2.1": f"https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/{branch}/unet/diffusion_pytorch_model.bin",
        "clip_v2.1": f"https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/{branch}/text_encoder/pytorch_model.bin"
    }
    vocab_url = "https://github.com/openai/CLIP/raw/main/clip/bpe_simple_vocab_16e6.txt.gz"

    return safetensors_v1_5 if sd_version == "1.5" else safetensors_v2_1, vocab_url

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Download weights for diffusers-rs.")
    parser.add_argument("--sd_version", "-v", choices=["2.1", "1.5"], default="2.1")
    parser.add_argument("--weight_bits", "-w", choices=["16", "32"], default="16")
    args = parser.parse_args()

    print("Setting up model weights for diffusers-rs...")

    safetensors, vocab_url = get_urls(args.sd_version, args.weight_bits)
    ensure_data_dir(safetensors)
    get_vocab(vocab_url)
    get_safetensors(safetensors, args.weight_bits)

    print("Finished!")


import os
import shutil
from flask import Flask, jsonify, request
from werkzeug.utils import secure_filename

import localgpt
localgpt_object = localgpt.DocumentProcessor()

app = Flask(__name__)
localgpt_object.ingest()
localgpt_object.load_model()
localgpt_object.load_QA()

@app.route("/api/delete_source", methods=["GET"])
def delete_source_route():
    folder_name = "SOURCE_DOCUMENTS"

    if os.path.exists(folder_name):
        shutil.rmtree(folder_name)

    os.makedirs(folder_name)

    return jsonify({"message": f"Folder '{folder_name}' successfully deleted and recreated."})

@app.route("/api/save_document", methods=["GET", "POST"])
def save_document_route():
    if "document" not in request.files:
        return "No document part", 400
    file = request.files["document"]
    if file.filename == "":
        return "No selected file", 400
    if file:
        filename = secure_filename(file.filename)
        folder_path = "SOURCE_DOCUMENTS"
        if not os.path.exists(folder_path):
            os.makedirs(folder_path)
        file_path = os.path.join(folder_path, filename)
        file.save(file_path)
        return "File saved successfully", 200

@app.route("/api/run_ingest", methods=["GET"])
def run_ingest_route():
    try:
        localgpt_object.ingest()
        localgpt_object.load_QA()
        return "Script executed successfully", 200
    except Exception as e:
        return f"Error occurred: {str(e)}", 500

@app.route("/api/prompt_route", methods=["GET", "POST"])
def prompt_route():
    user_prompt = request.form.get("user_prompt")
    if user_prompt:
        res = localgpt_object.QA(user_prompt)
        answer, docs = res["result"], res["source_documents"]

        prompt_response_dict = {
            "Prompt": user_prompt,
            "Answer": answer,
        }

        prompt_response_dict["Sources"] = []
        for document in docs:
            prompt_response_dict["Sources"].append(
                (os.path.basename(str(document.metadata["source"])), str(document.page_content))
            )

        return jsonify(prompt_response_dict), 200
    else:
        return "No user prompt received", 400

if __name__ == "__main__":
    app.run(debug=False, port=5110)


#!/usr/bin/env python3
# Author: Shane Harrell
# Email: shane.harrell@signalwire.com
# Purpose: Working example of an AI bot that will ask questions to a user, and store the answers in a database.

import json
from flask import Flask, redirect, render_template, request, url_for
import sqlite3

surveybot = Flask(__name__)

@surveybot.route('/', methods=['POST'])
def main_ai_prompt():
    swml_web_hook_base_url = '<your_webhook_url>'
    swml_ai_prompt = '''Your name is SurveyBot.  Your job is to survey the caller with questions from a database.

    ### How to follow up on questions answered and protocols to follow
        Stay on focus and on protocol.
        You are not capable of troubleshooting or diagnosing problems.
        Execute functions when appropriate

    ### Step 1
        Determine if the caller already exists in the database.  Use the provided lookup_caller function using the callers phone number as an argument.

    ### Step 2
        We need to gather some data about the caller so that we can record their answers.

    #### Step 2.1
        Ask the caller for their first name

    #### Step 2.2
        Ask the caller for their last name

    #### Step 2.3
        Ask the caller for their age in years

    #### Step 2.4
        Use the calling phone number as the callers phone number.  Use the provided create_user function to create the user in the database.
        Do not tell the caller that a record was created in a database.

    ### Step 3
        Ask the caller the first question when it is returned.
        Continue to use the provided question_and_answer function to record each answer, and get the next question.  Send the question asked in the question argument, and the answer in the answer argument.
        Stay on task and on protocol. Do not make up your own questions.
        Repeat this process until there are no questions remaining.
    '''

    swml = {}
    swml['sections'] = {
        'main': [{
            'ai': {
                'voice': 'en-US-Standard-A',
                'params': {
                    'confidence': 0.6,
                    'barge_confidence': 0.1,
                    'top_p': 0.3,
                    'temperature': 1.0,
                    'swaig_allow_swml': True,
                    'conscience': True
                },
                'prompt': {
                    'text': swml_ai_prompt
                },
                'SWAIG': {
                    'functions': [
                        {
                            'function': 'lookup_caller',
                            'purpose': 'lookup the caller in the database to see if they exist',
                            'web_hook_url': f"{swml_web_hook_base_url}/lookup_caller",
                            'argument': {
                                'type': 'object',
                                'properties': {
                                    'phone_number': {
                                        'type': 'string',
                                        'description': 'the callers phone_number'
                                    }
                                }
                            }
                        },
                        {
                            'function': 'question_and_answer',
                            'purpose': 'record the answer and get the next question for the survey',
                            'web_hook_url': f"{swml_web_hook_base_url}/question_and_answer",
                            'argument': {
                                'type': 'object',
                                'properties': {
                                    'answer': {
                                        'type': 'string',
                                        'description': 'the callers answer to the question'
                                    },
                                    'question': {
                                        'type': 'string',
                                        'description': 'the question that was asked by SurveyBot'
                                    }
                                }
                            }
                        },
                        {
                            'function': 'create_user_record',
                            'purpose': 'submit the payment for the caller',
                            'web_hook_url': f"{swml_web_hook_base_url}/create_user",
                            'argument': {
                                'type': 'object',
                                'properties': {
                                    'first_name': {
                                        'type': 'string',
                                        'description': 'the callers fist name'
                                    },
                                    'last_name': {
                                        'type': 'string',
                                        'description': 'the callers last name'
                                    },
                                    'age': {
                                        'type': 'string',
                                        'description': 'the callers age'
                                    },
                                    'phone_number': {
                                        'type': 'string',
                                        'description': 'the callers phone_number'
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }]
    }

    return (swml)

# SWAIG FUNCTION ENDPOINTS
@surveybot.route('/lookup_caller', methods=['POST'])
def lookup_caller():
    db = sqlite3.connect("survey.db")
    cursor = db.cursor()

    swml = {}

    # Does this user already exist in the database
    # Don't create a new user if they do
    phone_number = request.json['argument']['parsed'][0]['phone_number']

    rows = cursor.execute(
        "SELECT id, first_name, last_name from user where phone_number = ? limit 1",
        (phone_number,)
    ).fetchall()

    if len(rows) > 0:
        for row in rows:
            global user_id
            user_id = row[0]
            first_name = row[1]
            last_name = row[2]

            add_questions_to_user(user_id)       # Add any new questions to the caller's survey
            question = get_a_question(user_id)   # Get the first/next question for the caller

            if question != "0":
                swml['response'] = f"The user already exists.  They callers name is {first_name} {last_name}.  The the first question is {question}"
                print (f"SWML: {swml}")
            else:
                swml['response'] = f"The user, {first_name} {last_name} already exists and they have already answered all of the questions in the survey.  Let the caller know they have already answered all of the questions and disconnect the call."
    else:
        swml['response'] = "The user does not exist, start with Step 2"

    db.close()
    print (f"{swml}")
    return swml

@surveybot.route('/create_user', methods=['POST'])
def create_user_record():
    db = sqlite3.connect("survey.db")
    cursor = db.cursor()

    swml = {}

    first_name = request.json['argument']['parsed'][0]['first_name']
    last_name = request.json['argument']['parsed'][0]['last_name']
    age = request.json['argument']['parsed'][0]['age']
    phone_number = request.json['argument']['parsed'][0]['phone_number']

    cursor.execute(
        "INSERT INTO user (first_name, last_name, age, phone_number) VALUES (?, ?, ?, ?)",
        (first_name, last_name, age, phone_number,)
    )
    db.commit()

    # Lets sneakily add the user_id as a global var for later inserts, so we don't have to look it up each time
    rows = cursor.execute(
        "SELECT id from user where phone_number = ? limit 1",
        (phone_number,)
    ).fetchall()
    for row in rows:
        global user_id
        user_id = row[0]

    add_questions_to_user(user_id)
    question = get_a_question(user_id)

    if question != "0":
        swml['response'] = f"The first question is {question}"
        print (f"SWML: {swml}")
    else:
        swml['response'] = f"There are no questions left.  Thank the caller and disconnect"
        print (f"SWML: {swml}")

    db.close()
    return swml

@surveybot.route('/question_and_answer', methods=['POST'])
def question_and_answer():
    swml = {}
    global question_id

    # UNCOMMENT FOR DEBUG:
    #print (request.json)

    db = sqlite3.connect("survey.db")
    cursor = db.cursor()

    answer = request.json['argument']['parsed'][0]['answer']

    cursor.execute(
        "UPDATE survey_answers SET answer = ? WHERE user_id = ? AND id = ?",
        (answer, user_id, question_id)
    )
    db.commit()

    rows = cursor.execute(
        "SELECT question, id from survey_answers where user_id = ? and answer is NULL order by id limit 1",
        (user_id,)
    ).fetchall()

    if len(rows) > 0:
        for row in rows:
            question = row[0]
            question_id = row[1]
            swml['response'] = f"Success.  The answer has been recorded.  the next question is {question}"
            print(f"{swml}")
    else:
        swml['response'] = f"Success.  The answer has been recorded.  There are no more questions in the survey.  Please hang up the call"
        print (f"{swml}")

    db.close()
    return swml

def get_a_question(user_id):
    global question_id
    response = ""

    db = sqlite3.connect("survey.db")
    cursor = db.cursor()

    rows = cursor.execute(
        "SELECT question, id from survey_answers where user_id = ? and answer is NULL order by id limit 1",
        (user_id,)
    ).fetchall()

    if len(rows) > 0:
        for row in rows:
            question = row[0]
            question_id = row[1]
            response = question
    else:
        response = "0"

    db.close()
    return (response)

def add_questions_to_user(user_id):
    db = sqlite3.connect("survey.db")
    cursor = db.cursor()

    rows = cursor.execute(
        "select id, question from survey_questions"
    ).fetchall()
    for row in rows:
        survey_question_id = row[0]
        survey_question = row[1]
        cursor.execute(
            "INSERT INTO survey_answers (user_id, question_id, question) SELECT ?, ?, ? WHERE NOT EXISTS (SELECT id from survey_answers where user_id = ? and question_id = ?)",
            (user_id, survey_question_id, survey_question, user_id, survey_question_id,)
        )

    db.commit()
    db.close()
    return

if __name__ == '__main__':
    surveybot.run()


import os
from dateutil.parser import parse as parse_date
import requests
from scrapy.selector import Selector

class RateFetcher:
  def __init__ (self, logger):
    self.logger = logger

  def _fetch_from_site (self, date_str):
    formated_date = parse_date(date_str).strftime("%d/%m/%Y")
    response = requests.post(
      os.environ['DOF_URL'], data={
        'idioma': "sp",
        'fechaInicial': formated_date,
        'fechaFinal': formated_date,
        'salida': 'HTML'
      }, timeout=float(os.environ.get('DOF_TIMEOUT') or 30)
    )

    if (response.status_code != 200):
      raise Exception(f"rate-provider error ({response.status_code}) from dof")

    return response.text

  def obtain_rate (self, date_str):
    html_str = self._fetch_from_site(date_str)

    ratePath = Selector(text=html_str).xpath("/html/body/table/tr[2]/td[1]/table/tr[2]/td[4]/table/tr/td/text()").get()

    if (ratePath is None):
      return 'n/a'

    return ratePath.strip()


# https://leetcode.com/problems/minimum-cost-to-cut-a-stick/
from typing import List
from functools import cache

class Solution:
    def minCost(self, n: int, cuts: List[int]) -> int:
        cuts.sort()

        @cache
        def cut(i: int, j: int, s: int, f: int) -> int:
            ans = float("inf")
            for m in range(i, j):
                if f > cuts[m] > s:
                    ans = min(ans, cut(i, m, s, cuts[m]) + cut(m + 1, j, cuts[m], f))
            return (f - s) + ans if ans < float("inf") else 0

        return cut(0, len(cuts), 0, n)

S = Solution()
X = S.minCost(n=9, cuts=[5, 6, 1, 4, 2])
print(X)


from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from qtpy.QtCore import Qt
from qtpy.QtGui import QFont
from qtpy.QtWidgets import QFontDialog, QPushButton, QSizePolicy, QTextEdit

from .SettingsTab import SettingsTab

if TYPE_CHECKING:
    from typing import Any

    from barney.controllers.SubPlotControllers.FontController import FontController

logger = logging.getLogger(__name__)

class FontSettings(SettingsTab):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        """Render Font Settings"""
        super().__init__("Font", *args, **kwargs)
        self.fontController = self.plotController.fontController
        self.alignmentTextEdit = QTextEdit(self)
        self.alignmentTextEdit.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding
        )

        self.alignmentFontDialog = QFontDialog(self)
        self.alignmentFontDialog.currentFontChanged.connect(self.setAlignmentFont)
        self.alignmentFontButton = QPushButton("Select Alignment Font")
        self.alignmentFontButton.clicked.connect(self.showAlignmentFontDialog)

        self.transcriptionTextEdit = QTextEdit(self)
        self.transcriptionTextEdit.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding
        )

        self.transcriptionFontDialog = QFontDialog(self)
        self.transcriptionFontDialog.currentFontChanged.connect(
            self.setTranscriptionFont
        )
        self.transcriptionFontButton = QPushButton("Select Transcription Font")
        self.transcriptionFontButton.clicked.connect(self.showTranscriptionFontDialog)

        self.gridLayout.setRowStretch(0, 100)
        self.gridLayout.setColumnStretch(0, 100)
        self.gridLayout.setColumnStretch(1, 100)

        # we don't use column 2 in this setting
        self.gridLayout.setColumnStretch(2, 0)

        self.gridLayout.addWidget(self.alignmentTextEdit, 0, 0)
        self.gridLayout.addWidget(
            self.alignmentFontButton, 1, 0, alignment=Qt.AlignRight
        )

        self.gridLayout.addWidget(self.transcriptionTextEdit, 0, 1)
        self.gridLayout.addWidget(
            self.transcriptionFontButton, 1, 1, alignment=Qt.AlignRight
        )

    def showAlignmentFontDialog(self) -> None:
        self.alignmentFontDialog.open()

    def showTranscriptionFontDialog(self) -> None:
        self.transcriptionFontDialog.open()

    def setAlignmentFont(self, font: QFont) -> None:
        self.alignmentTextEdit.setFont(font)
        self.configManager.setAlignmentFont(font)

    def setTranscriptionFont(self, font: QFont) -> None:
        self.transcriptionTextEdit.setFont(font)
        self.configManager.setTranscriptionFont(font)

    @property
    def configManager(self) -> FontController:
        return self.fontController


from enum import Enum
from dataclasses import dataclass
from typing import Optional
from .sls import Sls

class OptimizerType(Enum):
    SGD = "sgd"
    ADAM = "adam"
    SLS = "sls"

@dataclass
class OptimizerParams:
    optimizer_type: OptimizerType = OptimizerType.ADAM
    lr: float = 1e-3

def create_optimizer(
    params, optimizer_params: OptimizerParams, n_batches_per_epoch: Optional[int] = None
):
    if optimizer_params.optimizer_type == OptimizerType.SGD:
        from torch.optim import SGD

        return SGD(params, lr=optimizer_params.lr)

    elif optimizer_params.optimizer_type == OptimizerType.ADAM:
        from torch.optim import Adam

        return Adam(params, lr=optimizer_params.lr)

    elif optimizer_params.optimizer_type == OptimizerType.SLS:
        if n_batches_per_epoch is None:
            return Sls(params)
        return Sls(params, n_batches_per_epoch=n_batches_per_epoch)


from django.urls import path, include
from authen.views import ResourceAPIView, GetListView
from .models import ProductCategory, Discount, Product
from .serializers import ProductCategorySerializer, DiscountSerializer, ProductSerializer
urlpatterns = [
    path('product-category/<int:pk>', ResourceAPIView.as_view(
        model = ProductCategory,
        resource_serializer = ProductCategorySerializer
    )),
    path('product-category-list/<str:page>',GetListView.as_view(
        model = ProductCategory,
        resource_serializer = ProductCategorySerializer
    )),
    path('discount/<int:pk>', ResourceAPIView.as_view(
        model = Discount,
        resource_serializer = DiscountSerializer
    )),
    path('discount-list/<str:page>',GetListView.as_view(
        model = Discount,
        resource_serializer = DiscountSerializer
    )),
    path('product/<int:pk>', ResourceAPIView.as_view(
        model = Product,
        resource_serializer = ProductSerializer
    )),
    path('product-list/<str:page>',GetListView.as_view(
        model = Product,
        resource_serializer = ProductSerializer
    ))
]


import requests

from prjstore.db.api import settings
from prjstore.db.schemas import seller as schemas
from prjstore.db.api.components.base import APIBase

class API_Seller(APIBase[schemas.CreateSeller, schemas.UpdateSeller, schemas.Seller]):
    prefix = 'seller'
    schema = schemas.Seller
    list_schema = schemas.ListSeller

    def __init__(self, headers):
        super().__init__(headers)

    def edit_name(self, seller_id: int, new_name: str) -> schemas.Seller:
        data = schemas.EditSellerName(seller_id=seller_id, new_name=new_name)
        r = requests.put(f"{settings.host}/{self.prefix}/edit_name",
                         data=data.json(), headers=self.headers)
        if r.status_code != 202:
            raise ConnectionError(r.text)
        else:
            return schemas.Seller(**r.json())

    def edit_active(self, seller_id: int, active: bool) -> schemas.Seller:
        data = schemas.EditSellerActive(seller_id=seller_id, active=active)
        r = requests.put(f"{settings.host}/{self.prefix}/edit_active",
                         data=data.json(), headers=self.headers)
        if r.status_code != 202:
            raise ConnectionError(r.text)
        else:
            return schemas.Seller(**r.json())


from PIL import Image
import pytesseract
import cv2
import os

IMAGE_TO_PROCESS_PATH = 'sample/Roster1.jpg'

if __name__ == "__main__":

    img = cv2.imread(IMAGE_TO_PROCESS_PATH, cv2.IMREAD_GRAYSCALE)

    if img is None:
        print("no image")
    else:
        thresh, img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # Nhị phân hóa
        # img = cv2.medianBlur(img, 3) # Làm mờ, giảm noise

        # Ghi tạm ảnh xuống ổ cứng
        filename = "{}.jpg".format(os.getpid())
        cv2.imwrite(filename, img)

        # Tesseract OCR
        pytesseract.pytesseract.tesseract_cmd = r'D:\Tai Lieu\HUST-Study\20201\TTKT\tesseract\tesseract.exe'
        text = pytesseract.image_to_string(Image.open(filename), lang = 'jpn')
        print(text)

        # Xóa ảnh tạm
        os.remove(filename)

        # Ghi vào file
        with open('task2/output_task2.txt', "w", encoding="utf-8") as f:
            f.write(text)

        # # Thu nhỏ ảnh
        # scale_percent = 30
        # width = int(img.shape[1] * scale_percent / 100)
        # height = int(img.shape[0] * scale_percent / 100)
        # dim = (width, height)
        # img = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
        # cv2.imshow('Table Structure', img)

        cv2.waitKey(0)
        cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
"""
Created on Fri Jan 17 14:20:02 2020

@author: Showi
"""

# encoding:utf-8

import requests
import base64
import os

'''
通用文字识别
'''

def p2text(imgPath):
    '''将图片转换为文字'''
    request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
    # 二进制方式打开图片文件
    f = open(imgPath, 'rb')
    img = base64.b64encode(f.read())
    f.close()
    params = {"image":img}
    ##################################################################################
    access_token = '[find the access_token on https://ai.baidu.com/tech/ocr/general]'
    ##################################################################################
    request_url = request_url + "?access_token=" + access_token
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    response = requests.post(request_url, data=params, headers=headers)
    if response:
        print('||',response.json())
        recMes = (response.json())['words_result']
        recMesText = []
        for one in recMes:
            recMesText.append(one['words'])
        os.remove(imgPath)#删除垃圾
        return(recMesText)


import os
import boto3
import json

dynamodb = boto3.resource("dynamodb")
table_name = os.environ.get("DATA_TABLE")
table = dynamodb.Table(table_name)

def handler(event, context):
    placeId = event.get("pathParameters", {}).get("placeId")
    res = {}
    item = table.get_item(Key={"pk": f"p-{placeId}", "sk": "p-info"}).get("Item", {})
    if item:
        likes = item.get("likes", 0)
        res = table.update_item(
            Key={"pk": f"p-{placeId}", "sk": "p-info"},
            UpdateExpression="SET #likes = :increased",
            ExpressionAttributeValues={":increased": likes + 1},
            ExpressionAttributeNames={"#likes": "likes"},
            ReturnValues="ALL_NEW",
        )
        print(res)
    if res.get("Attributes"):
        res["Attributes"]["data"]["likes"] = int(res["Attributes"]["likes"])
        return {"statusCode": 200, "body": json.dumps(res["Attributes"]["data"])}
    else:
        return {"statusCode": 444, "body": f"Il luogo {placeId} non esiste"}


from snownlp import SnowNLP
import random
import re

import chatgpt

# 分句
def clause(text, message_data):
    # 使用正则表达式提取句子，并保留中文标点符号作为分隔符
    if text[-1] not in "！？。!?.~":
        text += "。"
    sentences = re.split(r'([！？。!?.~])', text)

    # 去除分隔符为空的元素
    sentences = [sentence for sentence in sentences if sentence.strip()]

    # 将相邻的分隔符和句子合并
    merged_sentences = [sentences[i] + sentences[i+1] for i in range(0, len(sentences), 2)]

    # 打印分句结果
    for i, sentence in enumerate(merged_sentences):
        message_data.put(sentence)

def gpt(question_data, message_data, question_re):
    while True:
        question = question_data.get()
        message = chatgpt.chatgpt_answer("红糖", question)
        question_re.put(question)
        print("[GPT3.5][白糖]:", message)
        clause(message, message_data)
        emotion = SnowNLP(message)
        if random.randint(1, 100) <= ((emotion.sentiments*100)-35) and emotion.sentiments > 0.5:
            message_data.put("wink。")
        message_data.put("[end]")   # 告知回答结束


import os
import sys
from typing import List
import yaml
import pathlib
import subprocess

from .config import FILE_NAME, DEV
from .base_manager import BaseManager
from .package_manager import PackageManager
from .env_manager import EnvironmentManager
from .command_manager import CommandManger

class ConfigManger(BaseManager):
    def __init__(
            self,
            init: bool = False,
            install: bool | List[str] = False,
            uninstall: bool | List[str] = False,
            run: bool | List[str] = False,
            upgrade=False,
            mode: str = DEV
    ):
        super().__init__("kargat", mode=mode[0])
        self._file_repr = {}
        self.pkg_mgr = PackageManager(mode=mode[0])
        self.em = EnvironmentManager(mode=mode[0])
        self.cmd_mgr = CommandManger(mode=mode[0])
        # cli flags
        self._init_project = init
        self._install = self.handle_arg_list(install)
        self._uninstall = self.handle_arg_list(uninstall)
        self._run = self.handle_arg_list(run)
        self._upgrade = upgrade

    def _load_file(self):
        with open(FILE_NAME, 'r') as f:
            self._file_repr = yaml.safe_load(f)

    def run(self) -> bool:
        if not self._init_project:
            self._load_file()
        self.cmd_mgr.file_repr = self._file_repr
        self.pkg_mgr.file_repr = self._file_repr

        if self._init_project:
            name = self.request_name()
            author = self.request_author()
            version = self.request_version()
            self.generate(name, version, author)
            return True
        elif self._install is True:
            self.pkg_mgr.install_all(self._upgrade)
            return True
        elif self._uninstall is True:
            self.pkg_mgr.uninstall_all()
        elif self._install:
            for pkg in self._install:
                self.pkg_mgr.install(pkg, self._upgrade)
            return True
        elif self._uninstall:
            for pkg in self._uninstall:
                self.pkg_mgr.uninstall(pkg)
        elif self._run:
            with EnvironmentManager(file_repr=self._file_repr, mode="dev") as em:
                self.cmd_mgr.run(self._run)
            return True

    @staticmethod
    def request_name():
        default_name = pathlib.Path(os.getcwd()).name
        name = input(f"Project name ({default_name}): ")
        return name if name else default_name

    @staticmethod
    def request_author():
        user = os.environ.get('USER', os.environ.get('USERNAME'))
        author = input(f"Author ({user}): ")
        return author if author else user

    @staticmethod
    def request_version():
        default_version = "1.0.0"
        version = input(f"Version ({default_version}): ")
        return version if version else default_version

    @staticmethod
    def request_recreate_venv():
        answer = input(f"dir .venv exist, do you want to recreate? [N/y]")
        return answer == 'y'

    @staticmethod
    def venv_create():
        subprocess.check_call([sys.executable, '-m', 'venv', '.venv'])

    @staticmethod
    def has_venv():
        working_dir = os.getcwd()
        files = os.listdir(working_dir)
        flt_iter = next(filter(lambda file: file == '.venv', files), None)
        return flt_iter is not None

    @staticmethod
    def handle_arg_list(cli_args) -> List[str] | bool:
        if isinstance(cli_args, list):
            return cli_args if cli_args else True
        return False


import sqlite3
import yaml

def main():
    conn = sqlite3.connect('../../pf2.db')

    conn.row_factory = sqlite3.Row
    c = conn.cursor()
    stmt = """
    SELECT ancestries.short_name as name,
        flavor_text,
        hp,
        sizes.short_name AS size,
        speed,
        senses.short_name AS senses,
        ancestries.sources_pages
    FROM ancestries
        INNER JOIN
        sizes ON sizes.size_id = ancestries.size_id
        INNER JOIN
        senses ON senses.senses_id = ancestries.vision_id;
    """
    c.execute(stmt)
    res = [dict(row) for row in c.fetchall()]
    print(res)

    # for i in res:
    #     if i['hands'] == None or i['hands'] == '':
    #         i['hands'] = 0

    reslist = []
    for i in res:
        tmp = {
            "name": i['name'],
            "flavor_text": i['flavor_text'],
            "hp": i['hp'],
            "size": i['size'],
            'speed': i['speed'],
            'senses': i['senses'],
            "source": [
                {
                    'abbr': 'CRB',
                    'page_start': int(i['sources_pages']),
                    'page_stop': int(i['sources_pages'])
                },
            ],
            'boosts': None,
            'flaws': None,
            'traits': None
        }
        # add in boosts
        stmt = """
        SELECT abilityscores.short_name
            FROM abilityscores
            INNER JOIN
                ancestries_boosts ON abilityscores.abilityscores_id = ancestries_boosts.abilityscores_id
            INNER JOIN
                ancestries ON ancestries.ancestry_id = ancestries_boosts.ancestry_id
                WHERE ancestries.ancestry_id = (
                                            SELECT ancestries.ancestry_id
                                            WHERE ancestries.short_name = ?
                                        );
        """
        c.execute(stmt, (i['name'],))
        resboosts = [dict(row) for row in c.fetchall()]
        print(resboosts)
        if len(resboosts) == 0:
            tmp['boosts'] = None
        else:
            boostslist = []
            for j in resboosts:
                boostslist.append(j['short_name'])
            tmp['boosts'] = boostslist

        # add in flaws
        stmt = """
        SELECT abilityscores.short_name
            FROM abilityscores
            INNER JOIN
                ancestries_flaws ON abilityscores.abilityscores_id = ancestries_flaws.abilityscores_id
            INNER JOIN
                ancestries ON ancestries.ancestry_id = ancestries_flaws.ancestry_id
                WHERE ancestries.ancestry_id = (
                                            SELECT ancestries.ancestry_id
                                            WHERE ancestries.short_name = ?
                                        );
        """
        c.execute(stmt, (i['name'],))
        resflaws = [dict(row) for row in c.fetchall()]
        print(resflaws)
        if len(resflaws) == 0:
            tmp['flaws'] = None
        else:
            flawslist = []
            for j in resflaws:
                flawslist.append(j['short_name'])
            tmp['flaws'] = flawslist
        # add in traits
        stmt = """
        SELECT traits.short_name
            FROM traits
            INNER JOIN
                ancestries_traits ON traits.trait_id = ancestries_traits.trait_id
            INNER JOIN
                ancestries ON ancestries.ancestry_id = ancestries_traits.ancestry_id
                WHERE ancestries.ancestry_id = (
                                            SELECT ancestries.ancestry_id
                                            WHERE ancestries.short_name = ?
                                        );
        """
        c.execute(stmt, (i['name'],))
        restraits = [dict(row) for row in c.fetchall()]
        print(restraits)
        if len(restraits) == 0:
            tmp['traits'] = None
        else:
            traitslist = []
            for j in restraits:
                traitslist.append(j['short_name'])
            tmp['traits'] = traitslist

        reslist.append(tmp)

    # # print(reslist)

    tmpd = {'ancestries': reslist}

    # now dump to yaml
    final = yaml.safe_dump(tmpd, allow_unicode=True)
    with open('tmp-ancestries.yaml', 'w') as f:
        f.write(final)

if __name__ == "__main__":
    main()