import cv2
import os
import tkinter as tk
import glob
import tkinter.filedialog
from tkinter import *
from PIL import Image, ImageTk, ImageGrab
from math import sqrt

screen = tk.Tk()
pixelVirtual = tk.PhotoImage(width=1, height=1)
txtvar = tk.StringVar() # Для поля ввода мм в пкс
screen_name_jpg = ()
pic = 0
cnt = 0
tmp1 = [] # Координаты 1-го овала
tmp2 = [] # Координаты 2-го овала

# Захват кадра и сохранение
def jpg_camera():
    global screen_name_jpg
    cap = cv2.VideoCapture(0)
    if cap.isOpened():
        ret, frame = cap.read()
        if ret:
            screen_name_jpg = 'file000.jpg'
            cv2.imwrite(screen_name_jpg, frame)
    cap.release()

# Открытие выбранного изображения
def openfile():
    global pic
    canvas.delete(tk.ALL)
    zz = Image.open(tk.filedialog.askopenfilename(title="Open Photo",
                                                filetypes=(
                                                ("jpeg files", "*.jpg"), ("all files", "*.*"))))
    pic = ImageTk.PhotoImage(zz)
    canvas.create_image(0, 0, anchor='nw', image=pic)

# Сохранение файла с запоминанием места сохранения(создаётся txt файл)
def savefile():
    if not os.path.exists('./config.txt'):
        savefolder = tkinter.filedialog.askdirectory(mustexist=True, title="Выбрать папку для сохранения")
        with open("config.txt", encoding='utf-8', mode="w") as file:
            file.write(savefolder+"\n")
            file.close()
        savefile()
    else:
        with open("config.txt", encoding='utf-8', mode="r") as file:
            savefolder = file.readline()[0:-1]
        filepaths = glob.glob(savefolder + '/' + 'file_*.jpg')
        image = ImageGrab.grab(bbox=(canvas.winfo_rootx(), canvas.winfo_rooty(), canvas.winfo_rootx() + canvas.winfo_width(),
           canvas.winfo_rooty() + canvas.winfo_height()))
        if len(filepaths) == 0:
            image.save("{}file_000.jpg".format(savefolder+'/'))
        else:
            string = filepaths[-1]
            first_index = string.find("_", string.find("file_"))
            last_digits = string[first_index+1: first_index+4]
            image.save("{}file_{:03d}.jpg".format(savefolder+'/', int(last_digits)+1))

# Точка в меcте клика и вырисовка линии
def click(event):
    global cnt, tmp1, tmp2, im, screen_name_jpg, line, text_line
    if cnt == 0 or cnt == 2:
        cnt = 0
        tmp1.clear()
        tmp2.clear()
        canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3,
                      fill="#FF0000", activefill="#00FF00")
        tmp1.extend((event.x, event.y, event.x, event.y))
        print(tmp1)
        cnt += 1
    elif cnt == 1:
        canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3,
                      fill="#FF0000", activefill="#00FF00")
        tmp2.extend((event.x, event.y, event.x, event.y))
        print(tmp2)
        line = canvas.create_line(tmp1[0], tmp1[1], event.x, event.y)
        text_line = canvas.create_text((sum((tmp1[0], event.x))/2)+15, (sum((tmp1[1], event.y))/2)+10,
                      text=linelen(tmp1[0], event.x, tmp1[1], event.y))
        cnt += 1

    print("x: {}, y: {}".format(event.x, event.y))

# Расчёт расстояния
def linelen(x1, x2, y1, y2):
    return "{0:.2f} mm".format(float((sqrt((x2-x1)**2+(y2-y1)**2))*float(txtvar.get())))

# Удаление всех элементов
def clear_items():
    canvas.delete(tk.ALL)

# Ф-ция чтобы удалить запоминание места сохранения
def del_config():
    os.remove('config.txt')

# Ф-ция для передвижения точек
def move_item(event):
    item_teg = tk.CURRENT
    canvas.coords(item_teg, event.x - 3, event.y - 3, event.x + 3, event.y + 3)
    canvas.delete(line)
    canvas.delete(text_line)
    canvas.bind('<ButtonRelease-3>', create_line)

# Ф-ция, перед перемещением получаем координаты для сравнения, чтобы понимать какую точку двигаем
def info(event):
    global x_y_current
    item_teg = tk.CURRENT
    x_y_current = canvas.coords(item_teg)
    x_y_current = x_y_current[0] + 3, x_y_current[1] + 3, x_y_current[2] - 3, x_y_current[3] - 3
    x_y_current = list(map(int, x_y_current))
    print(x_y_current)

# Ф-ция, после передвижения точки строит линию и перезаписывает координаты точки
def create_line(event):
    global line, text_line
    if x_y_current[0] == tmp2[0]:
        line = canvas.create_line((tmp1[0], tmp1[1], event.x, event.y))
        text_line = canvas.create_text((sum((tmp1[0], event.x)) / 2) + 15, (sum((tmp1[1], event.y)) / 2) + 10,
                                       text=linelen(tmp1[0], event.x, tmp1[1], event.y))
        tmp2.clear()
        x_y_current.clear()
        tmp2.extend((event.x, event.y, event.x, event.y))
    elif x_y_current[0] == tmp1[0]:
        line = canvas.create_line((tmp2[0], tmp2[1], event.x, event.y))
        text_line = canvas.create_text((sum((tmp2[0], event.x)) / 2) + 15, (sum((tmp2[1], event.y)) / 2) + 10,
                                       text=linelen(tmp2[0], event.x, tmp2[1], event.y))
        tmp1.clear()
        x_y_current.clear()
        tmp1.extend((event.x, event.y, event.x, event.y))

# Ф-ция для удаления объектов
def delete_item(event):
    item_teg = tk.CURRENT
    canvas.delete(item_teg, event.x - 3, event.y - 3, event.x + 3, event.y + 3)

# Вызов ф-ции для начала работы с кадром
jpg_camera()

# Кнопка для открытия файла
open_btn = tk.Button(screen, text="Открыть файл", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=openfile)
open_btn.place(x=640, y=0)

# Кнопка для сохранения файла
save_btn = tkinter.Button(text="Сохранить в файл", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=savefile)
save_btn.place(x=640, y=30)

# Кнопка чтобы удалить запоминание места сохранения
del_config_btn = tk.Button(screen, text="Удалить привязку", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=del_config)
del_config_btn.place(x=640, y=60)

# Кнопка для очистки окна
clear_btn = tk.Button(screen, text="Удалить ВСЕ элементы", image=pixelVirtual,
                          width=150,
                          height=20,
                          compound="c", command=clear_items)
clear_btn.place(x=640, y=90)

# Поле ввода кол-ва мм в пкс
ent = tk.Entry(screen, textvariable=txtvar)
ent.insert(0, "Тут пкс в мм надо")
ent.place(x=642, y=120)

# Определение размера окна
im = Image.open(screen_name_jpg)
(width_screen, height_screen) = im.size
print("Разрешение изображения:", im.size)

screen.geometry('800x481')
canvas = tk.Canvas(screen, width = width_screen, height = height_screen)
canvas.pack()
photo = ImageTk.PhotoImage(im)
canvas.create_image(0, 0, anchor = 'nw', image = photo)
canvas.place(x = 0, y = 0)
canvas.bind('<Button-1>', click)
canvas.bind('<B3-Motion>', move_item)
canvas.bind('<Button-3>', info)
canvas.bind('<Button-2>', delete_item)
screen.mainloop()

'''
#Сохранение элемента
def save_screen():
    global im, screen_name_jpg
    box = (canvas.winfo_rootx(), canvas.winfo_rooty(), canvas.winfo_rootx() + canvas.winfo_width(),
           canvas.winfo_rooty() + canvas.winfo_height())
    im = ImageGrab.grab(bbox=box)
    im.save(screen_name_jpg)

save_btn = tk.Button(screen, text="Сохранить элементы",
                              command=save_screen)
save_btn.place(x=150, y=480)

'''


from django.urls import path
from . import views

urlpatterns = [
    path('bank/', views.BankDetailsAPIView.as_view(), name='bank'),
    path('bank/<int:id>', views.BankDetailsDetailsAPIView.as_view(),
         name='bankDetails'),
    path('wallet/', views.WalletAPIView.as_view(), name='walletAddress'),
    path('wallet/<int:id>', views.WalletDetailsAPIView.as_view(),
         name='walletAddressDetails'),
    path('transaction/', views.WalletTransactionAPIView.as_view(), name='transaction'),
    path('transaction/<int:id>', views.WalletTransactionDetailsAPIView.as_view(),
         name='transactionDetails'),
    path('withdraw/', views.WalletWithdrawAPIView.as_view(), name='withdraw'),
    path('withdraw/<int:id>', views.WalletWithdrawDetailsAPIView.as_view(),
         name='withdrawDetails'),
    path('walletamount/', views.WalletGetAPI.as_view(), name='walletamount'),
    path('wallettransection/', views.WalletTransectionGetAPI.as_view(),
         name='wallettransection'),
    path('bankshow/', views.WalletBankGetAPI.as_view(), name='bankshow'),
    path('getwithdraw/', views.WalletWithdrawGetAPI.as_view(), name='getwithdraw'),
    path('vendorwithdraw/', views.vendorWithdrawRequest.as_view(),
         name='vendorwithdraw'),
    path('vendorpayment/', views.vendorPayment.as_view(), name='vendorpayment'),
    path('vendorPaymentCancel/', views.vendorPaymentCancel.as_view(),
         name='vendorPaymentCancel'),
    path('sendMail/', views.sendMail.as_view(), name='sendMail'),
    path('emailView/', views.emailView, name='emailView'),
    path('adminPointTransction/', views.adminPointTransction.as_view(), name='adminPointTransction'),

]


from allauth.account import views as allauth_views
from django.urls import re_path
from user_sessions import views as user_sessions_views

from routechoices.dashboard import views

