from rest_framework.views import APIView
from rest_framework.response import Response
from image_convert.serializers import ImageConvertSerializer
from django.conf import settings
from .models import Image
import os
import shutil

class TextTransform(APIView):

    @staticmethod
    def post(request):

        data = {
            "name": str(request.data["image_raw"]),
            "image_raw": request.data["image_raw"],
            "image_converted": request.data["image_raw"]
        }

        # Delete all notes from database
        Image.objects.all().delete()

        # Delete media
        try:
            shutil.rmtree(settings.MEDIA_ROOT)
        except OSError as e:
            print("Error: %s - %s." % (e.filename, e.strerror))

        serializer = ImageConvertSerializer(data=data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)


from tkinter import*
# from PIL import Image,ImageTk
from tkinter import ttk ,messagebox
import sqlite3
# dk=Tk()
class productClass:
    def __init__(self,dk):
        self.dk=dk
        self.dk.geometry("1100x500+220+130")
        self.dk.title("Inventory Management System  | by dk")
        self.dk.config(bg="white")
        self.dk.focus_force()
# ***************************************************************

# ==========================all variable==============
        self.var_sarchby=StringVar()
        self.var_searchtext=StringVar()

        self.cat_list=[]
        self.sup_list=[]
        self.fetch_cat_sup()

        self.var_pro_id=StringVar()
        self.var_pro_cat=StringVar()
        self.var_pro_sup=StringVar()
        self.var_pro_name=StringVar()
        self.var_pro_price=StringVar()
        self.var_pro_qty=StringVar()
        self.var_pro_status=StringVar()
# ================================main category frame1=====================
        product_frame=Frame(self.dk,bd=2,relief=RIDGE,bg="white")
        product_frame.place(x=10,y=10,width=450,height=480)

#========================title ====
        title=Label(product_frame,text="Manage Product Details",font=("goudy old style",15,"bold"),bg="cyan4",fg="white").pack(side=TOP,fill=X)
# ======================naming lable============
        lbl_category=Label(product_frame,text="Category",font=("goudy old style",18),bg="white").place(x=30,y=60)
        lbl_supplier=Label(product_frame,text="Supplier",font=("goudy old style",18),bg="white").place(x=30,y=110)
        lbl_product=Label(product_frame,text="Name",font=("goudy old style",18),bg="white").place(x=30,y=160)
        lbl_price=Label(product_frame,text="Price",font=("goudy old style",18),bg="white").place(x=30,y=210)
        lbl_quantity=Label(product_frame,text="Quantity",font=("goudy old style",18),bg="white").place(x=30,y=260)
        lbl_status=Label(product_frame,text="Status",font=("goudy old style",18),bg="white").place(x=30,y=310)
# ================naming entry and combobox ===========================

        cmb_category=ttk.Combobox(product_frame,textvariable=self.var_pro_cat,values=self.cat_list,state='readonly',justify=CENTER,font=("goudy old style",15))
        cmb_category.place(x=150,y=60,width=200)
        cmb_category.current(0)

        cmb_supplier=ttk.Combobox(product_frame,textvariable=self.var_pro_sup,values=self.sup_list,state='readonly',justify=CENTER,font=("goudy old style",15))
        cmb_supplier.place(x=150,y=110,width=200)
        cmb_supplier.current(0)

        text_name=Entry(product_frame,textvariable=self.var_pro_name,font=("goudy old style",15,"bold"),bg="light yellow").place(x=150,y=160,width=200)
        text_price=Entry(product_frame,textvariable=self.var_pro_price,font=("goudy old style",15,"bold"),bg="light yellow").place(x=150,y=210,width=200)
        text_qty=Entry(product_frame,textvariable=self.var_pro_qty,font=("goudy old style",15,"bold"),bg="light yellow").place(x=150,y=260,width=200)

        cmb_status=ttk.Combobox(product_frame,textvariable=self.var_pro_status,values=("Active","Inactive"),state='readonly',justify=CENTER,font=("goudy old style",15))
        cmb_status.place(x=150,y=310,width=200)
        cmb_status.current(0)
# ===================all buttom for frame1 =========================

        btm_save=Button(product_frame,text="Save",command=self.add,font=("goudy old style",15,"bold"),bg="dark turquoise",fg="white",cursor="hand2").place(x=10,y=400,width=100,height=40)
        btm_update=Button(product_frame,text="Update",command=self.update,font=("goudy old style",15,"bold"),bg="yellow4",fg="white",cursor="hand2").place(x=120,y=400,width=100,height=40)
        btm_delet=Button(product_frame,text="Delete",command=self.delete,font=("goudy old style",15,"bold"),bg="springGreen2",fg="white",cursor="hand2").place(x=230,y=400,width=100,height=40)
        btm_clear=Button(product_frame,text="Clear",command=self.clear,font=("goudy old style",15,"bold"),bg="maroon1",fg="white",cursor="hand2").place(x=340,y=400,width=100,height=40)
# =================== sarchframe ========================
        sarchframe=LabelFrame(self.dk,text="Serch Product",font=("goudy old style",12,"bold"),bd=2,relief=RIDGE,bg="white")
        sarchframe.place(x=480,y=10,width=600,height=80)
        # option====
        cmb_sarch=ttk.Combobox(sarchframe,textvariable=self.var_sarchby,values=("Select","Category","Supplier","Name"),state='readonly',justify=CENTER,font=("goudy old style",15))
        cmb_sarch.place(x=10,y=10,width=180)
        cmb_sarch.current(0)

        text_sarch=Entry(sarchframe,textvariable=self.var_searchtext,font=("goudy old style",15),bg="lightyellow").place(x=200,y=10)
        btm_sarch=Button(sarchframe,text="Search",command=self.search,font=("goudy old style",15,"bold"),bg="purple4",fg="white",cursor="hand2").place(x=420,y=9,width=150,height=30)
# ============= treview and product details========================

        p_frame=Frame(self.dk,bd=3,relief=RIDGE)
        p_frame.place(x=480,y=100,width=600,height=400)

        scrolly=Scrollbar(p_frame,orient=VERTICAL)
        scrollx=Scrollbar(p_frame,orient=HORIZONTAL)

        self.productTable=ttk.Treeview(p_frame,columns=("pid","Category","Supplier","name","price","qty","status"),yscrollcommand=scrolly.set,xscrollcommand=scrollx.set)
        scrollx.pack(side=BOTTOM,fill=X)
        scrolly.pack(side=RIGHT,fill=Y)
        scrollx.config(command=self.productTable.xview)
        scrolly.config(command=self.productTable.yview)
        self.productTable.heading("pid",text="Pro ID")
        self.productTable.heading("Category",text="Category")
        self.productTable.heading("Supplier",text="Supplier")
        self.productTable.heading("name",text="Name")
        self.productTable.heading("price",text="Price")
        self.productTable.heading("qty",text="Qty")
        self.productTable.heading("status",text="Status")

        self.productTable["show"]="headings"

        self.productTable.column("pid",width=90)
        self.productTable.column("Category",width=100)
        self.productTable.column("Supplier",width=100)
        self.productTable.column("name",width=100)
        self.productTable.column("price",width=100)
        self.productTable.column("qty",width=100)
        self.productTable.column("status",width=100)

        self.productTable.pack(fill=BOTH,expand=1)
        self.productTable.bind("<ButtonRelease-1>",self.get_data)

        self.show()

#========================buttom data base =================================

    def fetch_cat_sup(self):
        con=sqlite3.connect(database='ims.db')
        cur=con.cursor()
        self.cat_list.append("Empty")
        self.sup_list.append("Empty")
        try:
            cur.execute("select name from category")
            cat=cur.fetchall()
            # print(cat)
            # cat_list=[]

            if len(cat)>0:
                del self.cat_list[:]
                self.cat_list.append("Select")
                for i in cat:
                    self.cat_list.append(i[0])
            # print(self.cat_list)

            cur.execute("select name from supplier")
            sup=cur.fetchall()
            # print(sup)
            if len(sup)>0:
                del self.sup_list[:]
                self.sup_list.append("Select")
                for i in sup:
                    self.sup_list.append(i[0])

        except Exception as ex:
            messagebox.showerror("error",f"error due to : {str(ex)}",parent=self.dk)

    def add(self):
        con=sqlite3.connect(database='ims.db')
        cur=con.cursor()
        try:
            if self.var_pro_cat.get()=="Select" or self.var_pro_cat.get()=="Empty" or self.var_pro_sup.get()=="Select" or self.var_pro_name.get()=="":
                messagebox.showerror("error","All fields are required",parent=self.dk)
            else:
                cur.execute("select * from product where name=?",(self.var_pro_name.get(),))
                row=cur.fetchone()
                if row!=None:
                    messagebox.showerror("error","Product already prasent ,try another",parent=self.dk)
                else:
                    cur.execute("Insert into product (Category,Supplier,name,price,qty,status) values(?,?,?,?,?,?)",(
                    self.var_pro_cat.get(),
                    self.var_pro_sup.get(),
                    self.var_pro_name.get(),
                    self.var_pro_price.get(),
                    self.var_pro_qty.get(),
                    self.var_pro_status.get(),
                    ))
                    con.commit()
                    messagebox.showinfo("success","Product added successfully",parent=self.dk)
                    self.show()
        except Exception as ex:
            messagebox.showerror("error",f"error due to : {str(ex)}",parent=self.dk)

    def show(self):
        con=sqlite3.connect(database='ims.db')
        cur=con.cursor()
        try:
            cur.execute("select * from product")
            rows=cur.fetchall()
            self.productTable.delete(*self.productTable.get_children())
            for row in rows:
                self.productTable.insert('',END,values=row)

        except Exception as ex:
            messagebox.showerror("error",f"error due to : {str(ex)}",parent=self.dk)

    def get_data(self,ev):
        f=self.productTable.focus()
        content=(self.productTable.item(f))
        row=content['values']
        # print(row)
        self.var_pro_id.set(row[0])
        self.var_pro_cat.set(row[1])
        self.var_pro_sup.set(row[2])
        self.var_pro_name.set(row[3])
        self.var_pro_price.set(row[4])
        self.var_pro_qty.set(row[5])
        self.var_pro_status.set(row[6])

    def update(self):
        con=sqlite3.connect(database='ims.db')
        cur=con.cursor()
        try:
            if self.var_pro_id.get()=="":
                messagebox.showerror("error","please select product from list",parent=self.dk)
            else:
                cur.execute("select * from product where pid=?",(self.var_pro_id.get(),))
                row=cur.fetchone()
                if row==None:
                    messagebox.showerror("error"," Invalid Product  ",parent=self.dk)
                else:
                    cur.execute("Update Product set Category=?,Supplier=?,name=?,price=?,qty=?,status=? where pid=? ",(
                    self.var_pro_cat.get(),
                    self.var_pro_sup.get(),
                    self.var_pro_name.get(),
                    self.var_pro_price.get(),
                    self.var_pro_qty.get(),
                    self.var_pro_status.get(),
                    self.var_pro_id.get()
                    ))
                    con.commit()
                    messagebox.showinfo("Success","Product Update Successfully",parent=self.dk)
                    self.show()
        except Exception as ex:
            messagebox.showerror("error",f"error due to : {str(ex)}",parent=self.dk)

    def delete(self):
        con=sqlite3.connect(database='ims.db')
        cur=con.cursor()
        try:
            if self.var_pro_id.get()=="":
                messagebox.showerror("error","please select product from the list",parent=self.dk)
            else:
                cur.execute("select * from product where pid=?",(self.var_pro_id.get(),))
                row=cur.fetchone()
                if row==None:
                    messagebox.showerror("error"," Invalid Product ",parent=self.dk)
                else:
                    op=messagebox.askyesno("Confirm","Do you really wnat to delet?",parent=self.dk)
                    if op==True:
                        cur.execute("delete from product where pid=?",(self.var_pro_id.get(),))
                        con.commit()
                        messagebox.showinfo("Success","Product Deleted Successfully",parent=self.dk)
                        self.show()
                        # self.clear()

        except Exception as ex:
            messagebox.showerror("error",f"error due to : {str(ex)}",parent=self.dk)

    def clear(self):
        self.var_pro_id.set("")
        self.var_pro_cat.set("Select")
        self.var_pro_sup.set("Select")
        self.var_pro_name.set("")
        self.var_pro_price.set("")
        self.var_pro_qty.set("")
        self.var_pro_status.set("Active")

        self.var_sarchby.set("Select")
        self.var_searchtext.set("")
        self.show()

    def search(self):
        con=sqlite3.connect(database='ims.db')
        cur=con.cursor()
        try:
            if self.var_sarchby.get()=="Select":
                messagebox.showerror("Error","Select Search By Option",parent=self.dk)
            elif self.var_searchtext.get()=="":
                messagebox.showerror("Error","Search Input Should be required",parent=self.dk)

            else:
                cur.execute("select * from product where "+self.var_sarchby.get()+" LIKE '%"+self.var_searchtext.get()+"%'")
                rows=cur.fetchall()
                if len(rows)!=0:
                    self.productTable.delete(*self.productTable.get_children())
                    for row in rows:
                        self.productTable.insert('',END,values=row)
                else:
                    messagebox.showerror("Error","No record fund",parent=self.dk)

        except Exception as ex:
            messagebox.showerror("error",f"error due to : {str(ex)}",parent=self.dk)

