import os
import pygame as pg
import sys

pg.init()

size = width, height = (1920, 1080)
screen = pg.display.set_mode(size)

from layout import *
from classes import *

#⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
#⣿⣿⣿⣿⣿⣿⣿⣿⡇⢀⢀⠍⠙⢿⡟⢿⣿⣿⣿⣿⣿⣿⣿⣿
#⠹⣿⣿⣿⣿⣿⣿⣿⠁⠈⢀⡤⢲⣾⣗⠲⣿⣿⣿⣿⣿⣿⣟⠻
#⡀⢙⣿⣿⣿⣿⣿⣿⢀⠰⠁⢰⣾⣿⣿⡇⢀⣿⣿⣿⣿⣿⣿⡄
#⣇⢀⢀⠙⠷⣍⠛⠛⢀⢀⢀⢀⠙⠋⠉⢀⢀⢸⣿⣿⣿⣿⣿⣷
#⡙⠆⢀⣀⠤⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢸⣿⣿⣿⣿⣿⣿
#⣷⣖⠋⠁⢀⢀⢀⢀⢀⢀⣀⣀⣄⢀⢀⢀⢀⢸⠏⣿⣿⣿⢿⣿
#⣿⣷⡀⢀⢀⢀⢀⢀⡒⠉⠉⢀⢀⢀⢀⢀⢀⢈⣴⣿⣿⡿⢀⡿
#⣿⣿⣷⣄⢀⢀⢀⢀⠐⠄⢀⢀⢀⠈⢀⣀⣴⣿⣿⣿⡿⠁⢀⣡
#⠻⣿⣿⣿⣿⣆⠢⣤⣄⢀⢀⣀⠠⢴⣾⣿⣿⡿⢋⠟⢡⣿⣿⣿
#⢀⠘⠿⣿⣿⣿⣦⣹⣿⣀⣀⣀⣀⠘⠛⠋⠁⡀⣄⣴⣿⣿⣿⣿
#⢀⢀⢀⠈⠛⣽⣿⣿⣿⣿⣿⣿⠁⢀⢀⢀⣡⣾⣿⣿⣿⡟⣹⣿
#⢀⢀⢀⢀⢰⣿⣿⣿⣿⣿⣿⣿⣦⣤⣶⣿⡿⢛⢿⡇⠟⠰⣿⣿
#⢀⢀⢀⢀⣿⣿⣿⡿⢉⣭⢭⠏⣿⡿⢸⡏⣼⣿⢴⡇⢸⣿⣶⣿
#⢀⢀⢀⢰⣿⣿⣿⢃⣶⣶⡏⠸⠟⣱⣿⣧⣛⣣⢾⣿⣿⣿⣿⣿
#⢀⢀⢀⣾⣿⣿⣿⣾⣿⣿⠟⢻⡿⡉⣷⣬⡛⣵⣿⣿⣿⣿⣿⣿
#⢀⢀⣸⣿⣿⣿⣿⣿⣿⡿⢰⠘⣰⣇⣿⣿⣰⣿⣿⣿⣿⣿⣿⣿
#⢀⢀⠘⢿⣿⣿⣿⣿⣿⡷⢺⣿⠟⣩⣭⣽⣇⠲⠶⣿⣿⣿⣿⣿
#⢀⠐⢀⣾⣿⣿⣿⣿⠟⢐⡈⣿⣷⣶⠎⣹⡟⠟⣛⣸⣿⣿⣿⣿
#⠠⢀⣼⣿⣿⣿⣿⣯⣼⣿⣷⣿⣷⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿

def toggle_previewing():
	if g.previewing:
		g.previewing = False
		g.music_playing = False
		pg.mixer.music.pause()

	else:
		g.previewing = True

		if g.tmr > 0:
			g.music_playing = True
			pg.mixer.music.unpause()

def toggle_paused():
	if g.editing and not g.previewing:
		if g.paused:
			g.paused = False
		else:
			g.paused = True

	else:
		if g.paused:
			g.paused = False
			if g.music_playing:
				pg.mixer.music.unpause()
		else:
			g.paused = True
			if g.music_playing:
				pg.mixer.music.pause()

def toggle_options():
	pass

def toggle_editing():
	if g.editing:
		g.editing = False
		g.placing = False

		if g.tmr > 0:
			g.music_playing = True
			pg.mixer.music.unpause()

		# Unhide game overlay
		player_portrait.hidden = False
		player_name.hidden = False
		player_desc.hidden = False

		score_img.hidden = False
		score_label.hidden = False
		score_disp.hidden = False

		# Hide editor
		e_name_lbl.hidden = True
		e_name.hidden = True
		e_audio_lbl.hidden = True
		e_audio.hidden = True
		e_bpm.hidden = True
		e_bpm_lbl.hidden = True
		e_load.hidden = True
		e_save.hidden = True

		b_s_lbl.hidden = True
		b_s.hidden = True
		a_s_lbl.hidden = True
		a_s.hidden = True
		o_s_lbl.hidden = True
		o_s.hidden = True

	else:
		g.editing = True
		g.placing = False
		g.previewing = False

		g.music_playing = False
		pg.mixer.music.pause()

		g.tmr_targ = g.tmr

		# Hide game overlay
		player_portrait.hidden = True
		player_name.hidden = True
		player_desc.hidden = True

		score_img.hidden = True
		score_label.hidden = True
		score_disp.hidden = True

		# Unhide editor
		e_name_lbl.hidden = False
		e_name.hidden = False
		e_audio_lbl.hidden = False
		e_audio.hidden = False
		e_bpm.hidden = False
		e_bpm_lbl.hidden = False
		e_load.hidden = False
		e_save.hidden = False

		b_s_lbl.hidden = False
		b_s.hidden = False
		a_s_lbl.hidden = False
		a_s.hidden = False
		o_s_lbl.hidden = False
		o_s.hidden = False

		# Set editor fields
		e_name.set_text(g.name)
		e_audio.set_text(g.audio)
		e_bpm.set_text(str(60000 / g.time_mul))

		b_s.set_text(str(g.score_thresh[0]))
		a_s.set_text(str(g.score_thresh[1]))
		o_s.set_text(str(g.score_thresh[2]))

	game_l.cache_r()
	pause_l.cache_r()

	# Unpause the game.
	toggle_paused()

def quit_to_menu():
	global in_game

	hide_level_select()
	in_game = False

def quit():
	pg.quit()
	sys.exit()

def save_chart():
	g.name = e_name.get_text()

	tm_notes = [[], [], [], []]
	for i in range(4):
		for n in g.notes[i]:
			tm_notes[i].append(n / g.time_mul)

	dat = json.dumps({"name": g.name, "audio": g.audio, "notes": tm_notes, "time_mul": g.time_mul, "score_thresh": g.score_thresh, "speed": g.speed})
	fout = open("charts/custom/" + g.name + ".json", "w")
	fout.write(dat)
	fout.close()

def load_chart():
	g.name = e_name.get_text()

	g.load("charts/custom/" + g.name + ".json")

	e_audio.set_text(g.audio)

	g.reset()

def set_bpm(e_w):
	try:
		g.time_mul = 60000 / float(e_w.get_text())
	except ValueError:
		e_w.set_text(str(60000 / g.time_mul))

def set_score_thresh(e_w, i):
	try:
		g.score_thresh[i] = float(e_w.get_text())
	except ValueError:
		e_w.set_text(str(g.score_thresh[i]))

def set_name(self):
	g.name = self.get_text()

def set_audio(self):
	g.audio = self.get_text()

	pg.mixer.music.stop()
	pg.mixer.music.load("audio/" + g.audio + ".mp3")
	pg.mixer.music.play()
	if g.tmr < 0:
		pg.mixer.music.pause()

def show_level_select():
	level_select_m.hidden = False

	menu_m.hidden = True

	# Detect and add files to the level select
	songs = os.listdir(level_select_cwd)

	level_list_m.children = []

	for p in songs:
		if os.path.isdir(level_select_cwd + p):
			level_list_m.add_widget(label_w(p[:len(p)-p[::-1].find(".")-1], gui_fnt, (0, 0, 0), r=ui_rect(), draw_hitbox=(0, 0, 0), name="Level Select Directory \"" + p + "\""))

	for p in songs:
		if os.path.isfile(level_select_cwd + p):
			level_list_m.add_widget(label_w(p[:len(p)-p[::-1].find(".")-1], gui_fnt, (0, 0, 0), r=ui_rect(), draw_hitbox=(0, 0, 0), name="Level Select Song \"" + p + "\""))

def hide_level_select():
	global level_select_cwd

	level_select_m.hidden = True

	level_list_m.children = []

	menu_m.hidden = False

	level_select_cwd = "charts/SheepToaster/"

def set_selected_level(lbl):
	global selected_level
	global level_select_cwd

	full_path = level_select_cwd + lbl.txt

	# If the path without the json extension exists, it's a directory. Follow it.
	if os.path.exists(full_path):
		level_select_cwd = full_path + "/"
		show_level_select()

		level_back_cwd_m.set_text("Back")

	# Otherwise, it's a file. Set it as selected
	else:
		selected_level = lbl.txt

		level_load_m.set_text("Load " + selected_level)

def instantiate_game_from_selected():
	global g
	global in_game

	g = Game(level_select_cwd + selected_level + ".json", screen)
	in_game = True

# Removes the first folder from the cwd and reloads the level select.
def back_cwd():
	global level_select_cwd

	if level_select_cwd == "charts/":
		hide_level_select()
	else:
		level_select_cwd = level_select_cwd[:len(level_select_cwd) - level_select_cwd[-2::-1].find("/")-1]
		show_level_select()

		if level_select_cwd == "charts/":
			level_back_cwd_m.set_text("Back to Main Menu")

def begin_story():
	pass

clock = pg.time.Clock()