urlpatterns = [
    re_path(r"^$", views.home_view, name="home_view"),
    re_path(r"^account/?$", views.account_edit_view, name="account_edit_view"),
    re_path(r"^account/emails/?$", views.email, name="account_emails"),
    re_path(
        r"^account/change-password/?$",
        allauth_views.password_change,
        name="account_password_change",
    ),
    re_path(
        r"^account/delete/?$", views.account_delete_view, name="account_delete_view"
    ),
    re_path(
        r"^account/sessions/?$",
        view=user_sessions_views.SessionListView.as_view(),
        name="account_session_list",
    ),
    re_path(
        r"^account/sessions/delete-others/?$",
        view=views.CustomSessionDeleteOtherView.as_view(),
        name="account_session_delete_other",
    ),
    re_path(r"^club/?$", views.club_view, name="club_view"),
    re_path(
        r"^club/send-invite/?$", views.club_invite_add_view, name="club_invite_add_view"
    ),
    re_path(
        r"^club/custom-domain/?$",
        views.club_custom_domain_view,
        name="club_custom_domain_view",
    ),
    re_path(
        r"^club/delete/?$",
        views.club_delete_view,
        name="club_delete_view",
    ),
    re_path(
        r"^club/(?P<club_id>[A-Za-z0-9_-]+)/?$",
        views.club_set_view,
        name="club_set_view",
    ),
    re_path(r"^clubs/?$", views.club_select_view, name="club_select_view"),
    re_path(r"^clubs/new/?$", views.club_create_view, name="club_create_view"),
    re_path(r"^devices/?$", views.device_list_view, name="device_list_view"),
    re_path(r"^devices/new/?$", views.device_add_view, name="device_add_view"),
    re_path(r"^devices.csv$", views.device_list_download, name="device_list_download"),
    re_path(r"^maps/?$", views.map_list_view, name="map_list_view"),
    re_path(r"^maps/new/?$", views.map_create_view, name="map_create_view"),
    re_path(r"^maps/draw/?$", views.map_draw_view, name="map_draw_view"),
    re_path(
        r"^maps/upload-kmz/?$", views.map_kmz_upload_view, name="map_upload_kmz_view"
    ),
    re_path(
        r"^maps/upload-gpx/?$", views.map_gpx_upload_view, name="map_upload_gpx_view"
    ),
    re_path(
        r"^maps/(?P<map_id>[A-Za-z0-9_-]+)/?$",
        views.map_edit_view,
        name="map_edit_view",
    ),
    re_path(
        r"^maps/(?P<map_id>[A-Za-z0-9_-]+)/delete/?$",
        views.map_delete_view,
        name="map_delete_view",
    ),
    re_path(r"^events/?$", views.event_list_view, name="event_list_view"),
    re_path(r"^events/new/?$", views.event_create_view, name="event_create_view"),
    re_path(
        r"^events/(?P<event_id>[A-Za-z0-9_-]+)/?$",
        views.event_edit_view,
        name="event_edit_view",
    ),
    re_path(
        r"^events/(?P<event_id>[A-Za-z0-9_-]+)/competitors/?$",
        views.event_competitors_view,
        name="event_competitors_view",
    ),
    re_path(
        r"^events/(?P<event_id>[A-Za-z0-9_-]+)/competitors-printer-friendly/?$",
        views.event_competitors_printer_view,
        name="event_competitors_printer_view",
    ),
    re_path(
        r"^events/(?P<event_id>[A-Za-z0-9_-]+)/delete/?$",
        views.event_delete_view,
        name="event_delete_view",
    ),
    re_path(
        r"^events/(?P<event_id>[A-Za-z0-9_-]+)/route-upload/?$",
        views.event_route_upload_view,
        name="event_route_upload_view",
    ),
    re_path(r"^event-sets/?$", views.event_set_list_view, name="event_set_list_view"),
    re_path(
        r"^event-sets/new/?$", views.event_set_create_view, name="event_set_create_view"
    ),
    re_path(
        r"^event-sets/(?P<event_set_id>[A-Za-z0-9_-]+)/?$",
        views.event_set_edit_view,
        name="event_set_edit_view",
    ),
    re_path(
        r"^event-sets/(?P<event_set_id>[A-Za-z0-9_-]+)/delete/?$",
        views.event_set_delete_view,
        name="event_set_delete_view",
    ),
    re_path(
        r"^quick-event/?$",
        views.quick_event,
        name="quick_event_view",
    ),
    re_path(r"^upgrade/?$", views.upgrade, name="upgrade"),
]


import argparse
import yaml
import pandas as pd
import os
from utils import load_pkl

def subset_df(dataf):
    target_columns = dataf.columns.tolist()[2:5]
    return dataf[target_columns]

def main(args):
    DATASET = args.dataset
    results_root = args.results_root
    is_zero_shot = args.is_zero_shot
    # print(f'Working with {DATASET}; zero-shot? {is_zero_shot}')

    files = os.listdir(results_root)
    files_filtered = [file for file in files if DATASET in file]

    if is_zero_shot:
        files_filtered = [file for file in files_filtered if 'zero_shot' in file]

    print('Working with the following files: ', files_filtered)

    for file in files_filtered:
        path = os.path.join(results_root, file)
        df = load_pkl(path)

        df_subset = subset_df(df)
        # print(df_subset.describe())
        print(df_subset.mean())

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--dataset', type=str,
                        default='CUB',
                        choices=['CUB', 'ABO', 'fashion200k', 'coco', 'f30k'],
                        help='dataset type')
    parser.add_argument('--results_root', type=str, default='CLIP/data/results',
                    help='Configuration file')
    parser.add_argument('--is_zero_shot', type=bool, default=False,
                        help='Do we use CLIP in zero-shot way?')
    args = parser.parse_args()
    main(args)


# import pygame library
import tracemalloc
from tracemalloc import start
import pygame
import time

# initialise the pygame font
pygame.font.init()

# Total window
screen = pygame.display.set_mode((700, 700))

# Title and Icon
pygame.display.set_caption("SUDOKU SOLVER USING BACKTRACKING")
img = pygame.image.load('android.svg')
pygame.display.set_icon(img)

x = 0
y = 0
dif = 500 / 9
val = 0
# Default Sudoku Board.
grid =[
		[7, 8, 0, 4, 0, 0, 1, 2, 0],
		[6, 0, 0, 0, 7, 5, 0, 0, 9],
		[0, 0, 0, 6, 0, 1, 0, 7, 8],
		[0, 0, 7, 0, 4, 0, 2, 6, 0],
		[0, 0, 1, 0, 5, 0, 9, 3, 0],
		[9, 0, 4, 0, 6, 0, 0, 0, 5],
		[0, 7, 0, 3, 0, 0, 0, 1, 2],
		[1, 2, 0, 0, 0, 7, 4, 0, 0],
		[0, 4, 9, 2, 0, 6, 0, 0, 7]
	]

# Load test fonts for future use
font1 = pygame.font.SysFont("comicsans", 30)
font2 = pygame.font.SysFont("comicsans", 10)
def get_cord(pos):
	global x
	x = pos[0]//dif
	global y
	y = pos[1]//dif

# Highlight the cell selected
def draw_box():
	for i in range(2):
		pygame.draw.line(screen, (255, 0, 0), (x * dif-3, (y + i)*dif), (x * dif + dif + 3, (y + i)*dif), 7)
		pygame.draw.line(screen, (255, 0, 0), ( (x + i)* dif, y * dif ), ((x + i) * dif, y * dif + dif), 7)

# Function to draw required lines for making Sudoku grid
def draw():
	# Draw the lines

	for i in range (9):
		for j in range (9):
			if grid[i][j]!= 0:

				# Fill blue color in already numbered grid
				pygame.draw.rect(screen, (0, 153, 153), (i * dif, j * dif, dif + 1, dif + 1))

				# Fill grid with default numbers specified
				text1 = font1.render(str(grid[i][j]), 1, (0, 0, 0))
				screen.blit(text1, (i * dif+17, j * dif+5))
	# Draw lines horizontally and verticallyto form grid
	for i in range(10):
		if i % 3 == 0 :
			thick = 7
		else:
			thick = 1
		pygame.draw.line(screen, (0, 0, 0), (0, i * dif), (500, i * dif), thick)
		pygame.draw.line(screen, (0, 0, 0), (i * dif, 0), (i * dif, 500), thick)

# Fill value entered in cell
def draw_val(val):
	text1 = font1.render(str(val), 1, (0, 0, 0))
	screen.blit(text1, (x * dif + 15, y * dif + 15))

# Raise error when wrong value entered
def raise_error1():
	text1 = font1.render("WRONG !!!", 1, (0, 0, 0))
	screen.blit(text1, (20, 570))
def raise_error2():
	text1 = font1.render("Wrong !!! Not a valid Key", 1, (0, 0, 0))
	screen.blit(text1, (20, 570))

# Check if the value entered in board is valid
def valid(m, i, j, val):
	for it in range(9):
		if m[i][it]== val:#check column
			return False
		if m[it][j]== val:#check row
			return False
	#check square
	it = i//3
	jt = j//3
	for i in range(it * 3, it * 3 + 3):
		for j in range (jt * 3, jt * 3 + 3):
			if m[i][j]== val:
				return False
	return True

# Solves the sudoku board using depth first search
def solve(grid, i, j):
	#print(grid)
	#สร้างตัวแปร save ขึ้นมาเพื่อเก็บค่าที่เป็นไปได้แต่ละช่อง
	save = [
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []],
				[[], [], [], [], [], [], [], [], []]
				]
	# สร้างตัวแปรในการทำ loop ตรวจสอบแต่ละ squre
	i_ref = 0
	j_ref = 0
	count = 0
	while i <= 8 and j <= 8 :
		if grid[i][j] == 0 :
			# print("Empty")
			for it in range(1,10) :   #หาค่าที่เป็นไปได้ในช่องนั้นๆ แล้วเก็บเข้า save
				if valid(grid,i,j,it) == True :
					#print(i,j,"= ",it)
					save[i][j].append(it)
			if len(save[i][j]) == 1 :   #ถ้าค่าที่เป็นไปได้มีแค่ค่าเดียวให้ใส่ลงช่อง แล้วเอาค่านั้นออกจากต save
				grid[i][j] = save[i][j][0]
				save[i][j].pop()
			pygame.event.pump()
			screen.fill((255, 255, 255))
			draw()
			draw_box()
			pygame.display.update()
			pygame.time.delay(80)
		# else :
		# 	print(grid[i][j])
		if i - i_ref < 2 :
			i+=1
		else :
			if j - j_ref < 2 :
				i = i_ref
				j += 1
			else :
				#print(save)
				i_ref += 3
				i = i_ref
				j = j_ref
				count += 1
				if (count)%3 == 0 and count != 0:
					# print("New squre")
					j_ref += 3
					j = j_ref
					i_ref = 0
					i = i_ref
	#print(save)
	for i_check in range(8) :    #เช็ค save ว่ายังมีค่าที่เป็นไปได้เหลือป่าว ถ้าเหลือก็ recursive ถ้าไม่เหลือก็เสร็จ
		for j_check in range(8) :
			if save[i_check][j_check] != [] :
				#print(save[i_check][j_check])
				solve(grid,0,0)
				break
	#save.sort()

	# print(save[0][2])
	#print(grid)
# Display instruction for the game
def instruction():
	text1 = font2.render("PRESS D TO RESET TO DEFAULT / R TO EMPTY", 1, (0, 0, 0))
	text2 = font2.render("ENTER VALUES AND PRESS ENTER TO VISUALIZE", 1, (0, 0, 0))
	screen.blit(text1, (20, 520))
	screen.blit(text2, (20, 540))

# Display options when solved
def result():
	text1 = font1.render("FINISHED PRESS R or D", 1, (0, 0, 0))
	screen.blit(text1, (20, 570))
run = True
flag1 = 0
flag2 = 0
rs = 0
error = 0

