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

petasco = Tk()

petasco.title('KFC ONLINE FOOD ORDERING')
petasco.geometry('1300x700')
petasco.config(bg='#F0F8FF')
introlbl = Label(petasco, text='WELCOME TO PETASCO KFC', font=('algeria', 28, 'bold'), bg='blue', fg='gold', width=55)
introlbl.place(x=15, y=1)

# --------------------------------------------------- customer info label -----------------------------------------------------------
Label(petasco,
      text='================================= Customer Info =================================',
      font=('Arial', 15, 'bold'), bg='#F0F8FF').place(x=160, y=60)

customerlbl = Label(petasco, text='Customer Name:', font=('times', 13, 'bold'), bg='#F0F8FF')
customerlbl.place(x=15, y=90)

customerName_var = StringVar()
customer_entry = Entry(petasco, textvariable=customerName_var, font=('times', 13, 'bold'), bd=2)
customer_entry.focus()
customer_entry.place(x=145, y=90)

customerPhone = Label(petasco, text='Phone No:', font=('times', 13, 'bold'), bg='#F0F8FF')
customerPhone.place(x=350, y=90)
customerPhone_var = StringVar()
phone_entry = Entry(petasco, textvariable=customerPhone_var, font=('times', 13, 'bold'), bd=2)
phone_entry.place(x=430, y=90)

billNo_lbl = Label(petasco, text='Bill No:', font=('Arial', 13, 'bold'), bg='#F0F8FF')
billNo_lbl.place(x=630, y=90)
customerBill_var = StringVar()
bill_entry = Entry(petasco, textvariable=customerBill_var, font=('times', 13, 'bold'), bd=2)
bill_entry.place(x=690, y=90)

customerAddress = Label(petasco, text='Customer Address: ', font=('Arial', 13, 'bold'), bg='#F0F8FF')
customerAddress.place(x=890, y=90)
customerAddress_var = StringVar()
customerAddress_en = Entry(petasco, textvariable=customerAddress_var, font=('times', 13, 'bold'), bd=2)
customerAddress_en.place(x=1050, y=90)
# ----------------------------------------------Food  Menu ---------------------------------------------------------------------------

Fmenu_lbl = Label(petasco, text='============FOOD MENU============', font=('times', 14, 'bold'), bg='#F0F8FF')
Fmenu_lbl.place(y=120, x=15)
# ------------------------------ Items label -------------------------------
items = Label(petasco, text='ITEM', font=('times', 13, 'bold'), bg='#F0F8FF')
items.place(y=150, x=20)
# ====================================================================================
chicken_lbl = Label(petasco, text='Chicken', font=('times', 13, 'bold'), bg='#F0F8FF')
chicken_lbl.place(x=20, y=180)

imagechicken = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\chicken.jpg'))
chickenpic_lbl = Label(petasco, image=imagechicken)
chickenpic_lbl.place(x=110, y=180)

chicken_price = Label(text='$5.0', font=('times', 13, 'bold'), bg='#F0F8FF')
chicken_price.place(y=180, x=180)

chickenVar = IntVar()
chicken_qty = Entry(petasco, textvariable=chickenVar, font=('times', 13, 'bold'), bd=2, width=7)
chicken_qty.place(y=180, x=300)
# chicken = int(chicken_qty.get())

# =========================================================================================

# ====================================================================================

pizza_lbl = Label(petasco, text='Pizza', font=('times', 13, 'bold'), bg='#F0F8FF')
pizza_lbl.place(x=20, y=220)
image = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\Pizzaa.jpg'))
pizzapic_lbl = Label(petasco, image=image)
pizzapic_lbl.place(x=110, y=220, height=35)
pizzapic_lbl['compound'] = tk.RIGHT

pizza_price = Label(text='$10.0', font=('times', 13, 'bold'), bg='#F0F8FF')
pizza_price.place(y=220, x=180)

pizzaVar = IntVar()
pizza_qty = Entry(petasco, textvariable=pizzaVar, font=('times', 13, 'bold'), bd=2, width=7)
pizza_qty.place(y=220, x=300)

# =========================================================================================
friesvar = DoubleVar()
fries_lbl = Label(petasco, text='Fries', font=('times', 13, 'bold'), bg='#F0F8FF')
fries_lbl.place(x=20, y=260)

imagefries = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\fries.jpg'))
friespic_lbl = Label(petasco, image=imagefries)
friespic_lbl.place(x=110, y=260)

fries_price = Label(text='$2.0', font=('times', 13, 'bold'), bg='#F0F8FF')
fries_price.place(y=260, x=180)

fries_qty = Entry(petasco, textvariable=friesvar, font=('times', 13, 'bold'), bd=2, width=7)
fries_qty.place(y=260, x=300)

# =========================================================================================

# ====================================================================================
ice_lbl = Label(petasco, text='Ice Cream', font=('times', 13, 'bold'), bg='#F0F8FF')
ice_lbl.place(x=20, y=300)

imageice = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\icecream.jpg'))
icepic_lbl = Label(petasco, image=imageice)
icepic_lbl.place(x=110, y=300)

ice_price = Label(text='$3.5', font=('times', 13, 'bold'), bg='#F0F8FF')
ice_price.place(y=300, x=180)
icevar = DoubleVar()
ice_qty = Entry(petasco, textvariable=icevar, font=('times', 13, 'bold'), bd=2, width=7)
ice_qty.place(y=300, x=300)

# ice_sum = 3 * int(ice_qty)
# =========================================================================================

# ====================================================================================
cheese_lbl = Label(petasco, text='Cheese', font=('times', 13, 'bold'), bg='#F0F8FF')
cheese_lbl.place(x=20, y=340)

imagecheese = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\cheese.jpg'))
cheesepic_lbl = Label(petasco, image=imagecheese)
cheesepic_lbl.place(x=110, y=340)

cheese_price = Label(text='$5.0', font=('times', 13, 'bold'), bg='#F0F8FF')
cheese_price.place(y=340, x=180)
cheesevar = DoubleVar()
cheese_qty = Entry(petasco, textvariable=cheesevar, font=('times', 13, 'bold'), bd=2, width=7)
cheese_qty.place(y=340, x=300)

# cheese_sum = 5 * int(cheese_qty)
# =========================================================================================

# ====================================================================================
sand_lbl = Label(petasco, text='Gob3', font=('times', 13, 'bold'), bg='#F0F8FF')
sand_lbl.place(x=20, y=380)

pic = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\gob33.jpg'))
pic_lbl = Label(petasco, image=pic)
pic_lbl.place(x=110, y=380)

sand_price = Label(text='$2.5', font=('times', 13, 'bold'), bg='#F0F8FF')
sand_price.place(y=380, x=180)
sandvar = DoubleVar()
sand_qty = Entry(petasco, textvariable=sandvar, font=('times', 13, 'bold'), bd=2, width=7)
sand_qty.place(y=380, x=300)

# sand_sum = 2.5 * int(sand_qty)
# =========================================================================================

# ====================================================================================
fufu_lbl = Label(petasco, text='Waakye', font=('times', 13, 'bold'), bg='#F0F8FF')
fufu_lbl.place(x=20, y=420)

imagewaakye = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\waakye.jpg'))
waakyepic_lbl = Label(petasco, image=imagewaakye)
waakyepic_lbl.place(x=110, y=420)

fufu_price = Label(text='$1.5', font=('times', 13, 'bold'), bg='#F0F8FF')
fufu_price.place(y=420, x=180)
futuvar = DoubleVar()
fufu_qty = Entry(petasco, textvariable=futuvar, font=('times', 13, 'bold'), bd=2, width=7)
fufu_qty.place(y=420, x=300)

# fufu_sum = 1 * int(fufu_qty)
# =========================================================================================

# ------------------------------ price label -------------------------------
price = Label(petasco, text='Price', font=('times', 13, 'bold'), bg='#F0F8FF')
price.place(y=150, x=180)

# ------------------------------ qauntity label -------------------------------
qty = Label(petasco, text='Qauntity', font=('times', 13, 'bold'), bg='#F0F8FF')
qty.place(y=150, x=300)

# ---------------------------------- Drinks Menu -------------------------------------------
Fmenu_lbl = Label(petasco, text='============DRINKS MENU============', font=('times', 14, 'bold'), bg='#F0F8FF')
Fmenu_lbl.place(y=120, x=450)

# ------------------------------ Items label -------------------------------
items = Label(petasco, text='ITEM', font=('times', 13, 'bold'), bg='#F0F8FF')
items.place(y=150, x=450)

# ------------------------------ price label -------------------------------
price = Label(petasco, text='Price', font=('times', 13, 'bold'), bg='#F0F8FF')
price.place(y=150, x=620)

# ------------------------------ qauntity label -------------------------------
qty = Label(petasco, text='Qauntity', font=('times', 13, 'bold'), bg='#F0F8FF')
qty.place(y=150, x=750)

# ====================================================================================
coke_lbl = Label(petasco, text='Coke', font=('times', 13, 'bold'), bg='#F0F8FF')
coke_lbl.place(x=450, y=190)

imagecoke = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\coke.jpg'))
cokepic_lbl = Label(petasco, image=imagecoke)
cokepic_lbl.place(x=570, y=190)

coke_price = Label(text='Ghs 10', font=('times', 13, 'bold'), bg='#F0F8FF')
coke_price.place(y=190, x=620)
cokevar = IntVar()
coke_qty = Entry(petasco, textvariable=cokevar, font=('times', 13, 'bold'), bd=2, width=7)
coke_qty.place(y=190, x=750)
coke = 10 * cokevar.get()
# =========================================================================================

# ========================================================================================
pepsi_lbl = Label(petasco, text='Pepsi', font=('times', 13, 'bold'), bg='#F0F8FF')
pepsi_lbl.place(x=450, y=230)

imagepepsi = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\pepsi1.jpg'))
pepsipic_lbl = Label(petasco, image=imagepepsi)
pepsipic_lbl.place(x=570, y=230)

pepsi_price = Label(text='Ghs 10', font=('times', 13, 'bold'), bg='#F0F8FF')
pepsi_price.place(y=230, x=620)
pepsivar = IntVar()
pepsi_qty = Entry(petasco, textvariable=pepsivar, font=('times', 13, 'bold'), bd=2, width=7)
pepsi_qty.place(y=230, x=750)
pepsi = 10 * pepsivar.get()
# =========================================================================================

# ========================================================================================
cola_lbl = Label(petasco, text='Coka Cola', font=('times', 13, 'bold'), bg='#F0F8FF')
cola_lbl.place(x=450, y=270)

imagecola = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\cola1.jpg'))
colapic_lbl = Label(petasco, image=imagecola)
colapic_lbl.place(x=570, y=265)

cola_price = Label(text='Ghs 15', font=('times', 13, 'bold'), bg='#F0F8FF')
cola_price.place(y=270, x=620)
colavar = IntVar()
cola_qty = Entry(petasco, textvariable=colavar, font=('times', 13, 'bold'), bd=2, width=7)
cola_qty.place(y=270, x=750)
cola = 15 * colavar.get()
# =========================================================================================

# ========================================================================================
dew_lbl = Label(petasco, text='Dew', font=('times', 13, 'bold'), bg='#F0F8FF')
dew_lbl.place(x=450, y=300)

imagedew = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Bluetooth\dew1.jpg'))
dewpic_lbl = Label(petasco, image=imagedew)
dewpic_lbl.place(x=570, y=300)