# Build the UI
gui_fnt = pg.font.Font("Font/OldWizard.ttf", int(18/1920*screen.get_width()))
sml_fnt = pg.font.Font("Font/OldWizard.ttf", int(46/1920*screen.get_width()))
big_fnt = pg.font.Font("Font/OldWizard.ttf", int(93/1920*screen.get_width()))
bgr_fnt = pg.font.Font("Font/OldWizard.ttf", int(110/1920*screen.get_width()))

in_game = False
level_select = False
level_select_cwd = "charts/SheepToaster/"
selected_level = "Roman Shuffle"

# Create background widget
background = image_w("img/TABLE.png", r=ui_rect(0, 1, 0, 1, 0, 0, 0, 0), name="background")

# Create main menu
main_l = layout(screen)

# Add Background
main_l.add_widget(background)

# Add Main Menu
menu_m = placeholder_w("main menu", r=ui_rect(0.5, 0.5, 0.5, 0.5, -150, 150, -250, 250), name = "menu_m", color=(0, 0, 0))
main_l.add_widget(menu_m)

# Add Main menu buttons.
story_m = button_w("Story", gui_fnt, (0, 0, 0), begin_story, r=ui_rect(0, 1, 0, 0, 20, -20, 20, 80), draw_hitbox=(0, 0, 0), name="story_m")
menu_m.add_widget(story_m)

level_select_button_m = button_w("Level Select", gui_fnt, (0, 0, 0), show_level_select, r=ui_rect(0, 1, 0, 0, 20, -20, 100, 160), draw_hitbox=(0, 0, 0), name="level_select_button_m")
menu_m.add_widget(level_select_button_m)

options_button_m = button_w("Options", gui_fnt, (0, 0, 0), show_level_select, r=ui_rect(0, 1, 0, 0, 20, -20, 180, 240), draw_hitbox=(0, 0, 0), name="level_select_button_m")
menu_m.add_widget(options_button_m)

quit_button_m = button_w("Quit", gui_fnt, (0, 0, 0), quit, r=ui_rect(0, 1, 0, 0, 20, -20, 260, 320), draw_hitbox=(0, 0, 0), name="level_select_button_m")
menu_m.add_widget(quit_button_m)

# Add Level select.
level_select_m = placeholder_w("level_select_m", r=ui_rect(0.5, 0.5, 0.5, 0.5, -200, 200, -300, 300), name="level_select_m", color=(0, 0, 0))
main_l.add_widget(level_select_m)
level_select_m.hidden = True

# Add the list of levels
level_list_m = v_scrolling_list_w([], 50, 999, set_selected_level, r=ui_rect(0, 1, 0, 1, 0, 0, 30, -30), draw_hitbox=(0, 0, 0), name="level_list_m")
level_select_m.add_widget(level_list_m)

# Add previous directory button
level_back_cwd_m = button_w("Back", gui_fnt, (0, 0, 0), back_cwd, r=ui_rect(0, 1, 0, 0, 0, 0, 0, 30), name="level_back_cwd_m")
level_select_m.add_widget(level_back_cwd_m)

# Add load level button
level_load_m = button_w("Load Roman Shuffle", gui_fnt, (0, 0, 0), instantiate_game_from_selected, r=ui_rect(0, 1, 1, 1, 0, 0, -30, 0), name="level_load_m")
level_select_m.add_widget(level_load_m)

# Create game layout
game_l = layout(screen)

# Add Background
game_l.add_widget(background)

# Add Player card.
player_bg = image_w("img/CHARACTER_CARD_BACKGROUND.png", r=ui_rect(0, 0, 0, 0, 18, 576, 18, 1062), name="player_bg")
game_l.add_widget(player_bg)

player_portrait = image_w("img/DAKE_THE_BARD.png", r=ui_rect(0, 0, 0, 0, 40, 0, 40, 0), name="player_portrait")
player_bg.add_widget(player_portrait)

player_name = label_w("Dake (Bard)", big_fnt, (0, 0, 0), r=ui_rect(0, 1, 0, 1, 0, 0, 640, 0), name="player_name", h_align=CENTER_ALIGN)
player_bg.add_widget(player_name)

player_desc = label_w("Dake is the type of guy who eats arsenic for fun. Balance his humors so he may yet live.", sml_fnt, (0, 0, 0), r=ui_rect(0, 1, 0, 1, 0, 0, 750, 0), name="player_desc", lmar=38)
player_bg.add_widget(player_desc)

# Build Edit menu
e_name_lbl = label_w("Filename:", gui_fnt, (0, 0, 0), r=ui_rect(0, 0.5, 0, 0, 20, 0, 20, 50), name="e_name_lbl", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0)
player_bg.add_widget(e_name_lbl)
e_name_lbl.hidden = True

e_name = entry_w("", gui_fnt, (0, 0, 0), r=ui_rect(0.5, 1, 0, 0, 0, -20, 20, 50), name="e_name", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0, return_behavior=set_name)
player_bg.add_widget(e_name)
e_name.hidden = True

e_audio_lbl = label_w("Audio File:", gui_fnt, (0, 0, 0), r=ui_rect(0, 0.5, 0, 0, 20, 0, 60, 90), name="e_audio_lbl", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0)
player_bg.add_widget(e_audio_lbl)
e_audio_lbl.hidden = True

e_audio = entry_w("", gui_fnt, (0, 0, 0), r=ui_rect(0.5, 1, 0, 0, 0, -20, 60, 90), name="e_audio", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0, return_behavior=set_audio)
player_bg.add_widget(e_audio)
e_audio.hidden = True

e_bpm_lbl = label_w("BPM:", gui_fnt, (0, 0, 0), r=ui_rect(0, 0.5, 0, 0, 20, 0, 100, 130), name="e_bpm_lbl", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0)
player_bg.add_widget(e_bpm_lbl)
e_bpm_lbl.hidden = True

e_bpm = entry_w("", gui_fnt, (0, 0, 0), r=ui_rect(0.5, 1, 0, 0, 0, -20, 100, 130), name="e_bpm", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0, return_behavior=set_bpm)
player_bg.add_widget(e_bpm)
e_bpm.hidden = True

# Score threshholds
b_s_lbl = label_w("Score for Beta Rank:", gui_fnt, (0, 0, 0), r=ui_rect(0, 0.5, 0, 0, 20, 0, 140, 170), name="b_s_lbl", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0)
player_bg.add_widget(b_s_lbl)
b_s_lbl.hidden = True

b_s = entry_w("", gui_fnt, (0, 0, 0), r=ui_rect(0.5, 1, 0, 0, 0, -20, 140, 170), name="b_s", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0, return_behavior=set_score_thresh, params=(0,))
player_bg.add_widget(b_s)
b_s.hidden = True

a_s_lbl = label_w("Score for Alpha Rank:", gui_fnt, (0, 0, 0), r=ui_rect(0, 0.5, 0, 0, 20, 0, 180, 210), name="a_s_lbl", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0)
player_bg.add_widget(a_s_lbl)
a_s_lbl.hidden = True

a_s = entry_w("", gui_fnt, (0, 0, 0), r=ui_rect(0.5, 1, 0, 0, 0, -20, 180, 210), name="a_s", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0, return_behavior=set_score_thresh, params=(1,))
player_bg.add_widget(a_s)
a_s.hidden = True

o_s_lbl = label_w("Score for Omega Rank:", gui_fnt, (0, 0, 0), r=ui_rect(0, 0.5, 0, 0, 20, 0, 220, 250), name="o_s_lbl", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0)
player_bg.add_widget(o_s_lbl)
o_s_lbl.hidden = True

o_s = entry_w("", gui_fnt, (0, 0, 0), r=ui_rect(0.5, 1, 0, 0, 0, -20, 220, 250), name="o_s", v_align=CENTER_ALIGN, lmar=0, rmar=0, tmar=0, bmar=0, return_behavior=set_score_thresh, params=(2,))
player_bg.add_widget(o_s)
o_s.hidden = True

# Load and Save buttons
e_load = button_w("Load", gui_fnt, (0, 0, 0), load_chart, r=ui_rect(0, 1, 1, 1, 40, -40, -170, -110), draw_hitbox=(255, 255, 255))
player_bg.add_widget(e_load)
e_load.hidden = True

e_save = button_w("Save", gui_fnt, (0, 0, 0), save_chart, r=ui_rect(0, 1, 1, 1, 40, -40, -80, -20), draw_hitbox=(255, 255, 255))
player_bg.add_widget(e_save)
e_save.hidden = True

# Add Scroll
scroll = image_w("img/SCROLL.png", r=ui_rect(1, 1, 0, 0, -962, 0, 0, 0))
game_l.add_widget(scroll)

# Add Score
mid_pane = widget(r=ui_rect(0, 1, 0, 1, 574, -935, 0, 0))
game_l.add_widget(mid_pane)

score_img = image_w(("img/RANK_GAMMA.png", "img/RANK_BETA.png", "img/RANK_ALPHA.png", "img/RANK_OMEGA.png"), r=ui_rect(0.5, 0.5, 0, 0, 0, 0, 18), iw=400, ih=400, h_align=CENTER_ALIGN)
mid_pane.add_widget(score_img)

score_label = label_w("Score", bgr_fnt, (0, 0, 0), r=ui_rect(0, 1, 1, 1, 0, 0, -600, 0), h_align=CENTER_ALIGN)
mid_pane.add_widget(score_label)

score_disp = label_w("0", bgr_fnt, (0, 0, 0), r=ui_rect(0, 1, 1, 1, 0, 0, -500, 0), h_align=CENTER_ALIGN)
mid_pane.add_widget(score_disp)

# Build Pause menu
pause_l = layout(screen)

pause_overlay = rect_w((0, 0, 0, 220), r=ui_rect(0, 1, 0, 1, 0, 0, 0, 0))
pause_l.add_widget(pause_overlay)

p_menu = placeholder_w("menu.png", r=ui_rect(0.5, 0.5, 0.1, 0.9, -150, 150, 100, -100), color=(255, 255, 255))
pause_l.add_widget(p_menu)

