'''
   File used to extract members of UNEP FI. From the extracted list, this file will determine whether a company is a member of UNEP FI
'''

# Install Relevant Libraries
# pip install openpyxl --upgrade --pre
# pip install fuzzywuzzy

# Import Libraries and UNEP FI data
import requests
import fuzzywuzzy as fw
from fuzzywuzzy import fuzz
from bs4 import BeautifulSoup

url = 'https://www.unepfi.org/members/'
page = requests.get(url)
soup = BeautifulSoup(page.content, "html.parser")
lst = soup.find_all("td")
membership_lst = []

for x in range(len(lst)):
    if x%5 == 0:
        curr = str(lst[x]).split('/">')[1]
        curr = curr.split("</")[0]
        membership_lst.append(curr)

## name = input("Input the company name: ")

# Function to detect UNEP FI members

def is_member_unepfi(name):
    '''
   Function used to check whether a company is member of UNEP FI

   Parameters
   ----------
   arg1 : name
       Name of company

   Returns
   -------
   boolean
       True if a company is member of UNEP FI, False otherwise
   '''

    for x in membership_lst:
        if x.lower() == 'ing' or x.lower() == 'tal' or x.lower() == 'an post':
            continue
        if fuzz.partial_ratio(x.lower(), name.lower()) >= 95:
            return True
    return False

# Output
## is_member(name)


# -*- coding: utf-8 -*-
"""
Input nom de jeu
"""

import tkinter as tk
import numpy as n
import pygame as p
import pygame.mixer as pm
import pygame.mixer_music as pmm

global Lmap
Lmap=[]
Map_dispo=10

# # Fonctions pour les menus # #
def Menu_principal():
    global Menu
    Menu = tk.Tk()
    Menu.geometry("800x500")
    centrefenetre(Menu)
    Menu.title("Nom du jeu - Menu principal")
    Menu.resizable(width=False, height=False)

    Case_Titre = tk.Frame(Menu,borderwidth=10,relief=tk.GROOVE)
    Case_Titre.pack(side=tk.TOP, pady=50)
    Titre = tk.Label(Case_Titre,text="Trouver un titre il faut",font="Arial 32")
    Titre.pack()

    Frame_jeu=tk.Frame(Menu,borderwidth=5, relief=tk.GROOVE)
    Frame_jeu.pack(side=tk.TOP, pady=10)
    bouton_jeu= tk.Button(Frame_jeu, text="Nouvelle partie", command= lambda fen=Menu,fonc=Newgame :chgmt_fen(fen,fonc))
    bouton_jeu.pack()

    Frame_info=tk.Frame(Menu,borderwidth=5, relief=tk.GROOVE)
    Frame_info.pack(side=tk.TOP, pady=10)
    bouton_info= tk.Button(Frame_info, text="A propos", command=Info)
    bouton_info.pack()

    Frame_quit = tk.Frame(Menu, borderwidth=5, relief=tk.GROOVE)
    Frame_quit.pack(side=tk.TOP, pady=10)
    bouton_quit=tk.Button(Frame_quit, text="Quitter", command=Menu.destroy)
    bouton_quit.pack()
    Menu.mainloop()

def Info():
    print("Jeu créé par moi")
    print("Musique : Land Below Fire Emblem Fates OST")

def Newgame():
    global Lmap
    Lmap=[]
    for i in range (Map_dispo):
        Lmap.append(eval("map"+str(i+1)))
    global Menu_Lvl
    Menu_Lvl= tk.Tk()
    Menu_Lvl.geometry("800x500")
    centrefenetre(Menu_Lvl)
    Menu_Lvl.title("Nom du jeu - Menu des niveaux")
    Menu_Lvl.resizable(width=False, height=False)

    Case_Titre = tk.Frame(Menu_Lvl,borderwidth=10,relief=tk.GROOVE)
    Case_Titre.grid(row=10,column=1,columnspan=8, pady=50) # Travailler sur le centrage
    Titre = tk.Label(Case_Titre,text="Choisissez un niveau",font="Arial 24")
    Titre.grid()
    for i in range (len(Lmap)):
        Case_niveau(i)

    Frame_quit = tk.Frame(Menu_Lvl, borderwidth=5, relief=tk.GROOVE)
    Frame_quit.grid(row=600,column=3,columnspan=3, pady=10)
    bouton_quit=tk.Button(Frame_quit, text="Retour au menu", command=lambda fen=Menu_Lvl,fonc=Menu_principal :chgmt_fen(fen,fonc))
    bouton_quit.grid()
    Menu_Lvl.mainloop()