dew_price = Label(text='Ghs 25', font=('times', 13, 'bold'), bg='#F0F8FF')
dew_price.place(y=300, x=620)
dewvar = IntVar()
dew_qty = Entry(petasco, textvariable=dewvar, font=('times', 13, 'bold'), bd=2, width=7)
dew_qty.place(y=300, x=750)
dew = 25 * dewvar.get()
# =========================================================================================

# =========================================================================================
cocktail_lbl = Label(petasco, text='Cocktail', font=('times', 13, 'bold'), bg='#F0F8FF')
cocktail_lbl.place(x=450, y=340)

cock_image = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Forex\cock.jpg'))
cock_pic_lbl = Label(petasco, image=cock_image)
cock_pic_lbl.place(x=565, y=340)
cock_price = Label(text='Ghs 20', font=('times', 13, 'bold'), bg='#F0F8FF').place(y=340, x=620)
cockvar = IntVar()
cock_qty = Entry(petasco, textvariable=cockvar, font=('times', 13, 'bold'), bd=2, width=7).place(y=340, x=750)
cock = 20 * cockvar.get()
# =========================================================================================

# =========================================================================================
orange_lbl = Label(petasco, text='Organge Juice', font=('times', 13, 'bold'), bg='#F0F8FF').place(x=450, y=380)

image_organge = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Forex\ORANGE.png'))
organe_piclbl = Label(petasco, image=image_organge)
organe_piclbl.place(y=380, x=565)
organge_price = Label(petasco, text='Ghs 15', font=("times", 13, 'bold'), bg="#F0F8FF").place(y=380, x=620)
orangevar = IntVar()
orange_qty = Entry(petasco, textvariable=orangevar, font=('times', 13, 'bold'), bd=2, width=7).place(y=380, x=750)
orange = 15 * orangevar.get()
# =========================================================================================

# =========================================================================================
beet_lbl = Label(petasco, text='Beet Juice', font=('times', 13, 'bold'), bg='#F0F8FF').place(x=450, y=420)
beet_image = ImageTk.PhotoImage(Image.open(r'C:\Users\peter\OneDrive\Desktop\Forex\beet.png'))
beet_pic_lbl = Label(petasco, image=beet_image)
beet_pic_lbl.place(y=420, x=565)
beet_price = Label(petasco, text='Ghs 12', font=('times', 13, 'bold'), bg='#F0F8FF').place(y=420, x=620)
beetvar = IntVar()
beet_Qty = Entry(petasco, textvariable=beetvar, font=('times', 13, 'bold'), bd=2, width=7).place(y=420, x=750)
beet = 12 * beetvar.get()
# =========================================================================================

# =================================== payment ============================================

payment = Entry(petasco, font=('times', 15, 'bold'), bd=2, width=35, bg='blue')
payment.place(x=450, y=570, height=6)

payment_lbl = Label(petasco, text='Make Payment', font=('times', 15, 'bold'), bg='#F0F8FF')
payment_lbl.place(x=565, y=560)

mtn_info = Label(petasco, text='Enter Your MoMo Number and Allow Cashout', font=('times', 8, 'bold'), fg='blue',
                 bg='#F0F8FF')
mtn_info.place(x=400, y=590)
# ==================================== Check box =======================================
checkbtnvar = IntVar()
mtn_checkbtn = Checkbutton(petasco, variable=checkbtnvar, onvalue=1, offvalue=0, bg='#F0F8FF').place(x=370, y=612)
Mtn_Method = Label(petasco, text='MTN', font=('times', 15, 'bold'), bg='#F0F8FF')
Mtn_Method.place(x=400, y=608)
momo_var = IntVar()
Momo_no = Entry(petasco, textvariable=momo_var, font=('times', 13, 'bold'), bd=2)
Momo_no.place(x=450, y=610)

voda_info = Label(petasco, text='Till No Below', font=('times', 8, 'bold'), fg='blue', bg='#F0F8FF')
voda_info.place(x=710, y=590)

Voda_Method = Label(petasco, text='VodaCash 48862', font=('times', 15, 'bold'), bg='#F0F8FF')
Voda_Method.place(x=710, y=608)

Checkbutton(petasco, variable=checkbtnvar, onvalue=0, offvalue=1, bg='#F0F8FF').place(x=680, y=612)

checkbtn = checkbtnvar.get()  # this assigns the value to the connected checkbox

# ======================================== Drinks Total ===================================

def drinkmenu():
    global drinkTotal
    drinkTotal = ((cokevar.get() * 10) + (pepsivar.get() * 10) + (colavar.get() * 15) + (dewvar.get() * 25) + (
            cockvar.get() * 20) + (orangevar.get() * 15) + (beetvar.get() * 12)) / 10
    drklbl.config(text='Total $ ' + str(drinkTotal))

drink_total = DoubleVar()
drinktotal = Button(petasco, text='Total', command=drinkmenu, font=('times', 15, 'bold'), bd=5, width=10)
drinktotal.place(x=480, y=480)

drklbl = Label(petasco, font=('times', 15, 'bold'), bg='#F0F8FF')
drklbl.place(x=650, y=480)
drinkmenu()

# ---------------------------------- Invoice  -------------------------------------------
Fmenu_lbl = Label(petasco, text='============INVOICE============', font=('times', 14, 'bold'), bg='#F0F8FF')
Fmenu_lbl.place(y=120, x=890)

bar = Scrollbar(petasco, orient='vertical')
bar.pack(side=RIGHT, fill='y')

invoice_txtarea = Text(petasco, font=('times', 13, 'bold'), bd=2, width=40, yscrollcommand=bar.set)
invoice_txtarea.place(y=150, x=890, height=470)

# --------------------------------------------------- Total Button ----------------------------------------
def Total():
    global total
    total = (chickenVar.get() * 5) + (pizzaVar.get() * 10) + (friesvar.get() * 2) + (icevar.get() * 3.5) + (
            cheesevar.get() * 5) + (sandvar.get() * 2.5) + (futuvar.get() * 1.5)
    totaloutput.config(text='Total $' + str(total))
    return total

food_total = DoubleVar()
btn = Button(petasco, text='Total', command=Total, font=('times', 15, 'bold'), bd=5, width=10)
btn.place(x=50, y=480)

totaloutput = Label(petasco, font=('times', 15, 'bold'), bg='#F0F8FF')
totaloutput.place(x=230, y=490)
Total()

def gross():
    global grossTotal
    grossTotal = float(total) + float(drinkTotal)
    grosslbl.config(text='Your Bill Is: $ ' + str(grossTotal), bg='#F0F8FF')

gross_total = DoubleVar()
grossbtn = Button(petasco, text='Gross Total', command=gross, font=('times', 15, 'bold'), bd=5, width=10)
grossbtn.place(x=50, y=580)

grosslbl = Label(petasco, font=('times', 15, 'bold'), bg='#F0F8FF')
grosslbl.place(x=230, y=580)

def confirmPayment():
    if checkbtnvar.get() == 1:
        if Momo_no.get() == '0':
            messagebox.showerror('Payment Info', 'Please Enter Your MTN Number!')
    elif checkbtnvar.get() == 0:
        messagebox.askquestion('Payment Info', 'Have you made payment to the Till Number?')
    else:
        messagebox.showwarning('Payment Info', 'Please Select a Payment')

# ================================================ Invoice Print Out =========================================================

def receipt():
    invoice_txtarea.delete(1.0, END)

    if gross_total.get() == 0:
        messagebox.showerror('Error', 'Please Make an Order to get a Receipt')
    else:

        # ==================================== customer info ============================
        invoice_txtarea.insert(END, "===========Customer Details============\n")
        invoice_txtarea.insert(END, 'Customer Name: 'f'{customerName_var.get()}\n')
        invoice_txtarea.insert(END, 'Phone Number: 'f'{customerPhone_var.get()}\n')
        invoice_txtarea.insert(END, 'Bill Number: 'f'{customerBill_var.get()}\n')
        invoice_txtarea.insert(END, 'Customer Address: 'f'{customerAddress_var.get()}\n\n')

        # ==================================== order info ==============================
        invoice_txtarea.insert(END, '=========== Food Order Details =========\n')
        invoice_txtarea.insert(END, 'Item\t\tPrice\tQty\tTotal\n')
        invoice_txtarea.insert(END, 'Chicken\t\t $5.0 \t 'f'{chickenVar.get()}\t  $ 'f'{chickenVar.get() * 5}\n')
        invoice_txtarea.insert(END, 'Pizza\t\t $10.0 \t 'f'{pizzaVar.get()}\t  $ 'f'{pizzaVar.get() * 10}\n')
        invoice_txtarea.insert(END, 'Fries\t\t $2.0 \t 'f'{friesvar.get()}\t  $ 'f'{friesvar.get() * 2}\n')
        invoice_txtarea.insert(END, 'Ice Cream\t\t $5.0 \t 'f'{icevar.get()}\t  $ 'f'{icevar.get() * 5}\n')
        invoice_txtarea.insert(END, 'Cheese\t\t $5.0 \t 'f'{cheesevar.get()}\t  $ 'f'{cheesevar.get() * 5}\n')
        invoice_txtarea.insert(END, 'Gob3\t\t $2.5 \t 'f'{sandvar.get()}\t  $ 'f'{sandvar.get() * 2.5}\n')
        invoice_txtarea.insert(END, 'Waakye\t\t $1.5 \t 'f'{futuvar.get()}\t  $ 'f'{futuvar.get() * 1.5}\n\n')
        # ================================ Total =========================================
        invoice_txtarea.insert(END, '=====Total:\t\t  'f'{total}\t\t  ======\n\n')

        invoice_txtarea.insert(END, '========== Drinks Order Details =========\n\n')
        invoice_txtarea.insert(END, 'Item\t\tPrice\tQty\tTotal\n')
        invoice_txtarea.insert(END, 'Coke\t\t Ghs10 \t 'f'{cokevar.get()}\t  Ghs 'f'{cokevar.get() * 10}\n')
        invoice_txtarea.insert(END, 'Pepsi\t\t Ghs10 \t 'f'{pepsivar.get()}\t  Ghs 'f'{pepsivar.get() * 10}\n')
        invoice_txtarea.insert(END, 'Coka Cola\t\t Ghs15 \t 'f'{colavar.get()}\t  Ghs 'f'{colavar.get() * 15}\n')
        invoice_txtarea.insert(END, 'Dew\t\t Ghs25 \t 'f'{dewvar.get()}\t  Ghs 'f'{dewvar.get() * 25}\n')
        invoice_txtarea.insert(END, 'Cocktail\t\t Ghs20 \t 'f'{cockvar.get()}\t  Ghs 'f'{cockvar.get() * 20}\n')
        invoice_txtarea.insert(END, 'Orange Juice\t\t Ghs15 \t 'f'{orangevar.get()}\t  Ghs 'f'{orangevar.get() * 15}\n')
        invoice_txtarea.insert(END, 'Beet Juice\t\t Ghs12 \t 'f'{beetvar.get()}\t  Ghs 'f'{beetvar.get() * 12}\n\n')
        # ============================================ Total =============================
        invoice_txtarea.insert(END, '=====Total:\t\t  'f'{drinkTotal}\t\t  ======\n\n')
        invoice_txtarea.insert(END,
                               '------------------------------------------------------------\nGross Total:\t\t  'f'{grossTotal}\t\t  \n------------------------------------------------------------\n\n')

        # ====================================== payment =================================
        invoice_txtarea.insert(END, '============ Payment Details ===========\n\n')
        if checkbtnvar.get() == 0:
            invoice_txtarea.insert(END, 'Payment Method : Voda Cash')
        elif checkbtnvar.get() == 1:
            if Momo_no.get() == '0':
                messagebox.showerror('Payment Info', 'Please Enter Your MTN Number!')
            else:
                invoice_txtarea.insert(END, f'Payment Method : MTN {Momo_no.get()}')
        else:
            messagebox.showinfo('Payment Info', 'Please select your mode of Payment')
    # ================================ Disabled Text Area =============================
    invoice_txtarea.config(state='disabled')