p_resume = button_w("Resume", gui_fnt, (255, 255, 255), toggle_paused, r=ui_rect(0.1, 0.9, 0, 0.08, 0, 0, 20, 0), draw_hitbox=(255, 255, 255))
p_menu.add_widget(p_resume)

p_options = button_w("Options", gui_fnt, (255, 255, 255), toggle_options, r=ui_rect(0.1, 0.9, 0.08, 0.16, 0, 0, 20, 0), draw_hitbox=(255, 255, 255))
p_menu.add_widget(p_options)

p_edit = button_w("Edit Chart", gui_fnt, (255, 255, 255), toggle_editing, r=ui_rect(0.1, 0.9, 0.16, 0.24, 0, 0, 20, 0), draw_hitbox=(255, 255, 255))
p_menu.add_widget(p_edit)

p_hard_quit = button_w("Quit to Menu", gui_fnt, (255, 255, 255), quit_to_menu, r=ui_rect(0.1, 0.9, 0.24, 0.32, 0, 0, 20, 0), draw_hitbox=(255, 255, 255))
p_menu.add_widget(p_hard_quit)

p_soft_quit = button_w("Quit to Desktop", gui_fnt, (255, 255, 255), quit, r=ui_rect(0.1, 0.9, 0.32, 0.4, 0, 0, 20, 0), draw_hitbox=(255, 255, 255))
p_menu.add_widget(p_soft_quit)

recv_drop = pg.transform.scale(pg.image.load("img/RECEIVING_DROP.png").convert_alpha(), (118, 186))

note_mask = pg.mask.from_surface(note_sprs[0])

# Initial Cache
main_l.cache_r()
game_l.cache_r()
pause_l.cache_r()

# These two functions define separate mainloops controlling the main menu and the game. Beneath these definitions is the code that calls them depending on the state of in_game
def main_menu_cycle():
	dt = clock.tick(60)

	for e in pg.event.get():
		main_l.handle_event(e)

		if e.type == pg.QUIT:
			pg.quit()
			sys.exit()

	screen.fill((255,255,255))

	main_l.cache_r()
	main_l.render_r(screen)

	pg.display.flip()

def game_cycle():
	dt = clock.tick(60)

	for e in pg.event.get():
		game_l.handle_event(e)
		pause_l.handle_event(e)

		if e.type == pg.QUIT:
			pg.quit()
			sys.exit()

		elif e.type == pg.WINDOWRESIZED:
			game_l.cache_r()
			pause_l.cache_r()

		elif e.type == pg.MOUSEBUTTONDOWN:
			if g.editing:
				if e.button == 2:
					toggle_previewing()

				elif e.button == 3:
					for n_i in range(len(g.note_sprites)):
						n = g.note_sprites[n_i]

						x, y = n.get_pos()

						x = int(e.pos[0] - x)
						y = int(e.pos[1] - y)

						if x < 0 or x >= note_mask.get_size()[0] or y < 0 or y >= note_mask.get_size()[1]:
							continue

						if note_mask.get_at((x, y)):
							del g.notes[n.kind-1][n.ind]
							del g.note_sprites[n_i]
							break

				elif e.button == 1:
					for n_i in range(len(g.note_sprites)):
						n = g.note_sprites[n_i]

						x, y = n.get_pos()

						x = int(e.pos[0] - x)
						y = int(e.pos[1] - y)

						if x < 0 or x >= note_mask.get_size()[0] or y < 0 or y >= note_mask.get_size()[1]:
							continue

						if note_mask.get_at((x, y)):
							del g.notes[n.kind-1][n.ind]
							del g.note_sprites[n_i]
							break

					g.placing = True

				elif e.button == 4:
					if pg.key.get_mods() & pg.KMOD_SHIFT:
						diff = g.time_mul * 2**round(math.log2(800 / g.time_mul))
					else:
						diff = g.time_mul * 2**round(math.log2(200 / g.time_mul))

					g.tmr_targ = round((g.tmr + diff) / diff) * diff
					g.delete_old_notes(False)

				elif e.button == 5:
					if pg.key.get_mods() & pg.KMOD_SHIFT:
						diff = g.time_mul * 2**round(math.log2(800 / g.time_mul))
					else:
						diff = g.time_mul * 2**round(math.log2(200 / g.time_mul))

					g.tmr_targ = round((g.tmr - diff) / diff) * diff
					g.delete_new_notes()

					# Spawn notes below the screen
					for i in range(0, 4):
						while True:
							if g.back_cursors[i] < len(g.notes[i]) and g.tmr - g.notes[i][g.back_cursors[i]] < 2000:
								g.note_sprites.insert(0, note_sprite(i+1, g.notes[i][g.back_cursors[i]], g.back_cursors[i], g))
								if g.back_cursors[i] == 0:
									break
								else:
									g.back_cursors[i] -= 1
							else:
								break

		elif e.type == pg.MOUSEBUTTONUP:
			if g.placing and not g.paused:
				g.placing = False

				x, y = e.pos

				c = math.ceil((x - (screen.get_width() - 890)) / scroll_columns_width * 4)

				if c >= 1 and c <= 4:
					t = (screen.get_height() * 0.8 - y) / screen.get_height() / g.speed + g.tmr

					if pg.key.get_mods() & pg.KMOD_SHIFT:
						t = round(t / (g.time_mul/4)) * (g.time_mul/4)

					if t >= 0:
						# Find where in the notes list this should be inserted.
						ind = bisect.bisect(g.notes[c-1], t)
						g.notes[c-1].insert(ind, t)

						# Find where in the note_sprites list this should be inserted.
						spr_ind = bisect.bisect_left(g.note_sprites, ind, key=lambda a: a.ind)

						if spr_ind < len(g.note_sprites):
							for i in g.note_sprites[spr_ind:]:
								i.ind += 1

						g.note_sprites.insert(spr_ind, note_sprite(c, t, ind, g))

						g.note_cursors[c-1] += 1

		elif e.type == pg.KEYDOWN:
			key_pos = 0

			if e.key == pg.K_l:
				if rate == 0.5:
					rate = 1
				else:
					rate = 0.5

			if e.key == pg.K_ESCAPE:
				toggle_paused()

			if not g.paused and not g.editing or g.previewing:
				if e.key == pg.K_RETURN:
					if g.editing:
						g.set_time(-1000, False, True)
					else:
						g.set_time(-1000, True, True)

				elif e.key == pg.K_LEFT:
					key_pos = 1
				elif e.key == pg.K_UP:
					key_pos = 2
				elif e.key == pg.K_DOWN:
					key_pos = 3
				elif e.key == pg.K_RIGHT:
					key_pos = 4

				if key_pos != 0:
					g.key_presses += 1

					# For all notes on the board in the appropriate column, check their time against the game timer.
					# The lowest note found is hit
					note_hit = None
					score_for_note = 0
					for n_i in range(len(g.note_sprites)):
						n = g.note_sprites[n_i]
						if n.kind == key_pos:
							if abs(n.t - g.tmr) < g.perfect_margin:
								note_hit = n_i
								score_for_note = 2
								break

							elif abs(n.t - g.tmr) < g.good_margin:
								note_hit = n_i
								score_for_note = 1
								break

					if note_hit is not None:
						note_hit_spr = g.note_sprites[note_hit]

						# Score
						g.add_hit_indicator(key_pos, score_for_note)
						if score_for_note == 1:
							g.goods += 1
							g.score += 10

							if note_hit_spr.ind > g.back_cursors[note_hit_spr.kind-1]:
								g.back_cursors[note_hit_spr.kind-1] = n.ind

							del g.note_sprites[note_hit]
						else:
							g.perfects += 1
							g.score += 20
							g.back_cursors[g.note_sprites[note_hit].kind-1] = n.ind

							if note_hit_spr.ind > g.back_cursors[note_hit_spr.kind-1]:
								g.back_cursors[note_hit_spr.kind-1] = n.ind

							del g.note_sprites[note_hit]

	# Detect if a note has passed below the screen
	g.delete_old_notes()

	# Delete fully transparent hit indicators
	i = 0
	while i < len(g.hit_indicator_sprites): # do NOT delete this while loop! It completes in linear time ALWAYS and does not slow down the game!
		if g.hit_indicator_sprites[i].s.get_alpha() == 0:
			del g.hit_indicator_sprites[i]
		else:
			i += 1

	if g.is_done() and not has_printed_score:
		print("perfects: %d" % g.perfects)
		print("goods: %d" % g.goods)
		print("bads: %d" % g.bads)
		print("misses: %d" % g.misses)
		print("keypresses: %d" % g.key_presses)
		has_printed_score = True

#	print("pa: %d, mp: %d, ed: %d, pv: %d, pl: %d, tmr: %d, trg: %d, off: %d" % (g.paused, g.music_playing, g.editing, g.previewing, g.placing, g.tmr, g.tmr_targ, g.offset))

	# Lerp towards the correct time.
	if g.editing and not g.previewing:
		g.set_time((g.tmr_targ - g.tmr) * 0.4 + g.tmr, False, False)

	g.update(dt)

	# Get current grade
	g.cache_grade()
	score_img.set_img(g.grade)

	score_disp.set_text(str(g.score))
	score_disp.cache()

	screen.fill((255,255,255))

	game_l.render_r(screen)

	# Draw receiving drops
	for i in range(1, 5):
		x = screen.get_width() - 890 + scroll_columns_width/4 * i - scroll_columns_width/8
		screen.blit(recv_drop, (x-note_w/2, perfect_line_height*screen.get_height() - note_h/2 - 30))

	g.draw_notes()

	# Draw timestamps in edit mode
	if g.editing:
		t = math.ceil(g.y2t(0) / g.time_mul)

		for t in range(t, t-40, -1):
			y = g.t2y(t * g.time_mul)

			if y > screen.get_height():
				break

			tsurf = sml_fnt.render(str(t), True, (0, 0, 0), (248, 212, 141))
			screen.blit(tsurf, (screen.get_width() - 950 - tsurf.get_width(), y - tsurf.get_height()/2))

	# Render note previews
	if g.placing:
		x, y = pg.mouse.get_pos()

		c = math.ceil((x - (screen.get_width() - 890)) / scroll_columns_width * 4)

		if c >= 1 and c <= 4:
			t = (screen.get_height() * 0.8 - y) / screen.get_height() / g.speed + g.tmr

			if pg.key.get_mods() & pg.KMOD_SHIFT:
				t = round(t / (g.time_mul/4)) * (g.time_mul/4)

			time_until_hit = t - g.tmr
			screen.blit(note_sprs[c-1], (screen.get_width() - 890 + scroll_columns_width/4 * c - scroll_columns_width/8 - note_w/2, perfect_line_height*screen.get_height() - time_until_hit*g.speed*screen.get_height() - note_h/2 - 30))

	g.draw_hit_indicators()

	# If paused, show the pause menu.
	if g.paused:
		pause_l.hidden = False
		pause_l.render_r(screen)
	else:
		pause_l.hidden = True

	pg.draw.line(screen, (0, 0, 0), (0, 900), (0, 900))

	pg.display.flip()