# The loop thats keep the window running
while run:

	# White color background
	screen.fill((255, 255, 255))

	# Loop through the events stored in event.get()
	for event in pygame.event.get():
		# Quit the game window
		if event.type == pygame.QUIT:
			run = False
		# Get the mouse position to insert number
		if event.type == pygame.MOUSEBUTTONDOWN:
			flag1 = 1
			pos = pygame.mouse.get_pos()
			get_cord(pos)
		# Get the number to be inserted if key pressed
		if event.type == pygame.KEYDOWN:
			if event.key == pygame.K_LEFT:
				x-= 1
				flag1 = 1
			if event.key == pygame.K_RIGHT:
				x+= 1
				flag1 = 1
			if event.key == pygame.K_UP:
				y-= 1
				flag1 = 1
			if event.key == pygame.K_DOWN:
				y+= 1
				flag1 = 1
			if event.key == pygame.K_1:
				val = 1
			if event.key == pygame.K_2:
				val = 2
			if event.key == pygame.K_3:
				val = 3
			if event.key == pygame.K_4:
				val = 4
			if event.key == pygame.K_5:
				val = 5
			if event.key == pygame.K_6:
				val = 6
			if event.key == pygame.K_7:
				val = 7
			if event.key == pygame.K_8:
				val = 8
			if event.key == pygame.K_9:
				val = 9
			if event.key == pygame.K_RETURN:
				flag2 = 1

			# If R pressed clear the sudoku board
			if event.key == pygame.K_r:
				rs = 0
				error = 0
				flag2 = 0
				grid =[
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0],
				[0, 0, 0, 0, 0, 0, 0, 0, 0]
				]
			# If D is pressed reset the board to default
			if event.key == pygame.K_d:
				rs = 0
				error = 0
				flag2 = 0
				grid =[
					[7, 8, 0, 4, 0, 0, 1, 2, 0],
					[6, 0, 0, 0, 7, 5, 0, 0, 9],
					[0, 0, 0, 6, 0, 1, 0, 7, 8],
					[0, 0, 7, 0, 4, 0, 2, 6, 0],
					[0, 0, 1, 0, 5, 0, 9, 3, 0],
					[9, 0, 4, 0, 6, 0, 0, 0, 5],
					[0, 7, 0, 3, 0, 0, 0, 1, 2],
					[1, 2, 0, 0, 0, 7, 4, 0, 0],
					[0, 4, 9, 2, 0, 6, 0, 0, 7]
				]

	if flag2 == 1:
		tracemalloc.start()
		start_time = time.time()
		if solve(grid, 0, 0)== False:
			error = 1
		else:
			rs = 1
		elasped_time = time.time()-start_time
		print("time=",end='')
		print(elasped_time)
		flag2 = 0
		print(tracemalloc.get_traced_memory())
		tracemalloc.stop()
	if val != 0:
		draw_val(val)
		# print(x)
		# print(y)
		if valid(grid, int(x), int(y), val)== True:
			grid[int(x)][int(y)]= val
			flag1 = 0
		else:
			grid[int(x)][int(y)]= 0
			raise_error2()
		val = 0

	if error == 1:
		raise_error1()
	if rs == 1:
		result()
	draw()
	if flag1 == 1:
		draw_box()
	instruction()

	# Update window
	pygame.display.update()

# Quit pygame window
pygame.quit()


import inspect
import string
import warnings
from collections import Counter

from vectorbt import _typing as tp
from vectorbt.base.array_wrapper import Wrapping
from vectorbt.utils import checks
from vectorbt.utils.attr_ import get_dict_attr
from vectorbt.utils.config import Config, merge_dicts, get_func_arg_names
from vectorbt.utils.figure import make_subplots, get_domain
from vectorbt.utils.tags import match_tags
from vectorbt.utils.template import deep_substitute

class MetaPlotsBuilderMixin(type):
    """Meta class that exposes a read-only class property `PlotsBuilderMixin.subplots`."""

    @property
    def subplots(cls) -> Config:
        """Subplots supported by `PlotsBuilderMixin.plots`."""
        return cls._subplots