payment_info = Label(petasco,
                     text='Payment Info:===================================================================================',
                     font='12', fg='red', bg='#F0F8FF')
payment_info.place(x=20, y=540)
confirmQ = Label(petasco, text='Made Payment?', font=('Arial', 12, 'bold'), fg='red', bg='#F0F8FF')
confirmQ.place(x=495, y=640)
confirmbtn = Button(petasco, text='Confirm', font=('times', 15, 'bold'), bd=5, width=7, bg='red',
                    command=confirmPayment)
confirmbtn.place(x=640, y=640, height=35)

print_btn = Button(petasco, command=receipt, text='Print', font=('times', 15, 'bold'), bd=5, width=7)
print_btn.place(x=920, y=628)

save_btn = Button(petasco, text='Save', font=('times', 15, 'bold'), bd=5, width=7)
save_btn.place(x=1100, y=628)

bar.config(command=invoice_txtarea.yview)
petasco.resizable(False, False)
petasco.mainloop()


import sounddevice as sd
from scipy.io.wavfile import write

fs = 44100
seconds = 10

print('I am listening... press ctrl+c to stop'  )
while True:
    myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=1)
    sd.wait()
    print("Finished and again, recordign size", len(myrecording))


import torch
import numpy as np
from scipy.sparse.csgraph import laplacian
import matplotlib.pyplot as plt
from methods import integrateSEIS

# 𝑃={′𝐴𝐵′,′𝐵𝐶′,′𝑀𝐵′,′𝑁𝐵′,′𝑁𝐿′,′𝑁𝑇′,′𝑁𝑆′,′𝑁𝑈′,′𝑂𝑁′,′𝑃𝐸′,′𝑄𝐶′,′𝑆𝐾′,′𝑌𝑇′}
# alpha and mu are disease dependant
beta=0.3
gamma=0.01
# K=Ks=Ke as susceptible pop is just as mobile as effected
K=0.2
Ki=0.01
theta=torch.tensor([beta,gamma,K,Ki])

S0=torch.FloatTensor([4345737,5020302,1360396,772094,523790,44598,965382,38787,14446515,154748,8433301,1168423,40369])
E0=torch.FloatTensor([1,5,1,0,0,0,0,0,10,0,3,1,0])
I0=torch.FloatTensor([0,1,0,0,0,0,0,0,3,0,0,0,0])
dt=1.0
nt=100
#minimuim(theta,mu1,nu)
S,E,I=integrateSEIS(theta,S0,E0,I0,dt,nt)

t=torch.arange(nt+1)*dt
for i in range (13):
     plt.figure(i)
     plt.plot(t,E[i],t,I[i])
plt.show()


"""
FFI builder module for minpack for usage from meson and from setup.py.

Since meson has the full knowledge about the build, it will handle
the generation of the C definitions in the meson.build file rather
than in the FFI builder. This allows to correctly keep track of
dependencies and updates in the build process.

For setup.py we have to do the preprocessing ourselves here, this
requires us to use the C compiler to preprocess the header file
of minpack because the CFFI C parser cannot handle certain C
preprocessor constructs. Also, we cannot rely on an external build
system fixing dependencies for us and therefore have to find those
ourselves using pkg-config.
"""

import os
import cffi

library = "minpack"
include_header = '#include "minpack.h"'
prefix_var = "MINPACK_PREFIX"
if prefix_var not in os.environ:
    prefix_var = "CONDA_PREFIX"

if __name__ == "__main__":
    import sys

    kwargs = dict(libraries=[library])

    header_file = sys.argv[1]
    module_name = sys.argv[2]

    with open(header_file) as f:
        cdefs = f.read()
else:
    import subprocess

    try:
        import pkgconfig

        if not pkgconfig.exists(library):
            raise ModuleNotFoundError("Unable to find pkg-config package 'minpack'")
        if pkgconfig.installed(library, "< 2.0.0"):
            raise Exception(
                "Installed 'minpack' version is too old, 2.0.0 or newer is required"
            )

        kwargs = pkgconfig.parse(library)
        cflags = pkgconfig.cflags(library).split()

    except ModuleNotFoundError:
        kwargs = dict(libraries=[library])
        cflags = []
        if prefix_var in os.environ:
            prefix = os.environ[prefix_var]
            kwargs.update(
                include_dirs=[os.path.join(prefix, "include")],
                library_dirs=[os.path.join(prefix, "lib")],
                runtime_library_dirs=[os.path.join(prefix, "lib")],
            )
            cflags.append("-I" + os.path.join(prefix, "include"))

    cc = os.environ["CC"] if "CC" in os.environ else "cc"

    module_name = "minpack._libminpack"

    p = subprocess.Popen(
        [cc, *cflags, "-DMINPACK_CFFI=1", "-E", "-"],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    out, err = p.communicate(include_header.encode())

    cdefs = out.decode()

ffibuilder = cffi.FFI()
ffibuilder.set_source(module_name, include_header, **kwargs)
ffibuilder.cdef(cdefs)

if __name__ == "__main__":
    ffibuilder.distutils_extension(".")


from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QHBoxLayout

class WidgetHorizontalButton(QWidget):
    def __init__(self, btn1, btn2, table, row, col):
        QWidget.__init__(self)
        self.btn1 = btn1
        self.btn2 = btn2
        self.table = table
        self.__layout__()
        self.__setWidth__()
        table.setCellWidget(row, col, self)

    def __layout__(self):
        layout = QHBoxLayout()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)
        self.setLayout(layout)

    def __setWidth__(self):
        width = 20
        width += self.btn1.width()
        width += self.btn2.width()
        self.setFixedWidth(width)


import cv2

#sift
sift = cv2.SIFT_create()

#feature matching
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)

#read images
img1 = cv2.imread("C:/Users/Ahmed Gamal/Desktop/FiQE8r1WIAAYrgK.jpg")
img2 = cv2.imread("C:/Users/Ahmed Gamal/Desktop/FiQE8r1WIAAYrgK - Copy.jpg")

#convert BGR to gray
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

#detect interest points and find the descriptors
keypoints_1, descriptors_1 = sift.detectAndCompute(img1,None)
keypoints_2, descriptors_2 = sift.detectAndCompute(img2,None)

#match the descriptors and sort them
matches = bf.match(descriptors_1,descriptors_2)
matches = sorted(matches, key = lambda x:x.distance)

#draw the matches
img3 = cv2.drawMatches(img1, keypoints_1, img2, keypoints_2, matches[300:1000], img2, flags=2)

cv2.imshow('SIFT', img3)

cv2.waitKey(0)


from abc import ABC, abstractmethod
from sqlalchemy import select, update
from sqlalchemy.orm import selectinload
from typing import List

from app.database import AsyncSessionLocal
from app.models.supermarkets import Supermarket
from app.schemas.supermarket import SupermarketIn
from app.models.users import User
from app.models.addresses import Address
from app.models.plans import Plan
from app.schemas.plan import PlanIn

class SupermarketRepository(ABC):

    @abstractmethod
    async def get_all() -> List[Supermarket]:
        async with AsyncSessionLocal() as session:
            query = select(Supermarket)
            result = await session.execute(query)

        return result.scalars().fetchall()

    @abstractmethod
    async def get_by_id(id: int) -> Supermarket:
        async with AsyncSessionLocal() as session:
            query = select(Supermarket).where(Supermarket.id == id)
            result = await session.execute(query)

        return result.scalar()

    @abstractmethod
    async def add(supermarket: SupermarketIn, user: User, address: Address, plan: Plan):
        async with AsyncSessionLocal() as session:
            supermarket = Supermarket(
                name=supermarket.name,
                business_name=supermarket.business_name,
                state_registration=supermarket.state_registration,
                phone_number=supermarket.phone_number,
                cnpj=supermarket.cnpj,
                address=address
            )

            supermarket.address = address
            supermarket.plan = plan
            supermarket.users.append(user)

            session.add(supermarket)

            await session.commit()
            await session.refresh(supermarket)

        return supermarket

    @abstractmethod
    async def update(id: int, supermarket_data: SupermarketIn):
        async with AsyncSessionLocal() as session:
            query = update(Supermarket).where(Supermarket.id == id).values(dict(supermarket_data))
            await session.execute(query)
            await session.commit()

        return id

    @abstractmethod
    async def update_plan(supermarket_id: int, plan_id: int):
        async with AsyncSessionLocal() as session:
            query = update(Supermarket)\
                .where(Supermarket.id == supermarket_id)\
                .values(id_plan=plan_id)

            await session.execute(query)
            await session.commit()

        return plan_id


from __future__ import absolute_import

from keystoneclient import exceptions
from oslo.config import cfg
from oslo.utils import timeutils
import six.moves.urllib.parse as urlparse
from swiftclient import client as swift

from ceilometer.central import plugin
from ceilometer.openstack.common.gettextutils import _
from ceilometer.openstack.common import log
from ceilometer import sample

LOG = log.getLogger(__name__)

OPTS = [
    cfg.StrOpt('reseller_prefix',
               default='AUTH_',
               help="Swift reseller prefix. Must be on par with "
               "reseller_prefix in proxy-server.conf."),
]

service_types_opts = [
    cfg.StrOpt('swift',
               default='object-store',
               help='Swift service type.'),
]

cfg.CONF.register_opts(OPTS)
cfg.CONF.register_opts(service_types_opts, group='service_types')

class _Base(plugin.CentralPollster):

    METHOD = 'head'
    _ENDPOINT = None

    @property
    def default_discovery(self):
        return 'tenant'

    @property
    def CACHE_KEY_METHOD(self):
        return 'swift.%s_account' % self.METHOD

    @staticmethod
    def _get_endpoint(ksclient):
        # we store the endpoint as a base class attribute, so keystone is
        # only ever called once
        if _Base._ENDPOINT is None:
            try:
                conf = cfg.CONF.service_credentials
                _Base._ENDPOINT = ksclient.service_catalog.url_for(
                    service_type=cfg.CONF.service_types.swift,
                    endpoint_type=conf.os_endpoint_type)
            except exceptions.EndpointNotFound:
                LOG.debug(_("Swift endpoint not found"))
        return _Base._ENDPOINT

    def _iter_accounts(self, ksclient, cache, tenants):
        if self.CACHE_KEY_METHOD not in cache:
            cache[self.CACHE_KEY_METHOD] = list(self._get_account_info(
                ksclient, tenants))
        return iter(cache[self.CACHE_KEY_METHOD])

    def _get_account_info(self, ksclient, tenants):
        endpoint = self._get_endpoint(ksclient)
        if not endpoint:
            raise StopIteration()

        for t in tenants:
            api_method = '%s_account' % self.METHOD
            yield (t.id, getattr(swift, api_method)
                                (self._neaten_url(endpoint, t.id),
                                 ksclient.auth_token))

    @staticmethod
    def _neaten_url(endpoint, tenant_id):
        """Transform the registered url to standard and valid format."""
        return urlparse.urljoin(endpoint.split('/v1')[0].rstrip('/') + '/',
                                'v1/' + cfg.CONF.reseller_prefix + tenant_id)