while True:
	if in_game:
		game_cycle()
	else:
		main_menu_cycle()


from flask import Flask, render_template,jsonify
import random
from objD import auxF
app = Flask(__name__)

@app.route("/")
def main():
	return render_template('index.html')

#example of using rest api for use with our website
@app.route("/api/iname")
def iname():
    #This will run some other scripts and return the name of item kept in iDabba
    # return auxF.getFromAPI()	#use this to get information from the microsoft API server. Internet connection needed.
    # return auxF.getViaHaar()	#use this to get information using our own generated haar cascades. No internet Needed.
    return auxF.getViaSift()	#use this to get information using sift Features calculated on the go. No internet Needed.
    # return auxF.test()

@app.route("/api/store/<string:data>")
def DataLoad(data):
	#stores the data into the log file
	fo = open("dataLog.txt","a+")
	fo.write(data)
	fo.write('\n')
	fo.close()
	return "recieved"

@app.route("/api/getrd")
def returnData():
	#returns data about object in iDabba
	fo = open("dataLog.txt")
	y = ""
	for x in fo:
		y = x
	p = y.replace("\n","_")
	z = p.split("_");

	d = {'objectName':iname(),'temp':z[0],'humidity':z[1],'weight':z[2],'rfid':z[3]}
	return jsonify(d)

@app.route("/api/click/<string:fname>")
def clickP(fname):
	#Clicks a picture of object inside iDabba and saves it as the given name
	im = auxF.getImageFromCam()
	auxF.cv2.imwrite('imdata/'+fname+'.jpg',im)
	return "Done"

if __name__ == "__main__":
	app.run(host='0.0.0.0',port=8080)
	# ,debug=True


import rsa
import socket
from threading import Lock
from lib.stream import Stream

class DPMClient():
    def __init__(self, uid=None, key=None):
        self._lock = Lock()
        self._uid = uid
        self._key = None
        if key:
            self._key =  rsa.PublicKey.load_pkcs1(key)

    def request(self, addr, port, buf):
        self._lock.acquire()
        try:
            return self._request(addr, port ,buf)
        finally:
            self._lock.release()

    def _request(self, addr, port, buf):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((addr, port))
        try:
            if self._key:
                stream = Stream(sock, uid=self._uid, key=self._key)
            else:
                stream = Stream(sock)
            stream.write( buf)
            if self._key:
                stream = Stream(sock)
            _, _, res = stream.readall()
            return res
        finally:
            sock.close()


from flask import Blueprint, render_template, request
from flask_login import login_required, current_user
from pathlib import Path
from csv import reader

main = Blueprint('main', __name__)
parent_dir = Path(__file__).parent.parent
guide_files = parent_dir / 'templates' / 'components' / 'guide'

def load_csv_files_in_directory():
	csv_data = {}
	for file in guide_files.iterdir():
		if file.suffix == '.csv':
			with open(file, "r", newline="") as csv_file:
				guide_reader = reader(csv_file, delimiter=';')
				data = []
				for row in guide_reader:
					row_set = list(row)
					data.append(row_set)
				csv_data[file.stem] = data
	return csv_data

@main.route('/')
def index():
	if current_user.is_authenticated:
		guide_tag = request.args.get('guide')
		guide = load_csv_files_in_directory()
	else:
		guide = None
		guide_tag = None
	return render_template('index.html', guide=guide, guide_tag=guide_tag)

@main.route('/profile')
@login_required
def profile():
	return render_template('profile.html', name=current_user.name)

@main.route('/goof')
@login_required
def goof():
	return render_template('goof.html')


import re

# specify input and output file paths
input_file = 'abc.txt'
output_file = 'output.txt'
ignored_keywords = ["NO BEFORE", "DEFAULT MERGEBLOCKRATIO", "TD MAP", "PRIMARY INDEX", "Request Text", "||Request|Text"]

with open("abc.txt") as f:

    # initialize variables to hold table information
    current_database = ''
    current_table = ''

    # open input and output files
    with open(input_file, 'r') as f_in, open(output_file, 'w') as f_out:
        # loop over each line in the input file
        for line in f_in:
            # remove leading and trailing whitespace from the line
            line = line.strip()
            # check if the line is a CREATE TABLE statement
            if line.startswith('CREATE MULTISET TABLE'):
                # extract the database and table names from the statement
                current_database, current_table = re.search(r'CREATE MULTISET TABLE (\S+)\.(\S+)', line).groups()
            # check if the line defines a column and if it should not be ignored
            elif re.search(r'^\w+ ', line) and not any(keyword in line for keyword in ignored_keywords):
                # extract the column name and data type from the line
                column_name_match = re.search(r'(\w+) (\w+\(\d+(,\d+)?\)|\w+)', line)
                # check if a match was found
                if column_name_match:
                    column_name = column_name_match.group(1)
                    data_type = column_name_match.group(2)
                    # write the table information to the output file
                    f_out.write(f'{current_database}|{current_table}|{column_name}|{data_type}\n')
                # if no match was found, print a warning message
                else:
                    print(f'Warning: line "{line}" does not define a column')
            # ignore all other lines and print them to the console
            else:
                print(f'Ignoring line "{line}"')

    print('Output file generated successfully.')


#!/usr/bin/env python

from __future__ import print_function
import fileinput, math, optparse, sys

okmethods = ["pctid", "logevalue", "minbit", "maxbit"]

usage = "%prog [options] < BLAST_results > distance_matrix"
description = """Turn a table of BLAST results into a distance matrix.
The distance matrix will be suitable for conversion into a heatmap with
plotHeatmap.py
It is suggested that the user use this with the results of
db_getBlastResultsBetweenSpecificGenes.py so that there are blast results
available for ALL pairs of genes in a specified list."""

parser = optparse.OptionParser(usage=usage, description=description)
parser.add_option("-m", "--method", help="Scoring metric to use (D=maxbit). OK methods: %s" %(" ".join(okmethods)), action="store", type="str", dest="method", default="maxbit")
parser.add_option("-d", "--default", help="Default score to use in case of missing pairs. (D: None)", action="store", type="float", dest="default", default=None)
(options, args) = parser.parse_args()

if not options.method in okmethods:
    sys.stderr.write("ERROR: Provided method %s is not in list of recognized scoring methods: %s\n" %(options.method, " ".join(okmethods) ) )
    exit(2)

# Keep unique until the end
queries = set()
targets = set()
# Dict from (query,target) pairs to the score between them
qt_to_score = dict()

for line in fileinput.input("-"):
    spl = line.strip("\r\n").split("\t")
    if options.method == "pctid":
        score = float(spl[3])
    elif options.method == "logevalue":
        score = math.log10(float(spl[10]))
    elif options.method == "minbit":
        score = float(spl[11])/min(float(spl[12]), float(spl[13]))
    elif options.method == "maxbit":
        score = float(spl[11])/min(float(spl[12]), float(spl[13]))
    queries.add(spl[0])
    targets.add(spl[1])
    if (spl[0], spl[1]) in qt_to_score:
        sys.stderr.write("WARNING: Multiple instances of the pair (%s, %s) in your list - only the first will be kept\n" %(spl[0], spl[1]))
        continue
    qt_to_score[ (spl[0], spl[1]) ] = score

queries = sorted(list(queries))
targets = sorted(list(targets))

print("\t" + "\t".join(targets))

for query in queries:
    row = query
    for target in targets:
        if (query, target) in qt_to_score:
            row = row + "\t" + str(qt_to_score[(query, target)])
        else:
            row = row + "\t" + str(options.default)
    print(row)


import os
GPUS = "3,4,5,6"
os.environ["CUDA_VISIBLE_DEVICES"] = GPUS
import torch
import torch.nn.functional as F
import torchvision.transforms as transforms
from tqdm import tqdm
import torch.optim as optim
import segmentation_models_pytorch as smp
from utils import (
	calc_dice,
	calc_jaccard,
	check_performance,
	getDatetime,
	save_dict_as_csv,
	load_checkpoint,
	save_checkpoint,
	get_loaders,
	save_predictions_as_imgs,
)
import time
import augmentations as aug

# Hyperparameters etc.
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
LEARNING_RATE = 5e-7
BATCH_SIZE = 16
MAX_NUM_EPOCHS = 100
NUM_WORKERS = 2
PIN_MEMORY = True
LOAD_MODEL = True
TRAIN_IMG_DIR = "../data/patches/ps_1024_po_0.8_mt_0.8/train/tissue"
TRAIN_MASK_DIR = "../data/patches/ps_1024_po_0.8_mt_0.8/train/viable"
VAL_IMG_DIR = "../data/patches/ps_1024_po_0.8_mt_0.8/val/tissue"
VAL_MASK_DIR = "../data/patches/ps_1024_po_0.8_mt_0.8/val/viable"
ENCODER = "resnet50"
ENCODER_WEIGHT_INITIALIZATION = None # None = random weight initialization, "imagenet" = imagenet weight innitialization
BCE_WEIGHT = 0.1
MAX_EPOCHS_WITHOUT_IMPROVEMENT = 5
TRAINING_INFO_FILENAME = "results.csv"
PARAMETER_INFO_FILENAME = "parameters.csv"
LOAD_MODEL_PATH = "e_2_l_0.2336_d_20230516T073406Z.pt"