def Case_niveau(i):
    global Lmap
    global Menu_Lvl
    Case_Lvl = tk.Frame(Menu_Lvl,borderwidth=5,relief=tk.GROOVE)
    Case_Lvl.grid(column=i%8,row=100+(i//8)*10,padx=24,pady=10)
    Bouton_Lvl = tk.Button(Case_Lvl,text="Lvl "+str(i+1),command=lambda fen=Menu_Lvl,fonc=Lmap[i] :chgmt_fen(fen,fonc))
    Bouton_Lvl.grid()

def Pause():
    global Play
    Play = False
    global Menu_pause
    Menu_pause=tk.Tk()
    Menu_pause.geometry("800x500")
    centrefenetre(Menu_pause)
    Menu_pause.title("Nom du jeu - Pause")
    Menu_pause.resizable(width=False, height=False)

    Case_Titre = tk.Frame(Menu_pause,borderwidth=10,relief=tk.GROOVE)
    Case_Titre.pack(side=tk.TOP, pady=50)
    Titre = tk.Label(Case_Titre,text="Pause",font="Arial 24")
    Titre.pack()

    Frame_reprendre=tk.Frame(Menu_pause,borderwidth=5, relief=tk.GROOVE)
    Frame_reprendre.pack(side=tk.TOP, pady=10)
    bouton_reprendre= tk.Button(Frame_reprendre, text="Reprendre", command=lambda fen=Menu_pause,fonc=reprendre :chgmt_fen(fen,fonc))
    bouton_reprendre.pack()

    Frame_recommencer=tk.Frame(Menu_pause,borderwidth=5, relief=tk.GROOVE)
    Frame_recommencer.pack(side=tk.TOP, pady=10)
    bouton_recommencer= tk.Button(Frame_recommencer, text="Recommencer", command=lambda fen=Menu_pause,fonc=recommencer :chgmt_fen(fen,fonc))
    bouton_recommencer.pack()

    Frame_quit = tk.Frame(Menu_pause, borderwidth=5, relief=tk.GROOVE)
    Frame_quit.pack(side=tk.TOP, pady=10)
    bouton_quit=tk.Button(Frame_quit, text="Retour au menu", command=lambda fen=Menu_pause,fonc=quitter :chgmt_fen(fen,fonc))
    bouton_quit.pack()
    Menu_pause.mainloop()

def reprendre():
    global Play
    Play=True
    Mouvement_adverse()

def recommencer():
    global fenetre
    fenetre.destroy()
    eval("map"+str(Niveau))()

def quitter():
    global fenetre
    pmm.stop()
    fenetre.destroy()
    Menu_principal()

def fenGO():
    global GO
    GO = tk.Tk()
    GO.geometry("800x500")
    centrefenetre(GO)
    GO.title("Game Over")
    GO.resizable(width=False, height=False)

    Case_Titre = tk.Frame(GO,borderwidth=10,relief=tk.GROOVE)
    Case_Titre.pack(side=tk.TOP, pady=50)
    Titre = tk.Label(Case_Titre,text="Vous avez perdu",font="Arial 24")
    Titre.pack()

    Frame_recommencer=tk.Frame(GO,borderwidth=5, relief=tk.GROOVE)
    Frame_recommencer.pack(side=tk.TOP, pady=10)
    bouton_recommencer= tk.Button(Frame_recommencer, text="Réessayer", command=lambda fen=GO,fonc=recommencer :chgmt_fen(fen,fonc))
    bouton_recommencer.pack()

    Frame_quit = tk.Frame(GO, borderwidth=5, relief=tk.GROOVE)
    Frame_quit.pack(side=tk.TOP, pady=10)
    bouton_quit=tk.Button(Frame_quit, text="Retour au menu", command=lambda fen=GO,fonc=quitter :chgmt_fen(fen,fonc))
    bouton_quit.pack()
    GO.mainloop()

def fenW():
    global W
    W = tk.Tk()
    W.geometry("800x500")
    centrefenetre(W)
    W.title("Fin de niveau")
    W.resizable(width=False, height=False)

    Case_Titre = tk.Frame(W,borderwidth=10,relief=tk.GROOVE)
    Case_Titre.pack(side=tk.TOP, pady=50)
    Titre = tk.Label(Case_Titre,text="Vous avez gagné",font="Arial 24")
    Titre.pack()

    Frame_recommencer=tk.Frame(W,borderwidth=5, relief=tk.GROOVE)
    Frame_recommencer.pack(side=tk.TOP, pady=10)
    bouton_recommencer= tk.Button(Frame_recommencer, text="Réessayer", command=lambda fen=W,fonc=recommencer :chgmt_fen(fen,fonc))
    bouton_recommencer.pack()

    Frame_Next_Lvl=tk.Frame(W,borderwidth=5, relief=tk.GROOVE)
    Frame_Next_Lvl.pack(side=tk.TOP, pady=10)
    bouton_Next_Lvl= tk.Button(Frame_Next_Lvl, text="Niveau suivant", command=lambda fen=W,fonc=Next_Lvl :chgmt_fen(fen,fonc))
    bouton_Next_Lvl.pack()

    Frame_quit = tk.Frame(W, borderwidth=5, relief=tk.GROOVE)
    Frame_quit.pack(side=tk.TOP, pady=10)
    bouton_quit=tk.Button(Frame_quit, text="Retour au menu", command=lambda fen=W,fonc=quitter :chgmt_fen(fen,fonc))
    bouton_quit.pack()
    W.mainloop()

def Next_Lvl():
    global fenetre
    fenetre.destroy()
    global Niveau
    eval("map"+str(Niveau+1))()

def geoliste(g):
    r=[i for i in range(0,len(g)) if not g[i].isdigit()]
    return [int(g[0:r[0]]),int(g[r[0]+1:r[1]]),int(g[r[1]+1:r[2]]),int(g[r[2]+1:])]

def centrefenetre(fen):
    fen.update_idletasks()
    l,h,x,y=geoliste(fen.geometry())
    fen.geometry("%dx%d%+d%+d" % (l,h,(fen.winfo_screenwidth()-l)//2,(fen.winfo_screenheight()-h)//2))

def chgmt_fen(fen,fonc):
    fen.destroy()
    fonc()

# # Création des map # #

def create_map():
    print("createMap")
    global Zone_interdite
    Zone_interdite=[]
    global Info_garde
    Info_garde=[]
    global Vision
    Vision=[]
    global Objet
    Objet=[]
    global Teleporteur
    Teleporteur=[]
#    global Porte
#    Porte=[]
    global Laser
    Laser=[]
    global Inventaire
    Inventaire=[0]
    global Play
    Play = True
    global Tps_mvt
    Tps_mvt=100
    global Alarme_active
    Alarme_active=False
    global Temps_ralentit
    Temps_ralentit=False
    global testp
    testp=0

    global fenetre
    fenetre = tk.Tk()
    fenetre.attributes('-fullscreen',True )
    global Event
    Event=tk.Frame(fenetre,borderwidth=2, relief=tk.GROOVE,width=269,height=244)
    Event.pack_propagate(False)
    Event.pack(side=tk.LEFT)
    label=tk.Label(Event,text="Rapport des évènements \n",font="Arial 14")
    label.pack()
    tk.Label(Event,text="Cliquez sur la fenêtre avant de jouer").pack()
    global Info
    Info=[]
    global Tps_ecoule
    Tps_ecoule=0
    Tps_Score=tk.Frame(fenetre)
    Tps_Score.pack(side=tk.RIGHT)
    label2=tk.Label(Tps_Score,text="                       \n",font="Arial 14")
    label2.pack()
    global Aff_Temps
    Aff_Temps=tk.StringVar()
    Aff_Temps.set("Temps : "+str(Tps_ecoule/1000))
    label1=tk.Label(Tps_Score,textvariable=Aff_Temps)
    label1.pack()
    global Aff_cle
    Aff_cle=tk.StringVar()
    Aff_cle.set("Vous avez "+str(Inventaire[0])+" clé(s)")
    label3=tk.Label(Tps_Score,textvariable=Aff_cle)
    label3.pack()
    # création du canvas
    global canvas
    canvas = tk.Canvas(fenetre, width=Longueur_map, height=Largeur_map, bg="ivory",highlightthickness=False)
    p.init()
    pmm.load("MusiqueBG.wav")
    pmm.play(-1)
    global Son_alarme
    Son_alarme=pm.Sound("Alarme.wav")

def map1():
    print("map1")
    global Niveau
    Niveau=1
    create_map()

    # # Murs # #
    obstacle(150,160,80,70)
    obstacle(260,110,60,160)
    obstacle(50,110,70,160)
    obstacle(120,50,150,80)
    obstacle(120,270,150,30)
    obstacle(340,330,40,30)
    obstacle(500,440,30,40)
    obstacle(440,490,40,40)
    obstacle(550,490,30,40)
    obstacle(480,550,60,30)
    obstacle(350,510,30,30)
    obstacle(900,440,300,60)
    obstacle(1020,300,60,300)
    # # Objets # #
    Creation_alarme(120,800)
    Cle(260,800)
    Portail(400,770,60,"v")
    Portail(900,800,60,"h")
    TimeSlower(600,800)
    Plaque_tp(2,20,20,300,300)
    Plaque_tp(1,800,800,1200,800)
    # # Lasers alarme # #
    Creation_alarme2f(120,500,200,500)
    Creation_alarme2f(60,500,60,700)
    Creation_alarme2m("h",120,550,80,550,650,5)
    Creation_alarme2m("v",150,950,80,120,230,5)
    # # Objectif # #
    global objectif
    objectif = canvas.create_rectangle(1400,1000,1400+Taille_perso,1000+Taille_perso,fill="yellow")
    # # Personage # #
    global Perso
    Perso = canvas.create_rectangle(0,0,Taille_perso,Taille_perso,fill="violet")

    # # Gardes # #

    Creation_garde(350,200,420,300,350,200,1,-10)
    Creation_garde(130,140,230,230,230,230,3,-5)
    Creation_garde(730,140,800,200,730,140,1,5)
    Creation_garde2(500,500,1,-500)   # OK
    Creation_garde2(1000,500,1,500)  #  35 gauche
    Creation_garde2(1080,500,1,-500)  # 35 droite et bas
    Creation_garde2(1000,420,1,-500)  # OK
    Creation_garde2(1080,420,1,500)   # 35 haut
    # obstacle au dessus ou à gauche --> 35
    Creation_garde2(700,700,4,0)
    Creation_garde(400,500,400,700,400,500,1,-10)
    Creation_garde2(100,660,1,0)
    Mouvement_adverse()

    canvas.focus_set()
    canvas.bind("<Key>", clavier)
    canvas.pack(expand=1)
    fenetre.mainloop()

def map2():
    global Niveau
    Niveau=2
    create_map()

    # # Murs # #
    obstacle(0,0,1440,300)
    obstacle(0,300,210,360)
    obstacle(0,660,1440,390)
    obstacle(1250,300,210,360)
    obstacle(210,420,160,80)
    obstacle(520,300,160,200)
    obstacle(290,540,120,80)
    obstacle(490,540,120,80)
    obstacle(850,420,120,240)
    obstacle(970,300,120,40)
    # # Objectif # #
    global objectif
    objectif = canvas.create_rectangle(1090,630,1090+Taille_perso,630+Taille_perso,fill="yellow")
    # # Personage # #
    global Perso
    Perso = canvas.create_rectangle(250,350,250+Taille_perso,350+Taille_perso,fill="violet")
    # # Guardes # #
    Creation_garde(380,460,490,460,380,460,1,5)
    Creation_garde(270,520,410,620,270,520,1,-5)
    Creation_garde(470,520,610,620,470,520,1,5)
    Creation_garde(750,510,750,630,750,510,1,5)
    Creation_garde2(680,480,1,500)
    Creation_garde2(830,480,3,500)
    Creation_garde2(750,350,2,0)
    Creation_garde2(980,640,4,0)
    Creation_garde2(1220,640,4,0)
    Creation_garde(1000,380,1080,500,1000,380,1,5)
    Creation_garde(1080,380,1200,460,1200,460,3,-5)
    Creation_garde(1000,500,1120,580,1080,500,1,-5)
    Creation_garde(1120,460,1200,580,1120,580,3,5)
    Mouvement_adverse()

    canvas.focus_set()
    canvas.bind("<Key>", clavier)
    canvas.pack(expand=1)
    fenetre.mainloop()

def map3():
    global Niveau
    Niveau=3
    create_map()

    # # Murs # #
    obstacle(100,0,120,350)
    obstacle(220,0,1220,100)
    obstacle(0,430,220,90)
    obstacle(910,180,170,340)
    obstacle(1200,260,100,60)
    obstacle(1070,380,120,60)
    obstacle(1310,380,130,60)
    obstacle(0,520,1080,160)
    obstacle(1070,600,140,160)
    obstacle(1290,600,150,350)
    obstacle(1080,840,210,100)
    obstacle(430,670,80,80)
    obstacle(310,730,80,100)
    obstacle(310,830,200,100)
    obstacle(0,670,80,260)
    obstacle(0,930,1440,120)
    # # Objectif # #
    global objectif
    objectif = canvas.create_rectangle(180,800,180+Taille_perso,800+Taille_perso,fill="yellow")
    # # Perso # #
    global Perso
    Perso = canvas.create_rectangle(0,0,Taille_perso,Taille_perso,fill="violet")
    # # Guardes # #
    for i in range (6):
        for j in range (4):
            Creation_garde2(260+120*i,120+120*j,2-(-1)**(i+j),500)
    Creation_garde(1080,190,1200,190,1080,190,1,5)
    Creation_garde(1300,190,1420,190,1420,190,1,5)
    Creation_garde(1080,230,1200,230,1200,230,1,5)
    Creation_garde(1300,230,1420,230,1300,230,1,5)
    Creation_garde(1080,280,1170,280,1080,280,1,5)
    Creation_garde(1310,280,1400,280,1400,280,1,5)
    Creation_garde2(1240,390,1,800)
    Creation_garde2(1160,450,1,0)
    Creation_garde2(1320,450,3,0)
    Creation_garde(1115,450,1115,570,1115,450,1,-5)
    Creation_garde(1365,450,1365,570,1365,570,1,5)
    Creation_garde2(1240,540,1,500)
    Creation_garde(1080,580,1200,580,1080,580,1,5)
    Creation_garde(1300,580,1420,580,1420,580,1,5)
    for i in range(11):
        Creation_garde(550+50*i,680,550+50*i,740,550+50*i,680+10*abs(5-i),2-signe(5-i),1)
        Creation_garde(550+50*i,850,550+50*i,910,550+50*i,850+10*abs(5-i),2+signe(5-i),1)
    Creation_garde(120,740,240,860,120,740,1,10)
    Creation_garde(120,740,240,860,240,740,2,10)
    Creation_garde(120,740,240,860,240,860,3,10)
    Creation_garde(120,740,240,860,120,860,4,10)

    Mouvement_adverse()

    canvas.focus_set()
    canvas.bind("<Key>", clavier)
    canvas.pack(expand=1)
    fenetre.mainloop()

def map4():
    global Niveau
    Niveau=4
    create_map()

    # # Murs # #
    obstacle(-20,60,90,330)
    obstacle(130,0,130,300)
    obstacle(130,320,130,60)
    obstacle(40,440,60,40)
    obstacle(160,440,60,40)
    obstacle(260,320,70,180)
    obstacle(-20,540,60,300)
    obstacle(-20,830,310,220)
    obstacle(90,540,240,120)
    obstacle(90,660,10,50)
    obstacle(90,780,10,50)
    obstacle(170,680,80,50)
    obstacle(170,760,80,50)
    obstacle(330,620,80,240)
    obstacle(290,920,180,130)
    obstacle(470,720,100,330)
    obstacle(570,840,210,210)
    obstacle(770,550,120,500)
    obstacle(410,620,160,40)
    obstacle(570,550,160,110)
    obstacle(720,660,10,50)
    obstacle(620,710,80,80)
    obstacle(330,320,50,150)
    obstacle(400,490,30,100)
    obstacle(570,470,10,80)
    obstacle(440,180,140,290)
    obstacle(370,180,70,80)
    obstacle(260,0,230,100)
    obstacle(490,0,140,130)
    obstacle(630,0,160,200)
    obstacle(790,0,100,500)
    obstacle(570,250,130,40)
    obstacle(690,250,30,110)
    obstacle(650,460,160,40)
    obstacle(620,340,30,160)
    obstacle(890,0,320,250)
    obstacle(890,800,320,250)
    obstacle(930,300,100,40)
    obstacle(1070,300,100,40)
    obstacle(950,400,60,90)
    obstacle(1090,400,60,90)
    obstacle(1020,560,60,90)
    obstacle(930,620,40,40)
    obstacle(1130,620,40,40)
    obstacle(970,700,160,60)
    obstacle(1210,0,230,490)
    obstacle(1210,550,140,400)
    obstacle(1210,950,80,100)
    # # Objectif # #
    global objectif
    objectif = canvas.create_rectangle(1400,1000,1400+Taille_perso,1000+Taille_perso,fill="yellow")
    # # Personage # #
    global Perso
    Perso = canvas.create_rectangle(0,0,Taille_perso,Taille_perso,fill="violet")
    # # Guardes # #
    Creation_garde(130,300,240,300,130,300,1,5)
    Creation_garde(20,420,100,480,20,420,1,5)
    Creation_garde(140,420,220,480,200,480,3,-5)
    Creation_garde2(0,520,1,1000)
    Creation_garde2(0,520,3,1000)
    Creation_garde2(100,660,2,0)
    Creation_garde(150,660,250,730,150,680,2,-5)
    Creation_garde(150,740,250,810,150,740,1,-5)
    Creation_garde(330,860,390,860,330,860,1,5)
    Creation_garde2(470,700,1,700)
    Creation_garde(600,690,700,790,700,690,1,-5)
    Creation_garde(600,690,700,790,600,690,2,-5)
    Creation_garde(600,690,700,790,600,790,3,-5)
    Creation_garde(600,690,700,790,700,790,4,-5)
    Creation_garde2(330,470,1,0)
    Creation_garde(440,490,470,570,440,490,1,-5)
    Creation_garde(500,490,540,570,540,570,3,-5)
    Creation_garde(340,260,420,300,340,260,1,5)
    Creation_garde(260,160,330,240,330,160,2,5)
    Creation_garde2(470,100,1,1200)
    Creation_garde2(470,100,3,1200)
    Creation_garde(720,200,770,250,720,200,1,-5)
    Creation_garde(660,370,760,370,660,370,1,5)
    Creation_garde(660,430,760,430,760,430,3,5)
    Creation_garde2(620,500,1,700)
    Creation_garde(910,280,1030,340,910,280,1,-5)
    Creation_garde(910,280,1030,340,1030,340,3,-5)
    Creation_garde(1050,280,1170,340,1050,280,1,-5)
    Creation_garde(1050,280,1170,340,1170,340,3,-5)
    Creation_garde(930,380,1010,490,930,380,1,5)
    Creation_garde(930,380,1010,490,1010,490,3,5)
    Creation_garde(1070,380,1150,490,1070,380,1,-5)
    Creation_garde(1070,380,1150,490,1150,490,3,-5)
    Creation_garde(910,600,970,660,910,600,1,5)
    Creation_garde(1000,540,1080,650,1000,540,1,-5)
    Creation_garde(1000,540,1080,650,1080,650,3,-5)
    Creation_garde(1110,600,1170,660,1100,600,1,-5)
    Creation_garde(950,680,1130,760,1040,680,1,-5)
    Creation_garde(950,680,1130,760,1040,760,3,-5)

    Mouvement_adverse()

    canvas.focus_set()
    canvas.bind("<Key>", clavier)
    canvas.pack(expand=1)
    fenetre.mainloop()

def map5():
    global Niveau
    Niveau=5
    create_map()
    # # Murs # #
    obstacle(0,0,350,180)
    obstacle(0,180,50,160)
    obstacle(0,340,150,120)
    obstacle(0,460,70,80)
    obstacle(0,620,70,80)
    obstacle(0,700,150,350)
    obstacle(120,220,150,40)
    obstacle(290,180,20,160)
    obstacle(230,260,40,200)
    obstacle(150,540,80,80)
    obstacle(180,720,20,50)
    obstacle(180,810,20,50)
    obstacle(150,900,130,40)
    obstacle(150,940,520,110)
    obstacle(270,420,80,40)
    obstacle(310,460,40,80)
    obstacle(350,480,100,60)
    obstacle(310,620,280,80)
    obstacle(230,700,280,80)
    obstacle(230,780,50,40)
    obstacle(300,780,50,40)
    obstacle(370,780,30,40)
    obstacle(420,780,30,40)
    obstacle(490,780,20,40)
    obstacle(300,900,50,40)
    obstacle(370,900,30,40)
    obstacle(420,900,30,40)
    obstacle(490,900,180,40)
    obstacle(550,780,40,180)
    obstacle(350,0,260,40)
    obstacle(610,0,120,20)
    obstacle(330,340,20,80)
    obstacle(330,240,80,100)
    obstacle(410,320,60,20)
    obstacle(410,190,60,110)
    obstacle(410,140,120,60)
    obstacle(410,120,140,20)
    obstacle(550,120,60,80)
    obstacle(610,140,160,60)
    obstacle(490,240,40,60)
    obstacle(590,640,80,60)
    obstacle(670,640,100,180)
    obstacle(670,900,40,30)
    obstacle(670,1030,160,20)
    obstacle(790,820,40,110)
    obstacle(770,450,60,370)
    obstacle(670,430,160,20)
    obstacle(610,430,60,120)
    obstacle(610,400,40,30)
    obstacle(550,240,40,80)
    obstacle(590,240,80,60)
    obstacle(610,300,60,80)
    obstacle(670,340,80,70)
    obstacle(770,220,60,190)
    obstacle(830,220,80,880)
    obstacle(770,140,180,80)
    obstacle(730,0,220,140)
    obstacle(610,140,160,60)
    obstacle(550,120,60,80)
    obstacle(510,420,80,200)
    obstacle(430,380,160,40)
    obstacle(490,320,100,60)
    obstacle(950,0,80,100)
    obstacle(1030,0,80,40)
    obstacle(1110,0,330,100)
    obstacle(1190,100,250,120)
    obstacle(1230,220,210,240)
    obstacle(1330,460,110,80)
    obstacle(1230,540,210,240)
    obstacle(1190,780,250,270)
    obstacle(1110,900,80,150)
    obstacle(1030,960,80,90)
    obstacle(950,900,80,150)
    obstacle(910,780,40,270)
    obstacle(1030,260,60,160)
    obstacle(960,550,60,180)
    obstacle(1120,550,60,180)
    # # Objets # #
    Cle(660,70)
    Cle(740,1000)
    Cle(1060,920)
    Portail(60,540,80,"v")
    Portail(50,540,80,"v")
    Portail(1230,460,80,"v")
    Plaque_tp(1,10,570,1060,60)
    # # Lasers alarme # #
    Creation_alarme2f(600,40,600,120)
    Creation_alarme2f(710,910,790,910)
    Creation_alarme2f(910,300,1030,300)
#    Creation_alarme2f(950,840,990,840)
#    Creation_alarme2f(1150,840,1190,840)
    Creation_alarme2m("h",1020,880,100,820,880,5)
    Creation_alarme2m("v",260,820,80,260,510,5)
#    Creation_alarme2m("v",957,760,50,955,1045,2)
#    Creation_alarme2m("v",1185,760,50,1095,1185,2)
    # # Objectif # #
    global objectif
    objectif = canvas.create_rectangle(1280,490,1280+Taille_perso,490+Taille_perso,fill="yellow")
    # # Personage # #
    global Perso
    Perso = canvas.create_rectangle(710,510,710+Taille_perso,510+Taille_perso,fill="violet")
    # # Gardes # #
    Creation_garde(590,300,590,505,590,300,1,4)
    Creation_garde(670,410,810,410,670,410,1,4)
    Creation_garde2(670,320,1,1000)
    Creation_garde2(670,320,3,1000)
    Creation_garde2(750,200,1,1000)
    Creation_garde2(750,200,3,1000)
    Creation_garde(530,140,530,280,530,140,1,5)
    Creation_garde(410,300,510,300,410,300,1,5)
    Creation_garde(355,360,405,440,355,360,1,5)
    Creation_garde2(490,420,1,800)
    Creation_garde2(490,420,3,800)
    Creation_garde2(490,600,1,800)
    Creation_garde2(490,600,3,800)
    Creation_garde2(430,540,1,800)
    Creation_garde(130,520,230,620,130,520,1,-5)
    Creation_garde(130,520,230,620,230,620,3,-5)
    Creation_garde2(70,520,1,1000)
    Creation_garde2(70,620,1,-1000)
    Creation_garde(160,700,160,850,160,700,1,6)
    Creation_garde(200,700,200,850,200,850,3,-6)
    Creation_garde(280,780,280,920,280,780,1,5)
    Creation_garde(350,780,350,920,350,850,1,5)
    Creation_garde(400,780,400,920,400,920,1,5)
    Creation_garde(450,780,450,920,450,780,1,5)
    Creation_garde(470,780,470,920,470,920,1,5)
    Creation_garde(590,700,650,760,590,700,1,-5)
    Creation_garde(660,830,760,870,760,870,3,-5)
    Creation_garde(690,950,790,950,690,950,1,5)
    Creation_garde(150,270,150,380,150,270,1,3)
    Creation_garde(180,295,180,405,180,405,1,3)
    Creation_garde(210,320,210,430,210,320,1,3)
    Creation_garde2(270,400,1,900)
    Creation_garde2(270,400,3,900)
    Creation_garde(310,180,310,320,310,180,1,3)
    Creation_garde(360,60,380,120,360,60,1,-5)
    Creation_garde(620,30,700,110,620,30,1,5)
    Creation_garde(960,150,1030,200,960,150,1,5)
    Creation_garde(1090,150,1160,200,1160,200,3,5)
    Creation_garde(910,340,1010,340,910,340,1,5)
    Creation_garde(910,380,1010,380,1010,380,3,5)
    Creation_garde(1090,300,1210,300,1090,300,1,5)
    Creation_garde(1090,380,1210,380,1210,380,3,5)
    Creation_garde2(1140,340,1,500)
    Creation_garde2(930,490,1,600)
    Creation_garde2(1190,490,3,600)
    Creation_garde2(1100,590,1,500)
    Creation_garde2(1020,650,3,500)
    Creation_garde2(1100,710,1,500)
    Creation_garde2(920,720,4,0)
    Creation_garde2(1200,720,4,0)
    Creation_garde(1060,490,1060,720,1060,490,1,6)
    Creation_garde2(990,820,3,-700)
    Creation_garde2(1130,820,1,-700)

    Mouvement_adverse()
    canvas.focus_set()
    canvas.bind("<Key>", clavier)
    canvas.pack(expand=1)
    fenetre.mainloop()

def map6():
    print(6)

def map7():
    print(7)

def map8():
    print(8)

def map9():
    print(9)

def map10():
    print(10)

def map11():
    print(11)

def map12():
    print(12)

# # Fonctions annexes # #
def signe(x):
    if x>=0:
        return 1
    else:
        return -1

def signe1(x):
    if x>0:
        return 3
    else:
        return 1

def signe3(x):
    if x>0:
        return 1
    else:
        return 3

def Add_Visionx(n,sens):
    if n==2 or (n==3 and sens>0) or(n==1 and sens<0):
        return Taille_perso
    else:
        return 0

def Add_Visiony(n,sens):
    if (n==3 and sens>0) or (n==1 and sens<0) or n==4:
        return Taille_perso
    else:
        return 0

def Reduce_Visionx(n,sens):
    if (n==2 and sens>0) or (n==4 and sens<0):
        return 10
    elif n==1 and sens<0:
        return 5
    else:
        return -1

def Reduce_Visionxr(n,sens):
    if n==3:
        return 5
    else:
        return -1

def Reduce_Visiony(n,sens):
    if n==3:
        return 10
    else:
        return -1

def Reduce_Visionyr(n,sens):
    if (n==4 and sens>0) or (n==2 and sens<0):
        return 5
    elif n==4 and sens<0:
        return -5
    else:
        return -1

def betweenL(x,a,b):
    m=a
    M=b
    if m>M:
        m,M = M,m
    if x>=m and x<=M:
        return True
    else:
        return False

def betweenS(x,a,b):
    m=a
    M=b
    if m>M:
        m,M = M,m
    if x>m and x<M:
        return True
    else:
        return False

def Suppr_List(L,i):
    return L[0:i]+L[i+1:]

def Add_info(texte):
    global Info
    global Event
    A=tk.Label(Event,text=texte)
    if len(Info)>6:
        for i in range (len(Info)-1):
            Info[i]=Info[i+1]
        Info[len(Info)-1]=texte
        for i in range(1,len(Event.winfo_children())):
            Event.winfo_children()[1].destroy()
        for i in range (len(Info)):
            tk.Label(Event,text=Info[i]).pack()
    else:
        Info.append(texte)
        A.pack()

# # Fonction canvas # #
def rotation(objet,point,angle):
    global canvas
    Nombre_points= len(canvas.coords(objet))
    Nouvelle_coords=[]
    for i in range(0,Nombre_points,2):
        X0s=point[0] + (canvas.coords(objet)[i]-point[0])*n.cos(angle) + (canvas.coords(objet)[i+1]-point[1])*n.sin(angle)
        Nouvelle_coords.append(X0s)
        Y0s=point[1] - (canvas.coords(objet)[i]-point[0])*n.sin(angle) + (canvas.coords(objet)[i+1]-point[1])*n.cos(angle)
        Nouvelle_coords.append(Y0s)
    canvas.coords(objet,Nouvelle_coords)

def Vision_garde(x0,y0,Taille_vision,sens):
    global canvas
    if sens>0:
        V=canvas.create_polygon([x0+Taille_perso,y0+Taille_perso/4,x0+Taille_perso,y0+3/4*Taille_perso,x0+Taille_perso+Taille_vision,y0+3/4*Taille_perso+Pente_cone*Taille_vision,x0+Taille_perso+Taille_vision,y0+Taille_perso/4-Pente_cone*Taille_vision],outline="black",fill="yellow")
    else:
        V=canvas.create_polygon([x0,y0+Taille_perso/4,x0,y0+3/4*Taille_perso,x0-Taille_vision,y0+3/4*Taille_perso+Pente_cone*Taille_vision,x0-Taille_vision,y0+Taille_perso/4-Pente_cone*Taille_vision],outline="black",fill="yellow")
    return V

def Reduire_visionr(i):
    global Zone_interdite
    global Info_garde
    Info_garde[i][8]=0
    canvas.delete(Info_garde[i][7])
    Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0],canvas.coords(Info_garde[i][0])[1],Info_garde[i][8],1)
    Centre=((canvas.coords(Info_garde[i][0])[0]+canvas.coords(Info_garde[i][0])[2])/2,(canvas.coords(Info_garde[i][0])[1]+canvas.coords(Info_garde[i][0])[3])/2)
    rotation(Info_garde[i][7],Centre,-signe(Info_garde[i][5])*(Info_garde[i][6]-1)*n.pi/2)
    while (Restriction_mouvement(canvas.coords(Info_garde[i][7])[4],canvas.coords(Info_garde[i][7])[5],"L")) and (Restriction_mouvement(canvas.coords(Info_garde[i][7])[6],canvas.coords(Info_garde[i][7])[7],"L")) and Info_garde[i][8]<50:
        Info_garde[i][8]=Info_garde[i][8]+5 # 1 : + précis mais ralentit le jeu
        canvas.delete(Info_garde[i][7])
        Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0],canvas.coords(Info_garde[i][0])[1],Info_garde[i][8],1)
        rotation(Info_garde[i][7],Centre,-signe(Info_garde[i][5])*(Info_garde[i][6]-1)*n.pi/2)