class ObjectsPollster(_Base):
    """Iterate over all accounts, using keystone."""
    def get_samples(self, manager, cache, resources):
        tenants = resources
        for tenant, account in self._iter_accounts(manager.keystone,
                                                   cache, tenants):
            yield sample.Sample(
                name='storage.objects',
                type=sample.TYPE_GAUGE,
                volume=int(account['x-account-object-count']),
                unit='object',
                user_id=None,
                project_id=tenant,
                resource_id=tenant,
                timestamp=timeutils.isotime(),
                resource_metadata=None,
            )

class ObjectsSizePollster(_Base):
    """Iterate over all accounts, using keystone."""
    def get_samples(self, manager, cache, resources):
        tenants = resources
        for tenant, account in self._iter_accounts(manager.keystone,
                                                   cache, tenants):
            yield sample.Sample(
                name='storage.objects.size',
                type=sample.TYPE_GAUGE,
                volume=int(account['x-account-bytes-used']),
                unit='B',
                user_id=None,
                project_id=tenant,
                resource_id=tenant,
                timestamp=timeutils.isotime(),
                resource_metadata=None,
            )

class ObjectsContainersPollster(_Base):
    """Iterate over all accounts, using keystone."""
    def get_samples(self, manager, cache, resources):
        tenants = resources
        for tenant, account in self._iter_accounts(manager.keystone,
                                                   cache, tenants):
            yield sample.Sample(
                name='storage.objects.containers',
                type=sample.TYPE_GAUGE,
                volume=int(account['x-account-container-count']),
                unit='container',
                user_id=None,
                project_id=tenant,
                resource_id=tenant,
                timestamp=timeutils.isotime(),
                resource_metadata=None,
            )

class ContainersObjectsPollster(_Base):
    """Get info about containers using Swift API."""

    METHOD = 'get'

    def get_samples(self, manager, cache, resources):
        tenants = resources
        for tenant, account in self._iter_accounts(manager.keystone,
                                                   cache, tenants):
            containers_info = account[1]
            for container in containers_info:
                yield sample.Sample(
                    name='storage.containers.objects',
                    type=sample.TYPE_GAUGE,
                    volume=int(container['count']),
                    unit='object',
                    user_id=None,
                    project_id=tenant,
                    resource_id=tenant + '/' + container['name'],
                    timestamp=timeutils.isotime(),
                    resource_metadata=None,
                )

class ContainersSizePollster(_Base):
    """Get info about containers using Swift API."""

    METHOD = 'get'

    def get_samples(self, manager, cache, resources):
        tenants = resources
        for tenant, account in self._iter_accounts(manager.keystone,
                                                   cache, tenants):
            containers_info = account[1]
            for container in containers_info:
                yield sample.Sample(
                    name='storage.containers.objects.size',
                    type=sample.TYPE_GAUGE,
                    volume=int(container['bytes']),
                    unit='B',
                    user_id=None,
                    project_id=tenant,
                    resource_id=tenant + '/' + container['name'],
                    timestamp=timeutils.isotime(),
                    resource_metadata=None,
                )


import datetime
import random
import json
from chore_assignments import CHORES_TO_PEOPLE,PEOPLE_TO_CHORES

CHORE_OPTIONS = (
    'kitchen','sweeping/mopping','trash','general pickup','recycling'
)

CHORE_FREQUENCIES = {
'kitchen' : datetime.timedelta(days=1),
'sweeping/mopping' : datetime.timedelta(days=7),
'trash' : datetime.timedelta(days=1),
'general pickup' : datetime.timedelta(days=3),
'recycling' : datetime.timedelta(days=2)
}

class Chore:
    def update_person(self):
        people = CHORES_TO_PEOPLE[self.chore]
        index = people.index(self.person)

        self.person = people[(index + 1) % len(people)]

    def update_date(self):
        if self.active:
            self.next_active_day += CHORE_FREQUENCIES[self.chore]

    def update_chore(self):
        self.update_person()
        self.update_date()

    @classmethod
    def from_dict(cls, dict):
        ''' Initializes a chore from a dict '''

        obj = cls()
        for key in dict.keys():
            obj.__dict__[key] = dict[key]
        obj.__dict__['next_active_day'] = datetime.datetime.strptime(obj.next_active_day,"%m/%d/%Y")
        obj.__dict__['active'] = obj.next_active_day == datetime.datetime.today()

        return obj

    def to_dict(self):
        '''
            Returns a custom dictionary representation of the
            chore, to use to convert the chore to json
        '''
        next_day = self.next_active_day.strftime('%m/%d/%y')
        ret = {
                'chore'             :   self.chore,
                'next_active_day'   :   next_day,
                'person'            :   self.person
              }
        return ret

    def accountability_msg(self):
        return "{} is responsible for {} today.".format(self.person,self.chore)

    def chore_msg(self):
        def get_random_greeting():
            random_greetings = ["Howdy","Buenas Dias","Sup fuckhead","Hey ballgobbler","Good'day",'Aloha', 'Suh','Praise Data',
                                "Eat my ballsack","Hi", "Hey", "Ayy", "Ahoy", "Buongiorno", "Hello", "What's up, ATTENTION"]
            return random.choice(random_greetings)
        return "{} {}, please do your chore: {}".format(get_random_greeting(),self.person,self.chore)

    def __str__(self):
        return "[{}, Active: {}".format(self.chore,self.active)


from django.shortcuts import render, redirect, get_object_or_404
from django.db import connection
# from cities.models import Cities, Reviews
from cities.models import CityReviews
from cities.forms import CreateReviewForm, UpdateReviewForm
from account.models import Account

######################################
#         Helper Functions           #
######################################

def dictfetchall(cursor):
    "Return all rows from a cursor as a dict"
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
    ]

# old function that was used in old deliverable
def get_cities_sql():
    with connection.cursor() as cursor:
        cursor.execute("SELECT City, Sum(Population) AS Population FROM `cities_cities` group by City Limit 10;")
        cities = dictfetchall(cursor)
    return cities

# query that is used to search for cities by name
def search_city_match(query=None):
    with connection.cursor() as cursor:
        cursor.execute("SELECT City_ID as CityID, City, State FROM C_US_MilitaryCities WHERE City LIKE '%" + str(query)+ "%' Order by length(City), City, State Limit 25")
        cities = dictfetchall(cursor)
    return cities

# need to change to be large query with tons of joins
def get_city_by_id(id=None):
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM C_US_MilitaryCities WHERE CITY_ID = "+str(id))
        city = dictfetchall(cursor)
    return city[0]

# pulls just city id and population
def get_population_by_id(id):
        with connection.cursor() as cursor:
            cursor.execute("SELECT City_ID, SUM(Population) AS Pop FROM C_ZipCodeFix WHERE CITY_ID = "+str(id)+" GROUP BY City_ID")
            id_pop = dictfetchall(cursor)
        if len(id_pop) > 0:
            return id_pop[0]
        else: return {"City_ID":id, "Pop":" No Population Data Found"}

def get_top_7_state_tax(cityid):
        with connection.cursor() as cursor:
            cursor.execute("select us.State as state, st.Tax_Type as tax, st.AMOUNT/1000000 as amount from C_UnitedStates as us, C_StateTax st, C_US_MilitaryCities as mil_c where mil_c.City_ID = "+str(cityid)+" and mil_c.State_ID = us.State_ID and us.State = st.State and st.Tax_Type <> 'Total Taxes' group by us.State, st.Tax_Type, st.AMOUNT order by amount desc limit 7")
            st_tax = dictfetchall(cursor)
        return st_tax

def get_state_tax(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''select * from
                                (select us.State as state, st.Tax_Type as tax, st.AMOUNT as amount
                                    from C_UnitedStates as us, C_StateTax st, C_US_MilitaryCities as mil_c
                                    where mil_c.City_ID = '''+str(cityid)+''' and mil_c.State_ID = us.State_ID
                                    and us.State = st.State and st.Tax_Type <> 'Total Taxes'
                                    group by us.State, st.Tax_Type, st.AMOUNT order by st.Tax_Type) a
                                left join (select st.Tax_Type as tax, avg(st.AMOUNT) as avg_amount
                                    from C_StateTax st
                                    where st.State <> 'Total_US'
                                    group by st.Tax_Type order by st.Tax_Type) b
                                on a.tax = b.tax
                                order by avg_amount''')
            st_tax_avg = dictfetchall(cursor)
        return st_tax_avg

def get_reviews_by_city(cityid):
    with connection.cursor() as cursor:
        cursor.execute("select mcs.City, mcs.State, cr.Rating, cr.Comments from (Select mc.City, us.State from (select State_ID, City from C_US_MilitaryCities where City_ID = "+str(cityid)+") mc left join C_UnitedStates us on us.State_ID = mc.State_ID) mcs left join cities_cityreviews cr on mcs.City = cr.City and mcs.State = cr.State")
        reviews = dictfetchall(cursor)
    return reviews

def get_cityavg_ratings_by_city(cityid):
    with connection.cursor() as cursor:
        cursor.execute("select mcs.City, mcs.State, avg(cr.Rating) as avg_rating from (Select mc.City, us.State from (select State_ID, City from C_US_MilitaryCities where City_ID = "+str(cityid)+") mc left join C_UnitedStates us on us.State_ID = mc.State_ID) mcs left join cities_cityreviews cr on mcs.City = cr.City and mcs.State = cr.State")
        rating = dictfetchall(cursor)
    return rating[0]

def get_stateavg_ratings_by_city(cityid):
    with connection.cursor() as cursor:
        cursor.execute("select mcs.State, avg(cr.Rating) as avg_rating from (Select us.State from (select State_ID from C_US_MilitaryCities where City_ID = "+str(cityid)+") mc left join C_UnitedStates us on us.State_ID = mc.State_ID) mcs left join cities_cityreviews cr on mcs.State = cr.State group by mcs.State")
        rating = dictfetchall(cursor)
    return rating[0]

def get_militarybases(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''select cs.State, mb.SiteName, mb.Component, mb.Status from M_MilitaryBases mb
                                right join (select us.State from C_US_MilitaryCities mc
                                	           left join C_UnitedStates us on us.State_ID = mc.State_ID
                                	           where mc.City_ID = '''+str(cityid)+''') cs on cs.State = mb.State order by Status ASC''')
            bases = dictfetchall(cursor)
        return bases

def get_militarycare(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''Select cf.FacilityName, cf.PRIM_SVC, cf.S_CITY, cf.S_STATE, cf.S_ADD1, cf.S_ADD2, cf.Type from M_Polytrauma_Care_Facility cf
                                right join (select City, State from C_US_MilitaryCities mc
                                where mc.City_ID = '''+str(cityid)+''') cs on cs.State = cf.S_STATE''')
            care_centers = dictfetchall(cursor)
        return care_centers

def get_militarygrantsavg(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''select g.GrantValue, a.g_avg from M_VA_HomeGrant g, (SELECT avg(GrantValue) as g_avg from M_VA_HomeGrant) a
                                where g.State = (select mc.State from C_US_MilitaryCities mc
                                					where mc.City_ID = '''+str(cityid)+''')''')
            avgs = dictfetchall(cursor)
        return avgs