def train_fn(loader, model, optimizer, loss_fn, scaler):
	print("Training model...")
	loop = tqdm(loader)

	for batch_idx, (data, targets) in enumerate(loop):
		data = data.float().to(device=DEVICE)
		targets = targets.float().to(device=DEVICE)

		# forward
		with torch.cuda.amp.autocast():
			predictions = model(data)
			loss = loss_fn(predictions, targets)

		# backward
		optimizer.zero_grad()
		scaler.scale(loss).backward()
		scaler.step(optimizer)
		scaler.update()

		# update tqdm loop
		loop.set_postfix(loss=loss.item())

def check_and_save_performance(train_loader, val_loader, model, loss_fn, epoch, train_time, filename=TRAINING_INFO_FILENAME):
	# check training set performance
	print("Checking training set performance...")
	train_set_performance_start_time = time.time()
	train_set_performance = check_performance(train_loader, model, loss_fn, result_prefix="train_", device=DEVICE)
	check_train_set_performance_time = time.time() - train_set_performance_start_time

	# check validation set perfromance
	print("Checking validation set performance...")
	val_set_performance_start_time = time.time()
	val_set_performance = check_performance(val_loader, model, loss_fn, result_prefix="val_", device=DEVICE)
	check_val_set_perfromance_time = time.time() - val_set_performance_start_time

	currentDatetime = getDatetime()

	training_info = {
		"epoch": epoch,
		**train_set_performance,
		**val_set_performance,
		"train_time": train_time,
		"check_train_set_performance_time": check_train_set_performance_time,
		"check_val_set_performance_time": check_val_set_perfromance_time,
		"datetime": currentDatetime,
	}

	# save training info to csv file
	save_dict_as_csv(filename, training_info)

	return training_info

def main():
	train_transforms = aug.TrainTransform()
	val_transforms = aug.TrainTransform()

	# model = UNet(in_channels=3, out_channels=1).to(device=DEVICE)
	model = smp.Unet(encoder_name=ENCODER, in_channels=3, classes=1, encoder_weights=ENCODER_WEIGHT_INITIALIZATION)
	model = torch.nn.DataParallel(model)
	model = model.to(device=DEVICE)

	def calc_loss(pred, target, bce_weight=BCE_WEIGHT):
		bce = F.binary_cross_entropy_with_logits(pred, target)

		pred = torch.sigmoid(pred)
		dice_score = calc_dice(pred, target)
		# jaccard = calc_jaccard(pred, target)
		loss = bce * bce_weight + (1.0 - dice_score) * (1.0 - bce_weight)

		return loss

	loss_fn = calc_loss
	# loss_fn = nn.BCEWithLogitsLoss() # Logits since we dont sigmoid output of model
	optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

	train_loader, val_loader = get_loaders(
		TRAIN_IMG_DIR,
		TRAIN_MASK_DIR,
		VAL_IMG_DIR,
		VAL_MASK_DIR,
		BATCH_SIZE,
		train_transforms,
		val_transforms,
		NUM_WORKERS,
		PIN_MEMORY,
	)

	if LOAD_MODEL:
		# vicreg_state_dict = torch.load(LOAD_MODEL_PATH)

		# total_sum = 0
		# for key, value in vicreg_state_dict.items():
		# 	total_sum += torch.sum(value)

		# print("The sum of all state dictionary parameters is:", total_sum.item())

		# state_dict = model.state_dict()

		# total_sum = 0
		# for key, value in state_dict.items():
		# 	total_sum += torch.sum(value)

		# print("The sum of all state dictionary parameters is:", total_sum.item())

		# model.module.encoder.load_state_dict(vicreg_state_dict)

		# state_dict = model.state_dict()

		# total_sum = 0
		# for key, value in state_dict.items():
		# 	total_sum += torch.sum(value)

		# print("The sum of all state dictionary parameters is:", total_sum.item())

		load_checkpoint(torch.load(LOAD_MODEL_PATH), model)
		# print(state_dict.items())
		# print(model.module)

		# exit()
	# training_info = check_and_save_performance(train_loader, val_loader, model, loss_fn, epoch=0, train_time=0)

	scaler = torch.cuda.amp.GradScaler()

	epochs_since_last_improvement = 0
	# best_val_loss = training_info["val_loss"]
	best_val_loss = 99999
	# Save hyperparameters
	save_dict_as_csv(
		PARAMETER_INFO_FILENAME, {
			"GPUS" : GPUS,
			"DEVICE" : DEVICE,
			"LEARNING_RATE" : LEARNING_RATE,
			"BATCH_SIZE" : BATCH_SIZE,
			"NUM_EPOCHS" : MAX_NUM_EPOCHS,
			"NUM_WORKERS" : NUM_WORKERS,
			"PIN_MEMORY" : PIN_MEMORY,
			"LOAD_MODEL" : LOAD_MODEL,
			"TRAIN_IMG_DIR" : TRAIN_IMG_DIR,
			"TRAIN_MASK_DIR" : TRAIN_MASK_DIR,
			"VAL_IMG_DIR" : VAL_IMG_DIR,
			"VAL_MASK_DIR" : VAL_MASK_DIR,
			"ENCODER" : ENCODER,
			"ENCODER_WEIGHT_INITIALIZATION" : ENCODER_WEIGHT_INITIALIZATION,
			"BCE_WEIGHT" : BCE_WEIGHT,
			"TRAINING_INFO_FILENAME" : TRAINING_INFO_FILENAME,
			"PARAMETER_INFO_FILENAME" : PARAMETER_INFO_FILENAME,
			"MAX_EPOCHS_WITHOUT_IMPROVEMENT" : MAX_EPOCHS_WITHOUT_IMPROVEMENT,
			"LOAD_MODEL_PATH" : LOAD_MODEL_PATH
		}
	)
	model.train()
	for epoch in range(MAX_NUM_EPOCHS):
		# Train model
		train_start_time = time.time()
		train_fn(train_loader, model, optimizer, loss_fn, scaler)
		train_time = time.time() - train_start_time

		# Check and save model performance
		training_info = check_and_save_performance(train_loader, val_loader, model, loss_fn, epoch + 1, train_time)

		current_val_loss = training_info['val_loss']
		# Save model checkpoint
		checkpoint = {
			"state_dict": model.state_dict(),
			"optimizer": optimizer.state_dict(),
		}
		save_checkpoint(checkpoint, f"e_{epoch + 1}_l_{current_val_loss:.4f}_d_{training_info['datetime']}.pt")

		if current_val_loss < best_val_loss:
			best_val_loss = current_val_loss
			epochs_since_last_improvement = 0
		else:
			epochs_since_last_improvement += 1
		print(f"Epochs without improvment: {epochs_since_last_improvement}/{MAX_EPOCHS_WITHOUT_IMPROVEMENT}")
		# print some examples to a folder
		#save_predictions_as_imgs(val_loader, model, folder="pred_samples/", device=DEVICE)
		if epochs_since_last_improvement >= MAX_EPOCHS_WITHOUT_IMPROVEMENT:
			break

if __name__ == "__main__":
	# torch.cuda.set_device(0)
	# os.environ["CUDA_VISIBLE_DEVICES"] = "1,2,3"
	# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
	main()


import os
import sys

if __name__ == "__main__":
    args = sys.argv
    sdir = args[1]
    ofile = args[2]
    f = open(ofile, "w")

    for root_dir, dirs, files in os.walk(sdir):
        for file in files:
            if file.lower().endswith((".jpg")):
                abs_path = os.path.abspath(root_dir + "/" + file)
                f.write(abs_path + "\n")


def abc(a:bool, b:float)->int:
    return

def convert(km: float) -> str:
    """
    Returns a string containing the length in miles and yards
    that is equivalent to km kilometers.
    Note that there are 1760 yards in a mile, and 1 mile is 1.6093 km.
    Assume that km is non-negative (error checking is not required).
    >>> convert(5)
    '3 miles and 188.22 yards'
            # it is fine if it returns something like:
            # '3.0 miles and 188.21599..... yards' for all examples
    >>> convert(0)
    '0 miles and 0.0 yards'
    >>> convert(1.6102144)
    '1 miles and 1.0 yards' # don't worry about singular/plural
    """
  #a= km//1.6093
   #b=km//1.6093*1760
    return km//1.6093,"miles and",(km//1.6093)*1760
Testcase=convert(5)
#print(Testcase)
Testcase=convert(0)
#print(Testcase)
Testcase=convert(1.6102144)
#print(Testcase)

import math
def length_of_chord(line:float,radius:float)->float:
    """
    Returns the length of the chord using the parameters of line and radius
    >>>length_of_chord(0,2)
    4.0
    >>>length_of_chord(1.26,3.55)
    6.637740579444183
    >>>length_of_chord(85,700.5)
    1390.647690826113
    """
    return 2*math.sqrt(radius**2-(line**2))

Test1=length_of_chord(0,2)
#print(Test1)
Test1=length_of_chord(1.26,3.55)
#print(Test1)
Test1=length_of_chord(85,700.5)
#print(Test1)