class PlotsBuilderMixin(metaclass=MetaPlotsBuilderMixin):
    """Mixin that implements `PlotsBuilderMixin.plots`.

    Required to be a subclass of `vectorbt.base.array_wrapper.Wrapping`."""

    def __init__(self):
        checks.assert_instance_of(self, Wrapping)

        # Copy writeable attrs
        self._subplots = self.__class__._subplots.copy()

    @property
    def writeable_attrs(self) -> tp.Set[str]:
        """Set of writeable attributes that will be saved/copied along with the config."""
        return {'_subplots'}

    @property
    def plots_defaults(self) -> tp.Kwargs:
        """Defaults for `PlotsBuilderMixin.plots`.

        See `plots_builder` in `vectorbt._settings.settings`."""
        from vectorbt._settings import settings
        plots_builder_cfg = settings['plots_builder']

        return merge_dicts(
            plots_builder_cfg,
            dict(settings=dict(freq=self.wrapper.freq))
        )

    _subplots: tp.ClassVar[Config] = Config(
        dict(),
        copy_kwargs=dict(copy_mode='deep')
    )

    @property
    def subplots(self) -> Config:
        """Subplots supported by `${cls_name}`.

        ```json
        ${subplots}
        ```

        Returns `${cls_name}._subplots`, which gets (deep) copied upon creation of each instance.
        Thus, changing this config won't affect the class.

        To change subplots, you can either change the config in-place, override this property,
        or overwrite the instance variable `${cls_name}._subplots`."""
        return self._subplots

    def plots(self,
              subplots: tp.Optional[tp.MaybeIterable[tp.Union[str, tp.Tuple[str, tp.Kwargs]]]] = None,
              tags: tp.Optional[tp.MaybeIterable[str]] = None,
              column: tp.Optional[tp.Label] = None,
              group_by: tp.GroupByLike = None,
              silence_warnings: tp.Optional[bool] = None,
              template_mapping: tp.Optional[tp.Mapping] = None,
              settings: tp.KwargsLike = None,
              filters: tp.KwargsLike = None,
              subplot_settings: tp.KwargsLike = None,
              show_titles: bool = None,
              hide_id_labels: bool = None,
              group_id_labels: bool = None,
              make_subplots_kwargs: tp.KwargsLike = None,
              **layout_kwargs) -> tp.Optional[tp.BaseFigure]:
        """Plot various parts of this object.

        Args:
            subplots (str, tuple, iterable, or dict): Subplots to plot.

                Each element can be either:

                * a subplot name (see keys in `PlotsBuilderMixin.subplots`)
                * a tuple of a subplot name and a settings dict as in `PlotsBuilderMixin.subplots`.

                The settings dict can contain the following keys:

                * `title`: Title of the subplot. Defaults to the name.
                * `plot_func` (required): Plotting function for custom subplots.
                    Should write the supplied figure `fig` in-place and can return anything (it won't be used).
                * `xaxis_kwargs`: Layout keyword arguments for the x-axis. Defaults to `dict(title='Index')`.
                * `yaxis_kwargs`: Layout keyword arguments for the y-axis. Defaults to empty dict.
                * `tags`, `check_{filter}`, `inv_check_{filter}`, `resolve_plot_func`, `pass_{arg}`,
                    `resolve_path_{arg}`, `resolve_{arg}` and `template_mapping`:
                    The same as in `vectorbt.generic.stats_builder.StatsBuilderMixin` for `calc_func`.
                * Any other keyword argument that overrides the settings or is passed directly to `plot_func`.

                If `resolve_plot_func` is True, the plotting function may "request" any of the
                following arguments by accepting them or if `pass_{arg}` was found in the settings dict:

                * Each of `vectorbt.utils.attr_.AttrResolver.self_aliases`: original object
                    (ungrouped, with no column selected)
                * `group_by`: won't be passed if it was used in resolving the first attribute of `plot_func`
                    specified as a path, use `pass_group_by=True` to pass anyway
                * `column`
                * `subplot_name`
                * `trace_names`: list with the subplot name, can't be used in templates
                * `add_trace_kwargs`: dict with subplot row and column index
                * `xref`
                * `yref`
                * `xaxis`
                * `yaxis`
                * `x_domain`
                * `y_domain`
                * `fig`
                * `silence_warnings`
                * Any argument from `settings`
                * Any attribute of this object if it meant to be resolved
                    (see `vectorbt.utils.attr_.AttrResolver.resolve_attr`)

                !!! note
                    Layout-related resolution arguments such as `add_trace_kwargs` are unavailable
                    before filtering and thus cannot be used in any templates but can still be overridden.

                Pass `subplots='all'` to plot all supported subplots.
            tags (str or iterable): See `tags` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            column (str): See `column` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            group_by (any): See `group_by` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            silence_warnings (bool): See `silence_warnings` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            template_mapping (mapping): See `template_mapping` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.

                Applied on `settings`, `make_subplots_kwargs`, and `layout_kwargs`, and then on each subplot settings.
            filters (dict): See `filters` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            settings (dict): See `settings` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            subplot_settings (dict): See `metric_settings` in `vectorbt.generic.stats_builder.StatsBuilderMixin`.
            show_titles (bool): Whether to show the title of each subplot.
            hide_id_labels (bool): Whether to hide identical legend labels.

                Two labels are identical if their name, marker style and line style match.
            group_id_labels (bool): Whether to group identical legend labels.
            make_subplots_kwargs (dict): Keyword arguments passed to `plotly.subplots.make_subplots`.
            **layout_kwargs: Keyword arguments used to update the layout of the figure.

        !!! note
            `PlotsBuilderMixin` and `vectorbt.generic.stats_builder.StatsBuilderMixin` are very similar.
            Some artifacts follow the same concept, just named differently:

            * `plots_defaults` vs `stats_defaults`
            * `subplots` vs `metrics`
            * `subplot_settings` vs `metric_settings`

            See further notes under `vectorbt.generic.stats_builder.StatsBuilderMixin`.

        Usage:
            See `vectorbt.portfolio.base` for examples.
        """
        from vectorbt._settings import settings as _settings
        plotting_cfg = _settings['plotting']

        # Resolve defaults
        if silence_warnings is None:
            silence_warnings = self.plots_defaults['silence_warnings']
        if show_titles is None:
            show_titles = self.plots_defaults['show_titles']
        if hide_id_labels is None:
            hide_id_labels = self.plots_defaults['hide_id_labels']
        if group_id_labels is None:
            group_id_labels = self.plots_defaults['group_id_labels']
        template_mapping = merge_dicts(self.plots_defaults['template_mapping'], template_mapping)
        filters = merge_dicts(self.plots_defaults['filters'], filters)
        settings = merge_dicts(self.plots_defaults['settings'], settings)
        subplot_settings = merge_dicts(self.plots_defaults['subplot_settings'], subplot_settings)
        make_subplots_kwargs = merge_dicts(self.plots_defaults['make_subplots_kwargs'], make_subplots_kwargs)
        layout_kwargs = merge_dicts(self.plots_defaults['layout_kwargs'], layout_kwargs)

        # Replace templates globally (not used at subplot level)
        if len(template_mapping) > 0:
            sub_settings = deep_substitute(settings, mapping=template_mapping)
            sub_make_subplots_kwargs = deep_substitute(make_subplots_kwargs, mapping=template_mapping)
            sub_layout_kwargs = deep_substitute(layout_kwargs, mapping=template_mapping)
        else:
            sub_settings = settings
            sub_make_subplots_kwargs = make_subplots_kwargs
            sub_layout_kwargs = layout_kwargs

        # Resolve self
        reself = self.resolve_self(
            cond_kwargs=sub_settings,
            impacts_caching=False,
            silence_warnings=silence_warnings
        )

        # Prepare subplots
        if subplots is None:
            subplots = reself.plots_defaults['subplots']
        if subplots == 'all':
            subplots = reself.subplots
        if isinstance(subplots, dict):
            subplots = list(subplots.items())
        if isinstance(subplots, (str, tuple)):
            subplots = [subplots]

        # Prepare tags
        if tags is None:
            tags = reself.plots_defaults['tags']
        if isinstance(tags, str) and tags == 'all':
            tags = None
        if isinstance(tags, (str, tuple)):
            tags = [tags]

        # Bring to the same shape
        new_subplots = []
        for i, subplot in enumerate(subplots):
            if isinstance(subplot, str):
                subplot = (subplot, reself.subplots[subplot])
            if not isinstance(subplot, tuple):
                raise TypeError(f"Subplot at index {i} must be either a string or a tuple")
            new_subplots.append(subplot)
        subplots = new_subplots

        # Handle duplicate names
        subplot_counts = Counter(list(map(lambda x: x[0], subplots)))
        subplot_i = {k: -1 for k in subplot_counts.keys()}
        subplots_dct = {}
        for i, (subplot_name, _subplot_settings) in enumerate(subplots):
            if subplot_counts[subplot_name] > 1:
                subplot_i[subplot_name] += 1
                subplot_name = subplot_name + '_' + str(subplot_i[subplot_name])
            subplots_dct[subplot_name] = _subplot_settings

        # Check subplot_settings
        missed_keys = set(subplot_settings.keys()).difference(set(subplots_dct.keys()))
        if len(missed_keys) > 0:
            raise ValueError(f"Keys {missed_keys} in subplot_settings could not be matched with any subplot")

        # Merge settings
        opt_arg_names_dct = {}
        custom_arg_names_dct = {}
        resolved_self_dct = {}
        mapping_dct = {}
        for subplot_name, _subplot_settings in list(subplots_dct.items()):
            opt_settings = merge_dicts(
                {name: reself for name in reself.self_aliases},
                dict(
                    column=column,
                    group_by=group_by,
                    subplot_name=subplot_name,
                    trace_names=[subplot_name],
                    silence_warnings=silence_warnings
                ),
                settings
            )
            _subplot_settings = _subplot_settings.copy()
            passed_subplot_settings = subplot_settings.get(subplot_name, {})
            merged_settings = merge_dicts(
                opt_settings,
                _subplot_settings,
                passed_subplot_settings
            )
            subplot_template_mapping = merged_settings.pop('template_mapping', {})
            template_mapping_merged = merge_dicts(template_mapping, subplot_template_mapping)
            template_mapping_merged = deep_substitute(template_mapping_merged, mapping=merged_settings)
            mapping = merge_dicts(template_mapping_merged, merged_settings)
            # safe because we will use deep_substitute again once layout params are known
            merged_settings = deep_substitute(merged_settings, mapping=mapping, safe=True)

            # Filter by tag
            if tags is not None:
                in_tags = merged_settings.get('tags', None)
                if in_tags is None or not match_tags(tags, in_tags):
                    subplots_dct.pop(subplot_name, None)
                    continue

            custom_arg_names = set(_subplot_settings.keys()).union(set(passed_subplot_settings.keys()))
            opt_arg_names = set(opt_settings.keys())
            custom_reself = reself.resolve_self(
                cond_kwargs=merged_settings,
                custom_arg_names=custom_arg_names,
                impacts_caching=True,
                silence_warnings=merged_settings['silence_warnings']
            )

            subplots_dct[subplot_name] = merged_settings
            custom_arg_names_dct[subplot_name] = custom_arg_names
            opt_arg_names_dct[subplot_name] = opt_arg_names
            resolved_self_dct[subplot_name] = custom_reself
            mapping_dct[subplot_name] = mapping

        # Filter subplots
        for subplot_name, _subplot_settings in list(subplots_dct.items()):
            custom_reself = resolved_self_dct[subplot_name]
            mapping = mapping_dct[subplot_name]
            _silence_warnings = _subplot_settings.get('silence_warnings')

            subplot_filters = set()
            for k in _subplot_settings.keys():
                filter_name = None
                if k.startswith('check_'):
                    filter_name = k[len('check_'):]
                elif k.startswith('inv_check_'):
                    filter_name = k[len('inv_check_'):]
                if filter_name is not None:
                    if filter_name not in filters:
                        raise ValueError(f"Metric '{subplot_name}' requires filter '{filter_name}'")
                    subplot_filters.add(filter_name)

            for filter_name in subplot_filters:
                filter_settings = filters[filter_name]
                _filter_settings = deep_substitute(filter_settings, mapping=mapping)
                filter_func = _filter_settings['filter_func']
                warning_message = _filter_settings.get('warning_message', None)
                inv_warning_message = _filter_settings.get('inv_warning_message', None)
                to_check = _subplot_settings.get('check_' + filter_name, False)
                inv_to_check = _subplot_settings.get('inv_check_' + filter_name, False)

                if to_check or inv_to_check:
                    whether_true = filter_func(custom_reself, _subplot_settings)
                    to_remove = (to_check and not whether_true) or (inv_to_check and whether_true)
                    if to_remove:
                        if to_check and warning_message is not None and not _silence_warnings:
                            warnings.warn(warning_message)
                        if inv_to_check and inv_warning_message is not None and not _silence_warnings:
                            warnings.warn(inv_warning_message)

                        subplots_dct.pop(subplot_name, None)
                        custom_arg_names_dct.pop(subplot_name, None)
                        opt_arg_names_dct.pop(subplot_name, None)
                        resolved_self_dct.pop(subplot_name, None)
                        mapping_dct.pop(subplot_name, None)
                        break

        # Any subplots left?
        if len(subplots_dct) == 0:
            if not silence_warnings:
                warnings.warn("No subplots to plot", stacklevel=2)
            return None

        # Set up figure
        rows = sub_make_subplots_kwargs.pop('rows', len(subplots_dct))
        cols = sub_make_subplots_kwargs.pop('cols', 1)
        specs = sub_make_subplots_kwargs.pop('specs', [[{} for _ in range(cols)] for _ in range(rows)])
        row_col_tuples = []
        for row, row_spec in enumerate(specs):
            for col, col_spec in enumerate(row_spec):
                if col_spec is not None:
                    row_col_tuples.append((row + 1, col + 1))
        shared_xaxes = sub_make_subplots_kwargs.pop('shared_xaxes', True)
        shared_yaxes = sub_make_subplots_kwargs.pop('shared_yaxes', False)
        default_height = plotting_cfg['layout']['height']
        default_width = plotting_cfg['layout']['width'] + 50
        min_space = 10  # space between subplots with no axis sharing
        max_title_spacing = 30
        max_xaxis_spacing = 50
        max_yaxis_spacing = 100
        legend_height = 50
        if show_titles:
            title_spacing = max_title_spacing
        else:
            title_spacing = 0
        if not shared_xaxes and rows > 1:
            xaxis_spacing = max_xaxis_spacing
        else:
            xaxis_spacing = 0
        if not shared_yaxes and cols > 1:
            yaxis_spacing = max_yaxis_spacing
        else:
            yaxis_spacing = 0
        if 'height' in sub_layout_kwargs:
            height = sub_layout_kwargs.pop('height')
        else:
            height = default_height + title_spacing
            if rows > 1:
                height *= rows
                height += min_space * rows - min_space
                height += legend_height - legend_height * rows
                if shared_xaxes:
                    height += max_xaxis_spacing - max_xaxis_spacing * rows
        if 'width' in sub_layout_kwargs:
            width = sub_layout_kwargs.pop('width')
        else:
            width = default_width
            if cols > 1:
                width *= cols
                width += min_space * cols - min_space
                if shared_yaxes:
                    width += max_yaxis_spacing - max_yaxis_spacing * cols
        if height is not None:
            if 'vertical_spacing' in sub_make_subplots_kwargs:
                vertical_spacing = sub_make_subplots_kwargs.pop('vertical_spacing')
            else:
                vertical_spacing = min_space + title_spacing + xaxis_spacing
            if vertical_spacing is not None and vertical_spacing > 1:
                vertical_spacing /= height
            legend_y = 1 + (min_space + title_spacing) / height
        else:
            vertical_spacing = sub_make_subplots_kwargs.pop('vertical_spacing', None)
            legend_y = 1.02
        if width is not None:
            if 'horizontal_spacing' in sub_make_subplots_kwargs:
                horizontal_spacing = sub_make_subplots_kwargs.pop('horizontal_spacing')
            else:
                horizontal_spacing = min_space + yaxis_spacing
            if horizontal_spacing is not None and horizontal_spacing > 1:
                horizontal_spacing /= width
        else:
            horizontal_spacing = sub_make_subplots_kwargs.pop('horizontal_spacing', None)
        if show_titles:
            _subplot_titles = []
            for i in range(len(subplots_dct)):
                _subplot_titles.append('$title_' + str(i))
        else:
            _subplot_titles = None
        fig = make_subplots(
            rows=rows,
            cols=cols,
            specs=specs,
            shared_xaxes=shared_xaxes,
            shared_yaxes=shared_yaxes,
            subplot_titles=_subplot_titles,
            vertical_spacing=vertical_spacing,
            horizontal_spacing=horizontal_spacing,
            **sub_make_subplots_kwargs
        )
        sub_layout_kwargs = merge_dicts(dict(
            showlegend=True,
            width=width,
            height=height,
            legend=dict(
                orientation="h",
                yanchor="bottom",
                y=legend_y,
                xanchor="right",
                x=1,
                traceorder='normal'
            )
        ), sub_layout_kwargs)
        fig.update_layout(**sub_layout_kwargs)  # final destination for sub_layout_kwargs

        # Plot subplots
        arg_cache_dct = {}
        for i, (subplot_name, _subplot_settings) in enumerate(subplots_dct.items()):
            try:
                final_kwargs = _subplot_settings.copy()
                opt_arg_names = opt_arg_names_dct[subplot_name]
                custom_arg_names = custom_arg_names_dct[subplot_name]
                custom_reself = resolved_self_dct[subplot_name]
                mapping = mapping_dct[subplot_name]

                # Compute figure artifacts
                row, col = row_col_tuples[i]
                xref = 'x' if i == 0 else 'x' + str(i + 1)
                yref = 'y' if i == 0 else 'y' + str(i + 1)
                xaxis = 'xaxis' + xref[1:]
                yaxis = 'yaxis' + yref[1:]
                x_domain = get_domain(xref, fig)
                y_domain = get_domain(yref, fig)
                subplot_layout_kwargs = dict(
                    add_trace_kwargs=dict(row=row, col=col),
                    xref=xref,
                    yref=yref,
                    xaxis=xaxis,
                    yaxis=yaxis,
                    x_domain=x_domain,
                    y_domain=y_domain,
                    fig=fig,
                    pass_fig=True  # force passing fig
                )
                for k in subplot_layout_kwargs:
                    opt_arg_names.add(k)
                    if k in final_kwargs:
                        custom_arg_names.add(k)
                final_kwargs = merge_dicts(subplot_layout_kwargs, final_kwargs)
                mapping = merge_dicts(subplot_layout_kwargs, mapping)
                final_kwargs = deep_substitute(final_kwargs, mapping=mapping)

                # Clean up keys
                for k, v in list(final_kwargs.items()):
                    if k.startswith('check_') or k.startswith('inv_check_') or k in ('tags',):
                        final_kwargs.pop(k, None)

                # Get subplot-specific values
                _column = final_kwargs.get('column')
                _group_by = final_kwargs.get('group_by')
                _silence_warnings = final_kwargs.get('silence_warnings')
                title = final_kwargs.pop('title', subplot_name)
                plot_func = final_kwargs.pop('plot_func', None)
                xaxis_kwargs = final_kwargs.pop('xaxis_kwargs', None)
                yaxis_kwargs = final_kwargs.pop('yaxis_kwargs', None)
                resolve_plot_func = final_kwargs.pop('resolve_plot_func', True)
                use_caching = final_kwargs.pop('use_caching', True)

                if plot_func is not None:
                    # Resolve plot_func
                    if resolve_plot_func:
                        if not callable(plot_func):
                            passed_kwargs_out = {}

                            def _getattr_func(obj: tp.Any,
                                              attr: str,
                                              args: tp.ArgsLike = None,
                                              kwargs: tp.KwargsLike = None,
                                              call_attr: bool = True,
                                              _final_kwargs: tp.Kwargs = final_kwargs,
                                              _opt_arg_names: tp.Set[str] = opt_arg_names,
                                              _custom_arg_names: tp.Set[str] = custom_arg_names,
                                              _arg_cache_dct: tp.Kwargs = arg_cache_dct) -> tp.Any:
                                if attr in final_kwargs:
                                    return final_kwargs[attr]
                                if args is None:
                                    args = ()
                                if kwargs is None:
                                    kwargs = {}
                                if obj is custom_reself and _final_kwargs.pop('resolve_path_' + attr, True):
                                    if call_attr:
                                        return custom_reself.resolve_attr(
                                            attr,
                                            args=args,
                                            cond_kwargs={k: v for k, v in _final_kwargs.items() if k in _opt_arg_names},
                                            kwargs=kwargs,
                                            custom_arg_names=_custom_arg_names,
                                            cache_dct=_arg_cache_dct,
                                            use_caching=use_caching,
                                            passed_kwargs_out=passed_kwargs_out
                                        )
                                    return getattr(obj, attr)
                                out = getattr(obj, attr)
                                if callable(out) and call_attr:
                                    return out(*args, **kwargs)
                                return out

                            plot_func = custom_reself.deep_getattr(
                                plot_func,
                                getattr_func=_getattr_func,
                                call_last_attr=False
                            )

                            if 'group_by' in passed_kwargs_out:
                                if 'pass_group_by' not in final_kwargs:
                                    final_kwargs.pop('group_by', None)
                        if not callable(plot_func):
                            raise TypeError("plot_func must be callable")

                        # Resolve arguments
                        func_arg_names = get_func_arg_names(plot_func)
                        for k in func_arg_names:
                            if k not in final_kwargs:
                                if final_kwargs.pop('resolve_' + k, False):
                                    try:
                                        arg_out = custom_reself.resolve_attr(
                                            k,
                                            cond_kwargs=final_kwargs,
                                            custom_arg_names=custom_arg_names,
                                            cache_dct=arg_cache_dct,
                                            use_caching=use_caching
                                        )
                                    except AttributeError:
                                        continue
                                    final_kwargs[k] = arg_out
                        for k in list(final_kwargs.keys()):
                            if k in opt_arg_names:
                                if 'pass_' + k in final_kwargs:
                                    if not final_kwargs.get('pass_' + k):  # first priority
                                        final_kwargs.pop(k, None)
                                elif k not in func_arg_names:  # second priority
                                    final_kwargs.pop(k, None)
                        for k in list(final_kwargs.keys()):
                            if k.startswith('pass_') or k.startswith('resolve_'):
                                final_kwargs.pop(k, None)  # cleanup

                        # Call plot_func
                        plot_func(**final_kwargs)
                    else:
                        # Do not resolve plot_func
                        plot_func(custom_reself, _subplot_settings)

                # Update global layout
                for annotation in fig.layout.annotations:
                    if 'text' in annotation and annotation['text'] == '$title_' + str(i):
                        annotation['text'] = title
                subplot_layout = dict()
                subplot_layout[xaxis] = merge_dicts(dict(title='Index'), xaxis_kwargs)
                subplot_layout[yaxis] = merge_dicts(dict(), yaxis_kwargs)
                fig.update_layout(**subplot_layout)
            except Exception as e:
                warnings.warn(f"Subplot '{subplot_name}' raised an exception", stacklevel=2)
                raise e

        # Remove duplicate legend labels
        found_ids = dict()
        unique_idx = 0
        for trace in fig.data:
            if 'name' in trace:
                name = trace['name']
            else:
                name = None
            if 'marker' in trace:
                marker = trace['marker']
            else:
                marker = {}
            if 'symbol' in marker:
                marker_symbol = marker['symbol']
            else:
                marker_symbol = None
            if 'color' in marker:
                marker_color = marker['color']
            else:
                marker_color = None
            if 'line' in trace:
                line = trace['line']
            else:
                line = {}
            if 'dash' in line:
                line_dash = line['dash']
            else:
                line_dash = None
            if 'color' in line:
                line_color = line['color']
            else:
                line_color = None

            id = (name, marker_symbol, marker_color, line_dash, line_color)
            if id in found_ids:
                if hide_id_labels:
                    trace['showlegend'] = False
                if group_id_labels:
                    trace['legendgroup'] = found_ids[id]
            else:
                if group_id_labels:
                    trace['legendgroup'] = unique_idx
                found_ids[id] = unique_idx
                unique_idx += 1

        # Remove all except the last title if sharing the same axis
        if shared_xaxes:
            i = 0
            for row in range(rows):
                for col in range(cols):
                    if specs[row][col] is not None:
                        xaxis = 'xaxis' if i == 0 else 'xaxis' + str(i + 1)
                        if row < rows - 1:
                            fig.layout[xaxis]['title'] = None
                        i += 1
        if shared_yaxes:
            i = 0
            for row in range(rows):
                for col in range(cols):
                    if specs[row][col] is not None:
                        yaxis = 'yaxis' if i == 0 else 'yaxis' + str(i + 1)
                        if col > 0:
                            fig.layout[yaxis]['title'] = None
                        i += 1

        # Return the figure
        return fig

    # ############# Docs ############# #

    @classmethod
    def build_subplots_doc(cls, source_cls: tp.Optional[type] = None) -> str:
        """Build subplots documentation."""
        if source_cls is None:
            source_cls = PlotsBuilderMixin
        return string.Template(
            inspect.cleandoc(get_dict_attr(source_cls, 'subplots').__doc__)
        ).substitute(
            {'subplots': cls.subplots.to_doc(), 'cls_name': cls.__name__}
        )

    @classmethod
    def override_subplots_doc(cls, __pdoc__: dict, source_cls: tp.Optional[type] = None) -> None:
        """Call this method on each subclass that overrides `subplots`."""
        __pdoc__[cls.__name__ + '.subplots'] = cls.build_subplots_doc(source_cls=source_cls)