def get_military_grant_per_population(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''SELECT hg.State, hg.GrantValue/pop.Pop as val_per_person,
                                 CASE When hg.State = (select State from C_US_MilitaryCities where City_ID = '''+str(cityid)+''')
                                     THEN "#e85d47" ELSE "#17a2b8" END AS color
                                 From M_VA_HomeGrant hg
                                 left join (SELECT us.ST_Code, p.Pop
                                     from C_UnitedStates us left join (select State_ID, SUM(Population) as Pop
                                                                         from C_ZipCodeFix group by State_ID) p
                                                              on p.State_ID = us.State_ID) pop
                                  on pop.ST_Code = hg.State order by val_per_person desc''')
            ratios = dictfetchall(cursor)
        return ratios

def get_bully_avg():
        with connection.cursor() as cursor:
            cursor.execute('''select avg(BiasOfSexAllegations) as sex_al,
                                avg(Sex_race_Origin_Allegations) as sex_race_al, avg(BiasOfDisabilityAllegations) as dis_al
                                from S_Bullying_HarrassmentReports''')
            avgs = dictfetchall(cursor)
        return avgs

def get_bully_data(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''select st.State, BiasOfSexAllegations as sex_al, Sex_race_Origin_Allegations as sex_race_al, BiasOfDisabilityAllegations as dis_al
                                 from S_Bullying_HarrassmentReports bhs
                                 right join (select State from C_UnitedStates
                                             where State_ID = (select State_ID from C_US_MilitaryCities where City_ID = '''+str(cityid)+''')) st
                                 on st.State = bhs.State''')
            state_vals = dictfetchall(cursor)
            avgs = get_bully_avg()
        return {"avgs":avgs[0], "state_vals":state_vals[0]}

def get_bully_data_by_state(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''SELECT bhr.State, bhr.NumOfSchools as schools, bhr.NumAllegations/bhr.NumOfSchools as al_per_school,
                                 CASE When bhr.State = (select State from C_UnitedStates us
                                                          right join (select State_ID from C_US_MilitaryCities where City_ID = '''+str(cityid)+''') st
                                                          on st.State_ID = us.State_ID)
                                  THEN "#20c8e3" ELSE "#17a2b8" END AS color From S_Bullying_HarrassmentReports bhr
                                  order by State asc''')
            values = dictfetchall(cursor)
        return values

def get_teach_data_by_state(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''SELECT tce.State, tce.FullTimeTeachers/tce.NumOfSchools as teach_per_school, tce.Cert_Lic_Percent,
                                     CASE When tce.State = (select State from C_UnitedStates us
                                                             right join (select State_ID from C_US_MilitaryCities where City_ID = '''+str(cityid)+''') st
                                                             on st.State_ID = us.State_ID)
                                     THEN "#20c8e3" ELSE "#17a2b8" END AS color
                                     From S_SCH_TeacherCertAndExperience tce
                                     order by State asc''')
            values = dictfetchall(cursor)
        return values

def get_sales_tax_by_state(cityid):
        with connection.cursor() as cursor:
            cursor.execute('''SELECT tx.State, tx.CombinedRate,
                                    CASE When tx.State = (select State from C_UnitedStates us
                                                            right join (select State_ID from C_US_MilitaryCities where City_ID = '''+str(cityid)+''') st
                                                            on st.State_ID = us.State_ID)
                                    THEN "#e85d47" ELSE "#17a2b8" END AS color From C_StateTaxPercent tx order by State asc''')
            values = dictfetchall(cursor)
        return values

def city_match_query(max_pop, min_pop, mil, base):
    # just pop
    if mil =="No" and base == "No":
        with connection.cursor() as cursor:
            cursor.execute('''Select mc.State as StateCode, mc.City, z.City_Id as CityID, z.total_pop from
                            (Select City_ID, Sum(Population) as total_pop from C_ZipCodeFix
                            group by City_ID
                            having total_pop >= '''+str(min_pop)+''' and total_pop <= '''+str(max_pop)+''') z
                            left join C_US_MilitaryCities mc on mc.City_ID = z.City_ID limit 100''')
            cities = dictfetchall(cursor)
    # pop plus bool mil aid
    elif mil !="No" and base == "No":
        with connection.cursor() as cursor:
            cursor.execute('''select * from (
                                Select us.State as State, mc.State as StateCode, mc.City, z.City_Id as CityID, z.total_pop
                                    from (Select City_ID, Sum(Population) as total_pop from C_ZipCodeFix
                                                group by City_ID
                                                having total_pop >= '''+str(min_pop)+''' and total_pop <= '''+str(max_pop)+''') z
                                                left join C_US_MilitaryCities mc on mc.City_ID = z.City_ID
                                                left join C_UnitedStates us on us.State_ID = mc.State_ID) base
                                    where City in (SELECT S_CITY from M_Polytrauma_Care_Facility)''')
            cities = dictfetchall(cursor)
    # pop plus base type
    elif mil =="No" and base != "No":
        with connection.cursor() as cursor:
            cursor.execute('''select * from (
                                Select us.State, mc.City, z.City_Id as CityID, z.total_pop
                                    from (Select City_ID, Sum(Population) as total_pop from C_ZipCodeFix
                                                group by City_ID
                                                having total_pop >= '''+str(min_pop)+''' and total_pop <= '''+str(max_pop)+''') z
                                                left join C_US_MilitaryCities mc on mc.City_ID = z.City_ID
                                                left join C_UnitedStates us on us.State_ID = mc.State_ID) base
                                    where State in (SELECT State from M_MilitaryBases where Component = "'''+str(base)+'''") limit 100''')
            cities = dictfetchall(cursor)
    # everything
    else:
        with connection.cursor() as cursor:
            cursor.execute('''select * from (
                                Select us.State as State, mc.State as StateCode, mc.City, z.City_Id as CityID, z.total_pop
                                    from (Select City_ID, Sum(Population) as total_pop from C_ZipCodeFix
                                                group by City_ID
                                                having total_pop >= '''+str(min_pop)+''' and total_pop <= '''+str(max_pop)+''') z
                                                left join C_US_MilitaryCities mc on mc.City_ID = z.City_ID
                                                left join C_UnitedStates us on us.State_ID = mc.State_ID) base
                                    where State in (SELECT State from M_MilitaryBases where Component = "'''+str(base)+'''")
                                    and City in (SELECT S_CITY from M_Polytrauma_Care_Facility)''')
            cities = dictfetchall(cursor)
    if len(cities) > 0:
        return cities
    else: return {"City":"No Cities found with those requirements"}

######################################
#          View Functions            #
######################################

def home_screen_view(request):
    context = {}
    return render(request, "cities/home.html", context)

def search_cities(request):
    context = {}
    if request.GET:
        query = request.GET['q']
        context['query'] = str(query)
        context['cities'] = search_city_match(query)
    return render(request, 'cities/search.html', context)

def city_match(request):
    context = {}
    if request.GET:
        max_pop = request.GET['max_pop']
        min_pop = request.GET['min_pop']
        mil = request.GET['military']
        base = request.GET['m_base']
        context['min_pop'] = int(min_pop)
        context['max_pop'] = int(max_pop)
        context['m_base'] = str(base)
        context['military'] = str(mil)
        context['cities'] = city_match_query(max_pop, min_pop, mil, base)
    return render(request, "cities/city_match.html", context)

def detail_city(request, id):
    context = {}
    city = get_city_by_id(id)
    cityid_pop = get_population_by_id(id)
    context['city'] = city
    context['cityid_pop'] = cityid_pop
    context['st_tax'] = get_top_7_state_tax(id)
    context['st_tax_avg'] = get_state_tax(id)
    context['reviews'] = get_reviews_by_city(id)
    context['city_rating'] = get_cityavg_ratings_by_city(id)
    context['state_rating'] = get_stateavg_ratings_by_city(id)
    context['militarybases'] = get_militarybases(id)
    context['militarycare'] = get_militarycare(id)
    context['military_grantavgs'] = get_militarygrantsavg(id)
    context['grant_per_pop'] = get_military_grant_per_population(id)
    context['school_bully'] = get_bully_data(id)
    context['school_bully_st'] = get_bully_data_by_state(id)
    context['school_teacher'] = get_teach_data_by_state(id)
    context['sales_tax'] = get_sales_tax_by_state(id)
    return render(request, 'cities/city_detail.html', context)

############### REVIEW ###############
def create_review(request):
    context = {}
    user = request.user
    if request.POST:
        form = CreateReviewForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            author = Account.objects.filter(email=request.user.email).first()
            obj.author = author
            obj.save()
    else:
        form = CreateReviewForm()
    context['form'] = form
    return render(request, 'cities/create_review.html', context)

def detail_review(request, slug):
    context = {}
    review = get_object_or_404(CityReviews, slug=slug)
    context['review'] = review
    return render(request, 'cities/detail_review.html', context)

def delete_review(request, slug):
    context = {}
    obj = get_object_or_404(CityReviews, slug=slug)
    context['object'] = obj
    if request.POST:
        obj.delete()
        return redirect('home')
    return render(request, "cities/delete_review.html", context)

def edit_review(request, slug):
    context = {}
    user = request.user

    review = get_object_or_404(CityReviews, slug=slug)
    if request.POST:
        form = UpdateReviewForm(request.POST or None, instance=review)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.save()
            context['success_message'] = "Updated Review for "+str(review.City)
            review = obj

    form = UpdateReviewForm(
			initial={
					"Comments": review.Comments,
					"Rating": review.Rating,
				}
			)
    context['form'] = form
    context['city'] = review.City
    return render(request, 'cities/edit_review.html', context)


import argparse
import json
import re

from pyspark.sql import SparkSession
from pyspark.sql.types import DateType, FloatType, StructField, StructType
from merlion.spark.dataset import read_dataset, write_dataset, TSID_COL_NAME
from merlion.spark.pandas_udf import anomaly

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--data", required=True, help="Path at which the dataset is stored.")
    parser.add_argument("--output_path", required=True, help="Path at which to save output anomaly scores.")
    parser.add_argument(
        "--train_test_split", required=True, help="First timestamp in the dataset which should be used for testing."
    )
    parser.add_argument("--file_format", default="csv", help="File format of train data & output file.")
    parser.add_argument(
        "--model",
        default=json.dumps({"name": "DefaultDetector"}),
        help="JSON dict specifying the model we wish to use for anomaly detection.",
    )
    parser.add_argument(
        "--index_cols",
        default="[]",
        help="JSON list of columns used to demarcate different time series. For example, if the dataset contains sales "
        'for multiple items at different stores, this could be \'["store", "item"]\'. '
        "If not given, we assume the dataset contains only 1 time series.",
    )
    parser.add_argument(
        "--time_col",
        default=None,
        help="Name of the column containing timestamps. If not given, use the first non-index column.",
    )
    parser.add_argument(
        "--data_cols",
        default="[]",
        help="JSON list of columns to use when modeling the data. If not given, use all non-index, non-time columns.",
    )
    parser.add_argument(
        "--predict_on_train", action="store_true", help="Whether to return the model's prediction on the training data."
    )
    args = parser.parse_args()

    # Parse index_cols JSON string
    try:
        index_cols = json.loads(re.sub("'", '"', args.index_cols))
        assert isinstance(index_cols, list)
    except (json.decoder.JSONDecodeError, AssertionError) as e:
        parser.error(
            f"Expected --index_cols to be a JSON list. Got {args.index_cols}.\n" f"Caught {type(e).__name__}({e})"
        )
    else:
        args.index_cols = index_cols

    # Parse data_cols JSON string
    try:
        data_cols = json.loads(re.sub("'", '"', args.data_cols))
        assert isinstance(data_cols, list)
    except (json.decoder.JSONDecodeError, AssertionError) as e:
        parser.error(
            f"Expected --data_cols to be a JSON list if given. Got {args.data_cols}.\n"
            f"Caught {type(e).__name__}({e})"
        )
    else:
        args.data_cols = data_cols

    # Parse JSON string for the model and set the model's target_seq_index
    try:
        model = json.loads(re.sub("'", '"', args.model))
        assert isinstance(model, dict)
    except (json.decoder.JSONDecodeError, AssertionError) as e:
        parser.error(
            f"Expected --model to be a JSON dict specifying a Merlion model. Got {args.model}.\n"
            f"Caught {type(e).__name__}({e})"
        )
    else:
        args.model = model

    return args