def growth_of_pig(common_weight: float, target_rate: float, pig1_growth_rate: float, pig2_growth_rate: float)->list:
    """
    Returns the number of weeks it takes for pig1's weight to become pig1_growth_rate bigger than the second pig. The parameters that are used are common_weight , target_rate, pig1_growth_rate, pig2_growth_rate
    Some assumptions are that all the rate values are between 0.0 to 100.0 , the farmers are constantly feeding the pigs equally, the first pig's growth rate is always more than pig 2's growth rate. The initial mass cannot be 0

   >>>growth_of_pig(100,33.3,5.5,2.8)
   [12, 50.832]
   >>>growth_of_pig(120,33.3,33.3,2.8)
   [2, 86.413]
   >>>growth_of_pig(200,45.8,1.5,0.8)
   [55, 7.18]
   """
    # Using a modified version of the compounding intrest formula
    lst=[]
    pig1_mass= common_weight
    pig2_mass= common_weight
    num_of_weeks=0
    while pig2_mass*(1+(target_rate/100)) > pig1_mass:
        pig1_mass += (pig1_growth_rate/100)* (pig1_mass)
        pig2_mass += (pig2_growth_rate/100) * (pig2_mass)
        num_of_weeks += 1
        #lst+=[num_of_weeks,round(pig1_mass-pig2_mass,2)]
    return [num_of_weeks,round(pig1_mass-pig2_mass,3)]

test=growth_of_pig(100,33.3,5.5,2.8)
#print(test)
test1=growth_of_pig(120,33.3,33.3,2.8)
#print(test1)
test2=growth_of_pig(10,45.8,1.5,0.8)
#print(test2)

def loop_function(size:int, start:int, operation:bool)->list:
    """
    >>>

    >>>

    >>>

    """
    lst=[]
    for i in range(0,size-1):
        lst+=[start]
        lst+=[start+1]
        if operation== True:
            i+=lst[i-1]
            i+=lst[i-2]
        elif operation== False:
            i-=lst[i-1]
            i-=lst[i-2]
    return lst

test=loop_function(5,-1,True)
#print(test)
test1=loop_function(6,5,False)
#print(test1)
test2=loop_function(9,2,False)
#print(test1)

def print_strs(my_set:set)->int:
    """
    """
    for i in my_set:
        if (type(i))==str:
            print (i)
test=print_strs({1,4.5,"cherry"})
print(test)
test1=print_strs({1,4.5,"cherry","melon"})
print(test1)
test2=print_strs({1,3,4,8})
print(test2)


#!/usr/bin/env python
"""Convert python strings to UTF16 USB descriptors"""

def descriptor_to_string(descriptor: bytes) -> str:
    """ Convert a USB string descriptor into a python string

    Keyword arguments:
    descriptor -- UTF-16 formatted USB descriptor string
    """
    b_length = descriptor[0]
    if b_length != len(descriptor):
        raise ValueError(
            'Length mismatch, ' +
            f'length_field:{b_length} length:{len(descriptor)}')

    b_descriptor_type = descriptor[1]
    if b_descriptor_type != 0x03:
        raise ValueError(
            f'Type mismatch, bDescriptorType:{b_descriptor_type:02x}'
            + 'expected:0x03')

    return descriptor[2:].decode('utf-16', errors='strict')

def string_to_descriptor(string: str) -> bytes:
    """ Convert a python string into a USB string descriptor

    Keyword arguments:
    string: String to convert
    """
    descriptor = bytearray()
    descriptor.append(0x00)  # placeholder for length
    descriptor.append(0x03)
    descriptor.extend(string.encode('utf-16')[2:])  # crop the BOM
    descriptor[0] = len(descriptor)

    return bytes(descriptor)

if __name__ == "__main__":
    MANUFACTURER = 'Mullvad'
    PRODUCT = 'MTA1-USB-V1'
    SERIAL = "68de5d27-e223-4874-bc76-a54d6e84068f"

    # serial = bytes([
    #    0x14,0x03,
    #    0x32,0x00,0x30,0x00,0x31,0x00,0x37,0x00,0x2D,0x00,
    #    0x32,0x00,0x2D,0x00,
    #    0x32,0x00,0x35,0x00
    #    ])
    # print(descriptor_to_string(serial))

    # sample_product = bytes([
    #    0x14,0x03,
    #    0x43,0x00,0x48,0x00,0x35,0x00,0x35,0x00,0x34,0x00,0x5F,0x00,
    #    0x43,0x00,0x44,0x00,0x43,0x00
    #    ])
    # print(descriptor_to_string(sample_product))
    # rt = string_to_descriptor(descriptor_to_string(sample_product))
    # print(descriptor_to_string(rt))
    #
    # print(['{:02x} '.format(i) for i in sample_product])
    # print(['{:02x} '.format(i) for i in rt])

    # sample_mfr = bytes([
    #    0x0A,0x03,
    #    0x5F,0x6c,0xCF,0x82,0x81,0x6c,0x52,0x60,
    #    ])
    # print(descriptor_to_string(sample_mfr))
    # rt = string_to_descriptor(descriptor_to_string(sample_mfr))
    # print(descriptor_to_string(rt))
    #
    # print(['{:02x} '.format(i) for i in sample_mfr])
    # print(['{:02x} '.format(i) for i in rt])

    with open('usb_strings.h', 'w', encoding='utf-8') as f:
        f.write('#ifndef USB_STRINGS\n')
        f.write('#define USB_STRINGS\n')

        f.write(
            f'unsigned char __code Prod_Des[]={{  // "{PRODUCT}"\n')
        f.write('    ')
        f.write(', '.join([f'0x{i:02x}'
                for i in string_to_descriptor(PRODUCT)]))
        f.write('\n};\n')

        f.write(
            'unsigned char __code Manuf_Des[]={  ' +
            f'// "{MANUFACTURER}"\n')
        f.write('    ')
        f.write(', '.join([f'0x{i:02x}'
                for i in string_to_descriptor(MANUFACTURER)]))
        f.write('\n};\n')

        f.write(
            f'unsigned char __code SerDes[]={{  // "{SERIAL}"\n')
        f.write('    ')
        f.write(', '.join([f'0x{i:02x}'
                for i in string_to_descriptor(SERIAL)]))
        f.write('\n};\n')

        f.write('#endif\n')


from flask import Flask, request, redirect, url_for, Blueprint, render_template, flash, jsonify
from db.roles.roles import Rol, nuevo_rol
from db import db

roles = Blueprint('roles', __name__)

@roles.route('/roles', methods=['GET'])
def rol():
    if request.method == 'GET':
        roles = Rol.query.all()
        response = jsonify( [r.__asdict__() for r in roles])
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response


from __future__ import print_function
import io
import os

import pytest

import numpy as np
from numpy.testing import assert_allclose, assert_equal
import pandas as pd
import patsy
from statsmodels.api import families
from statsmodels.tools.sm_exceptions import (
    ValueWarning,
    )
from statsmodels.othermod.betareg import BetaModel
from .results import results_betareg as resultsb

links = families.links

cur_dir = os.path.dirname(os.path.abspath(__file__))
res_dir = os.path.join(cur_dir, "results")

# betareg(I(food/income) ~ income + persons, data = FoodExpenditure)
_income_estimates_mean = u"""\
varname        Estimate  StdError   zvalue     Pr(>|z|)
(Intercept) -0.62254806 0.223853539 -2.781051 5.418326e-03
income      -0.01229884 0.003035585 -4.051556 5.087819e-05
persons      0.11846210 0.035340667  3.352005 8.022853e-04"""

_income_estimates_precision = u"""\
varname  Estimate StdError  zvalue     Pr(>|z|)
(phi) 35.60975   8.079598 4.407366 1.046351e-05
"""

_methylation_estimates_mean = u"""\
varname      Estimate StdError zvalue Pr(>|z|)
(Intercept)  1.44224    0.03401  42.404   2e-16
genderM      0.06986    0.04359   1.603    0.109
CpGCpG_1     0.60735    0.04834  12.563   2e-16
CpGCpG_2     0.97355    0.05311  18.331   2e-16"""

_methylation_estimates_precision = u"""\
varname Estimate StdError zvalue Pr(>|z|)
(Intercept)  8.22829    1.79098   4.594 4.34e-06
age         -0.03471    0.03276  -1.059    0.289"""

expected_income_mean = pd.read_table(
    io.StringIO(_income_estimates_mean), sep=r"\s+")
expected_income_precision = pd.read_table(
    io.StringIO(_income_estimates_precision), sep=r"\s+")

expected_methylation_mean = pd.read_table(
    io.StringIO(_methylation_estimates_mean), sep=r"\s+")
expected_methylation_precision = pd.read_table(
    io.StringIO(_methylation_estimates_precision), sep=r"\s+")

income = pd.read_csv(os.path.join(res_dir, 'foodexpenditure.csv'))
methylation = pd.read_csv(os.path.join(res_dir, 'methylation-test.csv'))

def check_same(a, b, eps, name):
    assert np.allclose(a, b, rtol=0.01, atol=eps), \
            ("different from expected", name, list(a), list(b))

def assert_close(a, b, eps):
    assert np.allclose(a, b, rtol=0.01, atol=eps), (list(a), list(b))