def Reduire_vision(i):
    global Zone_interdite
    global Info_garde
   # print(Info_garde[i][6])
    Info_garde[i][8]=0
    canvas.delete(Info_garde[i][7])
    Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0],canvas.coords(Info_garde[i][0])[1],Info_garde[i][8],signe(Info_garde[i][5]))
    Centre=((canvas.coords(Info_garde[i][0])[0]+canvas.coords(Info_garde[i][0])[2])/2,(canvas.coords(Info_garde[i][0])[1]+canvas.coords(Info_garde[i][0])[3])/2)
    rotation(Info_garde[i][7],Centre,-signe(Info_garde[i][5])*(Info_garde[i][6]-1)*n.pi/2)
    while (Restriction_mouvement(canvas.coords(Info_garde[i][7])[4],canvas.coords(Info_garde[i][7])[5],"L")) and (Restriction_mouvement(canvas.coords(Info_garde[i][7])[6],canvas.coords(Info_garde[i][7])[7],"L")) and Info_garde[i][8]<50:
        Info_garde[i][8]=Info_garde[i][8]+5  # 1 : + précis mais ralentit le jeu
        canvas.delete(Info_garde[i][7])
        Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0],canvas.coords(Info_garde[i][0])[1],Info_garde[i][8],signe(Info_garde[i][5]))
        rotation(Info_garde[i][7],Centre,-signe(Info_garde[i][5])*(Info_garde[i][6]-1)*n.pi/2)