if __name__=="__main__":
    dk=Tk()
    obj=productClass(dk)
    dk.mainloop()


import numpy as np
import torch
import matplotlib.pyplot as plt
from scipy import signal
import numpy as np
import time
import csv

coef = 6
width = 200*coef

def bit_signal(t):
    return signal.square(t).astype('float64')

np.random.seed(2)

T = 2
L = 500
N = 10

#x = np.empty((N, L), 'int64')
#x[:] = np.array(range(L)) + np.random.randint(-4 * T, 4 * T, N).reshape(N, 1)
#x[:] = np.array(range(L))
#x = np.linspace(0, 1, 500, endpoint=False)
#print(x)
#data = np.sin(x / 1.0 / T).astype('float64')
# data = bit_signal(x)
# print(data[0])
# plt.plot(x[0], data[0])
# plt.ylim(-2, 2)
#plt.savefig('tmp.pdf')
#plt.show()
#torch.save(data, open('traindata.pt', 'wb'))

#label,1,2,3,4,5,6,7,8,9,10
#0,154,232,....

#plt.figure()

def bit_signal_noise(coef_f, cycle=5, rate=100, level_noise=1.5, offset=0):
    t = np.linspace(0, 2*np.pi*cycle, 2*np.pi*cycle*rate, endpoint=False)
    t = t+offset
    noise = np.random.uniform(-pow(0.1,level_noise), pow(0.1, level_noise), [1,int(2*np.pi*cycle*rate)])[0]
    data = signal.square(t/pow(2,coef_f)) + noise
    data = data + abs(min(data))
    data = data/max(data)*255.0
    data = data.astype(int)

    return t, data

level_noise = 1.5
rate = 20 #resolution per cycle
#max_coef_f = 4
MAX_COEF_F = 4
cycle = 50

data_box = ''
for i in range(MAX_COEF_F):
    for j in range(int(rate)):
        buf_str = ','+str(i)+'x'+str(j)
        data_box += buf_str
    buf_str = '\n'
    data_box += buf_str

def compose_signals(label, max_coef_f, attack=False, attack_rate=0.2, visualize=False, attack_offset=False, offset_idx=None, offset_vol=None, attack_noise=False, noise_vol=None):
    labels = []

    plt.figure()
    composed_data = list()
    for i in range(max_coef_f):
        coef_f = i

        #generate offset signal
        if attack_offset and i == offset_idx:
            t, data = bit_signal_noise(coef_f=coef_f, cycle=cycle, rate=rate, offset=offset_vol)
            print('   >>> adding offset:', offset_vol, 'to_idx:', offset_idx)
        #generate attack noise signal
        elif attack_noise:
            t, data = bit_signal_noise(coef_f=coef_f, cycle=cycle, rate=rate, level_noise=noise_vol)
        #generate normal, abnormal_zeroba signal
        else:
            t, data = bit_signal_noise(coef_f=coef_f, cycle=cycle, rate=rate)

        #generate labels_basic
        buf_label = [0]*len(data)
        labels.append(buf_label)

        #add label based on categories
        #...in following if-states...

        #add abnormal_zerobar
        if attack:
            #add max value in signal in random spots
            rand_spots = np.random.randint(0, len(data), size=int(len(data)*attack_rate))
            bar = 10
            for idx in rand_spots:
                if idx+bar < len(data):
                    data[idx:idx+bar] = 0 #value attack 0
                    labels[i][idx:idx+bar] = [label]*bar #means attack-label 1

            print('attack', data[:10], type(data), max(data), min(data))

        elif attack_offset and i == offset_idx:
            labels[i][:] = [label]*len(data)
            print('attack offset', data[:10], type(data), max(data), min(data))

        elif attack_noise: #todo idx
            labels[i][:] = [label]*len(data)
            print('attack noise', data[:10], type(data), max(data), min(data))

        #do nothing on normal
        else:
            print('normal', data[:10], type(data), max(data), min(data))

        if visualize:
            plt.subplot(max_coef_f,1,coef_f+1)
            plt.plot(t, data)
        print('length of each slot:', len(data))
        composed_data.append(data)

    #print('total length t:', len(composed_data[0]))
    #input('ok?')
    if visualize:
        if attack:
            print('save attack...')
            plt.savefig('abnormal_composed.pdf')
        elif offset_idx != None:
            print('save attack_offset...')
            plt.savefig('abnormal_offset_composed.pdf')
        elif attack_noise:
            print('save attack_noise...')
            plt.savefig('abnormal_noise_composed.pdf')
        else:
            print('save normal...')
            plt.savefig('normal_composed.pdf')
    print('len of composed_data:', len(composed_data)*len(composed_data[0]))

    print('tmp/labels:', labels)

    return composed_data, labels

#slice and insert data
# normal_data = list()
# for i in range(max_coef_f):
#     coef_f = i
#     t, data = bit_signal_noise(coef_f=coef_f, cycle=cycle, rate=rate)
#     plt.subplot(max_coef_f,1,coef_f+1)
#     plt.plot(t, data)
#     normal_data.append(data)

seed=0

#compose normal signal
seed+=1; np.random.seed(seed)
normal_data, normal_labels = compose_signals(label=0, max_coef_f=MAX_COEF_F, attack=False, visualize=True)

seed+=1; np.random.seed(seed)
#compose abnormal signal (by zero bar noise)
abnormal_data, abnormal_labels = compose_signals(label=1, max_coef_f=MAX_COEF_F, attack=True, attack_rate=0.005, visualize=True)

seed+=1; np.random.seed(seed)
abnormal_offset_train_data, abnormal_offset_train_labels = compose_signals(label=2, max_coef_f=MAX_COEF_F, attack=False, attack_rate=0.0, visualize=True, attack_offset=True, offset_idx=1, offset_vol=20)

seed+=1; np.random.seed(seed)
abnormal_noise_train_data, abnormal_noise_train_labels = compose_signals(label=3, max_coef_f=MAX_COEF_F, attack=False, visualize=True, attack_noise=True, noise_vol=1.0)#normal:1.5, bigger, better

seed+=1; np.random.seed(seed)
normal_test_data, normal_test_labels = compose_signals(label=0, max_coef_f=MAX_COEF_F, attack=False, visualize=True)
#compose abnormal signal (by zero bar noise)
abnormal_test_data, abnormal_test_labels = compose_signals(label=1, max_coef_f=MAX_COEF_F, attack=True, attack_rate=0.005, visualize=True)

seed+=1; np.random.seed(seed)
abnormal_offset_test_data, abnormal_offset_test_labels = compose_signals(label=2, max_coef_f=MAX_COEF_F, attack=False, attack_rate=0.0, visualize=True, attack_offset=True, offset_idx=1, offset_vol=20)

seed+=1; np.random.seed(seed)
abnormal_noise_test_data, abnormal_noise_test_labels = compose_signals(label=3, max_coef_f=MAX_COEF_F, attack=False, visualize=True, attack_noise=True, noise_vol=1.0)#normal:1.5 bigger, better

#todo
#compose abnormal signal (by latency offset)
#abnormal_data_latency = ...

#print('total length t:', len(normal_data[0]))
#input('ok?')

plt.savefig('tmp.pdf')

#print(normal_data)
#input('ok?')

#loop have to be rebuilt
#
#for at t=0,1,2,... size-width
#   add label to buf
#   for at s=0,1,2,...n(sensors)
#      for at t_cursor=0,1,...,width
#         add data[s, t_cursor] to buf
#   add n to data
#   add buf to data

def make_images(ts_data, width, labels):
    time_start = time.time()
    images = list()

    for t in range(len(ts_data[0])-width):
        buf_label = list()
        for s in range(len(ts_data)):
            buf_label.append(max(labels[s][t:t+width]))
        label = max(buf_label) #during 4 signals

        buf = [label]
        #buf = []
        #for s in range(len(ts_data)):
        #print('len(ts_data) == 4?', len(ts_data), 't:', t, t+width)
        #input('ok?')
        for s in range(len(ts_data)):
            #buf += list(ts_data[s][t:t+width])
            buf += ts_data[s][t:t+width].tolist() #faster
        # print('a image:', buf)
        # input('ok?')
        images.append(buf)
        #print('t:', t, 'n of images:', len(images), 'n of each image:', len(buf))
        if t % 3000 == 0:
            print('progress:', t, '/', len(ts_data[0])-width)

    time_elapsed = time.time() - time_start
    print('total num of image:', len(images))
    print('time elapsed:', time_elapsed)

    return images