class TestBetaModel:

    @classmethod
    def setup_class(cls):
        model = "I(food/income) ~ income + persons"
        cls.income_fit = BetaModel.from_formula(model, income).fit()

        model = cls.model = "methylation ~ gender + CpG"
        Z = cls.Z = patsy.dmatrix("~ age", methylation)
        mod = BetaModel.from_formula(model, methylation, exog_precision=Z,
                                     link_precision=links.Identity())
        cls.meth_fit = mod.fit()
        mod = BetaModel.from_formula(model, methylation, exog_precision=Z,
                                     link_precision=links.Log())
        cls.meth_log_fit = mod.fit()

    def test_income_coefficients(self):
        rslt = self.income_fit
        assert_close(rslt.params[:-1], expected_income_mean['Estimate'], 1e-3)
        assert_close(rslt.tvalues[:-1], expected_income_mean['zvalue'], 0.1)
        assert_close(rslt.pvalues[:-1], expected_income_mean['Pr(>|z|)'], 1e-3)

    def test_income_precision(self):

        rslt = self.income_fit
        # note that we have to exp the phi results for now.
        assert_close(np.exp(rslt.params[-1:]),
                     expected_income_precision['Estimate'], 1e-3)
        # yield check_same, rslt.tvalues[-1:],
        #                   expected_income_precision['zvalue'], 0.1, "z-score"
        assert_close(rslt.pvalues[-1:],
                     expected_income_precision['Pr(>|z|)'], 1e-3)

    def test_methylation_coefficients(self):
        rslt = self.meth_fit
        assert_close(rslt.params[:-2],
                     expected_methylation_mean['Estimate'], 1e-2)
        assert_close(rslt.tvalues[:-2],
                     expected_methylation_mean['zvalue'], 0.1)
        assert_close(rslt.pvalues[:-2],
                     expected_methylation_mean['Pr(>|z|)'], 1e-2)

    def test_methylation_precision(self):
        # R results are from log link_precision
        rslt = self.meth_log_fit
        assert_allclose(rslt.params[-2:],
                        expected_methylation_precision['Estimate'],
                        atol=1e-5, rtol=1e-10)
        #     expected_methylation_precision['Estimate']
        # yield check_same, links.logit()(rslt.params[-2:]),
        #     expected_methylation_precision['Estimate'], 1e-3, "estimate"
        # yield check_same, rslt.tvalues[-2:],
        #     expected_methylation_precision['zvalue'], 0.1, "z-score"

    def test_precision_formula(self):
        m = BetaModel.from_formula(self.model, methylation,
                                   exog_precision_formula='~ age',
                                   link_precision=links.Identity())
        rslt = m.fit()
        assert_close(rslt.params, self.meth_fit.params, 1e-10)
        assert isinstance(rslt.params, pd.Series)

        with pytest.warns(ValueWarning, match="unknown kwargs"):
            BetaModel.from_formula(self.model, methylation,
                                   exog_precision_formula='~ age',
                                   link_precision=links.Identity(),
                                   junk=False)

    def test_scores(self):
        model, Z = self.model, self.Z
        for link in (links.Identity(), links.Log()):
            mod2 = BetaModel.from_formula(model, methylation, exog_precision=Z,
                                          link_precision=link)
            rslt_m = mod2.fit()

            # evaluate away from optimum to get larger score
            analytical = rslt_m.model.score(rslt_m.params * 1.01)
            numerical = rslt_m.model._score_check(rslt_m.params * 1.01)
            assert_allclose(analytical, numerical, rtol=1e-6, atol=1e-6)
            assert_allclose(link.inverse(analytical[3:]),
                            link.inverse(numerical[3:]), rtol=5e-7, atol=5e-6)

    def test_results_other(self):

        rslt = self.meth_fit
        distr = rslt.get_distribution()
        mean, var = distr.stats()
        assert_allclose(rslt.fittedvalues, mean, rtol=1e-13)
        assert_allclose(rslt.model._predict_var(rslt.params), var, rtol=1e-13)
        resid = rslt.model.endog - mean
        assert_allclose(rslt.resid, resid, rtol=1e-12)
        assert_allclose(rslt.resid_pearson, resid / np.sqrt(var), rtol=1e-12)

class TestBetaMeth():

    @classmethod
    def setup_class(cls):
        formula = "methylation ~ gender + CpG"
        mod = BetaModel.from_formula(formula, methylation,
                                     exog_precision_formula="~ age",
                                     link_precision=links.Log())
        cls.res1 = mod.fit(cov_type="eim")
        cls.res2 = resultsb.results_meth

    def test_basic(self):
        res1 = self.res1
        res2 = self.res2

        k_mean = 4
        p, se, zv, pv = res2.table_mean.T
        assert_allclose(res1.params[:k_mean], p, rtol=1e-6)
        assert_allclose(res1.bse[:k_mean], se, rtol=1e-6)
        assert_allclose(res1.tvalues[:k_mean], zv, rtol=1e-6)
        assert_allclose(res1.pvalues[:k_mean], pv, rtol=1e-5)

        p, se, zv, pv = res2.table_precision.T
        assert_allclose(res1.params[k_mean:], p, rtol=1e-6)
        assert_allclose(res1.bse[k_mean:], se, rtol=1e-6)
        assert_allclose(res1.tvalues[k_mean:], zv, rtol=1e-6)
        assert_allclose(res1.pvalues[k_mean:], pv, rtol=1e-5)

        assert_allclose(res1.llf, res2.loglik, rtol=1e-10)
        assert_allclose(res1.aic, res2.aic, rtol=1e-10)
        assert_allclose(res1.bic, res2.bic, rtol=1e-10)
        # dofferent definitions for prsquared
        assert_allclose(res1.prsquared, res2.pseudo_r_squared, atol=0.01)
        assert_equal(res1.df_resid, res2.df_residual)
        assert_equal(res1.nobs, res2.nobs)

        # null model compared to R betareg and lmtest
        df_c = res1.df_resid_null - res1.df_resid
        assert_equal(res1.k_null, 2)

        # > lrt = lrtest(res_meth_null, res_meth)  # results from R
        pv = 7.21872953868659e-18
        lln = 60.88809589492269
        llf = 104.14802840534323
        chisq = 86.51986502084107
        dfc = 4
        # stats.chi2.sf(86.51986502093865, 4)
        assert_equal(df_c, dfc)
        assert_allclose(res1.llf, llf, rtol=1e-10)
        assert_allclose(res1.llnull, lln, rtol=1e-10)
        assert_allclose(res1.llr, chisq, rtol=1e-10)
        assert_allclose(res1.llr_pvalue, pv, rtol=1e-6)

    def test_resid(self):
        res1 = self.res1
        res2 = self.res2
        assert_allclose(res1.fittedvalues, res2.resid['fittedvalues'],
                        rtol=1e-8)
        assert_allclose(res1.resid, res2.resid['response'],
                        atol=1e-8, rtol=1e-8)

    def test_oim(self):
        # estimate with default oim, cov_type nonrobust
        res1 = self.res1.model.fit()
        res2 = self.res2

        k_mean = 4
        # R betareg uses numerical derivatives from bfgs, has lower precision
        p, se, zv, pv = res2.table_mean_oim.T
        assert_allclose(res1.params[:k_mean], p, rtol=1e-6)
        assert_allclose(res1.bse[:k_mean], se, rtol=1e-5)
        assert_allclose(res1.tvalues[:k_mean], zv, rtol=1e-5)
        assert_allclose(res1.pvalues[:k_mean], pv, atol=1e-6, rtol=1e-5)

        p, se, zv, pv = res2.table_precision_oim.T
        assert_allclose(res1.params[k_mean:], p, rtol=1e-6)
        assert_allclose(res1.bse[k_mean:], se, rtol=1e-3)
        assert_allclose(res1.tvalues[k_mean:], zv, rtol=1e-3)
        assert_allclose(res1.pvalues[k_mean:], pv, rtol=1e-2)

    def test_predict_distribution(self):
        res1 = self.res1
        mean = res1.predict()
        var_ = res1.model._predict_var(res1.params)
        distr = res1.get_distribution()
        m2, v2 = distr.stats()
        assert_allclose(mean, m2, rtol=1e-13)
        assert_allclose(var_, v2, rtol=1e-13)

        # from R: > predict(res_meth, type="variance")
        var_r6 = [
            3.1090848852102e-04, 2.4509604000073e-04, 3.7199753140565e-04,
            2.8088261358738e-04, 2.7561111800350e-04, 3.3929220526847e-04]
        n = 6
        assert_allclose(v2[:n], var_r6, rtol=1e-7)

        ex = res1.model.exog[:n]
        ex_prec = res1.model.exog_precision[:n]
        mean6 = res1.predict(ex, transform=False)
        prec = res1.predict(which="precision")
        # todo: prec6 wrong exog if not used as keyword, no exception raised
        prec6 = res1.predict(exog_precision=ex_prec, which="precision",
                             transform=False)
        var6 = res1.model._predict_var(res1.params, exog=ex,
                                       exog_precision=ex_prec)

        assert_allclose(mean6, mean[:n], rtol=1e-13)
        assert_allclose(prec6, prec[:n], rtol=1e-13)
        assert_allclose(var6, var_[:n], rtol=1e-13)
        assert_allclose(var6, var_r6, rtol=1e-7)

        distr6 = res1.model.get_distribution(res1.params,
                                             exog=ex, exog_precision=ex_prec)
        m26, v26 = distr6.stats()
        assert_allclose(m26, m2[:n], rtol=1e-13)
        assert_allclose(v26, v2[:n], rtol=1e-13)

        distr6f = res1.get_distribution(exog=ex, exog_precision=ex_prec,
                                        transform=False)
        m26, v26 = distr6f.stats()
        assert_allclose(m26, m2[:n], rtol=1e-13)
        assert_allclose(v26, v2[:n], rtol=1e-13)

        # check formula transform works for predict, currently mean only
        df6 = methylation.iloc[:6]
        mean6f = res1.predict(df6)
        # todo: prec6 wrong exog if not used as keyword, no exception raised
        #       formula not supported for exog_precision in predict
        # prec6f = res1.predict(exog_precision=ex_prec, which="precision")
        assert_allclose(mean6f, mean[:n], rtol=1e-13)
        # assert_allclose(prec6f, prec[:n], rtol=1e-13)

        distr6f = res1.get_distribution(exog=df6, exog_precision=ex_prec)
        m26, v26 = distr6f.stats()
        assert_allclose(m26, m2[:n], rtol=1e-13)
        assert_allclose(v26, v2[:n], rtol=1e-13)
        # check that we don't have pandas in distr
        assert isinstance(distr6f.args[0], np.ndarray)

        # minimal checks for get_prediction
        pma = res1.get_prediction(which="mean", average=True)
        dfma = pma.summary_frame()
        assert_allclose(pma.predicted, mean.mean(), rtol=1e-13)
        assert_equal(dfma.shape, (1, 4))
        pm = res1.get_prediction(exog=df6, which="mean", average=False)
        dfm = pm.summary_frame()
        assert_allclose(pm.predicted, mean6, rtol=1e-13)
        assert_equal(dfm.shape, (6, 4))
        pv = res1.get_prediction(exog=df6, exog_precision=ex_prec,
                                 which="var", average=False)
        dfv = pv.summary_frame()
        assert_allclose(pv.predicted, var6, rtol=1e-13)
        assert_equal(dfv.shape, (6, 4))
        # smoke tests
        res1.get_prediction(which="linear", average=False)
        res1.get_prediction(which="precision", average=True)
        res1.get_prediction(exog_precision=ex_prec, which="precision",
                            average=False)
        res1.get_prediction(which="linear-precision", average=True)

        # test agg_weights
        pm = res1.get_prediction(exog=df6, which="mean", average=True)
        dfm = pm.summary_frame()
        aw = np.zeros(len(res1.model.endog))
        aw[:6] = 1
        aw /= aw.mean()
        pm6 = res1.get_prediction(exog=df6, which="mean", average=True)
        dfm6 = pm6.summary_frame()
        pmw = res1.get_prediction(which="mean", average=True, agg_weights=aw)
        dfmw = pmw.summary_frame()
        assert_allclose(pmw.predicted, pm6.predicted, rtol=1e-13)
        assert_allclose(dfmw, dfm6, rtol=1e-13)