__pdoc__ = dict()
PlotsBuilderMixin.override_subplots_doc(__pdoc__)

{'settings': 'vectorbt._settings.settings', '_settings': 'vectorbt._settings.settings'}.override_subplots_doc


from django.core.management.base import BaseCommand
from django.utils import timezone
from profile_app.models import Roiincome,Package,LevelIncome
from account.models import Account

class Command(BaseCommand):
    help = 'Roi Income'

    def sendLevelIncome(self,userId,income):

        try:
            user = Account.objects.get(id=userId)

            # send 1 level Income...
            firstleveluser = user.sponsor
            if firstleveluser.is_active1 and firstleveluser.is_able_for_income:
                levelincome = LevelIncome(user=firstleveluser, from_user=user,
                level="1", income=(income*15)/100)
                levelincome.save()
                firstleveluser.total_level_income += (income*15)/100
                firstleveluser.total_income += (income*15)/100
                firstleveluser.available_amount += (income*15)/100
                firstleveluser.save()

            # send 2 level Income...
            secondleveluser = firstleveluser.sponsor
            if secondleveluser.is_active1 and secondleveluser.is_able_for_income:
                levelincome = LevelIncome(user=secondleveluser, from_user=user,
                level="2", income=(income*12)/100)
                levelincome.save()
                secondleveluser.total_level_income += (income*12)/100
                secondleveluser.total_income += (income*12)/100
                secondleveluser.available_amount += (income*12)/100
                secondleveluser.save()

            # send 3 level Income...
            thirdleveluser = secondleveluser.sponsor
            if thirdleveluser.is_active1 and thirdleveluser.is_able_for_income:
                levelincome = LevelIncome(user=thirdleveluser, from_user=user,
                level="3", income=(income*9)/100)
                levelincome.save()
                thirdleveluser.total_level_income += (income*9)/100
                thirdleveluser.total_income += (income*9)/100
                thirdleveluser.available_amount += (income*9)/100
                thirdleveluser.save()

            # send 4 level Income...
            fourthleveluser = thirdleveluser.sponsor
            if fourthleveluser.is_active1 and fourthleveluser.is_able_for_income:
                levelincome = LevelIncome(user=fourthleveluser, from_user=user,
                level="4", income=(income*9)/100)
                levelincome.save()
                fourthleveluser.total_level_income += (income*9)/100
                fourthleveluser.total_income += (income*9)/100
                fourthleveluser.available_amount += (income*9)/100
                fourthleveluser.save()

            # send 5 level Income...
            fifthleveluser = fourthleveluser.sponsor
            if fifthleveluser.is_active1 and fifthleveluser.is_able_for_income:
                levelincome = LevelIncome(user=fifthleveluser, from_user=user,
                level="5", income=(income*9)/100)
                levelincome.save()
                fifthleveluser.total_level_income += (income*9)/100
                fifthleveluser.total_income += (income*9)/100
                fifthleveluser.available_amount += (income*9)/100
                fifthleveluser.save()

            # send 6 level Income...
            sixthleveluser = fifthleveluser.sponsor
            if sixthleveluser.is_active1 and sixthleveluser.is_able_for_income:
                levelincome = LevelIncome(user=sixthleveluser, from_user=user,
                level="6", income=(income*6)/100)
                levelincome.save()
                sixthleveluser.total_level_income += (income*6)/100
                sixthleveluser.total_income += (income*6)/100
                sixthleveluser.available_amount += (income*6)/100
                sixthleveluser.save()

            # send 7 level Income...
            sevenleveluser = sixthleveluser.sponsor
            if sevenleveluser.is_active1 and sevenleveluser.is_able_for_income:
                levelincome = LevelIncome(user=sevenleveluser, from_user=user,
                level="7", income=(income*6)/100)
                levelincome.save()
                sevenleveluser.total_level_income += (income*6)/100
                sevenleveluser.total_income += (income*6)/100
                sevenleveluser.available_amount += (income*6)/100
                sevenleveluser.save()

            # send 8 level Income...
            eightleveluser = sevenleveluser.sponsor
            if eightleveluser.is_active1 and eightleveluser.is_able_for_income:
                levelincome = LevelIncome(user=eightleveluser, from_user=user,
                level="8", income=(income*6)/100)
                levelincome.save()
                eightleveluser.total_level_income += (income*6)/100
                eightleveluser.total_income += (income*6)/100
                eightleveluser.available_amount += (income*6)/100
                eightleveluser.save()

            # send 9 level Income...
            nineleveluser = eightleveluser.sponsor
            if nineleveluser.is_active1 and nineleveluser.is_able_for_income:
                levelincome = LevelIncome(user=nineleveluser, from_user=user,
                level="9", income=(income*6)/100)
                levelincome.save()
                nineleveluser.total_level_income += (income*6)/100
                nineleveluser.total_income += (income*6)/100
                nineleveluser.available_amount += (income*6)/100
                nineleveluser.save()

            # send 10 level Income...
            tenleveluser = nineleveluser.sponsor
            if tenleveluser.is_active1 and tenleveluser.is_able_for_income:
                levelincome = LevelIncome(user=tenleveluser, from_user=user,
                level="10", income=(income*6)/100)
                levelincome.save()
                tenleveluser.total_level_income += (income*6)/100
                tenleveluser.total_income += (income*6)/100
                tenleveluser.available_amount += (income*6)/100
                tenleveluser.save()

            # send 11 level Income...
            elevenleveluser = tenleveluser.sponsor
            if elevenleveluser.is_active1 and elevenleveluser.is_able_for_income:
                levelincome = LevelIncome(user=elevenleveluser, from_user=user,
                level="11", income=(income*4)/100)
                levelincome.save()
                elevenleveluser.total_level_income += (income*4)/100
                elevenleveluser.total_income += (income*4)/100
                elevenleveluser.available_amount += (income*4)/100
                elevenleveluser.save()

            # send 12 level Income...
            twelveleveluser = elevenleveluser.sponsor
            if twelveleveluser.is_active1 and twelveleveluser.is_able_for_income:
                levelincome = LevelIncome(user=twelveleveluser, from_user=user,
                level="12", income=(income*4)/100)
                levelincome.save()
                twelveleveluser.total_level_income += (income*4)/100
                twelveleveluser.total_income += (income*4)/100
                twelveleveluser.available_amount += (income*4)/100
                twelveleveluser.save()

            # send 13 level Income...
            thirteenleveluser = twelveleveluser.sponsor
            if thirteenleveluser.is_active1 and thirteenleveluser.is_able_for_income:
                levelincome = LevelIncome(user=thirteenleveluser, from_user=user,
                level="13", income=(income*4)/100)
                levelincome.save()
                thirteenleveluser.total_level_income += (income*4)/100
                thirteenleveluser.total_income += (income*4)/100
                thirteenleveluser.available_amount += (income*4)/100
                thirteenleveluser.save()

            # send 14 level Income...
            fourtheenleveluser = thirteenleveluser.sponsor
            if fourtheenleveluser.is_active1 and fourtheenleveluser.is_able_for_income:
                levelincome = LevelIncome(user=fourtheenleveluser, from_user=user,
                level="14", income=(income*4)/100)
                levelincome.save()
                fourtheenleveluser.total_level_income += (income*4)/100
                fourtheenleveluser.total_income += (income*4)/100
                fourtheenleveluser.available_amount += (income*4)/100
                fourtheenleveluser.save()

            # send 15 level Income...
            fiftheenleveluser = fourtheenleveluser.sponsor
            if fiftheenleveluser.is_active1 and fiftheenleveluser.is_able_for_income:
                levelincome = LevelIncome(user=fiftheenleveluser, from_user=user,
                level="15", income=(income*4)/100)
                levelincome.save()
                fiftheenleveluser.total_level_income += (income*4)/100
                fiftheenleveluser.total_income += (income*4)/100
                fiftheenleveluser.available_amount += (income*4)/100
                fiftheenleveluser.save()