def main():
    args = parse_args()

    # Read the dataset as a Spark DataFrame, and process it.
    # This will add a TSID_COL_NAME column to identify each time series with a single integer.
    spark = SparkSession.builder.appName("anomaly").getOrCreate()
    df = read_dataset(
        spark=spark,
        file_format=args.file_format,
        path=args.data,
        time_col=args.time_col,
        index_cols=args.index_cols,
        data_cols=args.data_cols,
    )
    if args.time_col is None:
        args.time_col = df.schema.fieldNames()[0]
    args.index_cols = args.index_cols + [TSID_COL_NAME]

    # Use spark to predict anomaly scores for each time series in parallel
    index_fields = [df.schema[c] for c in args.index_cols]
    pred_fields = [StructField(args.time_col, DateType()), StructField("anom_score", FloatType())]
    output_schema = StructType(index_fields + pred_fields)
    anomaly_df = df.groupBy(args.index_cols).applyInPandas(
        lambda pdf: anomaly(
            pdf,
            index_cols=args.index_cols,
            time_col=args.time_col,
            train_test_split=args.train_test_split,
            model=args.model,
            predict_on_train=args.predict_on_train,
        ),
        schema=output_schema,
    )

    write_dataset(df=anomaly_df, time_col=args.time_col, path=args.output_path, file_format=args.file_format)

if __name__ == "__main__":
    main()


import subprocess

import argparse

def main():

    parser = argparse.ArgumentParser(description='Grab a Hardware Component from GitHub and place it in ScopeFoundryHW using git subtree add/pull.')

    parser.add_argument('name', type=str,
                    help='name of hardware')

    parser.add_argument('action', help='add or pull')

    parser.add_argument('--squash', action='store_true',
                            required=False, help='')

    args = parser.parse_args()
    print(args)
    print("-->", args['name'])

if __name__ == "__main__":
    main()


# Tic-Tac-Toe game

from time import sleep
import curses
from os import system

def winner(b, turn):
    players = ("Player 1", "Player 2")
    for i in range(3):
        if (b[i*3] == b[i*3+1] == b[i*3+2] != " " or
            b[i]   == b[i+3]   == b[i+6]   != " "   ):
            return f"{players[turn%2]} wins!"
    if (b[0] == b[4] == b[8] != " " or
        b[2] == b[4] == b[6] != " " ):
        return f"{players[turn%2]} wins!"
    return "No winner"

def main(stdscr):
    y,x = stdscr.getmaxyx()
    y = y//2-3
    x = x//2-5
    curses.curs_set(0)
    curses.mousemask(1)
    board = lambda b: "╔═══╦═══╦═══╗\n║ {} ║ {} ║ {} ║\n╠═══╬═══╬═══╣\n║ {} ║ {} ║ {} ║\n╠═══╬═══╬═══╣\n║ {} ║ {} ║ {} ║\n╚═══╩═══╩═══╝".format(*b)
    b = list(" "*9)
    xs = [2,6,10]
    ys = [1,3,5]
    #print(board(b1))
    #sleep(1)
    #print(board(b2))
    for i,r in enumerate(board(b).split("\n")):
        stdscr.addstr(y+i, x, r)
    turn = 0
    symbols = "XO"
    curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
    curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
    while True:
        key = stdscr.getch()
        if key == curses.KEY_MOUSE:
            _, mx, my, *_ = curses.getmouse()
            rx, ry = mx-x, my-y
            if rx in xs and ry in ys:
                ix, iy = xs.index(rx), ys.index(ry)
                if b[iy*3+ix] == " ":
                    b[iy*3+ix] = symbols[turn%2]
                else: continue
            else: continue
            for i,r in enumerate(board(b).split("\n")):
                stdscr.addstr(y+i, x, r)
            stdscr.addstr(my, mx, symbols[turn%2], curses.color_pair(turn%2+1))
            w = winner(b, turn)
            if w != "No winner":
                for i,r in enumerate(board(b).split("\n")):
                    stdscr.addstr(y+i, x, r)
                stdscr.addstr(y+7, x-1, w)
                stdscr.refresh()
                sleep(3)
                quit()
            if " " not in b:
                stdscr.addstr(y+7, x, w)
                stdscr.refresh()
                sleep(2)
                quit()
            turn += 1
curses.wrapper(main)


import asyncio
import random
import re
import json
from typing import List, Any

import discord
from discord.ext import commands
from discord.ext.commands import Bot

from moosebot.utils import *

class MooseBot:
    prefix = ""
    owner = ""
    admins = []
    currency = ""
    tarkovKey = ""

    def __init__(self, token):
        from moosebot import MooseDb

        self.phone_servers = []
        self.phone_channels = []

        self.token = token
        client = Bot(command_prefix=MooseBot.prefix)
        self.client = client
        self.client.moose = self
        self.database = MooseDb()
        self.db = self.database.db

        client.remove_command('help')

        @client.event
        async def on_ready():
            print("Logged in as {}({})".format(client.user.name, client.user.id))
            print("-----------------------------------------")

            await client.change_presence(activity=discord.Game(name=">cast a line and catch some fish!"))

        @client.event
        async def on_guild_join(guild):
            if guild.system_channel is not None:
                channel = guild.system_channel
            else:
                for c in guild.text_channels:
                    if not c.permissions_for(guild.me).send_messages:
                        continue
                    channel = c
            embed = discord.Embed(title="Thanks for inviting me! I am MooseBot.",
                                  description="I require admin permissions to fully function!", colour=0xb18dff)
            embed.add_field(name="Author", value=f"<@{MooseBot.owner}>")
            embed.add_field(name="Server count", value=f"{len(client.guilds)}")
            embed.add_field(name="Invite me to your server!",
                            value="[Invite link](https://discordapp.com/oauth2/authorize?client_id=445936072288108544&scope=bot&permissions=66186303)")
            embed.add_field(name="Join my server!", value="[Join here!](https://discord.gg/7Jcu6yn)")
            embed.set_thumbnail(url=guild.me.avatar_url_as(format='png'))
            await channel.send(embed=embed)
            self.database.db.lvl.insert_one({'serverid': str(guild.id)})
            self.database.db.xp.insert_one({'serverid': str(guild.id)})

        # @client.event
        # async def on_command_error(ctx, error):
        #     if isinstance(error, commands.CommandNotFound):
        #         print("{} is retarded and '{}' isn't a command.".format(ctx.author.display_name, ctx.message.content))

        @client.event
        async def on_member_join(member):
            winner = random.choice([i for i in member.guild.members if not i.bot]).mention
            choices = ("Welcome {}!", "{} has joined!", "{} is here to kick ass and chew bubblegum, "
                                                        "and we're all out of ass.", "Prepare yourselves, {} is here.",
                       "Pack your things, {} is here...", "{} has finally arrived.", "Ready player {}!",
                       "{} once promised me a bike, they never delivered.", "It's dangerous to go alone, take {}!",
                       "Hide the weed, {} is here!", "Party is over... {} showed up.",
                       "I thought {1} was lame, but now that {0} is here, I'm not sure.")

            server = await self.db.server.find_one({'serverid': str(member.guild.id)})
            await asyncio.gather(generate(str(member.id)))
            if server is None:
                await self.db.server.update_one({'serverid': str(member.guild.id)})
            elif 'welcomechannel' in server:
                welcome = client.get_channel(int(server['welcomechannel']))
                await welcome.send(random.choice(choices).format(member.mention, winner))
            else:
                return
            if 'defaultrole' in server:
                role = discord.utils.get(member.guild.roles, name=server['defaultrole'])
                await member.add_roles(role, reason="Joined server")

        async def generate(user):

            people = self.db.money
            userid = user
            person = people.find_one({'userid': userid})
            if person is None:
                await people.update_one({'userid': userid}, {'$set': {'fish.totalweight': 0}})
                await people.update_one({'userid': userid}, {'$set': {'fish.largestfish': 0}})
                await people.update_one({'userid': userid}, {'$set': {'fish.recentfish': 0}})
                await people.update_one({'userid': userid}, {'$set': {'fish.totalfish': 0}})
                await people.update_one({'userid': userid}, {'$set': {'fish.sincelastsell': 0}})
                await people.update_one({'userid': userid}, {'$set': {'fish.rod': 'None'}})
                await people.update_one({'userid': userid}, {'$set': {'fish.curbait': 'None'}})
                await people.update_one({'userid': userid}, {'$set': {'fish.bait.Bait': 0}})
                await people.update_one({'userid': userid}, {'$set': {'fish.bait.Game Bait': 0}})
                await people.update_one({'userid': userid}, {'$set': {'balance': 0}})
                await people.update_one({'userid': userid}, {'$set': {'daily': 'None'}})
                await people.update_one({'userid': userid}, {'$set': {'weekly': 'None'}})
                await people.update_one({'userid': userid}, {'$push': {'inventory': 'Yeet'}})
                await people.update_one({'userid': userid}, {'$pull': {'inventory': 'Yeet'}})
            else:
                return

        @client.event
        async def on_member_remove(member):
            winner = random.choice([i for i in member.guild.members if not i.bot]).mention
            choices = ("{} is outta here.", "{} is gone.", "Cya later {}!", "{} left.", "Adios {}.", "Sayonara {}",
                       "Don't let the door hit you on the way out {}!", "{1} kicked {0} to a whole new server.",
                       "Finally {} is gone.", "It's about time {} left.", "Time to celebrate {} is gone", "Ciao {}!",
                       "auf Wiedersehen {}!", "Bon voyage {}.", "Shalom {}")
            server = await self.db.server.find_one({'serverid': str(member.guild.id)})
            if server is None:
                await self.db.server.update_one({'serverid': str(member.guild.id)})
            elif 'welcomechannel' in server:
                welcome = client.get_channel(int(server['welcomechannel']))
                await welcome.send(random.choice(choices).format(member.mention, winner))
            else:
                return

        @client.event
        async def on_message(message):
            if isinstance(message.channel, discord.abc.PrivateChannel):
                await asyncio.gather(self.senddm(message))
            else:
                ctx = await client.get_context(message)
                await asyncio.gather(
                    self.rad(message),
                    self.dar(message),
                    self.mobile(ctx)
                )
            await client.process_commands(message)

    def launch(self, token):
        self.client.run(token)

    async def senddm(self, message):
        if message.guild is None:
            if message.author.id == 445936072288108544 or message.author.id == int(MooseBot.owner):
                return
            else:
                me = self.client.get_user(int(MooseBot.owner))
                format = f"**{message.author.display_name}**({message.author.id}): `{message.content}`"
                await me.send(format)

    async def rad(self, message):
        dard = self.client.get_emoji(446703695204450305)
        if message.content == "<:rad:428937672552349698>":
            await message.add_reaction(dard)

    async def dar(self, message):
        radical = self.client.get_emoji(428937672552349698)
        if message.content == "<:dar:446703695204450305>":
            await message.add_reaction(radical)

    # async def saveattach(self, message):
    #     if message.author.id == self.client.user.id:
    #         return None
    #     else:
    #         channel = message.guild.get_channel(449821022846320641)
    #         if len(message.attachments) >= 1:
    #             path = "database/attachments"
    #             for i in message.attachments:
    #                 url = i.url
    #                 data = get_image(url)
    #                 file_name = str(i.id)
    #                 file_type = i.url[-4:]
    #                 types = [".png", ".mp4", ".jpg", ".gif", ".gifv", ".mp3", ".jpeg", ".mov"]
    #                 if file_type in types:
    #                     save_image(path, file_name, data, file_type)
    #                 else:
    #                     file_type = i.url[-5:]
    #                     if file_type in types:
    #                         save_image(path, file_name, data, file_type)
    #                     else:
    #                         file_type = ".png"
    #                         save_image(path, file_name, data, file_type)
    #                 file_type = i.url[-4:]
    #                 file_path = os.path.join(path, file_name + file_type)
    #                 await asyncio.sleep(2)
    #                 if message.guild.id == 427010987334434816:
    #                     await channel.send(file=discord.File(file_path))

    async def mobile(self, ctx):
        channel = ctx.channel
        if ctx.message.author.bot:
            return None
        elif ctx.message.content == ">phone":
            return None
        elif len(ctx.message.embeds) > 0:
            return None
        elif len(ctx.message.attachments) > 0:
            return None
        elif len(self.phone_channels) == 2:
            if channel == self.phone_channels[0]:
                await self.phone_channels[1].send("**{}**#{}: {}".format(ctx.message.author.name,
                                                                         ctx.message.author.discriminator,
                                                                         ctx.message.content))
            elif channel == self.phone_channels[1]:
                await self.phone_channels[0].send("**{}**#{}: {}".format(ctx.message.author.name,
                                                                         ctx.message.author.discriminator,
                                                                         ctx.message.content))

    # async def what(self, ctx):
    #     m = ctx.message.content.lower()
    #
    #     whatlist = ["what", "wat", "wot", "wut", "scuseme"]
    #     for wat in whatlist:
    #         if m.strip(' ?!') == wat:
    #             message2 = await ctx.channel.history(before=ctx.message, limit=1).next()
    #             if message2.author == ctx.message.author:
    #                 await ctx.send("Are you dumb or something?")
    #             elif len(message2.embeds) >= 1:
    #                 await ctx.send("Yeah I'm not sure what they said either.")
    #             else:
    #                 unbolded = re.sub(r"\*\*(.+?)\*\*", r"\1", message2.content)
    #                 message = f"{message2.author.display_name} said: **{unbolded.upper()}**"
    #                 if len(message) > 2000:
    #                     await ctx.send("Yeah I'm not sure what they said either.")
    #                 else:
    #                     await ctx.send(message)

    @staticmethod
    async def is_owner(ctx):
        if str(ctx.author.id) in MooseBot.admins or ctx.author.id == int(MooseBot.owner):
            return True
        else:
            await ctx.send("You do not have permissions to use this command!")

    @staticmethod
    async def is_admin(ctx):
        perm = ctx.author.permissions_in(ctx.channel)
        if perm.administrator or await MooseBot.is_owner(ctx):
            return True
        else:
            return False

    @staticmethod
    async def is_mod(ctx):
        perm = ctx.author.permissions_in(ctx.channel)
        if perm.kick_members or perm.ban_members or await MooseBot.is_admin(ctx):
            return True
        else:
            return False

    @staticmethod
    async def can_kick(ctx):
        perm = ctx.author.permissions_in(ctx.channel)
        if perm.kick_members:
            return True
        else:
            return False

    @staticmethod
    async def can_ban(ctx):
        perm = ctx.author.permissions_in(ctx.channel)
        if perm.ban_members:
            return True

    #
    # async def generate(self, userid):
    #     userid = str(userid.id)
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.totalweight': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.largestfish': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.recentfish': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.totalfish': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.sincelastsell': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.rod': 'None'}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.curbait': 'None'}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.bait.Bait': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'fish.bait.Game Bait': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'balance': 0}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'daily': 'None'}})
    #     await self.db.money.update_one({'userid': userid}, {'$set': {'weekly': 'None'}})
    #     await self.db.money.update_one({'userid': userid}, {'$push': {'inventory': 'Yeet'}})
    #     await self.db.money.update_one({'userid': userid}, {'$pull': {'inventory': 'Yeet'}})