def Restriction_mouvement(x,y,Type):
    global Zone_interdite
    Possible = True
    i = 0
    while i < len(Zone_interdite) and Possible:
        if eval("between"+Type)(x,Zone_interdite[i][0],Zone_interdite[i][1]) and eval("between"+Type)(y,Zone_interdite[i][2],Zone_interdite[i][3]):
                Possible = False
        i=i+1
    return Possible

def clavier(event):
    if Play:
        touche = event.keysym
        if touche == "z" or touche == "s" or touche == "d" or touche == "q":
            Mouvement(touche)
        if touche == "Escape":
            Pause()
        if touche=="f":
            print(canvas.coords(Perso))
        if touche=="Return":
            Action()

def Mouvement(touche):
    global canvas
    global Perso
    global objectif
    global Last_moov
    if touche == "z" and canvas.coords(Perso)[1]>0 and Restriction_mouvement(canvas.coords(Perso)[0]+10, canvas.coords(Perso)[1]-8,"L"):
        canvas.move(Perso,0,-10)
    elif touche == "s" and canvas.coords(Perso)[1]<Largeur_map-Taille_perso and Restriction_mouvement(canvas.coords(Perso)[0]+10, canvas.coords(Perso)[1]+10+10,"L"):
       canvas.move(Perso,0,10)
    elif touche == "d" and canvas.coords(Perso)[0]<Longueur_map-Taille_perso and Restriction_mouvement(canvas.coords(Perso)[0]+10+10, canvas.coords(Perso)[1]+10,"L"):
       canvas.move(Perso,10,0)
    elif touche == "q" and canvas.coords(Perso)[0]>0 and Restriction_mouvement(canvas.coords(Perso)[0]-10+10, canvas.coords(Perso)[1]+10,"L"):
         canvas.move(Perso,-10,0)
    Last_moov=touche
    if Detection():
        Game_over()
    Detection_Laser()
    Test_TP()
    if canvas.coords(Perso)==canvas.coords(objectif):
        Victoire()

def Test_TP():
    global canvas
    global Perso
    global Teleporteur
    L=[canvas.coords(Perso)[0],canvas.coords(Perso)[1]]
    Recherche=False
    i=0
    while i<len(Teleporteur) and not Recherche:
        if L==Teleporteur[i][1:3]:
            Recherche=True
            Plaque=1
        elif L==Teleporteur[i][3:5]:
            Recherche=True
            Plaque=2
        else:
            pass
        i=i+1
    if Recherche:
        teleport(i-1,Plaque)

def Detection_Laser():
    global Laser
    global canvas
    global Perso
    X,Y=canvas.coords(Perso)[0],canvas.coords(Perso)[1]
    Vu = False
    i=0
    while i<len(Laser) and not Vu:
        Rayon=canvas.coords(Laser[i][1])
        if Rayon[1]==Rayon[3]:
            if (betweenL(X,Rayon[0],Rayon[2]) and betweenL(Rayon[1],Y,Y+Taille_perso)) or (betweenL(X+Taille_perso,Rayon[0],Rayon[2]) and betweenL(Rayon[1],Y,Y+Taille_perso)):
                Vu=True
        else:
            if (betweenL(Y,Rayon[1],Rayon[3]) and betweenL(Rayon[0],X,X+Taille_perso)) or (betweenL(Y+Taille_perso,Rayon[1],Rayon[3]) and betweenL(Rayon[0],X,X+Taille_perso)):
                Vu=True
        i=i+1
    if Vu:
        AlarmeON()

def Action():
    global Objet
    global canvas
    global Perso
    global Last_moov
    if Last_moov=="z":
        L=[canvas.coords(Perso)[0],canvas.coords(Perso)[1]-Taille_perso]
    elif Last_moov=="q":
        L=[canvas.coords(Perso)[0]-Taille_perso,canvas.coords(Perso)[1]]
    elif Last_moov=="s":
        L=[canvas.coords(Perso)[0],canvas.coords(Perso)[1]+Taille_perso]
    else:
        L=[canvas.coords(Perso)[0]+Taille_perso,canvas.coords(Perso)[1]]
    Recherche = False
    i=0
    while i<len(Objet) and not Recherche:
        if Objet[i][0]=="p":
            if Last_moov=="d" or Last_moov=="q":
                if (betweenL(canvas.coords(Objet[i][1])[0],L[0],L[0]+Taille_perso)) and (betweenL(L[1],canvas.coords(Objet[i][1])[1],canvas.coords(Objet[i][1])[3])):
                   Recherche = True
                   Type=Objet[i][0]
#            elif Last_moov=="q":
#                if (L[0]==canvas.coords(Objet[i][1])[0]) and (betweenL(L[1],canvas.coords(Objet[i][1])[1],canvas.coords(Objet[i][1])[3])):
#                   Recherche = True
#                   Type=Objet[i][0]
            else:
                if (betweenL(canvas.coords(Objet[i][1])[1],L[1],L[1]+Taille_perso)) and (betweenL(L[0],canvas.coords(Objet[i][1])[0],canvas.coords(Objet[i][1])[2])):
                   Recherche = True
                   Type=Objet[i][0]
        else:
            if canvas.coords(Objet[i][1])[0:2]==L:
                Recherche = True
                Type=Objet[i][0]
        i=i+1
    if Recherche:
        if Type=="a":
            AlarmeON()
#            info=canvas.create_text(Largeur_map//2,10,text="Vous activez l'alarme !")
#            canvas.after(3000,canvas.delete(info))
        elif Type=="c":
            Recup_cle(i-1)
#            info=canvas.create_text(Largeur_map//2,10,text="Vous récupérez une clé !")
#            canvas.after(3000,canvas.delete(info))
        elif Type=="p":
            Ouvrir_porte(i-1)
        elif Type=="t":
            TimeSlow(i-1)
#            info=canvas.create_text(Largeur_map//2,10,text="Le temps est ralenti !")
#            canvas.after(3000,canvas.delete(info))

def Recup_cle(i):
    global canvas
    global Objet
    global Zone_interdite
    global Inventaire
    global Aff_cle
    Inventaire[0]=Inventaire[0]+1
    indice=Objet[i][2]
    canvas.delete(Objet[i][1])
    Objet=Suppr_List(Objet,i)
    Zone_interdite=Suppr_List(Zone_interdite,indice)
    for j in range (len(Objet)):
        if Objet[j][0]!="a":
            if Objet[j][2]>indice:
                Objet[j][2]=Objet[j][2]-1
    Add_info("Vous récupérez une clé !")
    Aff_cle.set("Vous avez "+str(Inventaire[0])+" clé(s)")

def Ouvrir_porte(i):
    global canvas
    global Objet
    global Zone_interdite
    global Inventaire
    global Aff_cle
    if Inventaire[0]>0:
        Inventaire[0]=Inventaire[0]-1
        indice=Objet[i][2]
        canvas.delete(Objet[i][1])
        Objet=Suppr_List(Objet,i)
        Zone_interdite=Suppr_List(Zone_interdite,indice)
        for j in range (len(Objet)):
            if Objet[j][0]!="a":
                if Objet[j][2]>indice:
                    Objet[j][2]=Objet[j][2]-1
        Add_info("La porte s'ouvre !")
        Aff_cle.set("Vous avez "+str(Inventaire[0])+" clé(s)")

    else:
        Add_info("La porte est fermé à clé ...")

def TimeSlow(i):
    global canvas
    global Objet
    global Zone_interdite
    global Tps_mvt
    global Tps_slow
    global Temps_ralentit
    Tps_mvt=Tps_mvt*3
    Tps_slow=0
    Temps_ralentit=True
    indice=Objet[i][2]
    canvas.delete(Objet[i][1])
    Objet=Suppr_List(Objet,i)
    Zone_interdite=Suppr_List(Zone_interdite,indice)
    for j in range (len(Objet)):
        if Objet[j][0]!="a":
            if Objet[j][2]>indice:
                Objet[j][2]=Objet[j][2]-1
    Add_info("Le temps est ralentit !")

def teleport(i,j):
    global canvas
    global Perso
    global Teleporteur
    if j==1:
        anim_teleport(Perso,Teleporteur[i][3],Teleporteur[i][4])
        #canvas.coords(Perso,[Teleporteur[i][3],Teleporteur[i][4],Teleporteur[i][3]+Taille_perso,Teleporteur[i][4]+Taille_perso])
    elif j==2 and Teleporteur[i][0]==2:
        anim_teleport(Perso,Teleporteur[i][1],Teleporteur[i][2])
        #canvas.coords(Perso,[Teleporteur[i][1],Teleporteur[i][2],Teleporteur[i][1]+Taille_perso,Teleporteur[i][2]+Taille_perso])
    else:
        pass

def anim_teleport(objet,x,y):
    X,Y=canvas.coords(objet)[0],canvas.coords(objet)[1]
    Temps=[250,500,600,700,800,900,950,1000,1050,1100,1200,1300,1400,1500]
    L1=[X,Y,X+Taille_perso,Y+Taille_perso]
    L2=[X+5,Y+5,X+Taille_perso-5,Y+Taille_perso-5]
    for i in range (len(Temps)):
        if i%2==0:
            canvas.after(Temps[i], lambda cible=objet, coord=L2 : canvas.coords(cible,coord))
        else:
            canvas.after(Temps[i], lambda cible=objet, coord=L1 : canvas.coords(cible,coord))
        if i>=7:
            L1=[x,y,x+Taille_perso,y+Taille_perso]
            L2=[x+5,y+5,x+Taille_perso-5,y+Taille_perso-5]

def obstacle(x,y,Lx,Ly):
    global canvas
    global Zone_interdite
    canvas.create_rectangle(x,y,x+Lx,y+Ly,fill="black")
    Zone_interdite.append([x,x+Lx,y,y+Ly])

def Portail(x,y,taille,sens):
    global canvas
    global Objet
    global Zone_interdite
    if sens=="h":
        portail=canvas.create_rectangle(x,y,x+taille,y+10,fill="brown")
        Zone_interdite.append([x,x+taille,y,y+10])
    else:
        portail=canvas.create_rectangle(x,y,x+10,y+taille,fill="brown")
        Zone_interdite.append([x,x+10,y,y+taille])
    Objet.append(["p",portail,len(Zone_interdite)-1])

def Creation_alarme(x,y):
    global canvas
    global Objet
    global Zone_interdite
    alarme=canvas.create_rectangle(x,y,x+Taille_perso,y+Taille_perso,fill="brown")
    Zone_interdite.append([x,x+Taille_perso,y,y+Taille_perso])
    Objet.append(["a",alarme])

def Cle(x,y):
    global canvas
    global Objet
    global Zone_interdite
    cle=canvas.create_rectangle(x,y,x+Taille_perso,y+Taille_perso,fill="brown")
    Zone_interdite.append([x,x+Taille_perso,y,y+Taille_perso])
    Objet.append(["c",cle,len(Zone_interdite)-1])

def TimeSlower(x,y):
    global canvas
    global Objet
    global Zone_interdite
    TimeSlower=canvas.create_rectangle(x,y,x+Taille_perso,y+Taille_perso,fill="brown")
    Zone_interdite.append([x,x+Taille_perso,y,y+Taille_perso])
    Objet.append(["t",TimeSlower,len(Zone_interdite)-1])

def Plaque_tp(nb_sens,x1,y1,x2,y2):
    global canvas
    global Teleporteur
    canvas.create_rectangle(x1,y1,x1+Taille_perso,y1+Taille_perso,fill="green")
    canvas.create_rectangle(x2,y2,x2+Taille_perso,y2+Taille_perso,fill="green")
    Teleporteur.append([nb_sens,x1,y1,x2,y2])