# --------------------------------------------------------------------#
#                      |  # Super Level Income |                      #
# --------------------------------------------------------------------#

            # send 16 level Income...
            sixteenleveluser = fiftheenleveluser.sponsor
            pack50  = Package.objects.get(amount=50)
            if sixteenleveluser.is_active1 and sixteenleveluser.is_able_for_income and pack50 in  sixteenleveluser.supper_packages.all():
                levelincome = LevelIncome(user=sixteenleveluser, from_user=user,
                level="16", income=(income*3)/100)
                levelincome.save()
                sixteenleveluser.total_level_income += (income*3)/100
                sixteenleveluser.total_income += (income*3)/100
                sixteenleveluser.available_amount += (income*3)/100
                sixteenleveluser.save()

            # send 17 level Income...
            seventeenleveluser = sixteenleveluser.sponsor
            if seventeenleveluser.is_active1 and seventeenleveluser.is_able_for_income and pack50 in  seventeenleveluser.supper_packages.all():
                levelincome = LevelIncome(user=sixteenleveluser, from_user=user,
                level="17", income=(income*3)/100)
                levelincome.save()
                seventeenleveluser.total_level_income += (income*3)/100
                seventeenleveluser.total_income += (income*3)/100
                seventeenleveluser.available_amount += (income*3)/100
                seventeenleveluser.save()

            # send 18 level Income...
            eightteenleveluser = seventeenleveluser.sponsor
            if eightteenleveluser.is_active1 and eightteenleveluser.is_able_for_income and pack50 in  eightteenleveluser.supper_packages.all():
                levelincome = LevelIncome(user=eightteenleveluser, from_user=user,
                level="18", income=(income*3)/100)
                levelincome.save()
                eightteenleveluser.total_level_income += (income*3)/100
                eightteenleveluser.total_income += (income*3)/100
                eightteenleveluser.available_amount += (income*3)/100
                eightteenleveluser.save()

            # send 19 level Income...
            nineteenleveluser = eightteenleveluser.sponsor
            pack100  = Package.objects.get(amount=100)
            if nineteenleveluser.is_active1 and nineteenleveluser.is_able_for_income and pack100 in  nineteenleveluser.supper_packages.all():
                levelincome = LevelIncome(user=nineteenleveluser, from_user=user,
                level="19", income=(income*2)/100)
                levelincome.save()
                nineteenleveluser.total_level_income += (income*2)/100
                nineteenleveluser.total_income += (income*2)/100
                nineteenleveluser.available_amount += (income*2)/100
                nineteenleveluser.save()

            # send 20 level Income...
            twenteelevel = nineteenleveluser.sponsor
            if twenteelevel.is_active1 and twenteelevel.is_able_for_income and pack100 in  twenteelevel.supper_packages.all():
                levelincome = LevelIncome(user=twenteelevel, from_user=user,
                level="20", income=(income*2)/100)
                levelincome.save()
                twenteelevel.total_level_income += (income*2)/100
                twenteelevel.total_income += (income*2)/100
                twenteelevel.available_amount += (income*2)/100
                twenteelevel.save()

            # send 21 level Income...
            twenteeonelevel = twenteelevel.sponsor
            pack250  = Package.objects.get(amount=250)
            if twenteeonelevel.is_active1 and twenteeonelevel.is_able_for_income and pack250 in  twenteeonelevel.supper_packages.all():
                levelincome = LevelIncome(user=twenteeonelevel, from_user=user,
                level="21", income=(income*1)/100)
                levelincome.save()
                twenteeonelevel.total_level_income += (income*1)/100
                twenteeonelevel.total_income += (income*1)/100
                twenteeonelevel.available_amount += (income*1)/100
                twenteeonelevel.save()

            # send 22 level Income...
            twenteetwolevel = twenteeonelevel.sponsor
            if twenteetwolevel.is_active1 and twenteetwolevel.is_able_for_income and pack250 in  twenteetwolevel.supper_packages.all():
                levelincome = LevelIncome(user=twenteetwolevel, from_user=user,
                level="22", income=(income*1)/100)
                levelincome.save()
                twenteetwolevel.total_level_income += (income*1)/100
                twenteetwolevel.total_income += (income*1)/100
                twenteetwolevel.available_amount += (income*1)/100
                twenteetwolevel.save()

            # send 23 level Income...
            twenteethreelevel = twenteetwolevel.sponsor
            pack500  = Package.objects.get(amount=500)
            if twenteethreelevel.is_active1 and twenteethreelevel.is_able_for_income and pack250 in  twenteethreelevel.supper_packages.all():
                levelincome = LevelIncome(user=twenteethreelevel, from_user=user,
                level="23", income=(income*1)/100)
                levelincome.save()
                twenteethreelevel.total_level_income += (income*1)/100
                twenteethreelevel.total_income += (income*1)/100
                twenteethreelevel.available_amount += (income*1)/100
                twenteethreelevel.save()

            # send 24 level Income...
            twenteefourlevel = twenteethreelevel.sponsor
            if twenteefourlevel.is_active1 and twenteefourlevel.is_able_for_income and pack250 in  twenteefourlevel.supper_packages.all():
                levelincome = LevelIncome(user=twenteefourlevel, from_user=user,
                level="24", income=(income*1)/100)
                levelincome.save()
                twenteefourlevel.total_level_income += (income*1)/100
                twenteefourlevel.total_income += (income*1)/100
                twenteefourlevel.available_amount += (income*1)/100
                twenteefourlevel.save()

            # send 25 level Income...
            twenteefivelevel = twenteefourlevel.sponsor
            if twenteefivelevel.is_active1 and twenteefivelevel.is_able_for_income and pack250 in  twenteefivelevel.supper_packages.all():
                levelincome = LevelIncome(user=twenteefivelevel, from_user=user,
                level="24", income=(income*1)/100)
                levelincome.save()
                twenteefivelevel.total_level_income += (income*1)/100
                twenteefivelevel.total_income += (income*1)/100
                twenteefivelevel.available_amount += (income*1)/100
                twenteefivelevel.save()

        except Exception as e:
            print(e)

    def handle(self, *args, **kwargs):
        try:
            allActiveUsers = Account.objects.filter(is_active1=True)
            for user in allActiveUsers:
                if user.is_able_for_income:
                    for package in user.packages.all():
                        if Roiincome.objects.filter(user=user, package=package).count() <= 300:
                            income = (package.amount*1)/100
                            roi_obj = Roiincome(user=user, package=package, income=income)
                            roi_obj.save()

                            #update roiincome....
                            user.total_roi_income += income

                            #update available income.....
                            user.available_amount += income

                            # update total income.....
                            user.total_income += income

                            user.save()

                            self.sendLevelIncome(user.id,income)

        except Exception as e:
            print(e)


import logging
import sys
import os
import os.path
from copy import deepcopy
from xml.etree import ElementTree
import csv

logger = logging.getLogger('x4.' + __name__)

def require_python_version(major, minor):
    if sys.version_info.major < major or sys.version_info.minor < minor:
        logger.error('This script requires python 3.6 or higher.')
        exit(0)

def get_config():
    try:
        config = __import__('config')
    except ImportError:
        logger.exception('config.py not found, please run setup.sh before using this script!')
        exit(1)
    return config

class ModUtilMixin(object):

    @classmethod
    def clone(cls, xml):
        return deepcopy(xml)

    @classmethod
    def read_xml(cls, filepath, allow_fail=False):
        try:
            xml = ElementTree.parse(filepath)
        except Exception:
            if allow_fail:
                logger.info('read_xml failed', extra=dict(filepath=filepath, allow_fail=allow_fail))
                return
            logger.exception('read_xml error!', extra=dict(filepath=filepath, allow_fail=allow_fail))
            raise
        return xml

    @classmethod
    def write_xml(cls, filename, xml):
        os.makedirs(os.path.dirname(filename), exist_ok=True)
        with open(filename, 'wb') as of:
            xml.write(of, encoding='utf-8', xml_declaration=True)

    @classmethod
    def set_xml(cls, xml, path, key, value_template, row, label):
        el = xml.find(path)
        if el is None:
            logger.warning("path '{}' not found in {}".format(path, label))
            exit(0)
        try:
            value = value_template.format(**row)
        except Exception:
            logger.error('set_xml: {}, {}'.format(value_template, row), exc_info=True)
            exit(0)
        if value != '':
            # skip on blank value
            el.set(key, value)
        return True

    @classmethod
    def update_xml(cls, xml, row, mapping, label):
        for path, key, value_template in mapping:
            cls.set_xml(xml, path, key, value_template, row, label=label)

    @classmethod
    def get_macros(cls, src_path):
        xml = cls.read_xml(src_path + '/index/macros.xml')
        return {e.get('name'): e.get('value').replace('\\', '/') for e in xml.findall('./entry')}

    @classmethod
    def get_components(cls, src_path):
        xml = cls.read_xml(src_path + '/index/components.xml')
        return {e.get('name'): e.get('value').replace('\\', '/') for e in xml.findall('./entry')}

    @classmethod
    def get_wares(cls, src_path, allow_fail=False):
        return cls.read_xml(src_path + '/libraries/wares.xml', allow_fail=allow_fail)

    @classmethod
    def get_ts(cls, src_path, allow_fail=False, language=44):
        return cls.read_xml(src_path + '/t/0001-l{:03d}.xml'.format(language), allow_fail=allow_fail)

    @classmethod
    def read_csv(cls, filename: str, csv_data: dict):
        reader_rows = csv.reader(open(filename))
        header = None
        rows = None
        for row in reader_rows:
            col0 = row[0].strip().lower()
            if col0.startswith('h'):
                ware_type = col0[1:].lstrip()
                header = [h for h in row[1:] if h != '']
                rows = csv_data.setdefault(ware_type, [])
            elif col0 == 'd':
                rows.append({h: d for h, d in zip(header, row[1:])})

    @classmethod
    def pat_replace(cls, text, pat, repl_fn):
        out = []
        matches = pat.finditer(text)
        start = 0
        for m in matches:
            out.extend([
                text[start:m.start()],
                repl_fn(*m.groups()),
            ])
            start = m.end()
        out.append(text[start:])
        had_replacements = start > 0
        return u''.join(out), had_replacements