#make normal_data to images
normal_images = make_images(normal_data, width, normal_labels)#, 0)
#make abnormal_data to images
abnormal_images = make_images(abnormal_data, width, abnormal_labels)#, 1)
abnormal_offset_train_images =  make_images(abnormal_offset_train_data, width, abnormal_offset_train_labels)#, 2)
abnormal_noise_train_images =  make_images(abnormal_noise_train_data, width, abnormal_noise_train_labels)#, 2)

#make normal_data to images test
normal_test_images = make_images(normal_test_data, width, normal_test_labels)#, 0)
#make abnormal_data to images test
abnormal_test_images = make_images(abnormal_test_data, width, abnormal_test_labels)#, 1)
abnormal_noise_test_images =  make_images(abnormal_noise_test_data, width, abnormal_noise_test_labels)#, 2)

print('writing csv files...')
with open("ics_train.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerows(normal_images)
    # writer.writerows(abnormal_images)
    # writer.writerows(abnormal_offset_train_images)
    writer.writerows(abnormal_noise_train_images)

#test data == train data same temporarily
with open("ics_test.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerows(normal_test_images)
    # writer.writerows(abnormal_test_images)
    # writer.writerows(abnormal_offset_test_images)
    writer.writerows(abnormal_noise_test_images)


import sys
import re
import json
import subprocess
import io
import zipfile
from traceback import print_exc
from pathlib import Path
from contextlib import contextmanager
from threading import Thread, Event
from http.server import HTTPServer, BaseHTTPRequestHandler
from SCons.Errors import UserError

Import("env")

def make_install_manager_release_archive(project_dir, version):
    # Just use the current build and change the version in plugin.cfg
    buff = io.BytesIO()
    zf = zipfile.ZipFile(buff, mode="w", compression=zipfile.ZIP_STORED, allowZip64=False)
    addon_dir = Path(f"{project_dir}/addons/godot_python_install_manager").resolve()
    for item in addon_dir.rglob("*"):
        if item.is_dir():
            continue
        if item.name == "plugin.cfg":
            data = re.sub('version="[0-9.]+"', f'version="{version}"', item.read_text())
        else:
            data = item.read_bytes()
        zf.writestr(f"addons/godot_python_install_manager/{item.relative_to(addon_dir)}", data)
    zf.close()
    buff.seek(0)
    data = buff.read()
    return data

def make_godot_python_release_archive(project_dir, version):
    # TODO: use a real build of Godot Python !!!
    buff = io.BytesIO()
    zf = zipfile.ZipFile(buff, mode="w", compression=zipfile.ZIP_STORED, allowZip64=False)
    addon_dir = Path(f"{project_dir}/addons/godot_python_install_manager").resolve()
    for item in addon_dir.rglob("*"):
        if item.is_dir():
            continue
        if item.name == "plugin.cfg":
            data = re.sub('version="[0-9.]+"', f'version="{version}"', item.read_text())
        else:
            data = item.read_bytes()
        zf.writestr(f"addons/godot_python/{item.relative_to(addon_dir)}", data)
    zf.close()
    buff.seek(0)
    data = buff.read()
    return data

def get_supported_godot_feature():
    if sys.platform == "linux":
        return "X11"
    elif sys.platform == "darwin":
        return "OSX"
    elif sys.platform == "win32":
        return "Windows"
    else:
        raise RuntimeError(
            f"Cannot determine a suitable supported feature for Godot on this platform ({sys.platform})"
        )

class GithubServerMock:
    def __init__(self, project_dir):
        self.project_dir = project_dir
        self.server = None
        self._started = Event()
        self.addons = {"godot_python_install_manager": [], "godot_python": []}

    def add_release(self, name, data_path=None):
        match = re.search(r"^(.*)-([0-9]+\.[0-9]+\.[0-9]+)", name)
        assert match
        addon_name = match.group(1)
        version = match.group(2)
        tag_name = f"v{version}"
        releases = self.addons[addon_name]
        if data_path:
            browser_download_url = f"http://127.0.0.1:{self.port}/files/{data_path}"
        else:
            browser_download_url = f"http://127.0.0.1:{self.port}/releases/{addon_name}/{version}"
        release_new_asset = {"name": name, "browser_download_url": browser_download_url}
        for release in releases:
            if release["tag_name"] == tag_name:
                release["assets"].append(release_new_asset)
                break
        else:
            release = {"prerelease": False, "tag_name": tag_name, "assets": [release_new_asset]}
            self.addons[addon_name] = list(
                reversed(sorted([*releases, release], key=lambda x: x["tag_name"]))
            )

    @property
    def port(self):
        return self.server.server_port

    def _run(self):
        class HTTPRequestHandler(BaseHTTPRequestHandler):
            def do_GET(handler_self):
                return self._do_GET(handler_self)

        assert self.server is None
        with HTTPServer(("", 0), HTTPRequestHandler) as self.server:
            self._started.set()
            self.server.serve_forever()

    def _stop(self):
        self.server.shutdown()

    def _do_GET(self, request):
        if request.path.startswith("/files/"):
            file = Path(request.path[len("/files/") :])
            if not file.is_file():
                request.send_response(404)
                request.end_headers()
                return
            else:
                data = file.read_bytes()
                request.send_response(200)
                request.send_header("content-type", "application/zip")
                request.send_header("content-length", len(data))
                request.end_headers()
                request.wfile.write(data)
                return

        if request.path.startswith("/releases/"):
            _, _, addon_name, addon_release = request.path.split("/")
            if addon_name == "godot_python_install_manager":
                data = make_install_manager_release_archive(self.project_dir, addon_release)
            elif addon_name == "godot_python":
                data = make_godot_python_release_archive(self.project_dir, addon_release)
            else:
                request.send_response(404)
                request.end_headers()
                return
            request.send_response(200)
            request.send_header("content-type", "application/zip")
            request.send_header("content-length", len(data))
            request.end_headers()
            request.wfile.write(data)
            return

        for addon_name, addon_releases in self.addons.items():
            if request.path == f"/{addon_name.replace('_', '-')}/releases":
                data = json.dumps(addon_releases).encode("utf-8")
                request.send_response(200)
                request.send_header("content-type", "application/json")
                request.send_header("content-length", len(data))
                request.end_headers()
                request.wfile.write(data)
                return
        else:
            request.send_response(404)
            request.end_headers()
            return

    @classmethod
    @contextmanager
    def run(cls, project_dir):
        gh = cls(project_dir)

        thread = Thread(target=gh._run, daemon=True)
        thread.start()
        gh._started.wait()
        try:
            # Patch install manager addon config to head to our fake github api server
            addons_gd = Path(f"{project_dir}/addons/godot_python_install_manager/addons.gd")
            addons_gd.write_text(
                addons_gd.read_text().replace(
                    "https://api.github.com/repos/touilleMan", f"http://127.0.0.1:{gh.port}"
                )
            )
            # Also patch version so the tests won't become irrelevant with time
            plugin_cfg = Path(f"{project_dir}/addons/godot_python_install_manager/plugin.cfg")
            plugin_cfg.write_text(
                re.sub('version="[0-9.]+"', 'version="0.0.1"', plugin_cfg.read_text())
            )
            yield gh
        finally:
            gh._stop()
            thread.join()

def test_factory(target, action):
    target_project_dir = Dir(f"#build/tests/test_{target}_project")
    env.Command(
        target=target_project_dir,
        source=env["DIST_ROOT"],
        action=[
            Delete("$TARGET"),
            Copy(dest="$TARGET", src=env.Dir("test_project")),
            Copy(dest="$TARGET/addons", src="$DIST_ROOT/addons"),
        ],
    )
    env.Clean(target_project_dir, target_project_dir)
    env.AlwaysBuild(target_project_dir)

    env.Command(target=[target], source=[target_project_dir], action=action)
    env.Depends(target, env["godot_binary"])
    env.AlwaysBuild(target)

    return target

# Decorator to apply on test functions
def test(test_function):
    return test_factory(test_function.__name__, test_function)

def run_cmd(cmd, expected_returncode=0):
    def _attach_error_context(obj):
        @contextmanager
        def _error_context():
            try:
                yield
            except Exception as exc:
                print(f"Test failure !!!")
                print()
                print_exc()
                print()
                print(f"stdout: {obj.stdout.decode()}")
                print()
                print(f"stderr: {obj.stderr.decode()}")
                raise UserError(f"Test has failed {exc}") from exc

        obj.error_context = _error_context

    if isinstance(cmd, str):
        cmd = cmd.split()
    print(" ".join(cmd))
    try:
        out = subprocess.run(cmd, check=True, capture_output=True)
    except subprocess.CalledProcessError as exc:
        if expected_returncode == exc.returncode:
            _attach_error_context(exc)
            return exc
        print(f"Error !!! Non-zero return code: {exc.returncode}")
        print()
        print(f"stdout: {exc.stdout.decode()}")
        print()
        print(f"stderr: {exc.stderr.decode()}")
        raise UserError(f"Test has failed (returncode: {exc.returncode})") from exc
    else:
        if "ObjectDB instances leaked at exit" in out.stderr.decode():
            print(f"Error !!! ObjectDB instances leaked at exit !")
            print()
            print(f"stdout: {out.stdout.decode()}")
            print()
            print(f"stderr: {out.stderr.decode()}")
            raise UserError(f"ObjectDB instances leaked at exit !")
    # See https://github.com/godotengine/godot/issues/30207
    if "SCRIPT ERROR:" in out.stdout.decode():
        print(f"Godot error detected !!!")
        print()
        print(f"stdout: {out.stdout.decode()}")
        print()
        print(f"stderr: {out.stderr.decode()}")
        raise UserError(f"Test has failed (Godot error)")

    _attach_error_context(out)
    return out

def run_cli(project_path, cmd, **kwargs):
    return run_cmd(
        f"{env['godot_binary']} --verbose --path {project_path} --script res://addons/godot_python_install_manager/cli.gd {cmd}",
        **kwargs,
    )

@test
def test_cli_no_arguments(target, source, env):
    out = run_cli(source[0], "")
    with out.error_context():
        stdout = out.stdout.decode()
        assert (
            "Usage: godot [--path <project_path>] [--no-window] --script res://addons/godot_python_install_manager/cli.gd [options]"
            in stdout
        )

@test
def test_cli_info(target, source, env):
    out = run_cli(source[0], "info")
    with out.error_context():
        stdout = out.stdout.decode()
        assert "Install Manager: " in stdout
        assert "Godot Python: Not installed" in stdout

def _list_version_testbed(cmd, addon, source):
    supported_feature = get_supported_godot_feature()

    with GithubServerMock.run(source[0]) as gh:
        # No versions at all
        out = run_cli(source[0], cmd, expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Only incompatible versions
        gh.add_release(f"{addon}-2.0.0-godot42.zip")
        gh.add_release(f"{addon}-2.0.0-godot3-NotSupportedFeature.zip")
        gh.add_release(f"{addon}-2.0.0-godot3-{supported_feature}-NotSupportedFeature.zip")
        out = run_cli(source[0], cmd, expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Multiple compatible versions
        gh.add_release(f"{addon}-1.0.0-godot3.zip")
        gh.add_release(f"{addon}-1.1.0-godot3.zip")
        gh.add_release(f"{addon}-1.1.1-godot3-{supported_feature}.zip")
        out = run_cli(source[0], cmd)
        with out.error_context():
            stdout = out.stdout.decode().replace("\r\n", "\n")
            assert (
                f"""Available versions:
1.1.1 ({addon}-1.1.1-godot3-{supported_feature}.zip)
1.1.0 ({addon}-1.1.0-godot3.zip)
1.0.0 ({addon}-1.0.0-godot3.zip)
"""
                in stdout
            )

@test
def test_cli_list_versions(target, source, env):
    _list_version_testbed("list_versions", "godot_python", source)

@test
def test_cli_self_list_versions(target, source, env):
    _list_version_testbed("self_list_versions", "godot_python_install_manager", source)

@test
def test_cli_self_update(target, source, env):
    supported_feature = get_supported_godot_feature()

    with GithubServerMock.run(source[0]) as gh:
        # No versions at all
        out = run_cli(source[0], "self_upgrade", expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Only incompatible versions
        gh.add_release("godot_python_install_manager-2.0.0-godot42.zip")
        out = run_cli(source[0], "self_upgrade 2.0.0", expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Now we do the upgrade !
        gh.add_release("godot_python_install_manager-2.0.0-godot3.zip")
        out = run_cli(source[0], "self_upgrade 2.0.0")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Upgrading Install Manager to version 2.0.0" in stdout

        # Make sure the new version is installed
        out = run_cli(source[0], "info")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Install Manager: 2.0.0" in stdout

        # Upgrade to a new latest version
        gh.add_release("godot_python_install_manager-2.0.1-godot3.zip")
        out = run_cli(source[0], "self_upgrade")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Upgrading Install Manager to version 2.0.1" in stdout

        # Make sure the new version is installed
        out = run_cli(source[0], "info")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Install Manager: 2.0.1" in stdout

@test
def test_cli_install(target, source, env):
    supported_feature = get_supported_godot_feature()

    with GithubServerMock.run(source[0]) as gh:
        # No versions at all
        out = run_cli(source[0], "install", expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Only incompatible versions
        gh.add_release("godot_python-2.0.0-godot42.zip")
        out = run_cli(source[0], "install", expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Now we do the install !
        gh.add_release("godot_python-2.0.0-godot3.zip")
        out = run_cli(source[0], "install 2.0.0")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Upgrading Godot Python to version 2.0.0" in stdout

        # Make sure the version is installed
        out = run_cli(source[0], "info")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Godot Python: 2.0.0" in stdout

        # Retry the install should not do anything...
        out = run_cli(source[0], "install")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Godot Python is already installed in version 2.0.0" in stdout

        # ...even if a newer version is now available
        gh.add_release("godot_python-2.0.1-godot3.zip")
        out = run_cli(source[0], "install")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Godot Python is already installed in version 2.0.0" in stdout

@test
def test_cli_update(target, source, env):
    supported_feature = get_supported_godot_feature()

    with GithubServerMock.run(source[0]) as gh:
        # No versions at all
        out = run_cli(source[0], "upgrade", expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Only incompatible versions
        gh.add_release("godot_python-2.0.0-godot42.zip")
        out = run_cli(source[0], "upgrade 2.0.0", expected_returncode=1)
        with out.error_context():
            stdout = out.stdout.decode()
            assert "No compatible version found" in stdout

        # Now we do the upgrade !
        gh.add_release("godot_python-2.0.0-godot3.zip")
        out = run_cli(source[0], "upgrade 2.0.0")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Upgrading Godot Python to version 2.0.0" in stdout

        # Make sure the new version is installed
        out = run_cli(source[0], "info")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Godot Python: 2.0.0" in stdout

        # Upgrade to a new latest version
        gh.add_release("godot_python-2.0.1-godot3.zip")
        out = run_cli(source[0], "upgrade")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Upgrading Godot Python to version 2.0.1" in stdout

        # Make sure the new version is installed
        out = run_cli(source[0], "info")
        with out.error_context():
            stdout = out.stdout.decode()
            assert "Godot Python: 2.0.1" in stdout


# vim:set et sts=4 sw=4:
#
# python -m testime.batch

import unittest
import sys
import json

from PySide2.QtCore import QObject, qDebug, QEventLoop
from PySide2.QtWidgets import QApplication

from testime.IBusDriver import IBusDriver
from testime.FcitxDriver import FcitxDriver
from testime.keyboard import KeycodeToKeysym
from testime.keyboard import KeynameToKeysym, KeynameToKeycode
from testime.parse_hotkey import parse_hotkey
from test.hangul_compose import get_2bulsik_test, get_3bulsik_test

# check singleton instance
if not QApplication.instance():
    import dbus

    # Enable glib main loop support
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    app = QApplication(sys.argv)

class TestObject(QObject):
    def __init__(self, name):
        QObject.__init__(self)

        if name == 'Fcitx':
            self.driver = FcitxDriver(name)
        else:
            self.driver = IBusDriver(name)
        self.text = ""
        self.preedit = True
        self.driver.commitText.connect(self.onCommitText)
        self.driver.preeditChanged.connect(self.onPreeditChanged)
        self.driver.iface.FocusIn()

    def __del__(self):
        del self.driver

    def onCommitText(self, text):
        #qDebug("SLOT(commitText) : %s" % text)
        self.text += text
        self.preedit = False

    def onPreeditChanged(self):
        #qDebug("SLOT(preeditChanged) : %s" % self.driver.preedit())
        pass

    def keyPressEvent(self, key):
        # parse_hotkey() also works for simple keystroke
        # check '-' for speed
        if key != '-' and '-' in key:
            ks = parse_hotkey(key)
            keycode = ks.keycode
            modifier = ks.modifier
            keysym = KeycodeToKeysym[ks.keycode][modifier & 0x03]
        else:
            keysym = KeynameToKeysym[key]
            keycode = KeynameToKeycode[key]
            modifier = 0
        ret = self.driver.ProcessKeyEvent(keysym, keycode, modifier)
        #qDebug("keyPress : %s(%d) returns %d" % (keycode, keysym, ret))

    def clear(self):
        self.preedit = True
        self.text = ""

class FcitxTestCase(unittest.TestCase):
    def setUp(self):
        self.obj = TestObject("Fcitx")
        # IME key Contaol-space
        self.obj.keyPressEvent('C-space')

    def tearDown(self):
        del self.obj

    def test_sample(self):
        qDebug("KeySequence : %s" % ['k', 'f', 's'])
        self.obj.clear()
        self.obj.keyPressEvent('k')
        self.obj.keyPressEvent('f')
        self.obj.keyPressEvent('s')
        self.obj.keyPressEvent('Return')

        while self.obj.preedit:
            QEventLoop().processEvents(QEventLoop.AllEvents, 1)
        self.assertEqual(self.obj.text, u"간")

    def __real_test(self, cases):
        for code in cases:
            self.obj.clear()
            key_sequence = cases[code]
            qDebug("KeySequence : %s" % key_sequence)
            for key in key_sequence:
                self.obj.keyPressEvent(key)
            self.obj.keyPressEvent('Return')

            while self.obj.preedit:
                QEventLoop().processEvents(QEventLoop.AllEvents, 1)
            self.assertEqual(self.obj.text, code)

    def test_2bulsik(self):
        with open('test/2bulsik.json', 'r') as handle:
            cases = json.load(handle)
        self.__real_test(cases)

    def test_3bulsik(self):
        with open('test/3bulsik.json', 'r') as handle:
            cases = json.load(handle)
        self.__real_test(cases)

    def test_all_2bulsik(self):
        cases = get_2bulsik_test()
        self.__real_test(cases)

    def test_all_3bulsik(self):
        cases = get_3bulsik_test()
        self.__real_test(cases)

class IBusTestCase(unittest.TestCase):

    def setUp(self):
        self.obj = TestObject("IBus")
        # IME key Contaol-space
        self.obj.keyPressEvent('Shift-space')

    def tearDown(self):
        del self.obj

    def __real_test(self, cases):
        for code in cases:
            self.obj.clear()
            key_sequence = cases[code]
            qDebug("KeySequence : %s" % key_sequence)
            for key in key_sequence:
                self.obj.keyPressEvent(key)
            self.obj.keyPressEvent('Return')

            while self.obj.preedit:
                QEventLoop().processEvents(QEventLoop.AllEvents, 1)
            self.assertEqual(self.obj.text, code)

    def test_2bulsik(self):
        with open('test/2bulsik.json', 'r') as handle:
            cases = json.load(handle)
        self.__real_test(cases)

    def test_3bulsik(self):
        with open('test/3bulsik.json', 'r') as handle:
            cases = json.load(handle)
        self.__real_test(cases)

    def test_all_2bulsik(self):
        cases = get_2bulsik_test()
        self.__real_test(cases)

    def test_all_3bulsik(self):
        cases = get_3bulsik_test()
        self.__real_test(cases)

if __name__ == '__main__':
    if len(sys.argv) != 3 or '-h' in sys.argv:
        print('Usage : %s [IBus|Fcitx] [2bulsik|3bulsik]' % sys.argv[0])
        exit(0)

    IME = sys.argv[1]
    HANGUL_KEYBOARD = sys.argv[2]

    suite = unittest.TestSuite()
    if IME == 'Fcitx':
        testDriver = FcitxTestCase
    else:
        testDriver = IBusTestCase
    if HANGUL_KEYBOARD == '2bulsik':
    	suite.addTest(testDriver('test_all_2bulsik'))
    else:
    	suite.addTest(testDriver('test_all_3bulsik'))
    runner = unittest.TextTestRunner()
    runner.run(suite)
    #unittest.main()


import matplotlib.pyplot as plt
import numpy as np
import helper as hlp

plt.xkcd()
plt.grid(True)

title1 = 'Example8. Nagy p.190'

#====================
va = [1, 0, 4]
#c=0
b = 1
IC0 = [0, 0]
t0 = 0
tb = 10
N = 100
#====================

def y_ex(t):
	return 0.5*(hlp.heaviside(t-np.pi)-hlp.heaviside(t-2*np.pi))*np.sin(2*t)

vb = [1, -1, 2, 0]
vc = [np.pi, 2.0*np.pi, -np.pi, 2]

Z2 = hlp.mkSlnT1_c(va, vb, vc, IC0, t0, tb, N)

hlp.showNumSolution(plt, Z2, y_ex, title1)
hlp.showPhase(plt, Z2, title1)


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from absl import flags

import tensorflow as tf
from tensorflow_examples.models.pix2pix import data_download
from tensorflow_examples.models.pix2pix import pix2pix

FLAGS = flags.FLAGS

class Pix2PixTest(tf.test.TestCase):

  def test_one_step_with_function(self):
    epochs = 1
    batch_size = 1
    enable_function = True

    input_image = tf.random.uniform((256, 256, 3))
    target_image = tf.random.uniform((256, 256, 3))

    train_dataset = tf.data.Dataset.from_tensors(
        (input_image, target_image)).map(pix2pix.random_jitter).batch(
            batch_size)
    checkpoint_pr = pix2pix.get_checkpoint_prefix()

    pix2pix_obj = pix2pix.Pix2pix(epochs, enable_function)
    pix2pix_obj.train(train_dataset, checkpoint_pr)

  def test_one_step_without_function(self):
    epochs = 1
    batch_size = 1
    enable_function = False

    input_image = tf.random.uniform((256, 256, 3))
    target_image = tf.random.uniform((256, 256, 3))

    train_dataset = tf.data.Dataset.from_tensors(
        (input_image, target_image)).map(pix2pix.random_jitter).batch(
            batch_size)

    pix2pix_obj = pix2pix.Pix2pix(epochs, enable_function)

    checkpoint_pr = pix2pix.get_checkpoint_prefix()
    pix2pix_obj.train(train_dataset, checkpoint_pr)

class Pix2PixBenchmark(tf.test.Benchmark):

  def __init__(self, output_dir=None, **kwargs):
    self.output_dir = output_dir

  def benchmark_with_function(self):
    path = data_download.main("datasets")
    kwargs = {"epochs": 6, "enable_function": True, "path": path,
              "buffer_size": 400, "batch_size": 1}
    self._run_and_report_benchmark(**kwargs)

  def benchmark_without_function(self):
    path = data_download.main("datasets")
    kwargs = {"epochs": 6, "enable_function": False, "path": path,
              "buffer_size": 400, "batch_size": 1}
    self._run_and_report_benchmark(**kwargs)

  def _run_and_report_benchmark(self, **kwargs):
    time_list = pix2pix.main(**kwargs)
    # 1st epoch is the warmup epoch hence skipping it for calculating time.
    self.report_benchmark(wall_time=tf.reduce_mean(time_list[1:]))

if __name__ == "__main__":
  tf.test.main()


import datetime

from django.test import TestCase
from django.utils import timezone
from django.urls import reverse

from .models import Question

"""
a separate TestClass for each model or view
a separate test method for each set of conditions you want to test
test method names that describe their function
"""

#  to run use : python manage.py test polls
class QuestionModelsTests(TestCase):

    # check if published in future
    def test_was_published_recently_with_future_question(self):
        """
        was published_recently() returns False for questions whose pub_date is in the future
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

    # check if published yesterday
    def test_was_published_recently_old_future_question(self):
        """
        was_published_recently() returns False for questions whose pub_date
        is older than 1 day.
        """
        time = timezone.now() - datetime.timedelta(days=1, seconds=1)
        old_question = Question(pub_date=time)
        self.assertIs(old_question.was_published_recently(), False)

    # checking if published today
    def test_was_published_recently_with_recent_question(self):
        """
        was_published_recently() return True for questions whose pub_date is within last day
        """
        time = timezone.now() - datetime.timedelta(hours=23, minutes=59,seconds=59)
        recent_question = Question(pub_date=time)
        self.assertIs(recent_question.was_published_recently(),True)

# used to take some repetition out of the process of creating questions.
def create_question(question_text,days):
    """
    Create a question with the given `question_text` and published the
    given number of `days` offset to now (negative for questions published
    in the past, positive for questions that have yet to be published).
    """
    time = timezone.now() + datetime.timedelta(days=days)
    return Question.objects.create(question_text=question_text,pub_date=time)

class QuestionIndexViewTests(TestCase):

    # doesn’t create any questions, but checks the message: “No polls are available.” and verifies the latest_question_list is empty.
    def test_no_questions(self):
        """If no questions exist, an appropriate message is displayed"""
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code,200)
        self.assertContains(response,"No polls are available")

        # check if the list is null for no questions
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    # we create a question and verify that it appears in the list.
    def test_past_question(self):
        """Question with a pub_date in the past are displayed on the insdex page"""
        question = create_question(question_text="Past question.", days=-30)
        response = self.client.get(reverse("polls:index"))
        self.assertQuerysetEqual(
            response.context["latest_question_list"],
            [question],
        )

    # we create a question with a pub_date in the future. The database is reset for each test method,
    # so the first question is no longer there, and so again the index shouldn’t have any questions in it.
    def test_future_question(self):
        """Questions with a pub_date in the future aren't displayed on"""
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse("polls:index"))
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context["latest_question_list"], [])

    def test_future_question_and_past_question(self):
        """Evend if both past and future questions exist, only past questions are displayed"""
        question = create_question(question_text="Past question.", days=-30)
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse("polls:index"))
        self.assertQuerysetEqual(
            response.context["latest_question_list"],
            [question],
        )

    def test_two_past_questions(self):
        """The qustions index page may display multiple questions"""
        question1 = create_question(question_text="Past question 1.", days=-30)
        question2 = create_question(question_text="Past question 2.", days=-5)
        response = self.client.get(reverse("polls:index"))
        self.assertQuerysetEqual(
            response.context["latest_question_list"],
            [question2, question1],
        )

class QuestionDetailViewTests(TestCase):

    def test_future_question(self):
        """
        The detail view of a question with a pub_date in the future
        returns 404 not found.
        """
        future_question = create_question(question_text="Future question.", days=5)
        url = reverse("polls:detail", args=(future_question.id,))
        response = self.client.get(url)
        self.assertEqual(response.status_code,404)

    def test_past_question(self):
        """
        The detail view of a question with a pub_date in the past
        displays the question's text
        """
        past_question = create_question(question_text="Past Question.",days=-5)
        url = reverse("polls:detail",args=(past_question.id,))
        response = self.client.get(url)
        self.assertContains(response,past_question.question_text)


###
### <INCOMPLETE WORK>
###
### Iteration #2: attempt to separate ../face-req-v1/  logic into two parts and use threads
###  - Face Recognition handled in ./img_processing.py
###  - Communication with MQTT and WebSocket as in ../face-req-v1/
###

import logging
import time

import aiohttp
from aiohttp import web
import paho.mqtt.client as mqtt

import imutils
import pickle
import time
import cv2
import numpy as np
import io

from img_processing import ImgProcessing

# Debug
isVerbose = True
firstInstance = True

# MQTT
mqttServer = "192.168.1.41"
mqttPort = 1883
mqttTopic = "teddyCtrl"
mqttOrder = "clientOrder"
mqttClientOrder = None
mqttData = None

def on_publish(client, userdata, result):
    if(isVerbose): print("MQTT's publish ACK: client={}, result={}".format(client, result))
    pass

def get_mqttData():
    return mqttData

def set_mqttData(msg_data):
    mqttData = msg_data

# Face Recognition
frameWidth = 0
depth = None
xPos = None

encodingsP = "encodings.pickle"  #Determine faces from encodings.pickle file model created from train_model.py

def get_frameWidth():
    return frameWidth

def set_frameWidth(ww):
    frameWidth = ww

def get_xPos():
    return xPos

def set_xPos(position):
    xPos = position

def get_depth():
    return depth

def set_depth(d):
    depth = d

#
# Handle Websocket request and process image for face recognition
#
async def websocket_handler(request):
    #frame_count = 0
    #recognition_count = 0

    ws = web.WebSocketResponse()
    await ws.prepare(request)

    async for msg in ws:
        if(isVerbose): print("---------------     New WebSocket Message:     ---------------")
        if msg.type == aiohttp.WSMsgType.TEXT:
            if msg.data == 'close':
                await ws.close()
        if msg.type == aiohttp.WSMsgType.BINARY:

            # Process Image using ImgProcessing instance
            faceRecognitionProcessing.start(msg.data)

            # mqtt
            currentTime = time.time()
            #clientMQTT.connect(mqttServer, mqttPort)

            mqttClientOrder = clientMQTT.subscribe(mqttOrder)
            print("MQTT Client Order: {}".format(mqttClientOrder))
            print("MQTT to be published: {}".format(faceRecognitionProcessing.get_stringJSON_data()))

            if(mqttClientOrder in faceRecognitionProcessing.get_names()):
                mqtt_return = clientMQTT.publish(mqttTopic, faceRecognitionProcessing.get_stringJSON_data())
                logging.info("MQTT publish: done, in {0:.2g} sec.".format(time.time()-currentTime))
                if(isVerbose):
                    print("MQTT.publish return: {}".format(mqtt_return))

            # loop over the recognized faces
#
#             currentTime = time.time()
#             for ((top, right, bottom, left), name) in zip(faceRecognitionProcessing.get_boxes(), faceRecognitionProcessing.get_names()):
#                 # draw the predicted face name on the image - color is in BGR
#                 cv2.rectangle(frame, (left, top), (right, bottom),
#                         (0, 255, 225), 2)
#                 y = top - 15 if top - 15 > 15 else top + 15
#                 cv2.putText(frame, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
#                         .8, (0, 255, 255), 2)
#             logging.info("OpenCV draw rectanlges on image: done, in {0:.2g} sec.".format(time.time()-currentTime))

            # display the image to our screen
            cv2.imshow("Facial Recognition is Running", faceRecognitionProcessing.get_frame())
            #cv2.imwrite("dataset/recognitions/boxed_frame_%s.jpg" % recognition_count, frame)
            # recognition_count =  recognition_count + 1
            key = cv2.waitKey(1) & 0xFF

            # quit when 'q' key is pressed
            if key == ord("q"):
                # update the FPS counter
                fps.update()

                # stop the timer and display FPS information
                fps.stop()
                print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
                print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

                # do a bit of cleanup
                cv2.destroyAllWindows()
                #vs.stop()
                break

    print('websocket connection closed')

    return ws

# LOGGING setup
currentTime = time.time()
logging.basicConfig(format='%(asctime)s %(message)s',
#                     filename="log/raspberry4.log",
                    encoding='utf-8',
                    level=logging.DEBUG)
logging.info("[INFO] Face Recognition: loading encodings + face detector...")

# FACE RECOGNITION:
faceRecognitionProcessing = ImgProcessing()
# load the known faces and embeddings along with OpenCV's Haar cascade for face detection
logging.info("[INFO] Face Recognition: loading encodings + face detector...")
#print("[INFO] Face Recognition: loading encodings + face detector...")
data = pickle.loads(open(encodingsP, "rb").read())

# MQTT
logging.info("MQTT connecting to {}:{}...".format(mqttServer, mqttPort))
#print("[INFO] MQTT connecting to {}:{}...".format(mqttServer, mqttPort), end="")
clientMQTT = mqtt.Client()
clientMQTT.on_publish =  on_publish
clientMQTT.connect(mqttServer, mqttPort)
logging.info("MQTT connected.")
#print("MQTT connected.")

# WEBSOCKET
print("[INFO] WebSocket setup...", end="; ")
app = web.Application()
print("aiohttp application done", end="; ")
app.add_routes([web.get('/', websocket_handler)])
print("aiohttp routes added")
web.run_app(app)


import pandas as pd
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Layer, Dropout, Input, Dense
from sklearn.metrics import accuracy_score, confusion_matrix, ConfusionMatrixDisplay

url = 'C:/Users/johnn/OneDrive/Documentos/Deep Learning/Deep Learning com Python de A a Z - O Curso Completo/base_dados/wdbc.data'
cancer = datasets.load_breast_cancer()
dados = pd.read_csv(url, header=None)

entradas = dados.iloc[:,2:]
entradas.columns = cancer.feature_names
saidas = dados.iloc[:,1]

X = dados.iloc[:,2:].values
y = dados.iloc[:,1].replace('M', 1).replace('B', 0).values

# Divisão da base de dados em treino e teste
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)

# Rede Neural
classificador = Sequential()
classificador.add(Input(shape=30, name='Camada_entrada'))
classificador.add(Dense(units=16, activation='relu', kernel_initializer='uniform', name='Camada_oculta0'))
classificador.add(Dropout(rate=0.2, name='Camada_dropout0'))
classificador.add(Dense(units=1, activation='sigmoid', name='Camada_saida'))

classificador.compile(optimizer='adam', loss='binary_crossentropy', metrics=['binary_accuracy'])

classificador.fit(X_train, y_train, batch_size=10, epochs=100)
previsoes = classificador.predict(X_test) > 0.7
previsoes = previsoes.astype(int)

# Métricas de avaliação
accuracia1 = classificador.evaluate(X_test, y_test)
accuracia2 = accuracy_score(y_test, previsoes)

grafico = ConfusionMatrixDisplay(confusion_matrix(y_test, previsoes))
grafico.plot()


#!/usr/bin/python
# -*- coding: utf-8 -*-

""" Annotations for instance attributes, functions arguments, etc.
"""

import sys
import operator
import collections.abc
import logging
import typing

logging.getLogger().addHandler(logging.NullHandler())

T = typing.TypeVar('T')  # pylint: disable=invalid-name

@typing.runtime_checkable
class SupportsDescription(typing.Protocol):
    """ An ABC with description attribute of type string.

    Can be used with ``isinstance`` to check whether object contains such attribute.
    Supposed for using with custom enums in meta modules.
    """
    description: str

class Description:
    """ Description for attribute's or function argument's annotation

    ``description`` can be used for wide description.

    ``short_description`` can be used for short description, e.g. for label of input in HTML form.
    """
    description: str
    short_description: str = None

    def __init__(self, description: str, short_description: str = None):
        """ Initialize description.

        :param description: Description of attribute or argument.
        :param short_description: Short description (optional).
        """
        self.description = str(description)
        self.short_description = None if short_description is None else str(short_description)

class Volatile:
    """ Describes attribute or function argument which value even through not optional,
    but can be reevaluated each time when uses for instantiation or function calling.

    For example: some source demands interval [date_from; date_to] for download history data,
    but we need to download it every day. So we store this interval somewhere in configuration
    and mark date_to as ``Volatile`` with reevaluating as ``date.today()``
    every time we fetch parameters from configuration.
    Thus, interval widened every day without modifying configuration.

    ::

        class Params:
            isin: str
            date_from: datetime.date
            date_to: Annotated[datetime.date, Volatile(lambda ctx: datetime.date.today(), datetime.date.max)]
    """

    def __init__(self,
                 generator: typing.Callable[[typing.Dict[str, typing.Any]], T],
                 stub_value: T = None):
        """ Initialize volatile annotation.

        :param generator: Function for reevaluating;
                          takes context of instantiation or function calling (like ``kwargs``)
                          and returns new value of attribute.
        :param stub_value: Stub value for not optional attributes.
        """
        if not callable(generator):
            raise TypeError("generator is not callable")

        self.generator = generator
        self.stub_value = stub_value

    def generate(self, context: typing.Dict[str, typing.Any]) -> T:
        """ Generate actual value of attribute or function argument based on context.

        :param context: Context of instantiation or function calling (like ``kwargs``)
        :return: Actual value of volatile attribute.
        """
        return self.generator(context)

# Support legacy 3.8 version:
# Got from https://github.com/python/typing (typing_extensions module)

# After PEP 560, internal typing API was substantially reworked.
# This is especially important for Protocol class which uses internal APIs
# quite extensively.
PEP_560 = sys.version_info[:3] >= (3, 7, 0)

try:  # pragma: no cover
    # noinspection PyProtectedMember
    from typing import _tp_cache
except ImportError:  # pragma: no cover
    def _tp_cache(x):  # pylint: disable=invalid-name
        return x

LEGACY_ANNOTATIONS = True  # flag about legacy python version

# Python 3.9+ has PEP 593 (Annotated and modified get_type_hints)
if hasattr(typing, 'Annotated'):  # pragma: no cover

    Annotated = typing.Annotated
    get_type_hints = typing.get_type_hints

    # Not exported and not a public API, but needed for get_origin() and get_args()
    # to work.
    # noinspection PyUnresolvedReferences,PyProtectedMember
    _AnnotatedAlias = typing._AnnotatedAlias

    LEGACY_ANNOTATIONS = False

elif PEP_560:  # pragma: no cover

    # noinspection PyUnresolvedReferences,PyProtectedMember
    class _AnnotatedAlias(typing._GenericAlias, _root=True):
        # pylint: disable=consider-using-f-string
        """Runtime representation of an annotated type.
        At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'
        with extra annotations. The alias behaves like a normal typing alias,
        instantiating is the same as instantiating the underlying type, binding
        it to types is also the same.
        """
        def __init__(self, origin, metadata):
            if isinstance(origin, _AnnotatedAlias):
                metadata = origin.__metadata__ + metadata
                origin = origin.__origin__
            super().__init__(origin, origin)
            self.__metadata__ = metadata

        def copy_with(self, params):
            assert len(params) == 1
            new_type = params[0]
            return _AnnotatedAlias(new_type, self.__metadata__)

        def __repr__(self):
            return "typing_extensions.Annotated[{}, {}]".format(
                typing._type_repr(self.__origin__),
                ", ".join(repr(a) for a in self.__metadata__)
            )

        def __reduce__(self):
            return operator.getitem, (
                Annotated, (self.__origin__,) + self.__metadata__
            )

        def __eq__(self, other):
            if not isinstance(other, _AnnotatedAlias):
                return NotImplemented
            if self.__origin__ != other.__origin__:
                return False
            return self.__metadata__ == other.__metadata__

        def __hash__(self):
            return hash((self.__origin__, self.__metadata__))

    class Annotated:
        # pylint: disable=consider-using-f-string
        """Add context specific metadata to a type.
        Example: Annotated[int, runtime_check.Unsigned] indicates to the
        hypothetical runtime_check module that this type is an unsigned int.
        Every other consumer of this type can ignore this metadata and treat
        this type as int.
        The first argument to Annotated must be a valid type (and will be in
        the __origin__ field), the remaining arguments are kept as a tuple in
        the __extra__ field.
        Details:
        - It's an error to call `Annotated` with less than two arguments.
        - Nested Annotated are flattened::
            Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]
        - Instantiating an annotated type is equivalent to instantiating the
        underlying type::
            Annotated[C, Ann1](5) == C(5)
        - Annotated can be used as a generic type alias::
            Optimized = Annotated[T, runtime.Optimize()]
            Optimized[int] == Annotated[int, runtime.Optimize()]
            OptimizedList = Annotated[List[T], runtime.Optimize()]
            OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
        """

        __slots__ = ()

        def __new__(cls, *args, **kwargs):
            raise TypeError("Type Annotated cannot be instantiated.")

        @_tp_cache
        def __class_getitem__(cls, params):
            if not isinstance(params, tuple) or len(params) < 2:
                raise TypeError("Annotated[...] should be used "
                                "with at least two arguments (a type and an "
                                "annotation).")
            msg = "Annotated[t, ...]: t must be a type."
            # noinspection PyUnresolvedReferences,PyProtectedMember
            origin = typing._type_check(params[0], msg)
            metadata = tuple(params[1:])
            return _AnnotatedAlias(origin, metadata)

        def __init_subclass__(cls, *args, **kwargs):
            raise TypeError(
                "Cannot subclass {}.Annotated".format(cls.__module__)
            )

    def _strip_annotations(t):  # pylint: disable=invalid-name
        """Strips the annotations from a given type.
        """
        if isinstance(t, _AnnotatedAlias):
            return _strip_annotations(t.__origin__)
        # noinspection PyUnresolvedReferences,PyProtectedMember
        if isinstance(t, typing._GenericAlias):
            stripped_args = tuple(_strip_annotations(a) for a in t.__args__)
            if stripped_args == t.__args__:
                return t
            res = t.copy_with(stripped_args)
            # noinspection PyProtectedMember
            res._special = t._special
            return res
        return t

    def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
        """Return type hints for an object.
        This is often the same as obj.__annotations__, but it handles
        forward references encoded as string literals, adds Optional[t] if a
        default value equal to None is set and recursively replaces all
        'Annotated[T, ...]' with 'T' (unless 'include_extras=True').
        The argument may be a module, class, method, or function. The annotations
        are returned as a dictionary. For classes, annotations include also
        inherited members.
        TypeError is raised if the argument is not of a type that can contain
        annotations, and an empty dictionary is returned if no annotations are
        present.
        BEWARE -- the behavior of globalns and localns is counterintuitive
        (unless you are familiar with how eval() and exec() work).  The
        search order is locals first, then globals.
        - If no dict arguments are passed, an attempt is made to use the
          globals from obj (or the respective module's globals for classes),
          and these are also used as the locals.  If the object does not appear
          to have globals, an empty dictionary is used.
        - If one dict argument is passed, it is used for both globals and
          locals.
        - If two dict arguments are passed, they specify globals and
          locals, respectively.
        """
        hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
        if include_extras:
            return hint
        return {k: _strip_annotations(t) for k, t in hint.items()}

# Python 3.8 has get_origin() and get_args() but those implementations aren't
# Annotated-aware, so we can't use those, only Python 3.9 versions will do.
if sys.version_info[:2] >= (3, 9):  # pragma: no cover

    get_origin = typing.get_origin
    get_args = typing.get_args

elif PEP_560:  # pragma: no cover

    # noinspection PyUnresolvedReferences,PyProtectedMember
    from typing import _GenericAlias
    try:
        # 3.9+
        # noinspection PyProtectedMember
        from typing import _BaseGenericAlias
    except ImportError:
        _BaseGenericAlias = _GenericAlias
    try:
        # 3.9+
        from typing import GenericAlias
    except ImportError:
        GenericAlias = _GenericAlias

    def get_origin(tp):  # pylint: disable=invalid-name
        """Get the unsubscripted version of a type.

        This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
        and Annotated. Return None for unsupported types. Examples::

            get_origin(Literal[42]) is Literal
            get_origin(int) is None
            get_origin(ClassVar[int]) is ClassVar
            get_origin(Generic) is Generic
            get_origin(Generic[T]) is Generic
            get_origin(Union[T, int]) is Union
            get_origin(List[Tuple[T, T]][int]) == list
        """
        if isinstance(tp, _AnnotatedAlias):
            return Annotated
        if isinstance(tp, (_BaseGenericAlias, GenericAlias)):
            return tp.__origin__
        if tp is typing.Generic:
            return typing.Generic
        return None

    def get_args(tp):  # pylint: disable=invalid-name
        """Get type arguments with all substitutions performed.

        For unions, basic simplifications used by Union constructor are performed.
        Examples::
            get_args(Dict[str, int]) == (str, int)
            get_args(int) == ()
            get_args(Union[int, Union[T, int], str][int]) == (int, str)
            get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
            get_args(Callable[[], T][int]) == ([], int)
        """
        if isinstance(tp, _AnnotatedAlias):
            return (tp.__origin__,) + tp.__metadata__
        if isinstance(tp, (_GenericAlias, GenericAlias)):
            res = tp.__args__
            if tp.__origin__ is collections.abc.Callable and res[0] is not Ellipsis:
                res = (list(res[:-1]), res[-1])
            return res
        return ()


"""
The web application which will interact with users and control the underlying hardware
# https://towardsdatascience.com/python-webserver-with-flask-and-raspberry-pi-398423cc6f5d
"""
import datetime

from flask import Flask, render_template

from relay import Relay
from tempsensor import TemperatureSensor

flaskApp = Flask("JitterServer")

class JitterServer:
    _indexHtmlPath = "index.html"
    def __init__(self,
                heaterSensor: TemperatureSensor,
                heaterRelay: Relay,
                pump1Relay: Relay,
                pump2Relay: Relay):
        self._heaterSensor = heaterSensor
        self._heaterRelay = heaterRelay
        self._pump1Relay = pump1Relay
        self._pump2Relay = pump2Relay

    def index(self):
        now = datetime.datetime.now()
        timeString = now.strftime("%Y-%m-%d %H:%M:%S")
        templateData = {
                "title": "Jitter Server",
                "time": timeString,
                "isPump1On": self._pump1Relay.isRunning(),
        }
        return render_template(self._indexHtmlPath, **templateData)

class GlobalContainer:
    jitterServer = None

@flaskApp.route("/")
def index():
    return GlobalContainer.jitterServer.index()

@flaskApp.route("/pump1/startcycle", methods=["GET", "POST"])
def pump1StartCycle():
    didStart = GlobalContainer.jitterServer._pump1Relay.startCycle()
    return index()

@flaskApp.route("/pump1/killcycle", methods=["GET", "POST"])
def pump1KillCycle():
    didKill = GlobalContainer.jitterServer._pump1Relay.killCycle()
    return index()

def runJitterServer(heaterSensor, heaterRelay, pump1Relay, pump2Relay,
        port, shouldDebug):
    GlobalContainer.jitterServer = JitterServer(heaterSensor, heaterRelay,
            pump1Relay, pump2Relay)
    localhost = "0.0.0.0"
    flaskApp.run(debug=shouldDebug, port=port, host=localhost)


import os
import argparse
from PIL import Image
from tqdm import tqdm

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset
from torchvision.models import inception_v3
from torchvision import transforms
from torch.utils.data import DataLoader

class ImageDataset(Dataset):
    def __init__(self, directory, transform=None):
        self.directory = directory
        self.image_paths = sorted(os.listdir(directory))
        self.transform = transform

    def __len__(self):
        return len(self.image_paths)

    def __getitem__(self, index):
        image_path = os.path.join(self.directory, self.image_paths[index])
        image = Image.open(image_path).convert("RGB")

        if self.transform is not None:
            image = self.transform(image)

        return image

# Inception Scoreの計算
def compute_inception_score(generated_loader, inception_model, device):
    scores = []
    for batch in tqdm(generated_loader):
        batch = batch.to(device)
        batch = preprocess(batch)
        with torch.no_grad():
            # Inception Scoreの計算
            logits = inception_model(batch)
            probabilities = F.softmax(logits, dim=1)
            kl_divergence = torch.mean(
                torch.sum(
                    probabilities
                    * (
                        torch.log(probabilities)
                        - torch.log(torch.mean(probabilities, dim=0, keepdim=True))
                    ),
                    dim=1,
                )
            )
            score = torch.exp(kl_divergence)
            scores.append(score)

    scores = torch.stack(scores, dim=0)
    return scores.mean(), scores.std()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "--img_dir", type=str, required=True, help="img directory for evaluation"
    )
    args = parser.parse_args()

    # 生成された画像の確率分布を評価するためのデータセット
    # img_dir = "results/trans/trans64_dir_404to817_t500_run0"
    img_dir = args.img_dir
    generated_dataset = ImageDataset(directory=img_dir, transform=transforms.ToTensor())

    # Inceptionモデルの読み込みと前処理
    inception_model = inception_v3(pretrained=True, transform_input=False)
    inception_model.eval()
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    inception_model.to(device)

    # データローダーの設定
    batch_size = 64  # 適宜調整してください
    num_workers = 1  # 適宜調整してください
    generated_loader = DataLoader(
        generated_dataset, batch_size=batch_size, shuffle=False, num_workers=num_workers
    )

    # 画像の前処理
    preprocess = transforms.Compose(
        [
            transforms.Resize(299),
            # transforms.ToTensor(),
        ]
    )

    # Inception Scoreの計算結果の取得
    inception_score, inception_score_std = compute_inception_score(
        generated_loader, inception_model, device
    )
    print(
        "Inception Score: {:.2f} +/- {:.2f}".format(
            inception_score, inception_score_std
        )
    )


import codecs
from collections import Counter
import os
import glob
from textblob import TextBlob as tb
import math

def tf(word, blob):
	return (float)(blob.words.count(word)) / (float)(len(blob.words))

def n_containing(word, bloblist):
	return sum(1 for blob in bloblist if word in blob.words)

def idf(word, bloblist):
	return (float)(math.log(len(bloblist)) / (float)(1 + n_containing(word, bloblist)))

def tfidf(word, blob, bloblist):
	return tf(word, blob) * idf(word, bloblist)

words_list = []
stop = []
spam_bloblist = []
ham_bloblist = []
words_dict = {}
splsym = ["-",",","!","#","%","^","&","*","(",")","!", ":",".","{","}", "[","]",">","<","?","/", "*","~", "@"]

print(splsym)

stop_words = open("Stop_words.txt").read()
for line in stop_words:
	for word in line.split(' '):
		stop.append(word)

stop_string = ''.join(stop)

path_to_spam = "hw2_train/train/spam/*.txt"
path_to_ham = "hw2_train/train/ham/*.txt"

for file in glob.glob(path_to_spam):
	file_words = codecs.open(file, "r", encoding='utf-8', errors='ignore' )
	for line in file_words:
		for word in line.split():
			if not word in stop_string and not word in splsym and not word.isdigit():
				words_list.append(word)
	blob = tb(' '.join(words_list))
	spam_bloblist.append(blob)
	words_list = []

#print(spam_bloblist[3] + "\n")

for file in glob.glob(path_to_ham):
	file_words = codecs.open(file, "r", encoding='utf-8', errors='ignore' )
	for line in file_words:
		for word in line.split():
			if not word in stop_string and not word in splsym and not word.isdigit():
				words_list.append(word)
	blob = tb(' '.join(words_list))
	ham_bloblist.append(blob)
	words_list = []

prior_spam_probability = (len(spam_bloblist)) / (len(spam_bloblist) + len(ham_bloblist))

prior_ham_probability = 1.0 - prior_spam_probability

# for i, blob in enumerate(bloblist):

#print(ham_bloblist[3])

# for i in words:
# 	if not i in words_dict.keys():
# 		count = blob.words.count(i)
# 		words_dict[i] = count

spam_tfidf_dict = {}

for i, blob in enumerate(spam_bloblist):
	#print("Top words in document {}".format(i+1))
	scores = {word: tfidf(word, blob, spam_bloblist) for word in blob.words}
	sorted_words = sorted(scores.items(), key=lambda x: x[1], reverse=True)
	for word, score in sorted_words[:]:
	 	#print("\tWord: {}, TF-IDF: {}".format(word, round(score, 3)))
	 	if word in spam_tfidf_dict:
	 		spam_tfidf_dict[word] += round(score,3)
	 	else:
	 		spam_tfidf_dict[word] = round(score,3)

ham_tfidf_dict = {}

for i, blob in enumerate(ham_bloblist):
	print("Top words in document {}".format(i+1))
	scores = {word: tfidf(word, blob, ham_bloblist) for word in blob.words}
	sorted_words = sorted(scores.items(), key=lambda x: x[1], reverse=True)
	for word, score in sorted_words[:]:
	 	print("\tWord: {}, TF-IDF: {}".format(word, round(score, 3)))
	 	if word in ham_tfidf_dict:
	 		ham_tfidf_dict[word] += round(score,3)
	 	else:
	 		ham_tfidf_dict[word] = round(score,3)

# for i in words_dict.keys():
# # 	if words_dict[i] > 15:
# 	print(i, words_dict[i])


"""Sagemaker InvokeEndpoint API."""
import io
import json
from abc import abstractmethod
from typing import Any, Dict, Generic, Iterator, List, Mapping, Optional, TypeVar, Union

from langchain_core.callbacks import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM
from langchain_core.pydantic_v1 import Extra, root_validator

from langchain_community.llms.utils import enforce_stop_tokens

INPUT_TYPE = TypeVar("INPUT_TYPE", bound=Union[str, List[str]])
OUTPUT_TYPE = TypeVar("OUTPUT_TYPE", bound=Union[str, List[List[float]], Iterator])

class LineIterator:
    """
    A helper class for parsing the byte stream input.

    The output of the model will be in the following format:

    b'{"outputs": [" a"]}\n'
    b'{"outputs": [" challenging"]}\n'
    b'{"outputs": [" problem"]}\n'
    ...

    While usually each PayloadPart event from the event stream will
    contain a byte array with a full json, this is not guaranteed
    and some of the json objects may be split acrossPayloadPart events.

    For example:

    {'PayloadPart': {'Bytes': b'{"outputs": '}}
    {'PayloadPart': {'Bytes': b'[" problem"]}\n'}}

    This class accounts for this by concatenating bytes written via the 'write' function
    and then exposing a method which will return lines (ending with a '\n' character)
    within the buffer via the 'scan_lines' function.
    It maintains the position of the last read position to ensure
    that previous bytes are not exposed again.

    For more details see:
    https://aws.amazon.com/blogs/machine-learning/elevating-the-generative-ai-experience-introducing-streaming-support-in-amazon-sagemaker-hosting/
    """

    def __init__(self, stream: Any) -> None:
        self.byte_iterator = iter(stream)
        self.buffer = io.BytesIO()
        self.read_pos = 0

    def __iter__(self) -> "LineIterator":
        return self

    def __next__(self) -> Any:
        while True:
            self.buffer.seek(self.read_pos)
            line = self.buffer.readline()
            if line and line[-1] == ord("\n"):
                self.read_pos += len(line)
                return line[:-1]
            try:
                chunk = next(self.byte_iterator)
            except StopIteration:
                if self.read_pos < self.buffer.getbuffer().nbytes:
                    continue
                raise
            if "PayloadPart" not in chunk:
                # Unknown Event Type
                continue
            self.buffer.seek(0, io.SEEK_END)
            self.buffer.write(chunk["PayloadPart"]["Bytes"])

class ContentHandlerBase(Generic[INPUT_TYPE, OUTPUT_TYPE]):
    """A handler class to transform input from LLM to a
    format that SageMaker endpoint expects.

    Similarly, the class handles transforming output from the
    SageMaker endpoint to a format that LLM class expects.
    """

    """
    Example:
        .. code-block:: python

            class ContentHandler(ContentHandlerBase):
                content_type = "application/json"
                accepts = "application/json"

                def transform_input(self, prompt: str, model_kwargs: Dict) -> bytes:
                    input_str = json.dumps({prompt: prompt, **model_kwargs})
                    return input_str.encode('utf-8')

                def transform_output(self, output: bytes) -> str:
                    response_json = json.loads(output.read().decode("utf-8"))
                    return response_json[0]["generated_text"]
    """

    content_type: Optional[str] = "text/plain"
    """The MIME type of the input data passed to endpoint"""

    accepts: Optional[str] = "text/plain"
    """The MIME type of the response data returned from endpoint"""

    @abstractmethod
    def transform_input(self, prompt: INPUT_TYPE, model_kwargs: Dict) -> bytes:
        """Transforms the input to a format that model can accept
        as the request Body. Should return bytes or seekable file
        like object in the format specified in the content_type
        request header.
        """

    @abstractmethod
    def transform_output(self, output: bytes) -> OUTPUT_TYPE:
        """Transforms the output from the model to string that
        the LLM class expects.
        """

class LLMContentHandler(ContentHandlerBase[str, str]):
    """Content handler for LLM class."""

class SagemakerEndpoint(LLM):
    """Sagemaker Inference Endpoint models.

    To use, you must supply the endpoint name from your deployed
    Sagemaker model & the region where it is deployed.

    To authenticate, the AWS client uses the following methods to
    automatically load credentials:
    https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html

    If a specific credential profile should be used, you must pass
    the name of the profile from the ~/.aws/credentials file that is to be used.

    Make sure the credentials / roles used have the required policies to
    access the Sagemaker endpoint.
    See: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
    """

    """
    Args:

        region_name: The aws region e.g., `us-west-2`.
            Fallsback to AWS_DEFAULT_REGION env variable
            or region specified in ~/.aws/config.

        credentials_profile_name: The name of the profile in the ~/.aws/credentials
            or ~/.aws/config files, which has either access keys or role information
            specified. If not specified, the default credential profile or, if on an
            EC2 instance, credentials from IMDS will be used.

        client: boto3 client for Sagemaker Endpoint

        content_handler: Implementation for model specific LLMContentHandler

    Example:
        .. code-block:: python

            from langchain_community.llms import SagemakerEndpoint
            endpoint_name = (
                "my-endpoint-name"
            )
            region_name = (
                "us-west-2"
            )
            credentials_profile_name = (
                "default"
            )
            se = SagemakerEndpoint(
                endpoint_name=endpoint_name,
                region_name=region_name,
                credentials_profile_name=credentials_profile_name
            )

        #Use with boto3 client
            client = boto3.client(
                        "sagemaker-runtime",
                        region_name=region_name
                    )

            se = SagemakerEndpoint(
                endpoint_name=endpoint_name,
                client=client
            )

    """
    client: Any = None
    """Boto3 client for sagemaker runtime"""

    endpoint_name: str = ""
    """The name of the endpoint from the deployed Sagemaker model.
    Must be unique within an AWS Region."""

    region_name: str = ""
    """The aws region where the Sagemaker model is deployed, eg. `us-west-2`."""

    credentials_profile_name: Optional[str] = None
    """The name of the profile in the ~/.aws/credentials or ~/.aws/config files, which
    has either access keys or role information specified.
    If not specified, the default credential profile or, if on an EC2 instance,
    credentials from IMDS will be used.
    See: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html
    """

    content_handler: LLMContentHandler
    """The content handler class that provides an input and
    output transform functions to handle formats between LLM
    and the endpoint.
    """

    streaming: bool = False
    """Whether to stream the results."""

    """
     Example:
        .. code-block:: python

        from langchain_community.llms.sagemaker_endpoint import LLMContentHandler

        class ContentHandler(LLMContentHandler):
                content_type = "application/json"
                accepts = "application/json"

                def transform_input(self, prompt: str, model_kwargs: Dict) -> bytes:
                    input_str = json.dumps({prompt: prompt, **model_kwargs})
                    return input_str.encode('utf-8')

                def transform_output(self, output: bytes) -> str:
                    response_json = json.loads(output.read().decode("utf-8"))
                    return response_json[0]["generated_text"]
    """

    model_kwargs: Optional[Dict] = None
    """Keyword arguments to pass to the model."""

    endpoint_kwargs: Optional[Dict] = None
    """Optional attributes passed to the invoke_endpoint
    function. See `boto3`_. docs for more info.
    .. _boto3: <https://boto3.amazonaws.com/v1/documentation/api/latest/index.html>
    """

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

        extra = Extra.forbid

    @root_validator()
    def validate_environment(cls, values: Dict) -> Dict:
        """Dont do anything if client provided externally"""
        if values.get("client") is not None:
            return values

        """Validate that AWS credentials to and python package exists in environment."""
        try:
            import boto3

            try:
                if values["credentials_profile_name"] is not None:
                    session = boto3.Session(
                        profile_name=values["credentials_profile_name"]
                    )
                else:
                    # use default credentials
                    session = boto3.Session()

                values["client"] = session.client(
                    "sagemaker-runtime", region_name=values["region_name"]
                )

            except Exception as e:
                raise ValueError(
                    "Could not load credentials to authenticate with AWS client. "
                    "Please check that credentials in the specified "
                    "profile name are valid."
                ) from e

        except ImportError:
            raise ImportError(
                "Could not import boto3 python package. "
                "Please install it with `pip install boto3`."
            )
        return values

    @property
    def _identifying_params(self) -> Mapping[str, Any]:
        """Get the identifying parameters."""
        _model_kwargs = self.model_kwargs or {}
        return {
            **{"endpoint_name": self.endpoint_name},
            **{"model_kwargs": _model_kwargs},
        }

    @property
    def _llm_type(self) -> str:
        """Return type of llm."""
        return "sagemaker_endpoint"

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        """Call out to Sagemaker inference endpoint.

        Args:
            prompt: The prompt to pass into the model.
            stop: Optional list of stop words to use when generating.

        Returns:
            The string generated by the model.

        Example:
            .. code-block:: python

                response = se("Tell me a joke.")
        """
        _model_kwargs = self.model_kwargs or {}
        _model_kwargs = {**_model_kwargs, **kwargs}
        _endpoint_kwargs = self.endpoint_kwargs or {}

        body = self.content_handler.transform_input(prompt, _model_kwargs)
        content_type = self.content_handler.content_type
        accepts = self.content_handler.accepts

        if self.streaming and run_manager:
            try:
                resp = self.client.invoke_endpoint_with_response_stream(
                    EndpointName=self.endpoint_name,
                    Body=body,
                    ContentType=self.content_handler.content_type,
                    **_endpoint_kwargs,
                )
                iterator = LineIterator(resp["Body"])
                current_completion: str = ""
                for line in iterator:
                    resp = json.loads(line)
                    resp_output = resp.get("outputs")[0]
                    if stop is not None:
                        # Uses same approach as below
                        resp_output = enforce_stop_tokens(resp_output, stop)
                    current_completion += resp_output
                    run_manager.on_llm_new_token(resp_output)
                return current_completion
            except Exception as e:
                raise ValueError(f"Error raised by streaming inference endpoint: {e}")
        else:
            try:
                response = self.client.invoke_endpoint(
                    EndpointName=self.endpoint_name,
                    Body=body,
                    ContentType=content_type,
                    Accept=accepts,
                    **_endpoint_kwargs,
                )
            except Exception as e:
                raise ValueError(f"Error raised by inference endpoint: {e}")

            text = self.content_handler.transform_output(response["Body"])
            if stop is not None:
                # This is a bit hacky, but I can't figure out a better way to enforce
                # stop tokens when making calls to the sagemaker endpoint.
                text = enforce_stop_tokens(text, stop)

            return text


from typing import List, Optional

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from app.api.depends import get_db
from app.schemas.appointments import Appointments, AppointmentsCreate, AppointmentsUpdate, AppointmentsRequest
from app.service import appointments_service, medcard_service

router = APIRouter()

@router.get("/", response_model=List[Appointments])
def get_all_appointments(db: Session = Depends(get_db)):
    appointments = appointments_service.get_all_appointments(db=db)
    return appointments

@router.get("/{appointment_id}", response_model=Optional[Appointments])
def get_appointment_by_id(appointment_id: int, db: Session = Depends(get_db)):
    appointmetns = appointments_service.get_appointment_by_id(db=db, appointment_id=appointment_id)
    return appointmetns

@router.post("/", response_model=Appointments)
def create_appointment(appointment_request: AppointmentsRequest, db: Session = Depends(get_db)):
    medcard = medcard_service.get_medcard_by_passport_number(db=db, passportNumber=appointment_request.passportNumber)
    appointment_create = AppointmentsCreate(
        medcard_id=medcard.id,
        user_id=appointment_request.user_id,
        date=appointment_request.date,
        time=appointment_request.time,
        email=appointment_request.email
    )
    appointment = appointments_service.create_appointment(db=db, appointment_create=appointment_create)
    return appointment

@router.delete("/{appointment_id}", response_model=Appointments)
def delete_appointment(appointment_id: int, db: Session = Depends(get_db)):
    appointment = appointments_service.delete_appointment(db=db, appointment_id=appointment_id)
    return appointment