def Creation_alarme2f(x1,y1,x2,y2):
    global canvas
    global Laser
    rayon=canvas.create_line(x1,y1,x2,y2,fill="red")
    Laser.append(["f",rayon])

def Creation_alarme2m(Type,x0,y0,l,P1,P2,dmouv):
    global canvas
    global Laser
    if Type=="h":
        rayon=canvas.create_line(x0,y0,x0+l,y0,fill="red")
    else:
        rayon=canvas.create_line(x0,y0,x0,y0+l,fill="red")
    Laser.append([Type,rayon,P1,P2,dmouv,1])

def Creation_garde(x0,y0,x1,y1,XD,YD,Phase,dmouv):
    global canvas
    global Info_garde
    global Vision
    Garde=canvas.create_rectangle(XD,YD,XD+Taille_perso,YD+Taille_perso,fill="red")
    V = Vision_garde(XD,YD,50,signe(dmouv))
    rotation(V,(XD+Taille_perso/2,YD+Taille_perso/2),-signe(dmouv)*(Phase-1)*n.pi/2)
    if dmouv<0:
        rotation(V,(XD+Taille_perso/2,YD+Taille_perso/2),n.pi)
    Info_garde.append([Garde,x0,y0,x1,y1,dmouv,Phase,V,50])
    Vision.append([canvas.coords(V)[0],canvas.coords(V)[1],canvas.coords(V)[4],canvas.coords(V)[5]])

def Creation_garde2(x0,y0,Phase,dt):
    Garde=canvas.create_rectangle(x0,y0,x0+Taille_perso,y0+Taille_perso,fill="red")
    V = Vision_garde(x0,y0,50,1)
    if dt==0:
        rotation(V,(x0+Taille_perso/2,y0+Taille_perso/2),-(Phase-1)*n.pi/2)
    Info_garde.append([Garde,x0,y0,1,-4,dt,Phase,V,50])
    Vision.append([canvas.coords(V)[0],canvas.coords(V)[1],canvas.coords(V)[4],canvas.coords(V)[5]])

def Mouvement_adverse():
    global fenetre
    global canvas
    global Info_garde
    global Vision
    global Alarme_active
    global Temps_ralentit
    global Tps_alarme
    global Tps_slow
    global Laser
    global testp
    global Tps_ecoule
    global Aff_Temps
    if Play:
        for i in range(len(Info_garde)):
            if Info_garde[i][4]<0:    #dmouv=0 --> Tourne sur lui-même
                if Info_garde[i][3]==abs(Info_garde[i][5])//100:
                    Info_garde[i][6]=Info_garde[i][6]+1
                    if Info_garde[i][6]==5:
                        Info_garde[i][6]=1
                    Reduire_visionr(i)
                    Info_garde[i][3]=1
                else:
                    Info_garde[i][3]=Info_garde[i][3]+1
            else:

                if Info_garde[i][6]==1:
                    if canvas.coords(Info_garde[i][0])[0]*signe(Info_garde[i][5])<Info_garde[i][signe1(Info_garde[i][5])]*signe(Info_garde[i][5]):
                        canvas.move(Info_garde[i][0],Info_garde[i][5],0)

                        if Restriction_mouvement(canvas.coords(Info_garde[i][7])[4],canvas.coords(Info_garde[i][7])[5]-10,"L"):
                            canvas.move(Info_garde[i][7],Info_garde[i][5],0)
                        else:
                            Info_garde[i][8]=Info_garde[i][8]-abs(Info_garde[i][5])
                            canvas.delete(Info_garde[i][7])
                            Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0]-Info_garde[i][5],canvas.coords(Info_garde[i][0])[1],Info_garde[i][8],signe(Info_garde[i][5]))
                            canvas.move(Info_garde[i][7],Info_garde[i][5],0)

                    else:
                        Info_garde[i][6]=2
                        Reduire_vision(i)

                if Info_garde[i][6]==2:
                    if canvas.coords(Info_garde[i][0])[1]<Info_garde[i][4]:
                        canvas.move(Info_garde[i][0],0,abs(Info_garde[i][5]))

                        if Restriction_mouvement(canvas.coords(Info_garde[i][7])[4]+signe(Info_garde[i][5])*10,canvas.coords(Info_garde[i][7])[5],"L"):
                            canvas.move(Info_garde[i][7],0,abs(Info_garde[i][5]))
                        else:
                            Info_garde[i][8]=Info_garde[i][8]-abs(Info_garde[i][5])
                            canvas.delete(Info_garde[i][7])
                            Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0],canvas.coords(Info_garde[i][0])[1]+abs(Info_garde[i][5]),Info_garde[i][8],signe(Info_garde[i][5]))
                            Centre=((canvas.coords(Info_garde[i][0])[0]+canvas.coords(Info_garde[i][0])[2])/2,(canvas.coords(Info_garde[i][0])[1]+canvas.coords(Info_garde[i][0])[3])/2)
                            rotation(Info_garde[i][7],Centre,-signe(Info_garde[i][5])*n.pi/2) # Angle = Info_garde[i][6]-1
                            canvas.move(Info_garde[i][7],Info_garde[i][5],0)

                    else:
                        Info_garde[i][6]=3
                        Reduire_vision(i)

                if Info_garde[i][6]==3:
                    if canvas.coords(Info_garde[i][0])[0]*signe(Info_garde[i][5])>Info_garde[i][signe3(Info_garde[i][5])]*signe(Info_garde[i][5]):
                        canvas.move(Info_garde[i][0],-Info_garde[i][5],0)

                        if Restriction_mouvement(canvas.coords(Info_garde[i][7])[4],canvas.coords(Info_garde[i][7])[5]+10,"L"):
                            canvas.move(Info_garde[i][7],-Info_garde[i][5],0)
                        else:
                            Info_garde[i][8]=Info_garde[i][8]-abs(Info_garde[i][5])
                            canvas.delete(Info_garde[i][7])
                            Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0]-Info_garde[i][5],canvas.coords(Info_garde[i][0])[1],Info_garde[i][8],signe(Info_garde[i][5]))
                            Centre=((canvas.coords(Info_garde[i][0])[0]+canvas.coords(Info_garde[i][0])[2])/2,(canvas.coords(Info_garde[i][0])[1]+canvas.coords(Info_garde[i][0])[3])/2)
                            rotation(Info_garde[i][7],Centre,n.pi)
                            canvas.move(Info_garde[i][7],-Info_garde[i][5],0)

                    else:
                        Info_garde[i][6]=4
                        Reduire_vision(i)

                if Info_garde[i][6]==4:
                    if canvas.coords(Info_garde[i][0])[1]>Info_garde[i][2]:
                        canvas.move(Info_garde[i][0],0,-abs(Info_garde[i][5]))

                        if Restriction_mouvement(canvas.coords(Info_garde[i][7])[4]-signe(Info_garde[i][5])*10,canvas.coords(Info_garde[i][7])[5],"L"):
                            canvas.move(Info_garde[i][7],0,-abs(Info_garde[i][5]))
                        else:
                            Info_garde[i][8]=Info_garde[i][8]-abs(Info_garde[i][5])
                            canvas.delete(Info_garde[i][7])
                            Info_garde[i][7]=Vision_garde(canvas.coords(Info_garde[i][0])[0],canvas.coords(Info_garde[i][0])[1]+abs(Info_garde[i][5]),Info_garde[i][8],signe(Info_garde[i][5]))
                            Centre=((canvas.coords(Info_garde[i][0])[0]+canvas.coords(Info_garde[i][0])[2])/2,(canvas.coords(Info_garde[i][0])[1]+canvas.coords(Info_garde[i][0])[3])/2)
                            rotation(Info_garde[i][7],Centre,signe(Info_garde[i][5])*n.pi/2)
                            canvas.move(Info_garde[i][7],-Info_garde[i][5],0)

                    else:
                        Info_garde[i][6]=1
                        Reduire_vision(i)

            Vision[i]=[canvas.coords(Info_garde[i][0])[0]+Add_Visionx(Info_garde[i][6],Info_garde[i][5]),canvas.coords(Info_garde[i][0])[1]+Add_Visiony(Info_garde[i][6],Info_garde[i][5]),canvas.coords(Info_garde[i][7])[4],canvas.coords(Info_garde[i][7])[5]]
        if Detection():
            Game_over()
        if not Alarme_active or (Alarme_active and (-1)**testp>0):
            for i in range (len(Laser)):
                if Laser[i][0]=="h":
                    canvas.move(Laser[i][1],0,Laser[i][4]*(-1)**Laser[i][5])
                    if canvas.coords(Laser[i][1])[1]<=Laser[i][2]:
                        Laser[i][5]=2
                    elif canvas.coords(Laser[i][1])[1]>=Laser[i][3]:
                        Laser[i][5]=1
                elif Laser[i][0]=="v":
                    canvas.move(Laser[i][1],Laser[i][4]*(-1)**Laser[i][5],0)
                    if canvas.coords(Laser[i][1])[0]<=Laser[i][2]:
                        Laser[i][5]=2
                    elif canvas.coords(Laser[i][1])[0]>=Laser[i][3]:
                        Laser[i][5]=1
        Detection_Laser()
        #print(Info_garde[i][9])
        if Alarme_active:
            testp=testp+1
            Tps_alarme=Tps_alarme+Tps_mvt
            if Tps_alarme>10000:
                testp=0
                AlarmeOFF()
        if Temps_ralentit:
            Tps_slow=Tps_slow+Tps_mvt
            if Tps_slow>10000:
                SlowtimeOFF()
        if not Alarme_active:
            Tps_ecoule=Tps_ecoule+Tps_mvt
            Aff_Temps.set("Temps : "+str(Tps_ecoule/1000))
        elif Alarme_active and (-1)**testp>0:
            Tps_ecoule=Tps_ecoule+2*Tps_mvt
            Aff_Temps.set("Temps : "+str(Tps_ecoule/1000))
        fenetre.after(Tps_mvt,Mouvement_adverse)

def Detection():
    global canvas
    global Vision
    global Perso
    X=[canvas.coords(Perso)[0],canvas.coords(Perso)[0],canvas.coords(Perso)[2],canvas.coords(Perso)[2]]
    Y=[canvas.coords(Perso)[1],canvas.coords(Perso)[3],canvas.coords(Perso)[1],canvas.coords(Perso)[3]]
    i=0
    Vu= False
    while i<len(Vision) and not Vu:
        for j in range (4):
            if betweenL(X[j],Vision[i][0],Vision[i][2]) and betweenL(Y[j],Vision[i][1],Vision[i][3]):
                Vu = True
        i=i+1
    return Vu

def Game_over():
    global fenetre
    global canvas
    global Play
    Play=False
    canvas.create_text(740,525,text="Game over",font="Arial 40",fill="Red")
    fenetre.after(2000,fenGO)

def Victoire():
    global fenetre
    global canvas
    global Play
    global Map_dispo
    global Niveau
    Play=False
    if Niveau==Map_dispo:
        Map_dispo=Map_dispo+1
    canvas.create_text(740,525,text="Niveau terminé !",font="Arial 40",fill="Red")
    fenetre.after(2000,fenW)

def AlarmeON():
    global Alarme_active
    global Tps_mvt
    global Tps_alarme
    global Son_alarme
    Tps_alarme=0
    if not Alarme_active:
        Alarme_active=True
        Tps_mvt=Tps_mvt//2
        Add_info("L'alarme est activée !")
        Son_alarme.play()

def AlarmeOFF():
    global Alarme_active
    global Tps_mvt
    Alarme_active=False
    Tps_mvt=Tps_mvt*2

def SlowtimeOFF():
    global Temps_ralentit
    global Tps_mvt
    Temps_ralentit=False
    Tps_mvt=Tps_mvt//3

# # Caractéristiques générales du canvas # #

Longueur_map =1440
Largeur_map=1050
Taille_perso=20
Taille_vision=50
Pente_cone=Taille_perso/(4*Taille_vision)

# # Programme # #
Menu_principal()


import numpy as np
np.random.seed(0)

from bokeh.io import curdoc
from bokeh.layouts import widgetbox, row, column, gridplot
from bokeh.models import ColumnDataSource, Select, Slider
from bokeh.plotting import figure
from bokeh.palettes import Greys256
from bokeh.models.callbacks import CustomJS