"""
@file lexer.py
@author Nathan Houwaart (nathan.houwaart@student.hu.nl)
@brief This file contains all lexer related functions
@version 0.1
@date 11-05-2021
"""
import sys
import os

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import re

from typing import Tuple, Callable, Optional
from misc.token_types import *
from misc.error_message import generate_error_message

def search_match(
    characters: str,
    token_expressions: List[Tuple[str, TokenTypes]],
    total_index=0
) -> Optional[Tuple[re.match, str]]:
    """Function searches for a matching token expression. Starts searching for a match from the given index.

    Args:
        characters          : The characters that need to be matched.
        token_expressions   : A list of tuples each containing a regex string and identifier.
        total_index         : Try to find a match from this index in characters. Can be seen as characters[total_index:].

    Returns:
        If a match is found:
            A tuple containing a match that has been found and a tag saying what token it has found
        If no match was found:
            A tuple containing (None, None)
    """
    if len(token_expressions) == 0:
        return None, None
    head, *tail = token_expressions
    pattern, tag = head

    regex = re.compile(pattern)
    match = regex.match(characters, total_index)
    return (match, tag) if match else search_match(characters, tail, total_index)

def lex(
    characters: str,
    search_match_f: Callable[[str, List[Tuple[str, TokenTypes]], int], Optional[Tuple[re.match, str]]],
    token_expressions: List[Tuple[str, TokenTypes]],
    line_no: int=1,
    index: int=0,
    total_index: int=0
) -> List[Token]:
    """Function converts the provided characters into tokens. Uses a provided function to search for matches in characters

    Args:
        characters          : The characters that need to be lexed.
        search_match_f      : A function to match the provided characters with the provided tokens
        token_expressions   : Try to find a match from this index in characters. Can be seen as characters[total_index:].
        line_no             : The current line number that is being lexed, default=1.
        index               : The current line index that is being lexed, default=0.
        total_index         : The total index in characters that is being lexed, default=0

    Returns:
        If no errors occured:
            Returns a list of lexed tokens
        If no match was found:
            Raises a Syntax Error with a message of where the error occured
    """
    if len(characters) == total_index: # If the end characters has been reached return an EOF token
        return [Token(
            loc_={"start":{"line": line_no, "index":index}, "end":{"line": line_no, "index": index+3}},
            range_=[total_index,total_index+3] ,
            value_="\00",
            tokentype_=TokenTypes.EOF
        )]

    match, tokentype = search_match_f(characters, token_expressions, total_index)
    if not match:
        generate_error_message(line_no, index, characters, "Invalid Syntax", True)

    matched_text    = match.group(0)
    offset          = match.end(0) - match.start(0)
    token_location  = {"start":{"line": line_no, "index":index}, "end":{"line": line_no, "index": index+offset}}
    token_range     = [match.start(0), match.end(0)]

    token   = Token(loc_=token_location, range_=token_range, value_=matched_text, tokentype_=tokentype)

    if tokentype == TokenTypes.NEW_LINE: line_no +=1; index =0; offset = 0
    return [token] + lex(characters, search_match_f, token_expressions, line_no, index + offset, match.end(0))

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("No source file provided")
        exit()

    with open(sys.argv[1], 'rb') as f:
        code = f.read().decode("utf-8")

    lexed = lex(code, search_match, TokenExpressions)
    list(map(print, lexed))


from django.conf.urls import url
from bike import views

urlpatterns=[
    url('post_bike/', views.post_bike),
    url('view_bike/', views.view_bike),
    url('view_user/', views.view_user),
    url('update/(?P<idd>\w+)', views.update, name='update'),
    url('delete/(?P<idd>\w+)', views.delete, name='delete'),
    # url('Rent/(?P<idd>\w+)', views.Rent, name='fg')

]


from trie import Trie

# TrieNode => {children, is_end_word, char, mark_as_leaf(), unmark_as_leaf()}
def total_words(root):
    result = 0

    # Leaf denotes end of a word
    if root.is_end_word:
        result += 1

    for i in range(26):
        # Check if the node has children
        if root.children[i] is not None:
            # Recursively return the word count
            result += total_words(root.children[i])
    return result

keys = ["the", "a", "there", "answer", "any", "by", "bye", "their", "abc"]

trie = Trie()

for key in keys:
    trie.insert(key)

print(total_words(trie.root))


from ball import Ball
from paddle import Paddle
import random