import os
import time
from tqdm import tqdm

import torch
import torchvision
from torch import nn, optim
from torch.utils.data import DataLoader
from tensorboardX import SummaryWriter

from dataset.config import BF_CONFIG, BF_ACTION_CLASS
from model.model import Anticipation_With_Backbone, Anticipation_Without_Backbone
from dataset.breakfast_dataset import BreakfastDataset, collate_fn_with_backbone, collate_fn_without_backbone
import utils.io as io
from model.utils import Mulit_Loss, WarmUpOptimizer

import argparse

# os.environ['CUDA_VISIBLE_DEVICES'] = '1'

def arg_parse():
    parser = argparse.ArgumentParser(description="Anticipation Training.")
    # For model
    parser.add_argument('--use_dec', action="store_false",
                        help='use decoder or not: action="store_false')
    # For dataset
    parser.add_argument('--split_idx', type=int, default=0, choices=[0,1,2,3],
                        help='dataset splited configuration: default=0')
    parser.add_argument('--task', type=str, default='recog_anti', choices=["recog_only", "recog_anti"],
                        help="which task do you want to conduct [recog_only or recog_anti]")
    parser.add_argument('--anti_feat', action="store_true",
                        help="return anticipation features or not: action='store_true'")
    parser.add_argument('--feat_type', type=str, default='offline', choices=["offline", "online"],
                        help="which type of feature do you want to use [offline or online]")
    # For training
    parser.add_argument('--ds', '--dataset', type=str, default='breakfast',
                        help='The dataset you want to train: default=breakfast')
    parser.add_argument('--nw', '--num_workers', type=int, default=0,
                        help='Number of workers used in dataloading: default=0')
    parser.add_argument('--bs', '--batch_size', type=int, default=2,
                        help='the size of minibatch: default=1')
    parser.add_argument('--optim', type=str, default='adam',
                        help='which optimizer to be used: default=adam')
    parser.add_argument('--lr', type=float, default=0.0001,
                        help='learning rate: default=0.0001')
    parser.add_argument('--wd', type=float, default=0.0,
                        help='weight decay: default=0.0')
    parser.add_argument('--warmup', action="store_true",
                        help='warmup stratery: action="store_true"')
    parser.add_argument('--e_epoch', type=int, default=300,
                        help='Number of training epoch: default=300')
    parser.add_argument('--s_epoch', type=int, default=0,
                        help='number of beginning epochs : 0')
    # For logging or saving
    parser.add_argument('--log_dir', type=str, default='./log',
                        help='path to save the log data like loss\accuracy... : ./log')
    parser.add_argument('--exp_ver', '--e_v', type=str, default='v1',
                        help='the version of code, will create subdir in log/ && checkpoints/ ')
    parser.add_argument('--save_dir', type=str, default='./checkpoints',
                        help='path to save the checkpoints: ./checkpoints')
    parser.add_argument('--print_every', type=int, default=10,
                        help='number of steps for printing training and validation loss: 10')
    parser.add_argument('--save_every', type=int, default=20,
                        help='number of steps for saving the model parameters: 20')
    return parser.parse_args()