from skimage.feature import blob_doh
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.util import invert

# define some helper functions
def Load_image(path):
    """
    :param path     path to image file

    Function that reads image, takes a patch, converts to gray
    Returns processed image and inverted image
    """
    # read test image
    im = imread(path)
    # take patch of image and convert to grayscale
    im = im[:256,:256]
    #im = im[:256,:256]
    im = rgb2gray(im)

    # prepare an inverted image for comparison
    # search for white blobs on black background AND black blobs on white background
    imIn = invert(im)
    return im, imIn

#Real Callback function
def blob_detector(imIn, overlap, threshold, min_sigma, max_sigma, log_scale):
    """

    :param imIn:        Inverted Image grayscale patch
    :param:             Hyper-Parameters for blob detector
        :overlap
        :threshold
        :min_sigma
        :max_sigma
        log_scale
    :return:
    """
    # Initialize and Invoke DoH blob detector
    blobs_doh = blob_doh(imIn, overlap=overlap, threshold=threshold, min_sigma=min_sigma,
                         max_sigma=max_sigma, log_scale=log_scale)
    #blobs_y, blobs_x, blobs_r = [],[],[]
    blobs_y = blobs_doh[:,0]
    blobs_x = blobs_doh[:,1]
    blobs_r = blobs_doh[:,2]
    """for blob in blobs_doh:
        y, x, r = blob # This code can be made better
        blobs_y.append(y)
        blobs_x.append(x)
        blobs_r.append(r)"""
    return blobs_y, blobs_x, blobs_r

# set up more callbacks
def update_blob_detector(attrname, old, new):
    global imIn
    logscale = logscale_select.value
    maxSigma = maxSigma_slider.value
    minSigma = minSigma_slider.value
    threshold = threshold_slider.value
    overlap = overlap_slider.value
    print("Calculating Blobs ..........")
    print("params are",logscale,maxSigma,minSigma,overlap)
    blobs_y, blobs_x, blobs_r = blob_detector(imIn, overlap, threshold, minSigma, maxSigma, logscale)
    source.data = dict(x=blobs_x, y= blobs_y, r=blobs_r)
    print("blobs updated")

def save_params(attrname, old, new):
    logscale = logscale_select.value
    maxSigma = maxSigma_slider.value
    minSigma = minSigma_slider.value
    threshold = threshold_slider.value
    overlap = overlap_slider.value
    input = str(logscale) +','+ str(maxSigma) +','+ str(minSigma) +','+ str(threshold) +','+ str(overlap)+'\n'
    if button.value:
        with open('./Flask_parameter_update/output.txt', 'a') as file:
            file.writelines(input)
    print('Params saved')

# set up widgets
logscale_vals=['True', 'False']
logscale_select = Select(value='True',
                          title='Logscale',
                          width=200,
                          options=logscale_vals)
overlap_slider = Slider(title="Overlap Parameter",
                        value=0.5,
                        start=0.0,
                        end=1.0,
                        step=0.1,
                        width=200)

threshold_slider = Slider(title="Filter Threshold",
                         value=0.005,
                         start=0.001,
                         end=0.1,
                         step=0.005,
                         width=200)

minSigma_slider = Slider(title="min_Sigma",
                         value=5,
                         start=0.0,
                         end=500.0,
                         step=2,
                         width=200)

maxSigma_slider = Slider(title="max_Sigma",
                         value=50,
                         start=0.0,
                         end=500.0,
                         step=2,
                         width=200,)

button_vals=['True', 'False']
button = Select(value='False',
                          title='Save Hyperparameters?',
                          width=200,
                          options=button_vals)

# set up plot (styling in theme.yaml)
path = './Flask_parameter_update/static/B4_2_test_500x.tif'
im, imIn = Load_image(path)
blobs_y, blobs_x, blobs_r = blob_detector(imIn, 0.5,0.005,5,50,True)
im_x = im.shape[0]
im_y = im.shape[1]

source = ColumnDataSource(data=dict(x=blobs_x, y= blobs_y, r=blobs_r))

# create a new plot
s2 = figure(plot_width=900, plot_height= 900, title='With Blobs', x_range= (0,im_x), y_range=(0,im_y))
# Superimpose DoH blobs on image
s2.image(image=[imIn], x=[0], y=[0], dw=[im_x], dh=[im_y], palette=list(reversed(Greys256)))
s2.circle( 'x', 'y', size= 'r', line_color='green', fill_color= None, line_width=1, fill_alpha=0.8, source=source)

#Callback Functions
logscale_select.on_change('value', update_blob_detector)
overlap_slider.on_change('value', update_blob_detector)
threshold_slider.on_change('value', update_blob_detector)
minSigma_slider.on_change('value', update_blob_detector)
maxSigma_slider.on_change('value', update_blob_detector)
button.on_change('value', save_params)

# set up layout
selects = row(logscale_select, width=200)
inputs = column(selects, widgetbox(overlap_slider, threshold_slider, minSigma_slider, maxSigma_slider, button))

# add to document
curdoc().add_root(row(inputs,s2))

#Inputs
#wbox = widgetbox(overlap_slider, threshold_slider, minSigma_slider, maxSigma_slider, width=200)
#curdoc().add_root(row(wbox,s1,s2))
curdoc().title = "Bokeh Parameter Search"


import argparse
import logging
import os
import sys
from pathlib import Path

import numpy as np
import torch

sys.path.append(".")

from config import cfg
from train_ctl_model import CTLModel

from inference_utils import (
    ImageDataset,
    ImageFolderWithPaths,
    calculate_centroids,
    create_pid_path_index,
    make_inference_data_loader,
    run_inference,
)

### Prepare logging
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
log = logging.getLogger(__name__)

### Functions used to extract pair_id
exctract_func = (
    lambda x: (x).rsplit(".", 1)[0].rsplit("_", 1)[0]
)  ## To extract pid from filename. Example: /path/to/dir/product001_04.jpg -> pid = product001
exctract_func = lambda x: Path(
    x
).parent.name  ## To extract pid from parent directory of an iamge. Example: /path/to/root/001/image_04.jpg -> pid = 001

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Create embeddings for images that will serve as the database (gallery)"
    )
    parser.add_argument(
        "--config_file", default="", help="path to config file", type=str
    )
    parser.add_argument(
        "--images-in-subfolders",
        help="if images are stored in the subfloders use this flag. If images are directly under DATASETS.ROOT_DIR path do not use it.",
        action="store_true",
    )
    parser.add_argument(
        "--print_freq",
        help="number of batches the logging message is printed",
        type=int,
        default=10,
    )
    parser.add_argument(
        "opts",
        help="Modify config options using the command-line",
        default=None,
        nargs=argparse.REMAINDER,
    )
    args = parser.parse_args()
    if args.config_file != "":
        cfg.merge_from_file(args.config_file)
    cfg.merge_from_list(args.opts)

    ### Data preparation
    if args.images_in_subfolders:
        dataset_type = ImageFolderWithPaths
    else:
        dataset_type = ImageDataset
    log.info(f"Preparing data using {dataset_type} dataset class")
    val_loader = make_inference_data_loader(cfg, cfg.DATASETS.ROOT_DIR, dataset_type)
    if len(val_loader) == 0:
        raise RuntimeError("Lenght of dataloader = 0")

    ### Build model
    model = CTLModel.load_from_checkpoint(cfg.MODEL.PRETRAIN_PATH)
    use_cuda = True if torch.cuda.is_available() and cfg.GPU_IDS else False

    ### Inference
    log.info("Running inference")
    embeddings, paths = run_inference(
        model, val_loader, cfg, print_freq=args.print_freq, use_cuda=use_cuda
    )

    ### Create centroids
    log.info("Creating centroids")
    if cfg.MODEL.USE_CENTROIDS:
        pid_path_index = create_pid_path_index(paths=paths, func=exctract_func)
        embeddings, paths = calculate_centroids(embeddings, pid_path_index)

    ### Save
    SAVE_DIR = Path(cfg.OUTPUT_DIR)
    SAVE_DIR.mkdir(exist_ok=True, parents=True)

    log.info(f"Saving embeddings and index to {str(SAVE_DIR)}")
    np.save(SAVE_DIR / "embeddings.npy", embeddings)
    np.save(SAVE_DIR / "paths.npy", paths)


from collections import deque
from typing import List

class Solution:
    def removeStones(self, stones: List[List[int]]) -> int:
        visited = set()

        points_by_row = {}
        points_by_col = {}
        for stone in stones:
            points_by_row.setdefault(stone[0], set()).add(tuple(stone))
            points_by_col.setdefault(stone[1], set()).add(tuple(stone))

        move_count = 0
        for row, col in stones:
            stone = (row, col)
            if stone in visited:
                continue
            visited.add(stone)

            queue = deque([stone])
            size = 1
            while queue:
                current_row, current_col = queue.popleft()
                other_stones = (
                    points_by_row[current_row] | points_by_col[current_col]
                ) - visited
                for other_stone in other_stones:
                    visited.add(other_stone)
                    queue.append(other_stone)
                    size += 1
            move_count += size - 1
        return move_count

print(Solution().removeStones([[0, 0], [0, 1], [1, 0], [1, 2], [2, 1], [2, 2]]))
print(Solution().removeStones([[0, 0], [0, 2], [1, 1], [2, 0], [2, 2]]))
print(Solution().removeStones([[0, 0]]))


from typing import List
from itertools import combinations, product

class Solution:
    def beautifulSubsets(self, nums: List[int], k: int) -> int:
        answer = len(nums)
        for i in range(2, len(nums) + 1):
            for comb in combinations(nums, i):
                is_beautiful = True
                for num1, num2 in product(comb, comb):
                    if abs(num1 - num2) == k:
                        is_beautiful = False
                        break
                answer += is_beautiful

        return answer

# TLE
# [15,6,3,25,14,29,21,16,28,23,11,9,4,30,24,12,26,1,27,18]
# 7


from flask import Flask, render_template, redirect, request
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField, RadioField
from wtforms.validators import DataRequired
from datetime import datetime

app = Flask(__name__)