class Game:

    def __init__(self, width : int, height : int, offset=10, max_points=10):
        # boundaries of the game board
        self.w = width
        self.h = height
        # score of the two players
        self.score = [0,0]
        print(self.score[1])
        # game ball
        self.ball = Ball(self.w//2, self.h//2)

        # paddles
        self.paddle1 = Paddle(offset, height//2)
        self.paddle2 = Paddle(width-offset, height//2)
        self.max_points = max_points

    def is_scored(self):
        position = self.ball.get_position()

        if position[1] >= self.w:
            self.score[1] += 1

        if position[0] <= 0:
            self.score[0] += 1

    def collision(self):
        x,y = self.ball.get_position()
        r = self.ball.r

        # check collision with paddles
        if x - r == self.paddle1.x + self.paddle1.w//2 and y <= self.paddle1.y + self.paddle1.l and y >= self.paddle1.y - self.paddle1.l:
            self.ball.dx = -self.ball.dx

        if x + r == self.paddle2.x - self.paddle2.w//2 and y <= self.paddle2.y + self.paddle2.l and y >= self.paddle2.y - self.paddle2.l:
            self.ball.dx = -self.ball.dx

        # change y component of the velocity if a collision on the top or bottom
        if y == r or y == self.h - r:
            self.ball.dy = -self.ball.dy

        # # change x cmoponent of the velocity if a collision on right or left
        if x == r or x == self.w - r:
            self.ball.set_velocity(0,0)
            self.point_scored()
        #     self.ball.dx = -self.ball.dx

    def point_scored(self):
        print(self.score)
        x,_ = self.ball.get_position()
        r = self.ball.r

        if x == r:
            self.score[0] += 1
            if self.score[0] == 10:
                self.game_won()
            self.reset_game()

        elif x == self.w - r:
            self.score[1] += 1
            if self.score[1] == 10:
                self.game_won()
            self.reset_game()

        else:
            print("Something went horribly wrong")

    # function used to reset the game
    def reset_game(self):
        init_velocity = random.choice([[1,1],[1,-1],[-1,1],[-1,-1]])

        self.ball.set_velocity(init_velocity[0], init_velocity[1])
        self.ball.x = self.w//2
        self.ball.y = self.h//2

        if self.score[0] == self.max_points or self.score[1] == self.max_points:
            self.score = [0,0]

    # movement of each paddle
    def move_paddle1(self, addY):

        if self.paddle1.y-self.paddle1.l//2 > 0 and self.paddle1.y+self.paddle1.l//2 < self.h:
            self.paddle1.move(addY)

        if self.paddle1.y-self.paddle1.l//2 == 0 and addY > 0:
            self.paddle1.move(addY)

        if self.paddle1.y+self.paddle1.l//2 == self.h and addY < 0:
            self.paddle1.move(addY)

    def move_paddle2(self, addY):
        if self.paddle2.y - self.paddle2.l // 2 > 0 and self.paddle2.y+self.paddle2.l//2 < self.h:
            self.paddle2.move(addY)

        if self.paddle2.y-self.paddle2.l//2 == 0 and addY > 0:
            self.paddle2.move(addY)

        if self.paddle2.y+self.paddle2.l//2 == self.h and addY < 0:
            self.paddle2.move(addY)

    # update per game loop
    def update(self):
        self.ball.move()
        self.collision()


import csv
import os
import glob
import cv2
import numpy as np

face_ids=[]
all_Image_ID=[]
for infile in sorted(glob.glob(r'C:\Implementations\Ccollected Images\all_faces/*.png')):
    face_ids.append(infile)
    all_Image_ID.append(infile[47:-4])

Neutral = r'C:\Implementations\MultiTask CNN Results\0'
Neutral_Multi_CNN = [name for name in os.listdir(Neutral) if os.path.isdir(os.path.join(Neutral, name))]

Angry = r'C:\Implementations\MultiTask CNN Results\1'
Angry_Multi_CNN = [name for name in os.listdir(Angry) if os.path.isdir(os.path.join(Angry, name))]

Disgust=r'C:\Implementations\MultiTask CNN Results\2'
Disgust_Multi_CNN = [name for name in os.listdir(Disgust) if os.path.isdir(os.path.join(Disgust, name))]

Fear = r'C:\Implementations\MultiTask CNN Results\3'
Fear_Multi_CNN = [name for name in os.listdir(Fear) if os.path.isdir(os.path.join(Fear, name))]

Happy=r'C:\Implementations\MultiTask CNN Results\4'
Happy_Multi_CNN = [name for name in os.listdir(Happy) if os.path.isdir(os.path.join(Happy, name))]

Sad=r'C:\Implementations\MultiTask CNN Results\5'
Sad_Multi_CNN = [name for name in os.listdir(Sad) if os.path.isdir(os.path.join(Sad, name))]

Surprise=r'C:\Implementations\MultiTask CNN Results\6'
Surprise_Multi_CNN = [name for name in os.listdir(Surprise) if os.path.isdir(os.path.join(Surprise, name))]

face_id2=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\angry/*.png')):
    face_id2.append(infile)
angry_CNN_Simple=[]
for i in range(len(face_id2)):
    angry_CNN_Simple.append(face_id2[i][60:-4])

face_id1_=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\disgust/*.png')):
    face_id1_.append(infile)
Disgust_CNN_Simple=[]
for i in range(len(face_id1_)):
    Disgust_CNN_Simple.append(face_id1_[i][62:-4])

face_id3=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\fear/*.png')):
    face_id3.append(infile)
fear_CNN_Simple=[]
for i in range(len(face_id3)):
    fear_CNN_Simple.append(face_id3[i][59:-4])

face_id4=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\happy/*.png')):
    face_id4.append(infile)
happy_CNN_Simple=[]
for i in range(len(face_id4)):
    happy_CNN_Simple.append(face_id4[i][60:-4])

face_id1=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\neutral/*.png')):
    face_id1.append(infile)
Neutral_CNN_Simple=[]
for i in range(len(face_id1)):
    Neutral_CNN_Simple.append(face_id1[i][62:-4])

face_id5=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\sad/*.png')):
    face_id5.append(infile)
sad_CNN_Simple=[]
for i in range(len(face_id5)):
    sad_CNN_Simple.append(face_id5[i][58:-4])

face_id6=[]
for infile in sorted(glob.glob(r'C:\Implementations\SimpleCNN_Emotions+Gender\emotions\surprise/*.png')):
    face_id6.append(infile)
Surprise_CNN_Simple=[]
for i in range(len(face_id6)):
    Surprise_CNN_Simple.append(face_id6[i][58:-4])

face_id1=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\angry/*.png')):
    face_id1.append(infile)
Angry_Xception=[]
for i in range(len(face_id1)):
    Angry_Xception.append(face_id1[i][71:-4])

face_id2=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\disgust/*.png')):
    face_id2.append(infile)
Disgust_Xception=[]
for i in range(len(face_id2)):
    Disgust_Xception.append(face_id2[i][73:-4])

face_id3=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\fear/*.png')):
    face_id3.append(infile)
Fear_Xception=[]
for i in range(len(face_id3)):
   Fear_Xception.append(face_id3[i][70:-4])

face_id4=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\happy/*.png')):
    face_id4.append(infile)
Happy_Xception=[]
for i in range(len(face_id4)):
    Happy_Xception.append(face_id4[i][71:-4])

face_id5=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\neutral/*.png')):
    face_id5.append(infile)
Neutral_Xception=[]
for i in range(len(face_id5)):
    Neutral_Xception.append(face_id5[i][73:-4])

face_id6=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\sad/*.png')):
    face_id6.append(infile)
Sad_Xception=[]
for i in range(len(face_id6)):
    Sad_Xception.append(face_id6[i][69:-4])

face_id7=[]
for infile in sorted(glob.glob(r'C:\Implementations\XCeption_Emotions +Gender\emotion_BigXception\surprise/*.png')):
    face_id7.append(infile)
Surprise_Xception=[]
for i in range(len(face_id7)):
    Surprise_Xception.append(face_id7[i][74:-4])

### OpneFace ####

Angry = r'C:\Implementations\Emotions from AUs of OpenFace\0'
Angry_OpenFace = [name for name in os.listdir(Angry) if os.path.isdir(os.path.join(Angry, name))]

Disgust=r'C:\Implementations\Emotions from AUs of OpenFace\1'
Disgust_OpenFace = [name for name in os.listdir(Disgust) if os.path.isdir(os.path.join(Disgust, name))]

Fear=r'C:\Implementations\Emotions from AUs of OpenFace\2'
Fear_OpenFace = [name for name in os.listdir(Fear) if os.path.isdir(os.path.join(Fear, name))]

Happy=r'C:\Implementations\Emotions from AUs of OpenFace\3'
Happy_OpenFace = [name for name in os.listdir(Happy) if os.path.isdir(os.path.join(Happy, name))]

Sad=r'C:\Implementations\Emotions from AUs of OpenFace\4'
Sad_OpenFace = [name for name in os.listdir(Sad) if os.path.isdir(os.path.join(Sad, name))]

def search(list, platform):
    for i in range(len(list)):
        if list[i] == platform:
            return True
    return False
TH=1

for i in range(1855):

    Image_ID=all_Image_ID[i]

    G=np.zeros([7,1])

    ### 1-Simple_CNN #####
    _yes1 =search(angry_CNN_Simple,Image_ID)
    if _yes1==True:
        G[0]=TH

    _yes2 =search(Disgust_CNN_Simple,Image_ID)
    if _yes2==True:
        G[1]=TH

    _yes3 = search(fear_CNN_Simple,Image_ID)
    if _yes3==True:
        G[2]=TH

    _yes4 =search(happy_CNN_Simple,Image_ID)
    if _yes4==True:
        G[3]=TH
    _yes4_ =search(Neutral_CNN_Simple,Image_ID)
    if _yes4_==True:
        G[4]=TH

    _yes5 =search(sad_CNN_Simple,Image_ID)
    if _yes5==True:
        G[5]=TH

    _yes5 =search(Surprise_CNN_Simple,Image_ID)
    if _yes5==True:
        G[6]=TH

    ### 2-MultiTask_CNN ###
    _yes1 =search(Angry_Multi_CNN,Image_ID)
    if _yes1==True:
        G[0]=TH

    _yes2 =search(Disgust_Multi_CNN,Image_ID)
    if _yes2==True:
        G[1]=TH

    _yes3 = search(Fear_Multi_CNN,Image_ID)
    if _yes3==True:
        G[2]=TH

    _yes4 =search(Happy_Multi_CNN,Image_ID)
    if _yes4==True:
        G[3]=TH
    _yes5 =search(Neutral_Multi_CNN,Image_ID)
    if _yes5==True:
        G[4]=TH

    _yes4 =search(Sad_Multi_CNN,Image_ID)
    if _yes4==True:
        G[5]=TH
    _yes5 =search(Surprise_Multi_CNN,Image_ID)
    if _yes5==True:
        G[6]=TH

    ## 3-Xceptionnet
    _yes1 =search(Angry_Xception,Image_ID)
    if _yes1==True:
        G[0]=TH

    _yes2 =search(Disgust_Xception,Image_ID)
    if _yes2==True:
        G[1]=TH

    _yes3 = search(Fear_Xception,Image_ID)
    if _yes3==True:
        G[2]=TH

    _yes4 =search(Happy_Xception,Image_ID)
    if _yes4==True:
        G[3]=TH

    _yes5 =search(Neutral_Xception,Image_ID)
    if _yes5==True:
        G[4]=TH

    _yes6 =search(Sad_Xception,Image_ID)
    if _yes6==True:
        G[5]=TH

    _yes7 =search(Surprise_Xception,Image_ID)
    if _yes7==True:
        G[6]=TH

    ### 4-OpenFace ####

    _yes1 =search(Angry_OpenFace,Image_ID)
    if _yes1==True:
        G[0]=TH

    _yes2 =search(Disgust_OpenFace,Image_ID)
    if _yes2==True:
        G[1]=TH

    _yes3 = search(Fear_OpenFace,Image_ID)
    if _yes3==True:
        G[2]=TH

    _yes4 =search(Happy_OpenFace,Image_ID)
    if _yes4==True:
        G[3]=TH
    _yes5 =search(Sad_OpenFace,Image_ID)
    if _yes5==True:
        G[5]=TH

    ## genrating the text file
    path=r'C:\Implementations\Multi_Label/'+str(Image_ID)+'.txt'
    with open(path, 'w') as f:
        for item in G:
            #f.write(str(item) + "\n")
            y=' '.join(map(str, item))
            f.write(f"{y}\n")

import os
import glob
import numpy as np

text_path=r'C:\Implementations\Multi_Label/'
def READ_DAT():
    image_w=224
    image_h=224
    img_ = []
    text_=[]
    for i in range(1384):
        img=cv2.imread(face_ids[i])
        Image_ID=all_Image_ID[i]
        img = cv2.resize (img, (image_w,image_h), interpolation = cv2.INTER_AREA)
        img=img/255

        img_.append(img)

        u=text_path+Image_ID+'.txt'
        with open(u) as f:
            lines = f.readlines()
            A=[float(k) for k in lines]
            text_.append(A)

            #for line in f:
                #if line: #avoid blank lines
                    #text_.append(float(line.strip()))

    img_ = np.array(img_)
    text_ = np.array(text_)

    return img_,text_

images,text_files=READ_DAT()

Generate Multi-Class Labels/Generate Multi-Task Labels.py


import json
import boto3

def lambda_handler(event, context):
    region = "us-east-1"
    EC2_RESOURCE = boto3.resource('ec2', region_name=region)
    INSTANCE_NAME_TAG_VALUE = 'DevOps'

    instancesTag = EC2_RESOURCE.instances.filter(
        Filters=[
            {
                'Name': 'tag:Group',
                'Values': [
                INSTANCE_NAME_TAG_VALUE
                ]
            }
        ]
    )

    for instance in instancesTag:
            try:
                instance.stop()
                #print(f'Starting EC2 instance: {instance.id}')
                #instance.wait_until_stopped()
                #print(f'EC2 instance "{instance.id}" has been started')
                print('Parou')
            except:
                print(f'Error stopping {instance}')


#In[]:

import os
import win32com.client as win32
import fitz
import openpyxl

#In[]:

Word_Path = r"C:\Python\MR_APP\MR-App-Repo\Word"
Path_Toetsingen= r"C:\Python\MR_APP\MR-App-Repo\Toetsingen\Botova_1449959 + 1449958 + 1449957 + 1449956_T3.xlsx"
Path_C = r"C:\Python\MR_APP\MR-App-Repo\Certificaten"

#In[]:

# # create a new instance of Word application
# word = win32.gencache.EnsureDispatch('Word.Application')

# # open the document
# doc = word.Documents.Open(Word_Path)

# # save the document as PDF
# pdf_path = os.path.splitext(doc.FullName)[0] + ".pdf"
# doc.ExportAsFixedFormat(pdf_path, win32.constants.wdExportFormatPDF)

# # close the document and quit Word application
# doc.Close()
# word.Quit()

#In[]:

lines = []

# iterate over all files in the folder
for filename in os.listdir(Word_Path):
    if filename.endswith(".pdf"):
        filepath = os.path.join(Word_Path, filename)
        with fitz.open(filepath) as doc:
            # iterate over all pages in the PDF
            for page_num in range(doc.page_count):
                page = doc.load_page(page_num)
                text = page.get_text("text")
                # split the text content into lines and add them to the list
                lines.extend(text.splitlines())

#In[]:

Monster_MHPoly = []
for filename in os.listdir(Path_C):
    f = os.path.join(Path_C, filename)
    # Load the Excel file
    workbook = openpyxl.load_workbook(f)
    # Select the active worksheet
    ws  = workbook.active
    # Iterate through the first 10 rows
    for row in ws.iter_rows(min_row=1, max_row=10):
        # Check if column A contains the target text
        if row[0].value == "Projectomschrijving":
            # Extract values after column C
            Monster_MHPoly.extend(cell.value for cell in row[3:])

#In[]:

Useless_List = []

for val in Monster_MHPoly:
    if val != None :
        Useless_List.append(val)

Monster_MHPoly = Useless_List
Useless_List = []
for x in Monster_MHPoly:
    Useless_List.append(x + " ")

Monster_MHPoly = Useless_List

#In[]:

Index = []
for i, entry in enumerate(lines):
    if "Hoofd grondsoort" in entry:
        Index.append(i)

#In[]:

Output_Monsters = []
Output_Grondstof = []
Useless_List = []
Row = 13942

for x in Index:
    Useless_List = [elem for elem in lines[x-70:x] if elem in Monster_MHPoly]
    Output_Monsters.extend(Useless_List)
    for item in lines[x+2:x+2+len(Useless_List)]:
        Output_Grondstof.append(item)
    Useless_List = []

#In[]:

import pandas as pd

df = pd.DataFrame({'Monster': Output_Monsters, 'Grondsoort': Output_Grondstof})

#In[]:


import os
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression

SCRIPT_PATH = os.path.dirname(os.path.abspath( __file__ ))
dataset = pd.read_csv(SCRIPT_PATH + "/train.csv")

#features = ['Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked']

features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Cabin', 'Embarked']
training_data = dataset[features]

training_label = dataset['Survived']

#from above plt, it showed that Sex/Age/Fare matters in the importance
features = ['Sex', 'Age', 'Fare']
training_data = dataset[features]
training_data = training_data.fillna(0)
training_data['Sex'] = LabelEncoder().fit_transform(training_data['Sex'])#only sex needs to label encode
model = LogisticRegression(penalty='l2', class_weight='balanced', solver='newton-cg')
model.fit(training_data, training_label)

test_data = pd.read_csv(SCRIPT_PATH + "/test.csv")
preidction_data = test_data[features]
preidction_data = preidction_data.fillna(0)
preidction_data['Sex'] = LabelEncoder().fit_transform(preidction_data['Sex'])#only sex needs to label encode
result_labels = model.predict(preidction_data)
results = pd.DataFrame({
    'PassengerId' : test_data['PassengerId'],
    'Survived' : result_labels
})
results.to_csv(SCRIPT_PATH + "/submission5.csv", index=False)

cv_scores = cross_val_score(model, training_data, training_label, scoring = 'roc_auc', cv=5)
print(cv_scores)