def train_model_recog_anti():
    # prepare the data
    collate_fn = collate_fn_with_backbone if args.feat_type == "online" else collate_fn_without_backbone
    train_set = BreakfastDataset(mode="trainval", split_idx=args.split_idx, task=args.task, feat_type=args.feat_type, anti_feat=args.anti_feat, preproc=None, over_write=False)
    val_set = BreakfastDataset(mode="test", split_idx=args.split_idx, task=args.task, feat_type=args.feat_type, anti_feat=args.anti_feat, preproc=None, over_write=False, data_aug=False)
    train_dataloader = DataLoader(dataset=train_set, batch_size=args.bs, shuffle=True, num_workers=args.nw, collate_fn=collate_fn)
    val_dataloader = DataLoader(dataset=val_set, batch_size=args.bs, shuffle=True, num_workers=args.nw, collate_fn=collate_fn)
    dataset = {"train": train_set, "val": val_set}
    dataloader = {"train": train_dataloader, "val": val_dataloader}
    phase_list = ["train", 'val']
    print("Preparing data done!!!")

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    print("Training on {}.".format(device))

    # prepare the model
    assert args.use_dec == (args.task=="recog_anti"), f"args.use_dec(={args.use_dec}) should be TRUE if args.task(={args.task}) == recog_anti, vice versa."
    if args.feat_type == "online":
        model = Anticipation_With_Backbone(use_dec=args.use_dec)
    else:
        model = Anticipation_Without_Backbone(use_dec=args.use_dec)
    model.to(device)

    # get the numbers of parameters of the designed model
    param_dict = {}
    for param in model.named_parameters():
        moduler_name = param[0].split('.')[0]
        if moduler_name in param_dict.keys():
            param_dict[moduler_name] += param[1].numel()
        else:
            param_dict[moduler_name] = param[1].numel()
    for k, v in param_dict.items():
        print(f"{k} parameters: {v / 1e6} million.")
    print(f"Parameters in total: {sum(param_dict.values()) / 1e6} million.")

    # build optimizer && criterion
    if args.optim == 'sgd':
        optimizer = optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr, momentum=0.9, weight_decay=args.wd)
    elif args.optim == 'adam':
        optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr, weight_decay=args.wd)
    else:
        optimizer = optim.RMSprop(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr, weight_decay=args.wd)
    if BF_CONFIG['pre_norm']:
        scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5, min_lr=1e-9, verbose=True)
    else:
        optimizer = WarmUpOptimizer(optimizer, BF_CONFIG['d_input'], BF_CONFIG['lr_factor'], BF_CONFIG['warmup_step'])
        # pass

    criterion = Mulit_Loss(reduction='sum', eps=BF_CONFIG['eps'])

    #set up logger
    writer = SummaryWriter(log_dir=args.log_dir + '/' + args.ds + '/' + args.exp_ver)
    io.mkdir_if_not_exists(os.path.join(args.save_dir, args.ds, args.exp_ver), recursive=True)

    # start training
    t1 = time.time()
    train_iter_num = 0
    for epoch in range(args.s_epoch, args.e_epoch):
        loss_list = []
        for phase in phase_list:
            s_t = time.time()
            recog_epoch_loss = 0
            anti_epoch_loss = 0
            recog_sample_num = 0
            anti_sample_num = 0
            pre_iter_loss = 0
            all_epoch_loss = 0
            count = 0
            for data in tqdm(dataloader[phase]):
                # count += 1;
                # if count > 10: break
                obs_feat = data[0]
                obs_labels = data[1]
                obs_pad_num = data[2]
                anti_feat = data[3]
                anti_labels = data[4]
                anti_pad_num = data[5]
                data_dir = data[6]
                obs_itval_gt = data[7]
                anti_itval_gt = data[8]
                obs_feat, obs_labels, anti_feat, anti_labels, obs_itval_gt, anti_itval_gt = obs_feat.to(device), obs_labels.to(device), anti_feat.to(device), anti_labels.to(device), obs_itval_gt.to(device), anti_itval_gt.to(device)
                if phase == 'train':
                    model.train()
                    model.zero_grad()
                    recog_logits, anti_logits, recog_itval, anti_itval, *attn = model(obs_feat, obs_pad_num, anti_pad_num)
                    recog_loss, anti_loss, recog_t_loss, anti_t_loss = criterion(recog_logits, anti_logits, recog_itval, anti_itval, obs_labels, anti_labels, obs_itval_gt, anti_itval_gt)
                    loss = recog_loss * BF_CONFIG["loss_weight"][0] + anti_loss * BF_CONFIG["loss_weight"][1] + recog_t_loss * BF_CONFIG["loss_weight"][2] + anti_t_loss * BF_CONFIG["loss_weight"][3]
                    loss.backward()
                    # torch.nn.utils.clip_grad_norm_(model.parameters(), 1)
                    optimizer.step()
                else:
                    model.eval()
                    with torch.no_grad():
                        recog_logits, anti_logits, recog_itval, anti_itval, *attn = model(obs_feat, obs_pad_num, anti_pad_num)
                        recog_loss, anti_loss, recog_t_loss, anti_t_loss = criterion(recog_logits, anti_logits, recog_itval, anti_itval, obs_labels, anti_labels, obs_itval_gt, anti_itval_gt)
                        loss = recog_loss * BF_CONFIG["loss_weight"][0] + anti_loss * BF_CONFIG["loss_weight"][1] + recog_t_loss * BF_CONFIG["loss_weight"][2] + anti_t_loss * BF_CONFIG["loss_weight"][3]
                # epoch_loss += loss.item() * (labels.shape.numel() - pad_num.sum()).float()
                recog_epoch_loss += recog_loss.item()
                anti_epoch_loss += anti_loss.item()
                all_epoch_loss += loss.item()
                recog_sample_num += (obs_labels.shape.numel() - obs_pad_num.sum())
                anti_sample_num += (anti_labels.shape.numel() - anti_pad_num.sum())
                # plot training loss iteration by tieration
                if phase == 'train':
                    r_loss = recog_loss.item()/(obs_labels.shape.numel() - obs_pad_num.sum())
                    a_loss = anti_loss.item()/(anti_labels.shape.numel() - anti_pad_num.sum())
                    i_loss = r_loss + a_loss
                    writer.add_scalars('train_iter_loss', {'recog': r_loss, 'anti': a_loss, 'all': i_loss}, train_iter_num)
                    # to log the data which might be the outliers
                    if epoch > 50 and (i_loss - pre_iter_loss) > 2:
                        io.mkdir_if_not_exists('./result', recursive=True)
                        if pre_iter_loss == 0:
                            io.write('./result/outlier_data.txt', data_dir, 'w')
                        else:
                            io.write('./result/outlier_data.txt', data_dir, 'a')
                    pre_iter_loss = i_loss
                    train_iter_num += 1
            recog_epoch_loss /= recog_sample_num
            anti_epoch_loss /= anti_sample_num
            loss_list.append([recog_epoch_loss, anti_epoch_loss])
            # print loss
            if epoch == 0 or (epoch % args.print_every) == args.print_every-1:
                e_t = time.time()
                print(f"Phase:[{phase}] Epoch:[{epoch+1}/{args.e_epoch}] All_Loss:[{round(all_epoch_loss, 4)}] Recog_Loss:[{round(recog_epoch_loss, 4)}] Anti_Loss:[{round(anti_epoch_loss, 4)}] Execution_time:[{round(e_t-s_t, 1)}] second")

        # plot loss
        assert len(phase_list) == len(loss_list)
        if len(phase_list) == 2:
            writer.add_scalars('train_val_epoch_loss', {'train_loss': sum(loss_list[0]), 'train_recog_loss': loss_list[0][0], 'train_anti_loss': loss_list[0][1], \
                                                        'val_loss': sum(loss_list[1]), 'val_recog_loss': loss_list[1][0], 'val_anti_loss': loss_list[1][1]}, epoch)
            if BF_CONFIG['pre_norm']:
                scheduler.step(sum(loss_list[1]))
        else:
            writer.add_scalars('trainval_epoch_loss', {'trainval_loss': sum(loss_list[0]), 'recog_loss': loss_list[0][0], 'anti_loss': loss_list[0][1]}, epoch)
        # save training information and checkpoint
        if epoch % args.save_every == (args.save_every - 1) and epoch >= 0:
            opts = {'lr': args.lr, 'b_s': args.bs, 'optim': args.optim, 'use_dec': args.use_dec}
            save_info = {"arguments": opts, "config": BF_CONFIG}
            io.dumps_json(save_info, os.path.join(args.save_dir, args.ds, args.exp_ver, 'training_info.json'))
            save_name = "checkpoint_" + str(epoch+1) + "_epoch.pth"
            torch.save(model.state_dict(), os.path.join(args.save_dir, args.ds, args.exp_ver, save_name))

    writer.close()
    t2 = time.time()
    print("Training finished! It takes {} seconds.".format(round(t2-t1, 1)))

def train_model_recog_only():
    # prepare the data
    collate_fn = collate_fn_with_backbone if args.feat_type == "online" else collate_fn_without_backbone
    train_set = BreakfastDataset(mode="train", split_idx=args.split_idx, task=args.task, feat_type=args.feat_type, anti_feat=args.anti_feat, preproc=None, over_write=False)
    val_set = BreakfastDataset(mode="val", split_idx=args.split_idx, task=args.task, feat_type=args.feat_type, anti_feat=args.anti_feat, preproc=None, over_write=False, data_aug=False)
    train_dataloader = DataLoader(dataset=train_set, batch_size=args.bs, shuffle=True, num_workers=args.nw, collate_fn=collate_fn)
    val_dataloader = DataLoader(dataset=val_set, batch_size=args.bs, shuffle=True, num_workers=args.nw, collate_fn=collate_fn)
    dataset = {"train": train_set, "val": val_set}
    dataloader = {"train": train_dataloader, "val": val_dataloader}
    phase_list = ["train", 'val']
    print("Preparing data done!!!")

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    print("Training on {}!!!".format(device))

    # prepare the model
    assert args.use_dec == (args.task=="recog_anti"), "args.use_dec should be TRUE if args.task==recog_anti, vice versa"
    if args.feat_type == "online":
        model = Anticipation_With_Backbone(use_dec=args.use_dec)
    else:
        model = Anticipation_Without_Backbone(use_dec=args.use_dec)
    model.to(device)

    # get the numbers of parameters of the designed model
    param_dict = {}
    for param in model.named_parameters():
        moduler_name = param[0].split('.')[0]
        if moduler_name in param_dict.keys():
            param_dict[moduler_name] += param[1].numel()
        else:
            param_dict[moduler_name] = param[1].numel()
    for k, v in param_dict.items():
        print(f"{k} Parameters: {v / 1e6} million.")
    print(f"Parameters in total: {sum(param_dict.values()) / 1e6} million.")

    # build optimizer && criterion
    if args.optim == 'sgd':
        optimizer = optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr, momentum=0.9, weight_decay=0)
    elif args.optim == 'adam':
        optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr, weight_decay=0)
    else:
        optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr, weight_decay=0, amsgrad=True)
    # scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=args.scheduler_step, gamma=0.1)
    # for param_group in model.param_groups:
        # param_group['lr'] = new_lr
    # rec_criterion = nn.BCEWithLogitsLoss()
    rec_criterion = nn.CrossEntropyLoss(reduction='sum')    # 'mean' 'sum' 'none'

    #set up logger
    writer = SummaryWriter(log_dir=args.log_dir + '/' + args.ds + '/' + args.exp_ver)
    io.mkdir_if_not_exists(os.path.join(args.save_dir, args.ds, args.exp_ver), recursive=True)

    # start training
    for epoch in range(args.start_epoch, args.epoch):
        loss_list = []
        for phase in phase_list:
            s_t = time.time()
            epoch_loss = 0
            sample_num = 0
            # count = 0
            for data in tqdm(dataloader[phase]):
                import ipdb; ipdb.set_trace()
                # count += 1;
                # if count > 10: break
                feat = data[0]
                labels = data[1]
                pad_num = data[2]
                feat, labels = feat.to(device), labels.to(device)
                if phase == 'train':
                    model.train()
                    model.zero_grad()
                    logits = model(feat, pad_num)
                    loss = rec_criterion(logits.reshape(logits.shape[:-1].numel(), logits.shape[-1]), labels.reshape(labels.shape.numel()))
                    loss.backward()
                    optimizer.step()
                else:
                    model.eval()
                    with torch.no_grad():
                        logits = model(feat, pad_num)
                        loss = rec_criterion(logits.reshape(logits.shape[:-1].numel(), logits.shape[-1]), labels.reshape(labels.shape.numel()))
                # epoch_loss += loss.item() * (labels.shape.numel() - pad_num.sum()).float()
                epoch_loss += loss.item()
                sample_num += (labels.shape.numel() - pad_num.sum()).float()
            epoch_loss /= sample_num
            loss_list.append(epoch_loss)
            # print loss
            if epoch == 0 or (epoch % args.print_every) == 9:
                e_t = time.time()
                print(f"Phase:[{phase}] Epoch:[{epoch+1}/{args.epoch}]  Loss:[{epoch_loss}]  Execution_time:[{round(e_t-s_t, 1)}] second")
        # plot loss
        assert len(phase_list) == len(loss_list)
        if len(phase_list) == 2:
            writer.add_scalars('train_val_loss', {'train': loss_list[0], 'val': loss_list[1]}, epoch)
        else:
            writer.add_scalars('trainval_loss', {'trainval': loss_list[0]}, epoch)
        # save training information and checkpoint
        if epoch % args.save_every == (args.save_every - 1) and epoch >= 0:
            opts = {'lr': args.lr, 'b_s': args.bs, 'optim': args.optim, 'use_dec': args.use_dec}
            save_info = {"arguments": opts, "config": BF_CONFIG, 'parameters': param_dict}
            io.dumps_json(save_info, os.path.join(args.save_dir, args.ds, args.exp_ver, 'training_info.json'))
            save_name = "checkpoint_" + str(epoch+1) + "_epoch.pth"
            torch.save(model.state_dict(), os.path.join(args.save_dir, args.ds, args.exp_ver, save_name))

    writer.close()
    print("Training finished!!!")

if __name__ == "__main__":
    args = arg_parse()
    if args.task == "recog_only":
        train_model_recog_only()
    else:
        train_model_recog_anti()