app.config["SECRET_KEY"] = '1234'
class q1Form(FlaskForm):
    data = [
        [
            (0, "做一件事情下决心快，行动快，雷厉风行。"),
            (1, "喜欢做有趣的事情，为人充满乐趣与幽默感。"),
            (2, "在任何冲突中都不易受干扰，保持冷静。"),
            (3, "做事有节奏，完成一件事后才接受新事。")
        ],[
            (0, "行为外露，总给人一种强烈的想赢的欲望。"),
            (1, "喜欢展现自我，透过自我魅力来让别人接受自己。"),
            (2, "关心别人的感觉与需要，易于接受他人的观点，不坚持己见。"),
            (3, "喜欢控制自己的内心情感，几乎不向外人展露。")
        ],[
            (0, "反应快,思维敏捷"),
            (1, "充满激情、动力与兴奋。"),
            (2, "约束自我情感，心态平和。"),
            (3, "安静严肃，面无表情。")
        ],[
            (0, "对自己的能力很有自信，且经常向别人展示。"),
            (1, "不喜欢计划，喜欢运用语言、人格魅力，鼓励推动别人参与。"),
            (2, "容忍自己和别人的错误，冷静且包容心强。"),
            (3, "事前喜欢做详尽计划，然后按计划进行。")
        ],[
            (0, "做事自信，几乎不会犹豫。"),
            (1, "随性，不喜欢条例规定，不喜欢受约束。"),
            (2, "容易没有主见，做事容易犹豫不决。"),
            (3, "有原则，不易妥协。")
        ],[
            (0, "天生的领导者，无论在什么事情上都喜欢主导。"),
            (1, "喜欢到处走走，充满生机，精力充沛。"),
            (2, "不愿意主导，喜欢被领导。"),
            (3, "喜欢一个人独处。")
        ],[
            (0, "强势，让人觉得不能改变。"),
            (1, "滔滔不绝的发言者，不是好听众，不会留意别人也在讲话。"),
            (2, "易相处，易让人接近。"),
            (3, "很少说话，除非工作需要。")
        ],[
            (0, "不能忍受别人动作慢，效率低。"),
            (1, "喜欢吸引人，喜欢成为焦点。"),
            (2, "稳定，工作节奏慢，说话慢。"),
            (3, "总是避免自己成为注意力的中心。")
        ],[
            (0, "自我评价高，认为自己是最佳人选。"),
            (1, "容许别人（包括孩子）做他喜欢做的事，为的是讨好别人，让人喜欢。"),
            (2, "性格中庸，无高低情绪，很少表露感情。"),
            (3, "尽管期待好结果，但往往先看到事物的不利之处。")
        ],[
            (0, "成就动机强，并为此而不断工作。"),
            (1, "性格开朗，说话声与笑声总是能吸引别人注意。"),
            (2, "行动慢，不喜欢行动，安于现状。"),
            (3, "孤独离群，感到需要大量时间独处。")
        ],[
            (0, "为人坦诚，内心毫不保留，坦率发言。"),
            (1, "为人乐观开朗，相信任何事都会好转。"),
            (2, "愿意改变，只要别人意见合理，就会接受。"),
            (3, "会保留自己的意见，不轻易向别人表达。")
        ],[
            (0, "敢于冒险，敢于承担责任。"),
            (1, "喜欢带给别人欢乐，令人喜欢，容易相处。"),
            (2, "彬彬有礼，待人得体有耐心。"),
            (3, "做事井然有序，清晰有条理。")
        ],[
            (0, "独立能力强，自我支持，自我鼓励。"),
            (1, "需要旁人认同、赞赏，如同演艺家需要观众的掌声、笑声。"),
            (2, "避免矛盾，所以从不说也不做引起他人不满与反感的事。"),
            (3, "喜欢以自己认定的标准来衡量事情。")
        ],[
            (0, "决心依自己的意愿行事，不易被说服。"),
            (1, "喜欢开玩笑，忘情地表达自己的情感、喜好。"),
            (2, "容易被说服，被领导。"),
            (3, "喜欢深刻的谈话，不喜欢肤浅的聊天或喜好。")
        ],[
            (0, "工作狂，努力推动工作，喜欢领导别人。"),
            (1, "喜好吵闹的环境，出席各种宴会，结交各种朋友。"),
            (2, "喜欢安稳，不喜欢过于忙碌的工作和生活。"),
            (3, "偏安静，不喜欢嘈杂。")
        ]
    ]

    q1 = RadioField('01', choices = data[0])
    q2 = RadioField('02', choices = data[1])
    q3 = RadioField('03', choices = data[2])
    q4 = RadioField('04', choices = data[3])
    q5 = RadioField('05', choices = data[4])
    q6 = RadioField('06', choices = data[5])
    q7 = RadioField('07', choices = data[6])
    q8 = RadioField('08', choices = data[7])
    q9 = RadioField('09', choices = data[8])
    q10 = RadioField('10', choices = data[9])
    q11 = RadioField('11', choices = data[10])
    q12 = RadioField('12', choices = data[11])
    q13 = RadioField('13', choices = data[12])
    q14 = RadioField('14', choices = data[13])
    q15 = RadioField('15', choices = data[14])
    submit = SubmitField('Submit')

@app.route('/q1', methods = ['GET', 'POST'])
def q1():
    if(request.method == 'GET'):
        form = q1Form()
        return render_template('q1.html', form=form)
    else:
        dict = {
            0: 0,
            1: 0,
            2: 0,
            3: 0
        }

        req = request.values.to_dict()
        maxv = 0
        for key, value in req.items():
            if(key != 'submit' and key != 'csrf_token'):
                dict[int(value)]+=1

        for key, value in dict.items():
            if(value > maxv):
                maxv = value

        retS = '
'
        retS += "
"
        retS += "
性格	题数
"
        if(dict[0] == maxv):
            retS += '
'
        else:
            retS += '
'
        retS += "Power 力量型	"
        retS += "{}	".format(dict[0])
        retS += "
"

        if(dict[1] == maxv):
            retS += '
'
        else:
            retS += '
'
        retS += "Popular 社交型	"
        retS += "{}	".format(dict[1])
        retS += "
"

        if(dict[2] == maxv):
            retS += '
'
        else:
            retS += '
'
        retS += "Peace 和平型	"
        retS += "{}	".format(dict[2])
        retS += "
"

        if(dict[3] == maxv):
            retS += '
'
        else:
            retS += '
'
        retS += "Perfect 完美型	"
        retS += "{}	".format(dict[3])
        retS += "
"
        retS += "

"
        if(len(req) != 17):
            retS += '
总题数应为{}，但你只答了 {}题。
'.format(15, len(req) - 2)
        retS += '
大多数的人四种性格都有。而题数最高的那个，是你的主导性格。
'
        return retS


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2021/3/8 18:37
# @Author  : hzy
# @File    : 14_最长公共前缀.py
# @Software: PyCharm

"""
编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀，返回空字符串""。

示例 1：

输入：strs = ["flower","flow","flight"]
输出："fl"
示例 2：

输入：strs = ["dog","racecar","car"]
输出：""
解释：输入不存在公共前缀。

提示：

0 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成

链接：https://leetcode-cn.com/problems/longest-common-prefix
"""
from typing import List

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        result = ''
        if not strs:
            return result
        count = len(strs)
        if count == 1:
            return strs[0]
        length = len(strs[0])
        for i in range(1, length + 1):
            # 使用切片防止index超出
            a = strs[0][:i]
            for j in range(1, count):
                if a != strs[j][:i]:
                    return result
            result = strs[0][:i]
        return result

14_最长公共前缀.py


import requests
from bs4 import BeautifulSoup
import codecs

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; rv:47.0) Gecko/20100101 Firefox/47.0',
		'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}
session = requests.Session()

urls = []
jobs = []

def get_html(url):
    req = session.get(url, headers=headers)
    return req.text

def get_paggination_links(html, base_url, domain):
	urls.append(base_url)
	soup = BeautifulSoup(html, 'html.parser')
	pagination = soup.find('ul', class_= 'pagination')
	if pagination:
		pages = pagination.find_all('li')
		[ urls.append(domain+str(page.a['href'])) for page in pages[2:-1] ]
	return urls

def get_data(html, domain):
		soup = BeautifulSoup(html, 'html.parser')
		div_list = soup.find_all('div', attrs = {'class':'job-link'})
		for div in div_list:
			title = div.find('h2').find('a').text
			href = div.find('h2').find('a').get('href')
			short = div.p.text
			try:
				company = div.find('b').text
			except:
				company = 'No name'
			jobs.append({'href':domain+str(href), 'title':title, 'descript':short, 'company':company})

def main():
	base_url ='https://www.work.ua/jobs-kyiv-python/'
	domain = 'https://www.work.ua'

	# url в пагинации
	urls = get_paggination_links(get_html(base_url), base_url, domain)

	# парсим данные
	[ get_data(get_html(url), domain) for url in urls ]

if __name__ == '__main__':
    main()


from django.urls import path
from . import views

urlpatterns = [

    path('test/', views.Test, name='test'),

    path('sign-up/', views.SignUp, name='signup'),

    path('login/', views.Login, name='login'),
    path('logout/', views.Logout, name='logout'),

    path('donar-list/', views.DonorList, name='donor-list'),
]


import math
import pandas as pd
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
from data_manager import DataManager

JRCODE = 11

class JRMap:
    def __init__(self):
        self.data_manager = DataManager(JRCODE)
        self.graph = nx.Graph()
        self.construct_graph()

    def construct_graph(self):
        stations_df = self.data_manager.get_stations()
        station_cd_g_cd_dict = self.data_manager.generate_station_cd_g_cd_dict()
        joins = self.data_manager.get_joins()
        rows = stations_df.itertuples()

        # Adding nodes
        for row in rows:
            self.graph.add_node(row.station_g_cd)

        # Adding edges
        for line in joins.itertuples():
            src_cd = line.station_cd1
            dst_cd = line.station_cd2
            src_g_cd = station_cd_g_cd_dict[src_cd]
            dst_g_cd = station_cd_g_cd_dict[dst_cd]
            # print(line.line_cd)
            self.graph.add_edge(src_g_cd, dst_g_cd, line_cd=line.line_cd)
        # print(self.graph.edges.data())

    def visualize_nodes(self):
        station_g_cd_dict = self.data_manager.generate_station_g_cd_to_data_dict()
        lon_pts = []
        lat_pts = []
        for node in self.graph.nodes:

            data = station_g_cd_dict[node]
            lon = float(data[7])
            lat = float(data[8])
            lon_pts.append(lon)
            lat_pts.append(lat)

        plt.scatter(lon_pts, lat_pts, s=0.4)
        plt.show()

    def visualize_map(self):
        print("visualize_map")
        station_g_cd_dict = self.data_manager.generate_station_g_cd_to_data_dict()
        line_station_dict = {}

        for edge in self.graph.edges.data():
            src_idx = edge[0]
            dst_idx = edge[1]
            src_data = station_g_cd_dict[src_idx]
            dst_data = station_g_cd_dict[dst_idx]

            line_cd = edge[2]["line_cd"]

            if not line_cd in line_station_dict:
                line_station_dict[line_cd] = {"src": [], "dst": []}

            line_station_dict[line_cd]["src"].append(src_idx)
            line_station_dict[line_cd]["dst"].append(dst_idx)

        for line_cd in line_station_dict:
            # stations = np.unique(line_station_dict[line_cd])
            srcs = line_station_dict[line_cd]["src"]
            dsts = line_station_dict[line_cd]["dst"]
            color = np.random.rand(3, )

            # print(line_cd, stations)
            line_lon = []
            line_lat = []

            for src, dst in zip(srcs, dsts):
                src_data = station_g_cd_dict[src]
                dst_data = station_g_cd_dict[dst]
                # line_lon.append(float(src_data.lon))
                # line_lat.append(float(src_data.lat))
                src_lon = src_data[7]
                src_lat = src_data[8]
                dst_lon = dst_data[7]
                dst_lat = dst_data[8]
                plt.plot([src_lon, dst_lon], [src_lat, dst_lat], c=color)

        plt.show()

    def get_nearest_station(self, lon, lat, nums=1):
        stations_df = self.data_manager.get_stations()
        station_dist_dict = {}
        for station_data in stations_df.itertuples():
            station_lon = station_data.lon
            station_lat = station_data.lat

            squared_diff_lon = math.pow(lon - station_lon, 2)
            squared_diff_lat = math.pow(lat - station_lat, 2)

            station_dist_dict[station_data.station_g_cd] = squared_diff_lon + squared_diff_lat

        dist_sorted = sorted(station_dist_dict.items(), key=lambda x:x[1])

        station_names = []

        for i in range(nums):
            station_g_cd = dist_sorted[i][0]
            station_names.append(self.data_manager.get_station_name_from_g_cd(station_g_cd))

        return station_names

def main():
    jrm = JRMap()
    # jrm.visualize_map()

    lat = 35.534129
    lon = 137.791698

    print(jrm.get_nearest_station(lon, lat, 5))

if __name__ == "__main__":
    main()


#!/usr/bin/python3

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

import argparse
import pandas as pd
import os
import sys

if __name__=="__main__":
    parser = argparse.ArgumentParser(description='Filter for value stocks.')
    parser.add_argument('stocks_valuations', type=str, help='File including stocks valuations.')
    parser.add_argument('--fcf_margin_threshold', type=float,
                        help='This should be a margin on the average FCF of the last 4 years.', default=-0.10)
    parser.add_argument('--fcf_margin_threshold_last_yr', type=float,
                        help='This should be a margin on the average FCF of the last 4 years.', default=-0.10)
    parser.add_argument('--historical_margin_threshold', type=float,
                        help='This should be a margin on the average historical price of the last 10 years.', default=0.1)
    parser.add_argument('--fcf_interest_avg_threshold', type=float,
                        help='Ratio between free cash flow and debt interests in the last 4 years.', default=3.0)
    parser.add_argument('--fcf_interest_last_yr_threshold', type=float,
                        help='Ratio between free cash flow and debt interests last year.', default=4.0)
    parser.add_argument('--margin_analyst_low_threshold', type=float,
                        help='Margin between lowest analyst projection and current prices.', default=0.0)

    args = parser.parse_args()

    stocks_valuations_fn = os.path.expanduser(args.stocks_valuations)
    if not os.path.exists(stocks_valuations_fn):
        print("Invalid stocks_valuations path %s: file does not exist!")
        sys.exit()

    data = pd.read_csv(stocks_valuations_fn, sep="|")

    fcf = data["Margin FCF Avg"].astype(float)>args.fcf_margin_threshold
    fcf_last_yr = data["Margin FCF Last Yr"].astype(float) > args.fcf_margin_threshold_last_yr
    historical = data["Margin Historical"].astype(float)>args.historical_margin_threshold
    fcf_interest_avg = data["FCF / Interests Avg"].astype(float)>args.fcf_interest_avg_threshold
    fcf_interest_last_yr = data["FCF / Interests Last Yr"].astype(float) > args.fcf_interest_last_yr_threshold
    margin_analyst_low = data["Margin Analysts Low"].astype(float) > args.margin_analyst_low_threshold

    filtered_data = data[fcf & historical & fcf_last_yr & fcf_interest_avg & fcf_interest_last_yr &
                        margin_analyst_low]

    basepath = os.path.dirname(stocks_valuations_fn)
    fname = "filtered_%s"%os.path.basename(stocks_valuations_fn)
    out_fn = os.path.join(basepath, fname)
    filtered_data.to_csv(out_fn, sep="|")