class TestBetaIncome():

    @classmethod
    def setup_class(cls):

        formula = "I(food/income) ~ income + persons"
        exog_prec = patsy.dmatrix("~ persons", income)
        mod_income = BetaModel.from_formula(
            formula,
            income,
            exog_precision=exog_prec,
            link_precision=links.Log()
            )
        res_income = mod_income.fit(method="newton")

        mod_restricted = BetaModel.from_formula(
            formula,
            income,
            link_precision=links.Log()
            )
        res_restricted = mod_restricted.fit(method="newton")

        cls.res1 = res_income
        cls.resr = res_restricted

    def test_score_test(self):
        res1 = self.res1
        resr = self.resr
        params_restr = np.concatenate([resr.params, [0]])
        r_matrix = np.zeros((1, len(params_restr)))
        r_matrix[0, -1] = 1
        exog_prec_extra = res1.model.exog_precision[:, 1:]

        from statsmodels.base._parameter_inference import score_test
        sc1 = score_test(res1, params_constrained=params_restr,
                         k_constraints=1)
        sc2 = score_test(resr, exog_extra=(None, exog_prec_extra))
        assert_allclose(sc2[:2], sc1[:2])

        sc1_hc = score_test(res1, params_constrained=params_restr,
                            k_constraints=1, r_matrix=r_matrix, cov_type="HC0")
        sc2_hc = score_test(resr, exog_extra=(None, exog_prec_extra),
                            cov_type="HC0")
        assert_allclose(sc2_hc[:2], sc1_hc[:2])

    def test_influence(self):
        # currently only smoke test
        res1 = self.res1
        from statsmodels.stats.outliers_influence import MLEInfluence

        influ0 = MLEInfluence(res1)
        influ = res1.get_influence()
        attrs = ['cooks_distance', 'd_fittedvalues', 'd_fittedvalues_scaled',
                 'd_params', 'dfbetas', 'hat_matrix_diag', 'resid_studentized'
                 ]
        for attr in attrs:
            getattr(influ, attr)

        frame = influ.summary_frame()
        frame0 = influ0.summary_frame()
        assert_allclose(frame, frame0, rtol=1e-13, atol=1e-13)


from math import *
from tkinter import *

def func(x):
    return x ** 3 - 7

root = Tk()

canv = Canvas(root, width=420, height=600, bg="white")  # Создание окна
canv.create_line(210, 600, 210, 0, width=2, arrow=LAST)     # Создание вертикальной оси
canv.create_line(0, 300, 420, 300, width=2, arrow=LAST)     # Создание горизонтальной оси

for i in range(-15, 15):
    if i % 3 == 0:
        canv.create_line(-3 + 210, (i * 20) + 300, 3 + 210, (i * 20) + 300, width=0.5, fill='black')    # Рисуем штрихи на оси у
        canv.create_text(230, (i * 20) + 310, text=str(i * -1.0), fill="purple", font=("Helvectica", "10"))     # Ставим значения на оси у
        if i != 0:
            canv.create_line((i * 14) + 210, -3 + 300, (i * 14) + 210, 3 + 300, width=0.5, fill='black')    # Рисуем штрихи на оси у
            canv.create_text((i * 14) + 220, 315, text=str(i / 3), fill="purple", font=("Helvectica", "10"))    # Ставим значения на оси х

for i in range(10001):
    x = (-5 + i / 1000) * -1    # считаем значения х в зависимости от масштаба (умножаем на -1, т.к. график получается отзеркаленым относительно оси у
    try:
        y = func(-x) * 20 + 600     # считаем значения у в зависимости от масштаба
        canv.create_oval((x * 84) + 210, y, (x * 84) + 211, y + 1, fill='black')
    except ZeroDivisionError:
        pass

canv.pack()
root.mainloop()


"""
This module illustrates the Fraction object, useful for applications that
require accurate representations of integer fractions
"""
from fractions import Fraction

num1 = Fraction(1, 3)
num2 = Fraction(1, 7)

print(num1 * num2) # Fraction(1, 21)


"""
Creates a csv of all amazon book mentions to be used in seeding the database
"""
import csv
import re
import os
from glob import glob

URL_REGEX = re.compile(
    'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
)
# only matches amazon standard idenfitication number
ASIN_REGEX = re.compile(
    'http[s]?::/*amazon.co.*/(B[0-9]{2}[0-9A-Z]{7}|[0-9]{9}[X0-9])'
)

ISBN_REGEX = re.compile(
    '(amazon.co.*(?:dp|o|gp|-)/([0-9]{9}[X0-9]))'
)

COLUMNS = [
    'id', 'created_utc', 'subreddit', 'subreddit_id', 'author',
    'url', 'product_id', 'score', 'link_id', 'parent_id', 'body'
]

def get_product_mentions(line, index_of):
    """
    Parses a comment body for amazon product urls and returns a list of dictionaries containing
    the fields to be written to the data csv
    """
    body = line[index_of['body']]
    matches = ISBN_REGEX.findall(body)
    rows = []
    for url, isbn in matches:
        row = {'product_id': isbn, 'url': url}
        for col in COLUMNS:
            if col in index_of:
                row[col] = line[index_of[col]]
        rows.append(row)
    return rows

def write_csv(csv_writer, csv_reader):
    """ writes all product mentions in csv_reader to the csv_writer """
    header = next(csv_reader)
    index_of = {col: index for index, col in enumerate(header)}
    for line in csv_reader:
        rows_to_add = get_product_mentions(line, index_of)
        for row_dict in rows_to_add:
            csv_writer.writerow(row_dict)

def main():
    """
    Reads in the all the comment csvs in `csv_directory` and builds a csv containing all the
    product mentions found in the comments
    """
    csv_paths = sorted(glob(os.path.join('amazon', '*.csv')), key=lambda p: p.split('/'))
    with open('amazon_book_comments.csv', 'w+') as wf:
        csv_writer = csv.DictWriter(wf, fieldnames=COLUMNS)
        for csv_path in csv_paths:
            with open(csv_path) as rf:
                csv_reader = csv.reader(rf)
                write_csv(csv_writer, csv_reader)

if __name__ == '__main__':
    main()


def print_data(file):
    try:
        f = open(file)
        print(f.read())
    except FileNotFoundError:
        print("Файлу {} не існує".format(file))
    except PermissionError:
        print("Немає дозволу на відкриття файлу {}".format(file))
    else:
        f.close()

if __name__ == '__main__':
    while True:
        file = input("Введіть назву файлу: ")
        if file == "":
            break
        print_data(file)


#Importation des Bibliothèque
from bs4 import BeautifulSoup
import requests
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font

#Creation d'un Fichier Excel avec les titres de chaque colonne
wb = Workbook()
ws = wb.active
ws.title = 'Posts'

heading = ['Title', 'Category', 'Date', 'Content', 'Link', 'Img']
ws.append(heading)

# Number of pages to scraping from Hespress
NUMBER_OF_PAGES = 6

print('[+] Start scraping Hespress')

headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36'
}

# 29423 last page of Hesspress
for i in range(1, NUMBER_OF_PAGES):
    print(f'Filtrer les données de chaque page {str(i)} :')

    #Requesting
    html_text = requests.get('https://www.hespress.com/?action=ajax_listing&paged=' + str(i) +
                             '&tq=MjAyMi0wNC0wNiAwMDowNTowMA%3D%3D&all_listing=1', headers=headers).text

    #Parsing
    soup = BeautifulSoup(html_text, 'lxml')
    posts = soup.find_all('div', class_='overlay card')

    #Scraping Content
    for post in posts:
        print(f'[+] Scraping post')
        post_title = post.find('h3', class_='card-title').text
        post_category = post.find('span', class_='cat').text
        post_img = post.find('img', class_='wp-post-image')['src']
        post_link = post.find('a', class_='stretched-link')['href']
        post_date = post.find('small', class_='text-muted time').text

    #Scraping Post Content

    post_content_html_text = requests.get(post_link, headers=headers).text
    soup = BeautifulSoup(post_content_html_text, 'lxml')

    post_content_paragraphs = soup.find('div', class_='article-content').find_all('p')

    post_content = ''

    for p in post_content_paragraphs:
        post_content += p.text + '\n'

    # Add post to Excel file
    ws.append([post_title, post_category, post_date, post_content, post_link, post_img])

    # Add font to first line of Excel file
    for col in range(1, 7):
        ws[get_column_letter(col) + '1'].font = Font(bold=True)

    print('[+] Scraping post successfully')

# Save Excel file
wb.save('post.xlsx')
print('[+] Finish scraping Hesspress')


import sqlite3
import streamlit as st
import secrets

class SQLiteConnection:
    def __init__(self):
        self.db_name = st.secrets['DATABASE']['dbname']
        self.conn = sqlite3.connect(self.db_name, check_same_thread=False)
        self.cursor = self.conn.cursor()
        self.pmin = st.secrets['USER']['min_pwd_length']
        self.pmax = st.secrets['USER']['max_pwd_length']