import threading
import json
import logging

# see https://stackoverflow.com/a/2390997
class SafeFileDict(dict):  # dicts take a mapping or iterable as their optional first argument
  def __init__(self, *args, **kwargs):
    self.lock = threading.Lock()
    self.update(*args, **kwargs)
    self.doJournal = False
    self.journalFile = ""

  def enableJournal(self, journalFile):
     logging.info("Writing dict to: " + journalFile)
     self.journalFile = journalFile
     self.doJournal = True

  def writeJournal(self):
    if self.doJournal == False:
      logging.warning("Attempting to write Safe File Dict but no journal file specified.")
      return

    with self.lock:
      data = json.dumps (self, indent=2)
      with open(self.journalFile, 'w') as file:
        file.write(data)
        logging.debug("Wrote dict to: " + self.journalFile)

  def disableJournal(self):
    self.writeJournal()
    self.doJournal = False

  def readJournal(self, journalFile=""):
    if journalFile == "" and self.doJournal == False:
      logging.warning("No journal file specified.")
      return

    if journalFile != "":
      toRead = journalFile
    else:
      toRead = self.journalFile

    with open(toRead, 'r') as file:
      self.clear()
      self.update(json.loads(file.read()))
      logging.info("Read dict from: " + toRead)

  def __getitem__(self, key):
    with self.lock:
      val = dict.__getitem__(self, key)
      # print ('GET', key)
      return val

  def __setitem__(self, key, val):
    with self.lock:
      # print ('SET', key, val)
      dict.__setitem__(self, key, val)

  def __repr__(self):
    with self.lock:
      dictrepr = dict.__repr__(self)
      return '%s(%s)' % (type(self).__name__, dictrepr)

  def update(self, *args, **kwargs):
    # print ('update', args, kwargs)
    for k, v in dict(*args, **kwargs).items():
      self[k] = v


import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
import pickle
import keras
import tensorflow as tf

def text_classifier(vectorizer, transformer, classifier):
    return Pipeline(
        [("vectorizer", vectorizer),
         ("transformer", transformer),
         ("classifier", classifier)]
    )

def train_logreg():
    train = pd.read_csv('articles_train.csv')

    train.fillna('', inplace=True)

    texts_author = train.author
    texts_title = train.title
    texts_text = train.text
    labels = train.claps

    clf_author = text_classifier(CountVectorizer(), TfidfTransformer(), LinearRegression())
    print('-')
    clf_author.fit(texts_author, labels)
    print('-')
    clf_title = text_classifier(CountVectorizer(), TfidfTransformer(), LinearRegression())
    print('-')
    clf_title.fit(texts_title, labels)
    print('-')
    clf_text = text_classifier(CountVectorizer(), TfidfTransformer(), LinearRegression())
    print('-')
    clf_text.fit(texts_text, labels)
    print('-')

    confidence_author = clf_author.predict(train.author)
    confidence_title = clf_title.predict(train.title)
    confidence_text = clf_text.predict(train.text)

    x = list(zip(confidence_author, confidence_title, confidence_text))
    x = np.array(x)
    x = x.reshape((-1, 3))

    model = keras.Sequential()
    model.add(keras.layers.Dense(32))
    model.add(keras.layers.Activation('relu'))
    model.add(keras.layers.Dense(12))
    model.add(keras.layers.Activation('relu'))
    model.add(keras.layers.Dense(1))
    model.add(keras.layers.Activation('relu'))

    model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

    model.fit(x, labels, batch_size=128, epochs=40)

    test = pd.read_csv('articles_test.csv')

    test.fillna('', inplace=True)

    test_confidence_author = clf_author.predict(test.author)
    test_confidence_title = clf_title.predict(test.title)
    test_confidence_text = clf_text.predict(test.text)
    x_test = list(zip(test_confidence_author, test_confidence_title, test_confidence_text))
    x_test = np.array(x_test)
    x_test = x_test.reshape((-1, 3))

    ans = model.predict(x_test)
    answer = pd.DataFrame(ans)
    answer.to_csv('ans_nlp.csv')

train_logreg()


import pandas as pd
import numpy as np
import matplotlib
import random
from matplotlib import pyplot as plt
matplotlib.use("Agg")

np.random.seed(42)
class Scaler():
	def __call__(self,features, is_train=False):
		'''
		Arguments : features N X D all are numeric
		'''
		min=features.min(0)
		ptp=features.ptp(0)
		features_normed=(features-min)/ptp
		return features_normed

# Polynomial Basis function

def polyBasis(X):
	for x in range(X.shape[1]):
		X[:,x] = X[:,x]**x
	return X

# Square Basis function

def squareBasis(X):
	np.power(X,2)
	return X

def get_features(csv_path,is_train=False,scaler=None):
	feaures = ["scan","track","bright_t31","daynight","latitude","longitude","brightness","confidence","satellite"]
	data = pd.read_csv(csv_path)[feaures]
	X = data

	# Onehot encoding for Daynight
	temp = pd.get_dummies(X["daynight"])
	X = X.drop("daynight",axis=1)
	X["day"]=temp.iloc[:,0]
	X["night"]=temp.iloc[:,1]
	# Onehot encoding for satellite
	temp = pd.get_dummies(X["satellite"])
	X = X.drop("satellite",axis=1)
	X["aqua"]=temp.iloc[:,0]
	X["terra"]=temp.iloc[:,1]
	u = np.mean(X,0)
	std = np.std(X,0)
	X = (X-u)/std

	one = np.ones((X.shape[0],1))
	X = np.hstack((one,X))

	# X = polyBasis(X)			#uncomment to apply basis function 1
	# X = squareBasis(X)		#uncomment to apply basis function 2

	return X

def get_targets(csv_path):
	'''
	Description:
	read target outputs from the csv file
	return a numpy array of shape m x 1
	m is number of examples
	'''
	df = pd.read_csv(csv_path)
	return df.frp

def analytical_solution(feature_matrix, targets, C=0.0):
	A = np.linalg.inv(np.dot(feature_matrix.T,feature_matrix)+C*l2_regularizer(targets))
	B = np.dot(feature_matrix.T,targets)
	W = np.dot(A,B)
	return W

def get_predictions(feature_matrix, weights):
	Ypred=np.dot(feature_matrix,weights)
	return abs(Ypred)

def mse_loss(feature_matrix, weights, targets):
	Ypred  = get_predictions(feature_matrix,weights)
	targets = targets.values
	targets.reshape(targets.shape[0],1)
	loss = np.sum((Ypred - targets)**2)/(2*(feature_matrix.shape[0]))
	return loss

def l2_regularizer(weights):
	reg = np.sum(weights**2)**(0.5)
	return reg

def loss_fn(feature_matrix, weights, targets, C=0.0):
	mse = mse_loss(feature_matrix,weights,targets)
	l2 = l2_regularizer(weights)
	loss = mse + C*l2
	return loss

def compute_gradients(feature_matrix, weights, targets, C=0.0):
	predictions = get_predictions(feature_matrix,weights)
	predictions = predictions.reshape(predictions.shape[0],1)
	targets = targets.reshape(predictions.shape[0],1)
	temp = (np.dot(feature_matrix.T,np.subtract(predictions,targets)))
	reg = (C*l2_regularizer(weights))
	gradients = (temp+reg)/(2*feature_matrix.shape[0])
	return gradients

def sample_random_batch(feature_matrix, targets, batch_size):
	sampled_targets=[]
	indexes=random.sample(range(0, feature_matrix.shape[0]), batch_size)
	new_feature_matrix=[]
	for i in indexes:
	  new_feature_matrix.append(feature_matrix[i])
	  count = 0
	  sampled_targets.append(targets[i])
	return np.array(new_feature_matrix),np.array(sampled_targets)

def initialize_weights(n):
	w = np.zeros(n)
	return w

def update_weights(weights, gradients, lr):
	N=weights.shape[0]

	for i in range(0,N):
		weights[i] = weights[i] - lr*(1/N)*gradients[i]

	return weights

def early_stopping(patience=0):
	if patience >700:
	   return True
	return False

def plot_trainsize_losses(x_data, y_data,t):
	# %matplotlib inline
	print(x_data,y_data)
	plt.plot(x_data, y_data)
	plt.xlabel('Training Samples Count')
	plt.ylabel('Dev Loss')
	plt.title(t)
	plt.savefig('plot1.png')
	plt.show()
	return

def do_gradient_descent(train_feature_matrix,
						train_targets,
						dev_feature_matrix,
						dev_targets,
						lr=1.0,
						C=0.0,
						batch_size=32,
						max_steps=1000,
						eval_steps=5):
	check = 0
	loss =np.inf
	best_weights= None
	n = len(train_feature_matrix[0])
	weights = initialize_weights(n)
	dev_loss = mse_loss(dev_feature_matrix, weights, dev_targets)
	train_loss = mse_loss(train_feature_matrix, weights, train_targets)
	print("step {} \t dev loss: {} \t train loss: {}".format(0,dev_loss,train_loss))
	for step in range(1,max_steps+1):

		#sample a batch of features and gradients
		features,targets = sample_random_batch(train_feature_matrix,train_targets,batch_size)

		#compute gradients
		gradients = compute_gradients(features, weights, targets, C)

		#update weights
		weights = update_weights(weights, gradients, lr)

		if step%eval_steps == 0:
			dev_loss = mse_loss(dev_feature_matrix, weights, dev_targets)
			train_loss = mse_loss(train_feature_matrix, weights, train_targets)
			print("step {} \t dev loss: {} \t train loss: {}".format(step,dev_loss,train_loss))
		if early_stopping(check):
				print(f'Stopping at {step} steps')
				break
		if loss <= dev_loss:
			  check += 1
		else:
				loss = dev_loss
				best_weights = weights
				check= 0
	return best_weights

def do_evaluation(feature_matrix, targets, weights):
	predictions = get_predictions(feature_matrix, weights)
	loss =  mse_loss(feature_matrix, weights, targets)
	return loss
if __name__ == '__main__':
	scaler = False
	train_features, train_targets = get_features('./data/train.csv',True,scaler), get_targets('./data/train.csv')
	dev_features, dev_targets = get_features('./data/dev.csv',False,scaler), get_targets('./data/dev.csv')
	test_features = get_features('./data/test.csv',False,scaler)
	a_solution = analytical_solution(train_features, train_targets, C=1e-8)
	print('evaluating analytical_solution...')
	dev_loss=do_evaluation(dev_features, dev_targets, a_solution)
	train_loss=do_evaluation(train_features, train_targets, a_solution)
	print('analytical_solution \t train loss: {}, dev_loss: {} '.format(train_loss, dev_loss))
	print('training LR using gradient descent...')

	gradient_descent_soln = do_gradient_descent(train_features,
						train_targets,
						dev_features,
						dev_targets,
						lr=0.0009,
						C=1e-8,
						batch_size=50,
						max_steps=400000,
						eval_steps=20)

	print('evaluating iterative_solution...')
	dev_loss=do_evaluation(dev_features, dev_targets, gradient_descent_soln)
	train_loss=do_evaluation(train_features, train_targets, gradient_descent_soln)

	print('gradient_descent_soln \t train loss: {}, dev_loss: {} '.format(train_loss, dev_loss))


import datetime
from models import Record
from settings import celery, db
from utils import get_response_status, parse_yml_files

@celery.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    for parsed_data in parse_yml_files()['urls']:
        sender.add_periodic_task(parsed_data['delay'],
                                 save_response_status.s(parsed_data['url']))

@celery.task
def save_response_status(url):
    record = Record(url=url, status_code=get_response_status(url),
                    response_date=datetime.datetime.now())
    db.session.add(record)
    db.session.commit()