# -*- coding: utf-8 -*-
import sys
sys.path.append('modules')
from tkinter import *
from objets import *
from random import shuffle
from math import ceil
from chargement import *
from tkinter.filedialog import *
from tkinter.messagebox import * #Gestion des boites de dialogue
import gestion_inventaire
import pickle

class FrameChoix(Frame):

    def __init__(self, master, numE="", txtC="", *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.indiqueE = Label(self, text="Enfant")
        self.indiqueE.grid(row=0, column=0)
        self.indiqueE.bind("<Button-1>", self.clic)
        self.indiqueE.bind("<B1-Motion>",self.deplace)

        self.numeroEnfant = Entry(self, width=4)
        self.numeroEnfant.grid(row=0, column=1)
        self.numeroEnfant.insert(0, numE)
        self.numeroEnfant.bind("<KeyRelease>", self.modif)

        self.indiqueT = Label(self, text="Texte")
        self.indiqueT.grid(row=0, column=2)
        self.indiqueT.bind("<Button-1>", self.clic)
        self.indiqueT.bind("<B1-Motion>",self.deplace)

        self.texteChoix = Entry(self, width=15)
        self.texteChoix.grid(row=0, column=3)
        self.texteChoix.insert(0, txtC)
        self.texteChoix.bind("<KeyRelease>", self.modif)

        self.boutSupr = Button(self, width=1, height=1, text="X", command=self.erase)
        self.boutSupr.grid(row=0, column=4)

    def getChoix(self):

        try: return (int(self.numeroEnfant.get()), self.texteChoix.get())
        except: return False

    def erase(self):

        self.master.trace.remove(self)
        self.master.modifChoix()
        self.destroy()

        self.master.master.update_idletasks()
        self.master.master.master.config(scrollregion=self.master.master.master.bbox("all"))

    def modif(self, event):

        self.master.modifChoix()

    def clic(self, event):

        self.master.master.clic(event)

    def deplace(self, event):

        self.master.master.deplace(event)

class FrameChoixPara(Frame):

    def __init__(self, master, choix={}, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.trace = []
        self.nb = 1

        self.boutAjoute = Button(self, text="Ajouter Choix", command=lambda: self.ajoute())
        self.boutAjoute.grid(row=0, column=0)

        for num in choix:

            chFrame = FrameChoix(self, str(num), choix[num])
            chFrame.grid(row=self.nb, column=0)
            self.nb += 1
            self.trace.append(chFrame)

    def ajoute(self):

        chFrame = FrameChoix(self)
        chFrame.grid(row=self.nb, column=0)
        self.nb += 1
        self.trace.append(chFrame)

        self.master.update_idletasks()
        self.master.master.config(scrollregion=self.master.master.bbox("all"))

    def modifChoix(self):

        listeNum = []
        h = self.master.master.master.master.histoire

        for frameChoix in self.trace:

            choix = frameChoix.getChoix()
            if choix and (choix[0] in h):

                listeNum.append(choix[0])

                if self.master.num not in h[choix[0]].getParents():
                    h.ajout_choix(self.master.num, choix[0], choix[1])
                else:
                    h[self.master.num].ajout_choix(choix[0], choix[1])

        listeSupr = []
        for choix in h[self.master.num].getChoix():
            if choix not in listeNum: listeSupr.append(choix)

        for num in listeSupr:

            if self.master.num in h[num].getParents():
                h.supprime_choix(self.master.num, num)
            else:
                h[self.master.num].supprime_choix(num)

        self.master.master.master.setTraits()

    def supprimeChoix(self, numEnfant):

        for frameChoix in self.trace:

            choix = frameChoix.getChoix()
            if choix and (choix[0] == numEnfant):
                frameChoix.numeroEnfant.delete(0, END)
                frameChoix.texteChoix.delete(0, END)

    def ajustChoix(self, num, nouveauNum):

        for frameChoix in self.trace:

            choix = frameChoix.getChoix()
            if choix and (choix[0] == num):
                frameChoix.numeroEnfant.delete(0, END)
                frameChoix.numeroEnfant.insert(0, str(nouveauNum))

    def ajustChoixMel(self, correspondances):

        for frameChoix in self.trace:

            choix = frameChoix.getChoix()
            if choix:
                num = choix[0]
                frameChoix.numeroEnfant.delete(0, END)
                frameChoix.numeroEnfant.insert(0, str(correspondances[num]))

class FramePara(Frame):

    def __init__(self, master, num, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.num = num

        h = self.master.master.master.master.histoire

        self.textePara = Text(self, height=8, width=30)
        self.textePara.grid(row=1, column=0)

        self.textePara.insert(END, h[self.num].getTexte())
        self.textePara.bind("<KeyRelease>", self.modifTexte)

        self.cadreChoix = FrameChoixPara(self, h[self.num].getChoix())
        self.cadreChoix.grid(row=2, column=0)
        self.cadreChoix.bind("<Button-1>", self.clic)
        self.cadreChoix.bind("<B1-Motion>",self.deplace)

    def modifTexte(self, event):

        h = self.master.master.master.master.histoire
        h[self.num].setTexte(self.textePara.get(1.0, END)[:-1])

    def clic(self, event):

        self.master.master.clic(event)

    def deplace(self, event):

        self.master.master.deplace(event)

    def ajusteTitre(self, nouveauNum):

        self.num = nouveauNum
        self.master.master.num = nouveauNum
        self.master.master.info.config(text="Paragraphe "+str(self.num))

class FrameCan(Frame):

    clico = 0
    cloco = 0

    dimX = 298
    dimY = 188

    def __init__(self, master, num, x, y, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.num = num
        self.traceTraits = {}

        self.scrolling = Scrollbar(self, orient=VERTICAL)
        self.scrolling.grid(row=1, column=1, sticky=N+S)
        self.can = Canvas(self, height=160, width=285, yscrollcommand=self.scrolling.set)
        self.can.grid(row=1, column=0)
        self.can.bind("<Button-1>", self.clic)
        self.can.bind("<B1-Motion>", self.deplace)
        self.scrolling.config(command=self.can.yview)
        self.cadrePara = FramePara(self.can, num)
        self.cadrePara.bind("<Button-1>", self.clic)
        self.cadrePara.bind("<B1-Motion>", self.deplace)
        self.can.create_window(0, 0, window=self.cadrePara)

        self.minimise=False
        self.info = Label(self, text="Paragraphe "+str(self.num))
        self.info.grid(row=0, column=0)
        self.info.bind("<Button-1>", self.clic)
        self.info.bind("<B1-Motion>", self.deplace)

        self.cadrePara.update_idletasks()
        self.can.config(scrollregion=self.can.bbox("all"))

        self.cadreBout = Frame(self)

        self.boutmin = Button(self.cadreBout, text="_",fg="white",bg="grey", command=lambda:self.cache(not self.minimise))
        self.boutmin.grid(row=0, column=1)

        self.boutSupr = Button(self.cadreBout, text="X", command=self.supprime)
        self.boutSupr.grid(row=0, column=2)

        self.boutPlus = Button(self.cadreBout, text="+", command=self.ouvreOptionsAvancees)
        self.boutPlus.grid(row=0, column=0)

        self.cadreBout.grid(row=0, column=0, columnspan=2, sticky=E)

        self.id = self.master.create_window(x, y, window=self)

        self.bind("<Button-1>", self.clic)
        self.bind("<B1-Motion>", self.deplace)

    def cache(self,estminimise):
        if estminimise:
            self.can.grid_forget()
        else: self.can.grid(row=1, column=0)
        self.minimise = estminimise

    def clic(self, event):

        FrameCan.clico = event.x
        FrameCan.cloco = event.y

    def deplace(self, event):
        self.master.move(self.id, event.x-FrameCan.clico, event.y-FrameCan.cloco)
        self.setTraits()

    def supprime(self):

        self.master.supprime(self.num)
        self.destroy()

    def setTraits(self):

        coords = self.master.coords(self.id)

        listeLiens = [num for num in self.master.histoire[self.num].getChoix()]
        listeLiens.extend([num for num in self.master.histoire[self.num].getParents()])

        for num in listeLiens:

            coordsAutre = self.master.coords(self.master.trace[num].id)

            if num not in self.traceTraits:
                self.traceTraits[num] = self.master.create_line(coords[0], coords[1], coordsAutre[0], coordsAutre[1])
                self.master.trace[num].traceTraits[self.num] = self.traceTraits[num]

            else:
                self.master.coords(self.traceTraits[num], coords[0], coords[1], coordsAutre[0], coordsAutre[1])

        listeSupr = []
        for num in self.traceTraits:
            if num not in listeLiens:
                listeSupr.append(num)

        for num in listeSupr:

            self.master.delete(self.traceTraits[num])
            del self.master.trace[num].traceTraits[self.num]
            del self.traceTraits[num]

    def ajusteTrait(self, num, nouveauNum):

        self.traceTraits[nouveauNum] = self.traceTraits[num]
        del self.traceTraits[num]

    def ajusteTraitsMel(self, correspondances):

        nouvTraceTraits = {}

        for num in self.traceTraits:
            nouvTraceTraits[correspondances[num]] = self.traceTraits[num]

        self.traceTraits = nouvTraceTraits

    def ouvreOptionsAvancees(self):

        optAvanc = OptionsAvancees(self)
        optAvanc.mainloop()

class Editeur(Canvas):
    l=[]#contient les fenetres pour zoom dezoom
    ltaille=[160,285]#sauvegarde les tailles de fenetres pour zoom dezoom
    def __init__(self, master, histoire, *args, **kw):

        Canvas.__init__(self, master, *args, **kw)
        self.la=master.winfo_screenwidth() # Sinon ça s'affiche mal chez moi
        self.ho=master.winfo_screenheight()-150
        self.master=master
        self.config(width=self.la,height=self.ho)
        self.histoire = master.histoire
        self.trace = {}

        self.placement()

        self.bind("<Button-1>", self.clic)
        self.bind("<B1-Motion>", self.drag)
        self.bind("<Button-3>", self.creer)

##        self.bind("<KeyPress-+>", self.zoomin)
##        self.bind("<KeyPress-->", self.zoomout)
        self.focus_set()

    def zoomin(self,event):
##        d = event.delta
##        if d < 0:
##            k=0.9
##        else:
##            k=1.1
##        self.scale(ALL, self.la/2, self.ho/2 , k,k)
        Editeur.ltaille[0]+=10
        Editeur.ltaille[1]+=10
        for fenetre in Editeur.l:
            try:
                #fenetre.config(bg="blue",height=0,width=0)
                fenetre.can.config(height=Editeur.ltaille[0],width=Editeur.ltaille[1]) #gere la taille de la fenetre
                #fenetre.cadrePara.config(height=500,width=500)
                #fenetre.cadrePara.cadreChoix.boutAjoute.config(height=1,width=10) #gere la taille du bouton
                #fenetre.cadrePara.textePara.config(height=500,width=500)
            except:
                continue

    def zoomout(self,event):
##        d = event.delta
##        if d >0:
##            k=1.1
##        else:
##            k=0.9
##        self.scale(ALL, self.la/3, self.ho/2 , k, k)
        Editeur.ltaille[0]=Editeur.ltaille[0]-10
        Editeur.ltaille[1]=Editeur.ltaille[1]-10
        for fenetre in Editeur.l:
            try:
                #fenetre.config(bg="blue",height=0,width=0)
                fenetre.can.config(height=Editeur.ltaille[0],width=Editeur.ltaille[1])
            except:
                continue

    def clic(self, event):
        self.scan_mark(event.x, event.y)

    def drag(self, event):

        self.scan_dragto(event.x, event.y, gain=2)

    def creer(self, event):

        self.master.histoire.ajout_paragraphe()

        x, y = self.canvasx(event.x), self.canvasy(event.y)
        cadre = FrameCan(self, len(self.master.histoire), x, y)
        Editeur.l.append(cadre)
        self.trace[len(self.master.histoire)] = cadre

        self.master.setNbPar(len(self.master.histoire))

    def supprime(self, numSupr):

        for parent in self.master.histoire[numSupr].getParents():
            self.trace[parent].cadrePara.cadreChoix.supprimeChoix(numSupr)

        for numLien in self.trace[numSupr].traceTraits:

            self.delete(self.trace[numSupr].traceTraits[numLien])
            del self.trace[numLien].traceTraits[numSupr]

        for num in range(numSupr+1, len(self.trace)+1):

            self.trace[num].cadrePara.ajusteTitre(num-1)

            for numLien in self.trace[num].traceTraits:
                self.trace[numLien].ajusteTrait(num, num-1)

            for parent in self.master.histoire[num].getParents():
                self.trace[parent].cadrePara.cadreChoix.ajustChoix(num, num-1)

            self.trace[num -1] = self.trace[num]

        del self.trace[len(self.trace)]
        self.master.histoire.supprime_paragraphe(numSupr)

        self.master.setNbPar(len(self.master.histoire))

    def changeNum(self):

        listeNum = [num for num in range(2, len(self.master.histoire)+1)]
        listeAlea = listeNum[:]
        shuffle(listeAlea)
        correspondances = {listeNum[i]:listeAlea[i] for i in range(len(listeNum))}
        correspondances[1] = 1

        self.melangeNum(correspondances)

    def melangeNum(self, correspondances):

        nouvTrace = {}

        for num in self.trace:

            self.trace[num].cadrePara.ajusteTitre(correspondances[num])
            self.trace[num].cadrePara.cadreChoix.ajustChoixMel(correspondances)
            self.trace[num].ajusteTraitsMel(correspondances)
            nouvTrace[correspondances[num]] = self.trace[num]

        self.trace = nouvTrace
        self.master.histoire = self.master.histoire.melangeNum(correspondances)
        self.master.histoire.tags=self.master.tags
    def melangePara(self):

        self.master.histoire.melangePara()
        nouvDeb = self.master.histoire.getDebut()
        correspondances = {nouvDeb:1}
        correspondances[1] = nouvDeb

        for num in range(2, len(self.master.histoire)+1):
            if num != nouvDeb: correspondances[num] = num

        self.melangeNum(correspondances)

    def placement(self):

        dim = ceil(len(self.master.histoire)**0.5)
        i = j = 0
        depX = 160
        depY = 105

        for num in self.master.histoire:
            cadre = FrameCan(self, num, depX+i*310, depY+j*200)
            Editeur.l.append(cadre)
            self.trace[num] = cadre

            i+=1
            if i == dim:
                i=0
                j+=1

        self.actualiseTraits()

    def actualiseTraits(self):

        for num in self.trace:
            self.trace[num].setTraits()

class Application(Tk):

    def __init__(self, histoire, *args, **kw):

        Tk.__init__(self, *args, **kw)
        self.title('Editeur de Visual Novel : DRAGDROP EDITION 2017')

        self.histoire=histoire
        self.tags=self.histoire.tags
        self.edit = Editeur(self, self.histoire, bg="grey")
        self.edit.grid(row=0, column=0)

        self.nomProjet=StringVar()
        self.nomProjet.set("Veillez créer un ouvrir un projet")
        self.cadreBas = Frame(self)

        self.cadreAction = Frame(self.cadreBas)

        self.boutMelangeNum = Button(self.cadreAction, width=15, text="Mélanger Numéros", command=lambda: self.edit.changeNum())
        self.boutMelangeNum.grid(row=0, column=0)

        self.boutMelangePara = Button(self.cadreAction, width=15, text="Mélanger Paragraphes", command=lambda: self.edit.melangePara())
        self.boutMelangePara.grid(row=1, column=0, pady=5)

        Button(self.cadreAction, width=7, text="Zoomer", command=lambda: self.edit.zoomin("")).grid(row=0, column=1)
        Button(self.cadreAction, width=7, text="Dezoomer", command=lambda: self.edit.zoomout("")).grid(row=1, column=1)
        self.cadreAction.grid(row=0, column=0, padx=100, sticky=W)

        self.cadreInfo = Frame(self.cadreBas)

        self.nbPar = Label(self.cadreInfo, text="Nombre de paragraphes : "+str(len(histoire)))
        self.nbPar.grid(row=0, column=0)

        self.nomProj = Label(self.cadreInfo, textvariable=self.nomProjet)
        self.nomProj.grid(row=1, column=0)

        self.cadreInfo.grid(row=0, column=1, padx=100)

        self.cadreTest = Frame(self.cadreBas)

        self.boutTest = Button(self.cadreTest, width=7, text="Tester", command=lambda: compiler(self.histoire))
        self.boutTest.grid(row=0, column=0)

        self.cadreTest.grid(row=0, column=2, padx=100, sticky=E)

        self.cadreBas.grid(row=1, column=0)

        barre = Menu(self)
        option=Menu(barre,tearoff=1)
        edit=Menu(barre,tearoff=0)
        affichage=Menu(barre,tearoff=0)
        mobjet=Menu(barre,tearoff=1)
        aide=Menu(barre,tearoff=0)
        log=Menu(aide,tearoff=0)
        dev=Menu(edit,tearoff=0)
        theme=Menu(affichage,tearoff=0)
        hero= Menu(barre,tearoff=1)
        Mag= Menu(barre,tearoff=1)
        tag=Menu(barre,tearoff=0)
        barre.add_cascade(label="Fichier",menu=option)
        barre.add_cascade(label="Edition",menu=edit)
        barre.add_cascade(label="Gestion des personnages",menu=hero)
        barre.add_cascade(label="Tag",menu=tag)
        barre.add_cascade(label="Objet",menu=mobjet)
        barre.add_cascade(label="Magasins",menu=Mag)
        barre.add_cascade(label="Affichage",menu=affichage)
        barre.add_cascade(label="Aide",menu=aide)
        option.add_command(label="Nouveau projet",command=self.nouveauProjet)
        option.add_command(label="Ouvrir projet",command=self.ouvrirProjet)
        option.add_command(label="Enregistrer projet",command=lambda:sauverLEPROJET(self.histoire,self.nomProjet.get()))
        option.add_command(label="Exporter le projet (enregistrer sous)",command=lambda:exporterProjet(self.histoire))
        option.add_command(label="Importer images",command=importimage)
        option.add_command(label="Importer sons",command=importson)
        option.add_command(label="Exporter en HTML",command=lambda : html_export(self.histoire,self.nomProjet.get()))
        option.add_command(label="Informations sur le projet",command=info)
        option.add_separator()
        mobjet.add_command(label="Nouveau Objet",command=lambda:nouveau_objet(p.touslesobjets))
        mobjet.add_command(label="Liste des objets",command=self.listeobjets)
        option.add_command(label="Quitter",command=self.quitter)
        aide.add_cascade(label="Version du logiciel",menu=log)
        aide.add_command(label="Copyright",command=lambda: showinfo("Credit","Copyright (travail sur l'éditeur) : \n Bensitel Younes : Gestion des objets,magasins, ennemis, héros, drag_drop, options avancées, compiler, exporter, enregistrer, exporter en html, debugger, tester le jeu, fonction de recherche,gestion du jeu entier sauf les combats etc. \n Mekhelef Yassine : Gestion du zoom/dézoom, gestion des combats. \n 2016-2017"))
        affichage.add_command(label="Activer/Désactiver Plein écran", command=lambda:self.attributes("-fullscreen", not(self.attributes("-fullscreen"))))
        log.add_cascade(label="VERSION DEFINITIVE 1.0")
        hero.add_command(label="Paramètres du héros",command=creationHero)
        hero.add_command(label="Créer un ennemi",command=creationEnnemi)
        hero.add_command(label="Paramètres des ennemis",command=self.listeennemis)

        tag.add_command(label="Nouveau Tag",command=self.nouvTag)
        tag.add_command(label="Supprimer Tag",command=self.suprTag)
        Mag.add_command(label="Nouveau magasin",command=nouveau_magasin)
        Mag.add_command(label="Liste des magasins",command=listemagasins)
        edit.add_cascade(label="Développeur",menu=dev)
        dev.add_command(label="Git COMMIT",command=commit)
        dev.add_command(label="Git PULL",command=pull)
        edit.add_command(label="Rechercher",command=self.rechercher)
        self.config(menu=barre)
        option.entryconfig(3, state=DISABLED)
        option.entryconfig(4, state=DISABLED)
        option.entryconfig(5, state=DISABLED)
        try:self.wm_state('zoomed')
        except:
            try:self.attributes('-zoomed', True)
            except:self.state('zoomed')
        self.barre=barre
        self.option=option
        if sys.version[0]!="3":
            showinfo("Remarque importante","Vous lancez actuellement notre logiciel avec la version "+sys.version[0]+" de python, notre logiciel est cependant conçu pour python 3, il pourrait donc y avoir des problèmes de fonctionnement.")
        self.titre()
        self.mainloop()

    def quitter(self):

        self.quit()
        self.destroy()

    def setNbPar(self, nb):

        self.nbPar.config(text="Nombre de paragraphes : "+str(nb))

    def nouveauProjet(self):
        if os.name=="nt":
            self.nomProjet.set(savewindows({}))
        else:
            self.nomProjet.set(save({}))
        p.nom=self.nomProjet.get()
        for i in range(len(self.histoire)):
            self.edit.supprime(1)
        self.edit.delete(ALL)
        p.touslesobjets=gestion_inventaire.ToutObjet()
        p.touslesmagasins=gestion_inventaire.TousLesMagasins()
        p.touslesennemis={}
        self.option.entryconfig(3, state=ACTIVE)
        self.option.entryconfig(4, state=ACTIVE)
        self.option.entryconfig(5, state=ACTIVE)
        self.option.entryconfig(6, state=ACTIVE)

    def ouvrirProjet(self):
        global heros
        try:
            if os.name=="nt":
                tuplodocus=chargement2windows()
            else:
                tuplodocus=chargement2()
            self.histoire=tuplodocus[0]
            self.nomProjet.set(tuplodocus[2])
            self.edit = Editeur(self, self.histoire, bg="grey")
            self.edit.grid(row=0, column=0)
            self.nbPar.config(text="Nombre de paragraphes : "+str(len(self.histoire)))
            p.nom=self.nomProjet.get()
            p.touslesobjets=gestion_inventaire.chargerobj(p.nom+"/data/objets")
            p.touslesennemis=gestion_inventaire.chargerobj(p.nom+"/data/ennemis")
            p.touslesmagasins=gestion_inventaire.chargerobj(p.nom+"/data/magasins")
            try:
                self.histoire.tags=gestion_inventaire.chargerobj(p.nom+"/data/tags")
                self.tags=gestion_inventaire.chargerobj(p.nom+"/data/tags")
            except: pass

            try:
                heros=gestion_inventaire.chargerobj(p.nom+"/data/heros")
            except: pass
            self.option.entryconfig(3, state=ACTIVE)
            self.option.entryconfig(4, state=ACTIVE)
            self.option.entryconfig(5, state=ACTIVE)
            self.option.entryconfig(6, state=ACTIVE)
        except TypeError:
            pass
        except :
            montreinfo("Erreur","opération annulée : erreur "+str(sys.exc_info()[0])+" : "+ str(sys.exc_info()[1]),"red")
    def nouvTag(self):

        fenTag = AjoutTag(self)
        fenTag.mainloop()

    def suprTag(self):

        if self.histoire.tags != []:

            fenSupr = SuprTag(self)
            fenSupr.mainloop()

        else:
            pass

    def creationHero(self):

        fenHeros = FenHeros(self)
        fenHeros.mainloop()

    def search(self,string):
        h=self.histoire
        string=string.lower()
        try:
            l=[]
            for numPar in h:
                if string in h[numPar].getTexte():
                    l.append(numPar)
            self.rechercheiter=iter(l)
            numPar=next(self.rechercheiter)
            montreinfo("Paragraphe "+str(numPar),h[numPar].getTexte())
        except:  showerror("Recherche", "Désolé, nous n'avons pas trouvé ce terme.")

    def bouttonsuiv(self):
        h=self.histoire
        try:
            numPar=next(self.rechercheiter)
            showinfo("Paragraphe "+str(numPar),"Paragraphe "+str(numPar)+"\n"+h[numPar].getTexte())
        except: showinfo("Recherche terminée", "Aucun autre élément n'a été trouvé.")

    def rechercherTout(self,string):
        self.search(string)
        for i in self.rechercheiter:
            self.bouttonsuiv()

    def rechercher(self):
        rech=Toplevel(self)
        rech.wm_attributes("-topmost", 1)
        rech.geometry("%dx%d+%d+%d" % ((240,120) + (10, 10)))
        Label(rech,text="Rechercher un élément d'un paragraphe").grid(row=0)
        recherche=Text(rech,height=1,width=30)
        recherche.grid(row=1,column=0)
        Button(rech,text="Rechercher",command=lambda:self.search(recherche.get(1.0,END)[:-1])).grid(row=2)
        Button(rech,text="Rechercher Suivant",command=self.bouttonsuiv).grid(row=3)
        Button(rech,text="Rechercher Tout",command=lambda:self.rechercherTout(recherche.get(1.0,END)[:-1])).grid(row=4)

    def titre(self):
        fparam=Toplevel(self)
        fparam.wm_attributes("-topmost", 1)
        fparam.overrideredirect(1)
        Label(fparam,text="Bienvenue",bg="#101080",fg="white",font="Tahoma 12 bold").pack(fill=BOTH)
        Label(fparam,text="Auteurs : Younes Bensitel, Yassine Mekhelef",font="Tahoma 8").pack(fill=BOTH)
        Label(fparam,text="N'oubliez pas de créer ou d'ouvrir \n un projet avant de commencer à créer des paragraphes.",font="Tahoma 12 bold").pack()
        Button(fparam,text="Ouvrir un projet",command=lambda: self.tireboutton(fparam,self.ouvrirProjet),font=("Helvetica", 16)).pack()
        Button(fparam,text="Nouveau Projet",command=lambda: self.tireboutton(fparam,self.nouveauProjet),font=("Helvetica", 16)).pack()
        Button(fparam, text="X",fg="white",bg="red", command=fparam.destroy).pack(side=RIGHT)
        fparam.update_idletasks()
        w,h = fparam.winfo_screenwidth(),fparam.winfo_screenheight()
        taille = tuple(int(_) for _ in fparam.geometry().split('+')[0].split('x'))
        x,y = w/2 - taille[0]/2,h/2 - taille[1]/2
        fparam.geometry("%dx%d+%d+%d" % (taille + (x, y)))

    def tireboutton(self,toplevel,fonction):
        toplevel.destroy()
        fonction()

    def listeobjets(self):
        t=Toplevel()
        t.wm_attributes("-topmost", 1)
        t.geometry("%dx%d+%d+%d" % ((640,480) + (10, 10)))
        cadre2=Frame(t, padx=5, pady=5,bg="#101080")
        cadre2.pack(fill=BOTH)
        menu=Label(cadre2,text="Liste des objets existants",bg="#101080",fg="white",font="Tahoma 12 bold")
        menu.pack(fill=X)
        vbar = Scrollbar(t, orient=VERTICAL)
        vbar.pack(side=RIGHT,fill=Y)

        c = Canvas(t,yscrollcommand=vbar.set)
        c.pack(fill=BOTH)
        vbar.config(command=c.yview)
        fr = Frame(c)
        c.create_window(0, 0,  window=fr)
        if len(p.touslesobjets)==0:
            Label(t,text="Aucun objet n'a été crée pour le moment.").pack()
        touslesobjets=p.touslesobjets
        for objet in touslesobjets:
            a=Frame(fr)
            a.pack(fill=X)
            txt=p.touslesobjets[objet].getDescription()
            if len(txt)>70:
                txt=txt[0:70]+"..."
            Label(a,text=objet+" : "+txt).pack(side=LEFT)
            Button(a,text="Modifier",command=lambda t=t,touslesobjets=touslesobjets,objet=objet:nouveau_objet(touslesobjets,objet,t)).pack(side=LEFT)
            Button(a,text="X",command=lambda touslesobjets=touslesobjets,objet=objet:(self.checkbeforedelete(t,touslesobjets,objet,self.listeobjets))).pack(side=LEFT)
        fr.update_idletasks()
        c.config(scrollregion=c.bbox("all"))

    def checkbeforedelete(self,t,touslesobjets,objet,fct):
        import copy
        for paragraphe in self.histoire:
            try:
                if self.histoire[paragraphe].getObjet()[0]==objet:
                    self.histoire[paragraphe].removeObjet(touslesobjets[objet])
            except: pass
            tmp=copy.deepcopy(p.touslesmagasins)
            for magasin in p.touslesmagasins:
                for objets in p.touslesmagasins[magasin]:
                    if objet==objets:
                        tmp[magasin].supprime(objet)
            p.touslesmagasins=tmp

        supprdico(t,touslesobjets,objet,fct)

    def listeennemis(self):
        t=Toplevel()
        t.wm_attributes("-topmost", 1)
        t.geometry("%dx%d+%d+%d" % ((250,500) + (10, 10)))
        cadre2=Frame(t, padx=5, pady=5,bg="#101080")
        cadre2.pack(fill=BOTH)
        menu=Label(cadre2,text="Liste des ennemis existants",bg="#101080",fg="white",font="Tahoma 12 bold")
        menu.pack(fill=X)
        vbar = Scrollbar(t, orient=VERTICAL)
        vbar.pack(side=RIGHT,fill=Y)

        c = Canvas(t,yscrollcommand=vbar.set)
        c.pack(fill=BOTH)
        vbar.config(command=c.yview)
        fr = Frame(c)
        c.create_window(0, 0,  window=fr)
        if len(p.touslesennemis)==0:
            Label(t,text="Aucun ennemi n'a été crée pour le moment.").pack()
        touslesennemis=p.touslesennemis
        for ennemi in touslesennemis:
            a=Frame(fr)
            a.pack(fill=X)
            Label(a,text=ennemi).pack(side=LEFT)
            Button(a,text="Modifier",command=lambda t=t,touslesennemis=touslesennemis,ennemi=ennemi:creationEnnemi(ennemi,t)).pack(side=LEFT)
            Button(a,text="X",command=lambda t=t,touslesennemis=touslesennemis,ennemi=ennemi:(self.checkbeforedeleteEnnemi(t,touslesennemis,ennemi,self.listeennemis))).pack(side=LEFT)
        fr.update_idletasks()
        c.config(scrollregion=c.bbox("all"))

    def checkbeforedeleteEnnemi(self,t,touslesennemis,ennemi,fct):
        import copy
        for paragraphe in self.histoire:
            try:
                if self.histoire[paragraphe].getCombat()[0]==ennemi:
                    self.histoire[paragraphe].removeCombat()
            except: pass
        supprdico(t,touslesennemis,ennemi,fct)
#####################################################################################################################################################

def pull():
    os.system("git pull")

def commit(toplevel="",a=0,texto=""):
    if a==1:
        os.system("git add .")
        os.system('git commit -m "'+texto+'"')
        os.system("git push")
        toplevel.destroy()
    else:
        t=Toplevel()
        t.wm_attributes("-topmost", 1)
        Label(t,text="Texte du commit").pack()
        texte=Text(t)
        texte.pack()
        Button(t,text="PUSH",command=lambda: commit(t,1,texte.get(1.0,END))).pack()
def exporterProjet(histoire):
    import shutil
    if os.name=="nt":
        chemin=(savewindows({}))
    else:
        chemin=(save({}))
    sauverLEPROJET(histoire,chemin)
    shutil.rmtree(chemin+'/data/son')
    shutil.rmtree(chemin+'/data/image')
    shutil.copytree(p.nom+"/data/image",chemin+"/data/image")
    shutil.copytree(p.nom+"/data/son",chemin+"/data/son")

def info():
    param=Param()

class FrameImage(Frame):

    def __init__(self, master, actuel="", *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.indiqueImg = Label(self, text="Image :")
        self.indiqueImg.grid(row=0, column=0, sticky=W)

        self.indiqueImgActuel = Label(self, text=actuel)
        self.indiqueImgActuel.grid(row=0, column=1, padx=20)

        self.change = Button(self, text="Changer l'image", command=self.importeImage)
        self.change.grid(row=0, column=2)

        self.supprime = Button(self, text="X", command=self.reinit)
        self.supprime.grid(row=0, column=3, sticky=E)

    def importeImage(self):
        try:
            image = askopenfilename(title="Importation d'image",filetypes=[('image .gif','.gif')],defaultextension='.gif',initialdir=p.nom+"/data/image/",parent=self.master)

            nom = image.split("/")[-1]
            try:
                copyfile(image, p.nom+"/data/image/"+nom)
            except:
                pass
            self.indiqueImgActuel.config(text=nom)
            self.master.changeImage(nom)
        except: pass

    def reinit(self):

        self.indiqueImgActuel.config(text="")
        self.master.changeImage("")

class FrameSon(Frame):

    def __init__(self, master, actuel="", *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.indiqueSon = Label(self, text="Son :")
        self.indiqueSon.grid(row=0, column=0, sticky=W)

        self.indiqueSonActuel = Label(self, text=actuel)
        self.indiqueSonActuel.grid(row=0, column=1, padx=20)

        self.change = Button(self, text="Changer le son", command=self.importeSon)
        self.change.grid(row=0, column=2)

        self.supprime = Button(self, text="X", command=self.reinit)
        self.supprime.grid(row=0, column=3, sticky=E)

    def importeSon(self):
        try:
            son = askopenfilename(title="Importation de son",filetypes=[('audio .wav','.wav')],defaultextension='.wav',initialdir=p.nom+"/data/son/",parent=self.master)
            nom = son.split("/")[-1]
            try:
                copyfile(son, p.nom+"/data/son/"+nom)
            except:
                pass

            self.indiqueSonActuel.config(text=nom)
            self.master.changeSon(nom)
        except: pass

    def reinit(self):

        self.indiqueSonActuel.config(text="")
        self.master.changeSon("")

class ChoixObjet(Listbox):

    def __init__(self, master, *args, **kw):

        Listbox.__init__(self, master, *args, height=4, **kw)
        self.insert(END,"Aucun objet")
        if self.master.master.createur.master.histoire[self.master.master.createur.num].getObjet()!=None:
            self.insert(END,self.master.master.createur.master.histoire[self.master.master.createur.num].getObjet()[0])
            self.selection_set(1)
        for nom in p.touslesobjets:
            try:
                if nom!= self.master.master.createur.master.histoire[self.master.master.createur.num].getObjet()[0]:
                    self.insert(END,nom)
            except: self.insert(END,nom)

        self.bind("<<ListboxSelect>>", self.getObjet)

    def getObjet(self, event):

        select = self.get(self.curselection())

        if select == "Aucun objet":
            obj = None
        else:
            obj = select

        self.master.master.changeObjet(obj)

class FrameObjet(Frame):

    def __init__(self, master, *args, **kw):

        Frame.__init__(self, master, *args, **kw)
        scrollbar1 = Scrollbar(self)
        self.indiqueObj = Label(self, text="Choisir un objet")
        self.indiqueObj.grid(row=0, column=0)
        self.choixObj = ChoixObjet(self)
        scrollbar1.config(command = self.choixObj.yview)
        self.choixObj.config(yscrollcommand = scrollbar1.set)
        self.choixObj.grid(row=1, column=0)
        scrollbar1.grid(row=1,column=1)

class OptionsAvancees(Tk):

    def __init__(self, createur, *args, **kw):

        Tk.__init__(self, *args, *kw)
        self.wm_attributes("-topmost",1)
        self.createur = createur
        menu=Label(self,text="Options avancées",bg="#101080",fg="white",font="Tahoma 12 bold")
        menu.grid(row=0, column=0, pady=20,sticky=EW)

        self.imagePara = FrameImage(self, self.createur.master.histoire[self.createur.num].getImage())
        self.imagePara.grid(row=1, column=0, pady=10, sticky=W)

        self.sonPara = FrameSon(self, self.createur.master.histoire[self.createur.num].getSon())
        self.sonPara.grid(row=2, column=0, pady=10, sticky=W)

        Label(self,text="Combattre contre (laisser vide si pas de combat) : ").grid(row=3,column=0,pady=10)

        self.entreeennemi = Entry(self)
        self.entreeennemi.grid(row=3, column=1, pady=10)

        Label(self,text="Fond du combat (laisser vide si pas de combat) : ").grid(row=4,column=0,pady=10)
        self.entreefond = Entry(self)
        self.entreefond.grid(row=4, column=1, pady=10)
        if self.createur.master.histoire[self.createur.num].getCombat()!=None:
            self.entreeennemi.insert(0,self.createur.master.histoire[self.createur.num].getCombat()[0])
            self.entreefond.insert(0,self.createur.master.histoire[self.createur.num].getCombat()[1])

        Button(self,text="...",command=lambda :listeimages2(self.entreefond,self)).grid(row=4,column=2,pady=10)
        self.objetPara = FrameObjet(self)
        self.objetPara.grid(row=5, column=0, pady=10)

        Label(self,text="Donner de l'argent au héros : ").grid(row=6,column=0,pady=10)
        self.entreeargent = Entry(self)
        self.entreeargent.grid(row=6, column=1, pady=10)
        Label(self,text="Autoriser ce magasin : ").grid(row=7,column=0,pady=10)
        self.entreemagasin = Entry(self)
        self.entreemagasin.grid(row=7, column=1, pady=10)
        self.boutTermine = Button(self, text="Terminé", command=self.termine)
        self.boutTermine.grid(row=8, column=0, pady=20)
        try:
            int(str(self.createur.master.histoire[self.createur.num].getArgent()))
            self.entreeargent.insert(0,str(self.createur.master.histoire[self.createur.num].getArgent()))
        except: pass
        try:
            self.entreemagasin.insert(0,self.createur.master.histoire[self.createur.num].getShop())
        except: pass

    def termine(self):
        ceparagraphe=self.createur.master.histoire[self.createur.num]
        if self.entreeennemi.get()!="" and self.entreefond.get()!="":
            if self.entreeennemi.get() not in p.touslesennemis:
                montreinfo("Erreur d'ennemi","Attention, l'ennemi '"+self.entreeennemi.get()+"' n'existe pas.","red")
                return 0
            ceparagraphe.setCombat([self.entreeennemi.get(),self.entreefond.get()])
        try:
            if self.entreeargent.get()!="":
                ceparagraphe.setArgent(int(self.entreeargent.get()))
        except:
            montreinfo("Erreur d'argent","Attention, veuillez entrer des nombres décimaux et entiers uniquement.","red")
            return 0
        if self.entreemagasin.get()!="":
            if self.entreemagasin.get() not in p.touslesmagasins:
                montreinfo("Erreur de magasin","Attention, le magasin '"+self.entreemagasin.get()+"' n'existe pas.","red")
                return 0
            ceparagraphe.setShop(self.entreemagasin.get())

        self.destroy()
    def changeImage(self, image):
        self.createur.master.histoire[self.createur.num].setImage(image)

    def changeSon(self, son):
        self.createur.master.histoire[self.createur.num].setSon(son)

    def changePerso(self, perso):
        self.createur.master.histoire[self.createur.num].setEnnemi(perso)

    def changeObjet(self, objet):
        self.createur.master.histoire[self.createur.num].setObjet(objet,1)

####################################################################################################################################################

class ListeComparaison(Listbox):

    def __init__(self, master, *args, **kw):

        Listbox.__init__(self, master, *args, height=3, **kw)

        self.insert(END, "Inférieur à")
        self.insert(END, "Égal à")
        self.insert(END, "Supérieur à")

        self.bind("<<ListboxSelect>>", self.setCompar)

        self.choix = None

    def setCompar(self, event):

        try:
            select = self.get(self.curselection())
        except:
            pass
        else:

            if select == "Inférieur à":
                self.choix = "<"

            elif select == "Égal à":
                self.choix = "="

            elif select == "Supérieur à":
                self.choix = ">"

class FrameNiveau(Frame):

    def __init__(self, master, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.listeCompar = ListeComparaison(self)
        self.listeCompar.grid(row=0, column=0, padx=5)

        self.valeur = Entry(self, width=3)
        self.valeur.grid(row=0, column=1, padx=5)

    def getCond(self):

        try:
            val = int(self.valeur.get())
        except:
            return None
        else:
            if self.listeCompar.choix:
                return self.listeCompar.choix+str(val)
            else:
                return None

class FrameCondition(Frame):

    def __init__(self, master, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.element = Listbox(self, height=1)
        self.element.grid(row=0, column=0, padx=5)
        self.element.bind("<<ListboxSelect>>", self.setElement)

        self.element.insert(END, "Niveau")

        self.choix = None

        self.cadreCondition = Frame(self)
        self.cadreCondition.grid(row=0, column=1, padx=5)

        self.BoutSupr = Button(self, text="X", command=self.erase)
        self.BoutSupr.grid(row=0, column=2, padx=5)

    def setElement(self, event):

        try:
            select = self.element.get(self.element.curselection())
        except:
            pass
        else:

            if select == "Niveau":

                self.choix = "Niv"

                self.cadreCondition = FrameNiveau(self)
                self.cadreCondition.grid(row=0, column=1, padx=5)

    def getCondition(self):

        try:
            cond = self.cadreCondition.getCond()
        except:
            return None
        else:

            if self.choix and cond:
                return self.choix+cond
            else:
                return None

    def erase(self):

        self.master.trace.remove(self)
        self.destroy()

class FrameConditionTag(Frame):

    def __init__(self, master, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.trace = []
        self.nb = 1

        self.boutAjoute = Button(self, text="Ajouter Condition", command=self.ajoute)
        self.boutAjoute.grid(row=0, column=0, pady=5)

    def ajoute(self):

        condFrame = FrameCondition(self)
        condFrame.grid(row=self.nb, column=0, pady=5)
        self.nb += 1
        self.trace.append(condFrame)

    def getAllCondition(self):
        return [cond.getCondition() for cond in self.trace if cond.getCondition() != None]

class FrameInfosTag(Frame):

    def __init__(self, master, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.cadreNom = Frame(self)

        self.indiqueNom = Label(self.cadreNom, text="Nom du Tag :")
        self.indiqueNom.grid(row=0, column=0, padx=5)

        self.nomTag = Entry(self.cadreNom, width=30)
        self.nomTag.grid(row=0, column=1, padx=5)

        self.cadreNom.grid(row=0, column=0, pady=5)

        self.cadreCond = FrameConditionTag(self)
        self.cadreCond.grid(row=1, column=0, pady=5)

    def getInfos(self):

        return self.nomTag.get(), self.cadreCond.getAllCondition()

class FrameNum(Frame):

    def __init__(self, master, num, x, y, *args, **kw):

        Frame.__init__(self, master, *args, **kw)

        self.num = num

        self.indiqueNum = Label(self, text=str(num))
        self.indiqueNum.grid(row=0, column=0)

        self.bind("<Button-1>", self.clic)
        self.indiqueNum.bind("<Button-1>", self.clic)

        self.id = self.master.create_window(x, y, window=self, width=40, height=40)
        self.idCadre = self.master.create_rectangle(x-21, y-21, x+21, y+21)

    def clic(self, event):
        self.master.clicOnCadre(self.num)

class CanInfosTag(Canvas):

    def __init__(self, master, histoire, *args, **kw):

        Canvas.__init__(self, master, *args, width=600, height=600, **kw)

        self.prem = None
        self.der = None
        self.histoire = histoire
        self.trace = {}

        self.bind("<Button-1>", self.clic)
        self.bind("<B1-Motion>", self.drag)

        dim = ceil(len(histoire)**0.5)
        i = j = 0
        depX = 50
        depY = 50

        for num in histoire:

            cadre = FrameNum(self, num, depX+i*60, depY+j*60)
            self.trace[num] = cadre

            i+=1
            if i == dim:
                i=0
                j+=1

    def clicOnCadre(self, num):

        if self.prem == None or self.der != None:

            self.prem = num
            self.der = None

            for numCadre in self.trace: self.itemconfig(self.trace[numCadre].idCadre, outline="black")

            self.itemconfig(self.trace[num].idCadre, outline="green")

        else:

            self.der = num

            for num in self.histoire.fromTo(self.prem, self.der): self.itemconfig(self.trace[num].idCadre, outline="green")

    def clic(self, event):

        self.scan_mark(event.x, event.y)

    def drag(self, event):

        self.scan_dragto(event.x, event.y, gain=1)

class AjoutTag(Tk):

    def __init__(self, createur, *args, **kw):

        Tk.__init__(self, *args, **kw)

        self.createur = createur

        self.indiqueFonction = Label(self, text="Ajouter un Tag")
        self.indiqueFonction.grid(row=0, column=0, columnspan=2)

        self.infosTag = FrameInfosTag(self)
        self.infosTag.grid(row=1, column=0)

        self.infosHistoire = CanInfosTag(self, self.createur.edit.histoire)
        self.infosHistoire.grid(row=1, column=1)

        self.boutApplique = Button(self, text="Appliquer", command=self.applique)
        self.boutApplique.grid(row=2, column=0)

        self.boutQuit = Button(self, text="Annuler", command=self.destroy)
        self.boutQuit.grid(row=2, column=1)

    def applique(self):

        if self.infosHistoire.prem == None or self.infosHistoire.der == None:
            pass
        else:
            inf = self.infosTag.getInfos()
            self.createur.edit.histoire.ajouteTag(TagGroupe(inf[0], self.infosHistoire.prem, self.infosHistoire.der, inf[1]))
            self.destroy()

class SuprTag(Tk):

    def __init__(self, createur, *args, **kw):

        Tk.__init__(self, *args, **kw)

        self.createur = createur

        self.choixTag = Listbox(self, height=len(self.createur.edit.histoire.tags))
        self.choixTag.grid(row=0, column=0, columnspan=2)

        self.choix = None
        self.dicoTag = {tag.nom:tag for tag in self.createur.edit.histoire.tags}

        for nom in self.dicoTag:
            self.choixTag.insert(END, nom)

        self.choixTag.bind("<<ListboxSelect>>", self.setChoix)

        self.boutConf = Button(self, text="Confirmer", command=self.confirmer)
        self.boutConf.grid(row=1, column=0)

        self.boutQuit = Button(self, text="Annuler", command=self.destroy)
        self.boutQuit.grid(row=1, column=1)

    def setChoix(self, event):
        self.choix = self.dicoTag[self.choixTag.get(self.choixTag.curselection())]

    def confirmer(self):

        if self.choix:

            self.createur.edit.histoire.supprimeTag(self.choix)
            self.destroy()

        else:
            pass

#####################################################################################################################################################

def sauverLEPROJET(h,chemin):
    global heros
    sauvegardeSimple(h,chemin+"/data/data.txt")
    gestion_inventaire.sauvegardeobj(p.touslesobjets,chemin+"/data/objets")
    try:
        gestion_inventaire.sauvegardeobj(heros,chemin+"/data/heros")
    except:
        montreinfo("Erreur","Attention, vous n'avez pas configuré votre héros !")
        creationHero()
    gestion_inventaire.sauvegardeobj(p.touslesmagasins,chemin+"/data/magasins")
    gestion_inventaire.sauvegardeobj(p.touslesennemis,chemin+"/data/ennemis")
    gestion_inventaire.sauvegardeobj(h.tags,chemin+"/data/tags")

class Projet(object):
    def __init__(self,nom,t,touslesmagasins,ennemis={}):
        self.nom=nom
        self.touslesobjets=t
        self.touslesennemis=ennemis
        self.touslesmagasins=touslesmagasins

touslesobjets=gestion_inventaire.ToutObjet()
p=Projet("Veillez créer un ouvrir un projet",touslesobjets,{})

def importimage():
    nomProjet=p.nom
    files=askopenfilenames(title="Importation d'images pour les insérer",filetypes=[('image .gif','.gif')],defaultextension='.gif')
    listefichiers=files
    for file in listefichiers:
        nom=os.path.basename(file)
        copyfile(file,nomProjet+"/data/image/"+nom)

def importson():
    nomProjet=p.nom
    files=askopenfilenames(title="Importation de sons au format wav",filetypes=[('audio .wav','.wav')],defaultextension='.wav')
    listefichiers=files
    for file in listefichiers:
        nom=os.path.basename(file)
        copyfile(file,nomProjet+"/data/son/"+nom)

def listeimages2(entree,t):
    file=askopenfilename(title="Choisir une image",filetypes=[('*.gif','*.gif')],defaultextension='.gif',initialdir=p.nom+"/data/image/",parent=t)
    if file!="" and file!=():
        file2=file.split("/")
        entree.delete(0, END)
        entree.insert(0,file2[-1])

def listeimages(entree,t):
    file=askopenfilename(title="Choisir une image",filetypes=[('*.gif','*.gif')],defaultextension='.gif',initialdir=p.nom+"/data/image/",parent=t)
    if file!="" and file!=():
        file2=file.split("/")
        entree.delete(0, END)
        entree.insert(0,file2[-3]+"/"+file2[-2]+"/"+file2[-1])

def supprdico(top,touslesobjets,objet,fonction):
    del(touslesobjets[objet])
    top.destroy()
    fonction()

def confirmeHeros(nom,constitution,force,img1,img2,img3,img4,fen):
    global heros
    heros = Personnage(nom, {"force":int(force), "constit":int(constitution), "agi":100, "intel":100}, [img1,img2,img3,img4], [])
    fen.destroy()

def confirmeEnnemi(nom,constitution,force,img1,img2,img3,fen):
    p.touslesennemis[nom]=Personnage(nom, {"force":int(force), "constit":int(constitution), "agi":100, "intel":100}, [img1,img2,img3,""], [])
    fen.destroy()

def creationEnnemi(name="",fenetreAncienne=""):
    try:
        fenetreAncienne.destroy()
    except: pass
    t=Toplevel()
    t.wm_attributes("-topmost", 1)
    Label(t,text="Nom de l'Ennemi").pack()
    nom=Entry(t, width=20)
    nom.pack()
    Label(t,text="Constitution").pack()
    spv=Entry(t, width=5)
    spv.pack()
    Label(t,text="Force").pack()
    satt=Entry(t, width=5)
    satt.pack()
    Label(t,text="Image statique").pack()
    frameimg1=Frame(t)
    frameimg1.pack()
    img1 = Entry(frameimg1, width=20)
    img1.pack(side=LEFT)
    Button(frameimg1,text="...",command=lambda :listeimages2(img1,t)).pack(side=LEFT)
    Label(t,text="Image d'attaque").pack()
    frameimg2=Frame(t)
    frameimg2.pack()
    img2 = Entry(frameimg2, width=20)
    img2.pack(side=LEFT)
    Button(frameimg2,text="...",command=lambda :listeimages2(img2,t)).pack(side=LEFT)
    Label(t,text="Image lorsque l'ennemi est blessé").pack()
    frameimg3=Frame(t)
    frameimg3.pack()
    img3 = Entry(frameimg3, width=20)
    img3.pack(side=LEFT)
    Button(frameimg3,text="...",command=lambda :listeimages2(img3,t)).pack(side=LEFT)
    Button(t,text="Confirmer",command=lambda: confirmeEnnemi(nom.get(),spv.get(),satt.get(),img1.get(),img2.get(),img3.get(),t)).pack()
    if nom!="":
        try:
            nom.insert(0,name)
            spv.insert(0,p.touslesennemis[name].force)
            satt.insert(0,p.touslesennemis[name].constit)
            img1.insert(0,p.touslesennemis[name].passif)
            img2.insert(0,p.touslesennemis[name].att)
            img3.insert(0,p.touslesennemis[name].blesse)
        except: pass

def creationHero():
    t=Toplevel()
    t.wm_attributes("-topmost", 1)
    Label(t,text="Nom du héros").pack()
    nom=Entry(t, width=20)
    nom.pack()
    Label(t,text="Constitution").pack()
    spv=Entry(t, width=5)
    spv.pack()
    Label(t,text="Force").pack()
    satt=Entry(t, width=5)
    satt.pack()
    Label(t,text="Image statique").pack()
    frameimg1=Frame(t)
    frameimg1.pack()
    img1 = Entry(frameimg1, width=20)
    img1.pack(side=LEFT)
    Button(frameimg1,text="...",command=lambda :listeimages2(img1,t)).pack(side=LEFT)
    Label(t,text="Image d'attaque").pack()
    frameimg2=Frame(t)
    frameimg2.pack()
    img2 = Entry(frameimg2, width=20)
    img2.pack(side=LEFT)
    Button(frameimg2,text="...",command=lambda :listeimages2(img2,t)).pack(side=LEFT)
    Label(t,text="Image lorsque le héros est blessé").pack()
    frameimg3=Frame(t)
    frameimg3.pack()
    img3 = Entry(frameimg3, width=20)
    img3.pack(side=LEFT)
    Button(frameimg3,text="...",command=lambda :listeimages2(img3,t)).pack(side=LEFT)
    Label(t,text="gif animé de l'attaque ultime du héros").pack()
    frameimg4=Frame(t)
    frameimg4.pack()
    img4 = Entry(frameimg4, width=20)
    img4.pack(side=LEFT)
    Button(frameimg4,text="...",command=lambda :listeimages2(img4,t)).pack(side=LEFT)
    Button(t,text="Confirmer",command=lambda: confirmeHeros(nom.get(),spv.get(),satt.get(),img1.get(),img2.get(),img3.get(),img4.get(),t)).pack()
    try:
        nom.insert(0,heros.getNom())
        spv.insert(0,heros.getForce())
        satt.insert(0,heros.getConstit())
        img1.insert(0,heros.passif)
        img2.insert(0,heros.att)
        img3.insert(0,heros.blesse)
        img4.insert(0,heros.ultime)
    except: pass
    #files=askopenfilenames(title="Importation d'images pour les insérer",filetypes=[('image .gif','.gif')],defaultextension='.gif')

listeajoutobj=[]

def listemagasins():
    t=Toplevel()
    t.wm_attributes("-topmost", 1)
    t.geometry("%dx%d+%d+%d" % ((250,500) + (10, 10)))
    cadre2=Frame(t, padx=5, pady=5,bg="#101080")
    cadre2.pack(fill=BOTH)
    menu=Label(cadre2,text="Liste des magasins existants",bg="#101080",fg="white",font="Tahoma 12 bold")
    menu.pack(fill=X)
    vbar = Scrollbar(t, orient=VERTICAL)
    vbar.pack(side=RIGHT,fill=Y)

    c = Canvas(t,yscrollcommand=vbar.set)
    c.pack(fill=BOTH)
    vbar.config(command=c.yview)
    fr = Frame(c)
    c.create_window(0, 0,  window=fr)
    if len(p.touslesennemis)==0:
        Label(t,text="Aucun magasin n'a été crée pour le moment.").pack()
    touslesmagasins=p.touslesmagasins
    for magasin in touslesmagasins:
        a=Frame(fr)
        a.pack(fill=X)
        Label(a,text=magasin).pack(side=LEFT)
        Button(a,text="Modifier",command=lambda t=t,touslesmagasins=touslesmagasins,magasin=magasin:nouveau_magasin(magasin,t)).pack(side=LEFT)
        Button(a,text="X",command=lambda t=t,touslesmagasins=touslesmagasins,magasin=magasin:(supprdico(t,touslesmagasins,magasin,listemagasins))).pack(side=LEFT)
    fr.update_idletasks()
    c.config(scrollregion=c.bbox("all"))

def ajout_objet_magasin(c,fr,nom="",prix=0):
    global listeajoutobj
    a=Frame(fr)
    a.pack(fill=X)
    Label(a,text="Nom : ").pack(side=LEFT)
    nomobj=Entry(a)
    nomobj.pack(side=LEFT)
    nomobj.insert(0,nom)
    Label(a,text=" Prix :").pack(side=LEFT)
    prixobj=Entry(a)
    prixobj.pack(side=LEFT)
    prixobj.insert(0,str(prix))
    listeajoutobj.append((nomobj,prixobj))
    Button(a,text="X",command=a.destroy).pack(side=LEFT)
    fr.update_idletasks()
    c.config(scrollregion=c.bbox("all"))

def sauvegardemagasin(nom,img,fen):
    global listeajoutobj
    if nom=='':
        montreinfo("Attention","Le nom du magasin est vide, cela pourrait créer des erreurs.")
        return None
    p.touslesmagasins[nom]=gestion_inventaire.Magasin(nom,img)
    for tupleobj in listeajoutobj:
        try:
            p.touslesmagasins[nom].ajout(p.touslesobjets[tupleobj[0].get()],int(tupleobj[1].get()))
        except:
            montreinfo("Erreur","Attention, l'objet '"+tupleobj[0].get()+"' n'existe pas, veuillez vérifier l'orthographe et les majuscules.","red")
            return None
    fen.destroy()

def update_magasin(nomobjet):
    '''Pour mettre à jour les magasins lorsqu'on supprime un objet.'''
    for magasin in p.touslesmagasins:
        if nomobjet in p.touslesmagasins[magasin]:
            p.touslesmagasins[magasin][nomobjet][0]=p.touslesobjets[nomobjet]

def nouveau_magasin(magasin="",anciennefenetre=""):
    global listeajoutobj
    try:anciennefenetre.destroy()
    except: pass
    listeajoutobj=[]
    t=Toplevel()
    t.wm_attributes("-topmost", 1)
    cadre2=Frame(t, padx=5, pady=5,bg="#101080")
    cadre2.pack(fill=BOTH)
    menu=Label(cadre2,text="Nouveau Magasin",bg="#101080",fg="white",font="Tahoma 12 bold")
    menu.pack()
    Label(t,text="Nom du magasin").pack()
    nom = Entry(t, width=20)
    nom.pack()
    Label(t,text="Image du magasin").pack()
    frameimg=Frame(t)
    frameimg.pack()
    img = Entry(frameimg, width=20)
    img.pack(side=LEFT)
    Button(frameimg,text="...",command=lambda :listeimages2(img,t)).pack(side=LEFT)
    vbar = Scrollbar(t, orient=VERTICAL)
    c = Canvas(t,yscrollcommand=vbar.set)
    fr = Frame(c)
    Button(t,text="Sauvegarder et quitter",command= lambda: sauvegardemagasin(nom.get(),img.get(),t)).pack()
    Button(t,text="Ajouter un objet au magasin",command = lambda : ajout_objet_magasin(c,fr)).pack()
    vbar.pack(side=RIGHT,fill=Y)
    c.pack(fill=BOTH)
    vbar.config(command=c.yview)
    c.create_window(0, 0,  window=fr)
    if magasin!= "":
        for objet in p.touslesmagasins[magasin]:
            ajout_objet_magasin(c,fr,objet,p.touslesmagasins[magasin][objet][1])
        nom.insert(0,magasin)
        img.insert(0,p.touslesmagasins[magasin].getImage())
    fr.update_idletasks()
    c.config(scrollregion=c.bbox("all"))

def nouveau_objet(inv,objet="",master=""):
    t=Toplevel()
    t.wm_attributes("-topmost", 1)
    cadre2=Frame(t, padx=5, pady=5,bg="#101080")
    cadre2.pack(fill=BOTH)
    actionvar=StringVar()
    value = StringVar()
    value.set(0)
    actionvar.set(0)
    menu=Label(cadre2,text="Nouveau Objet",bg="#101080",fg="white",font="Tahoma 12 bold")
    menu.pack()
    Label(t,text="Nom de l'objet").pack()
    nom = Entry(t, width=20)
    nom.pack()
    Label(t,text="Description (optionnelle)").pack()
    description = Text(t,height=3,width=40)
    description.pack()
    Label(t,text="Image").pack()
    frameimg=Frame(t)
    frameimg.pack()
    img = Entry(frameimg, width=20)
    img.pack(side=LEFT)
    Button(frameimg,text="...",command=lambda :listeimages(img,t)).pack(side=LEFT)
    Label(t,text="Actions").pack()
    fb2=Frame(t)
    fb2.pack()
    fb3=Frame(t)
    fb3.pack()
    act1 = Radiobutton(fb2, text="Points de vie", variable=actionvar, value=1,command=lambda:commande2(fb3,t,actionvar.get()))
    act2 = Radiobutton(fb2, text="Paragraphe", variable=actionvar, value=2,command=lambda:commande2(fb3,t,actionvar.get()))
    act3 = Radiobutton(fb2, text="Aucune", variable=actionvar, value=0,command=lambda:commande2(fb3,t,actionvar.get()))
    act1.pack(side=LEFT)
    act2.pack(side=LEFT)
    act3.pack(side=LEFT)
    Label(t,text="Condition d'utilisation").pack()
    fb=Frame(t)
    fb.pack()
    fb4=Frame(t)
    fb4.pack()
    bouton1 = Radiobutton(fb, text="Points de vie", variable=value, value=1,command=lambda:commande(fb4,t,value.get()))
    bouton2 = Radiobutton(fb, text="Or", variable=value, value=2,command=lambda:commande(fb4,t,value.get()))
    bouton3 = Radiobutton(fb, text="Paragraphe", variable=value, value=3,command=lambda:commande(fb4,t,value.get()))
    bouton4 = Radiobutton(fb, text="Objet", variable=value, value=4,command=lambda:commande(fb4,t,value.get()))
    bouton5 = Radiobutton(fb, text="Aucune", variable=value, value=0,command=lambda:commande(fb4,t,value.get()))
    bouton1.pack(side=LEFT)
    bouton2.pack(side=LEFT)
    bouton3.pack(side=LEFT)
    bouton4.pack(side=LEFT)
    bouton5.pack(side=LEFT)
    Button(t,text="Créer l'objet",command=lambda:creerObjet(t,inv,actionvar.get(),value.get(),nom.get(),img.get(),description.get('1.0', END))).pack()
    if objet!="":
        condition=inv[objet].getCondition()
        master.destroy()
        nom.insert(0,objet)
        description.insert(INSERT,inv[objet].getDescription())
        img.insert(0,inv[objet].getImage())
        if inv[objet][0]=="hp":
            actionvar.set(1)
            commande2(fb3,t,actionvar.get())
            entact.insert(0,str(inv[objet][1]))
        elif inv[objet][0]=="paragraphe":
            actionvar.set(2)
            commande2(fb3,t,actionvar.get())
            entact.insert(0,str(inv[objet][1]))
        else:
            actionvar.set(0)
            commande2(fb3,t,actionvar.get())

        if condition[0]=="hp":
            value.set(1)
            commande(fb4,t,value.get())
            entcond.insert(0,condition[1][0])
            entcond2.insert(0,condition[1][1])
        elif condition[0]=="or":
            value.set(2)
            commande(fb4,t,value.get())
            entcond.insert(0,condition[1][0])
            entcond2.insert(0,condition[1][1])

        elif condition[0]=="paragraphe":
            value.set(3)
            commande(fb4,t,value.get())
            entcond.insert(0,condition[1])
        elif condition[0]=="objet":
            value.set(4)
            commande(fb4,t,value.get())
            entcond.insert(0,condition[1])
        else:
            value.set(0)
            commande(fb4,t,value.get())

class Param(object):

    def __init__(self):
        import time,platform
        t=Toplevel()
        t.wm_attributes("-topmost", 1)
        t.geometry("%dx%d+%d+%d" % ((640,480) + (10, 10)))
        cadre2=Frame(t, padx=5, pady=5,bg="#101080")
        cadre2.pack(fill=BOTH)
        menu=Label(cadre2,text="▸ Informations du Projet",bg="#101080",fg="white",font="Tahoma 12 bold")
        menu.pack()
        cadre3=Frame(t)
        cadre3.pack()
        cadre4=Frame(t)
        cadre4.pack()
        cadre5=Frame(t)
        cadre5.pack()
        cadre6=Frame(t)
        cadre6.pack()
        cadre7=Frame(t)
        cadre7.pack()
        cadre8=Frame(t)
        cadre8.pack()
        cadre9=Frame(t)
        cadre9.pack()
        cadre10=Frame(t)
        cadre10.pack()
        cadre11=Frame(t)
        cadre11.pack()
        Label(cadre3,text="Nom du projet : "+p.nom.split("/")[-1]).pack(side=LEFT)
        Label(cadre4,text="Musique d'écran titre : fukuin.wav").pack(side=LEFT)
        Label(cadre5,text="Son de chargement de partie : loadgame.wav ").pack(side=LEFT)
        Label(cadre6,text="Son de nouvelle partie partie : newgame.wav").pack(side=LEFT)
        Label(cadre7,text="Musique du menu d'objets et de magasins : menu.wav").pack(side=LEFT)
        Label(cadre8,text="Images d'animation au menu : im1.gif/im2.gif").pack(side=LEFT)
        Label(cadre9,text="Images Titre : imtitre1.gif/imtitre2.gif").pack(side=LEFT)
        Label(cadre10,text="Image Titre (image fixe) : titre.gif").pack(side=LEFT)
        Label(t,text="Date de modifications :%s" % time.ctime(os.path.getmtime(p.nom))).pack()
        Label(t,text="Date de création : %s" % time.ctime(os.path.getctime(p.nom))).pack()
        Label(t,text="Version de python : "+platform.python_version()).pack()
        Label(t,text="OS : "+platform.system()).pack()
    def valider(self):
        pass

def destroy(*args):
    for x in args:
        try:
            x.destroy()
        except: pass

cond=entcond=cond2=entcond2=""

def commande(fb4,t,val):
    global cond,entcond,cond2,entcond2
    destroy(cond,entcond,cond2,entcond2)
    if val=="1":
        cond=Label(fb4,text="Possède des points de vie  (== , < , >)  ")
        cond.pack(side=LEFT)
        entcond=Entry(fb4,width=1)
        entcond.pack(side=LEFT)
        cond2=Label(fb4,text="à")
        cond2.pack(side=LEFT)
        entcond2=Entry(fb4,width=12)
        entcond2.pack(side=LEFT)

    if val=="2":
        cond=Label(fb4,text="Possède de l'or  (== , < , >)  ")
        cond.pack(side=LEFT)
        cond.pack(side=LEFT)
        entcond=Entry(fb4,width=1)
        entcond.pack(side=LEFT)
        cond2=Label(fb4,text="à")
        cond2.pack(side=LEFT)
        entcond2=Entry(fb4,width=12)
        entcond2.pack(side=LEFT)
    if val=="3":
        cond=Label(fb4,text="Est au paragraphe numéro : ")
        cond.pack(side=LEFT)
        entcond=Entry(fb4,width=5)
        entcond.pack(side=LEFT)
    if val=="4":
        cond=Label(fb4,text="Possède l'objet suivant :")
        cond.pack(side=LEFT)
        entcond=Entry(fb4,width=20)
        entcond.pack(side=LEFT)

act,entact,act2,entact2=0,0,0,0
def commande2(fb3,t,val):
    global act,entact,act2,entact2
    destroy(act,entact,act2,entact2)
    if val=="1":
        act=Label(fb3,text="Redonne ")
        act.pack(side=LEFT)
        entact=Entry(fb3,width=3)
        entact.pack(side=LEFT)
        act2=Label(fb3,text="%")
        act2.pack(side=LEFT)
        entact2=Label(fb3,text="de points de vie.")
        entact2.pack(side=LEFT)

    if val=="2":
        act=Label(fb3,text="Redirige vers le paragraphe numéro : ")
        act.pack(side=LEFT)
        entact=Entry(fb3,width=3)
        entact.pack(side=LEFT)

#eval
def creerObjet(t,inv,action,val,nom,img,description):
    if action=="1":
        tact="hp"
        action=int(entact.get())
    elif action=="2":
        tact="paragraphe"
        action=int(entact.get())
    else:
        tact=""
        action=0
    if val=="1":
        tcond="hp"
        accond=(entcond.get(),int(entcond2.get()))
    elif val=="2":
        tcond="or"
        accond=(entcond.get(),int(entcond2.get()))

    elif val=="3":
        tcond="paragraphe"
        accond=(int(entcond.get()))
    elif val=="4":
        tcond="objet"
        accond=(entcond.get())
    else:
        tcond=""
        accond=(0)

    obj=gestion_inventaire.Objet([tact,action],nom,img,description,[tcond,accond])
    p.touslesobjets.ajout(obj)
    update_magasin(nom)
    t.destroy()

def compiler(histoire):
    data="/data"
    module="/module"
    img="/image"
    son="/son"
    chemin="Tests"
    test=Toplevel()
    test.wm_attributes("-topmost", 1)
    text=Text(test,width=50,height=20)
    text.pack()
    try:
        shutil.rmtree("Tests/")
    except: pass
    try:

        text.insert(END,"Création des dossiers...")
        try:
            os.makedirs(chemin)
            copyfile('import/JEU.py',chemin+"/Tests.py")
            os.makedirs(chemin+data)
            os.makedirs(chemin+data+"/sauvegarde")
            shutil.copytree(p.nom+data+module,chemin+data+module)
            shutil.copytree(p.nom+data+img,chemin+data+img)
            shutil.copytree(p.nom+data+son,chemin+data+son)
            copyfile('import/settings.ini',chemin+data+"/settings.ini")
            text.insert(END,"Sauvegarde du fichier data.txt... \n")
            sauvegardeSimple(histoire,chemin+data+"/data.txt")
        except FileExistsError:
            shutil.rmtree("Tests/")
            test.destroy()
            compiler(histoire)
            return None
        text.insert(END,"\n Sauvegarde des objets... \n")
        gestion_inventaire.sauvegardeobj(p.touslesobjets,chemin+"/data/objets")
        try:
            text.insert(END,"\n Sauvegarde du héros... \n")
            gestion_inventaire.sauvegardeobj(heros,chemin+"/data/heros")
        except:
            text.insert(END," \n ATTENTION : Vous avez mal configuré votre héros")
        text.insert(END,"\n Sauvegarde des magasins et des ennemis... \n")
        gestion_inventaire.sauvegardeobj(p.touslesmagasins,chemin+"/data/magasins")
        gestion_inventaire.sauvegardeobj(p.touslesennemis,chemin+"/data/ennemis")
        sys.path.append("Tests")
        text.insert(END,"Ouverture du fichier... \n")
        os.chdir("Tests/")
        try:
            os.system("python3 Tests.py")
            os.system("python Tests.py")
            os.system("Tests.py")
        except:
            os.system("python Tests.py")

    except:
        text.insert(END,"*************Erreur************")
        text.insert(END,"\n"+ str(sys.exc_info()[0])+" : "+ str(sys.exc_info()[1])+"\n"+"Vous pouvez envoyer l'erreur à 21506187@etu.unicaen.fr")
        try: shutil.rmtree("Tests/")
        except: pass
    os.chdir("..")

def montreinfo(titre="Information",texte="",couleur="black"):
    '''Alternative à showinfo.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''
    fparam=Toplevel()
    fparam.wm_attributes("-topmost", 1)
    fparam.config(bg="#99ccff")
    fparam.overrideredirect(1)
    Label(fparam,text=titre,bg="#101080",fg="white",font="Tahoma 12 bold").pack(fill=BOTH)
    Label(fparam,text=texte,bg="#99ccff",fg=couleur,font="Tahoma 12 bold",wraplength=350).pack()
    Button(fparam, text="X",fg="white",bg="red", command=fparam.destroy).pack(side=RIGHT)
    fparam.update_idletasks()
    w,h = fparam.winfo_screenwidth(),fparam.winfo_screenheight()
    taille = tuple(int(_) for _ in fparam.geometry().split('+')[0].split('x'))
    x,y = w/2 - taille[0]/2,h/2 - taille[1]/2
    fparam.geometry("%dx%d+%d+%d" % (taille + (x, y)))

###############################################################################

f = Application(Histoire())


# %load q02_outlier_removal/build.py
# Default imports
import pandas as pd

# Data
ny_housing = pd.read_csv('data/train.csv')
# Selecting 4 most relevant variables from the dataset fot the Cleaning and Preprocessing.
housing_data = ny_housing[['MasVnrArea', 'GrLivArea', 'LotShape', 'GarageType', 'SalePrice']]

def outlier_removal(df):
    qv = 0.95
    df_qv = df.quantile(q=qv, axis=0, numeric_only=True, interpolation='linear')
    numeric_features = [a for a in range(len(df.dtypes)) if df.dtypes[a] in ['int64','float64']]
    numeric_df = df.iloc[:, numeric_features]
    for feature in numeric_df.columns:
        df=df.drop(df[df[feature]>df_qv[feature]].index)
    return df


from tkinter import *
import time

main = Tk()

LARGE_FONT= ("Verdana", 21)
SMALL_FONT= ("Verdana", 12)

global lastBoard
lastBoard = 0
global currentBoard
currentBoard = 0

#door Setting
blueKey = 0
redKey = 0
easterEggKey = 0

#all the gates
changer51 = 0
changer15 = 0
changer95 = 0
changer913 = 0
changer59 = 0

#collision lists
topList = []
bottomList = []
rightList = []
leftList = []
changeList = []
blueKeyList = []

#reset gate state
def gateReset():
    global changer51
    global changer15
    global changer95
    global changer59
    changer51 = 0
    changer15 = 0
    changer95 = 0
    changer59 = 0

#tag collector
def tagCollector():
    for n in board.find_withtag("top"):
        topList.append(n)

    for n in board.find_withtag("right"):
        rightList.append(n)

    for n in board.find_withtag("left"):
        leftList.append(n)

    for n in board.find_withtag("bottom"):
        bottomList.append(n)

    for n in board.find_withtag("changer"):
        changeList.append(n)

    for n in board.find_withtag("blueKeyObj"):
        blueKeyList.append(n)

    for n in board.find_withtag("changer51"):
        global changer51
        changeList.append(n)
        changer51 = 1

    for n in board.find_withtag("changer15"):
        global changer15
        changeList.append(n)
        changer15 = 1

    for n in board.find_withtag("changer95"):
        global changer95
        changeList.append(n)
        changer95 = 1

    for n in board.find_withtag("changer913"):
        global changer913
        changeList.append(n)
        changer913 = 1

    for n in board.find_withtag("changer59"):
        global changer59
        changeList.append(n)
        changer59 = 1

    print(board.find_withtag("changer59"))

#handles movement of character
def up(event):
    board.move(char, 0, -10)

def down(event):
    board.move(char, 0, 10)

def left(event):
    board.move(char, -10, 0)

def right(event):
    board.move(char, 10, 0)

#checks for collision
def checkCollision():
    x1, y1, x2, y2 = board.coords(char)
    result = board.find_overlapping(x1, y1, x2, y2)

    #bounce off of borders based on window
    #topBlock
    for n in topList:
        if result == (1, n):
            board.move(char, 0, 10)

    #rightBlock
    for n in rightList:
        if result == (1, n):
            board.move(char, -10, 0)

    #leftBlock
    for n in leftList:
        if result == (1, n):
            board.move(char, 10, 0)

    #bottom blocks
    for n in bottomList:
        if result == (1, n):
            board.move(char, 0, -10)

    #check for board changer
    for n in changeList:
        if result == (1, n):
            print("yuay")
            if changer51 == 1:
                board.delete("board5")
                board1()
                board.move(char, 0, 460)
                break

            elif changer15 == 1:
                board.delete("board1")
                board5()
                board.move(char, 0, -460)
                break

            elif changer95 == 1:
                board.delete("board9")
                board5()
                board.move(char, 0, 460)
                break

            elif changer913 == 1:
                board.delete("board9")
                board13()
                board.move(char, 0, -460)
                break

            elif changer59 == 1:
                board.delete("board5")
                board9()
                board.move(char, 0, -460)
                break

    #check for key overlapping
    for n in blueKeyList:
        if result == (1, n):
            global blueKey
            blueKey = 1
            board.delete("board5")
            board5()

    main.after(10, checkCollision)

main.geometry("500x500")

#LEAVE THIS base canvas and bindings
board = Canvas(main, width = 500, height = 500, background = 'white')
board.bind('<Up>', up)
board.bind('<Down>', down)
board.bind('<Left>', left)
board.bind('<Right>', right)
board.focus_set()
board.pack()

#LEAVE THIS character
char = board.create_rectangle(100, 100, 110, 110, fill = 'black')

def board1():
    global currentBoard
    currentBoard = 1

    gateReset()

    #borders
    topBlock = board.create_rectangle(0, 0, 500, 20, fill = 'darkblue', tags = ("board1", "top"))
    rightBlock = board.create_rectangle(480, 0, 500, 500, fill = 'darkblue', tags = ("board1", "right"))
    leftBlock = board.create_rectangle(0, 0, 20, 500, fill = 'darkblue', tags = ("board1", "left"))
    bottomLeftBlock = board.create_rectangle(0, 480, 150, 500, fill = 'darkblue', tags = ("board1", "bottom"))
    bottomRightBlock = board.create_rectangle(500, 480, 350, 500, fill = 'darkblue', tags = ("board1", "bottom"))

    #screen changer
    changer = board.create_rectangle(150, 500, 350, 490, fill = 'white', tags = ("board1", "changer", "changer15"))

    #text
    title = board.create_text(100, 10, fill = 'darkblue', font = LARGE_FONT, text = 'Congrats!', tags = "board1")
    board.move(title, 120, 100)
    text = board.create_text(100, 10, fill = 'darkblue', font = SMALL_FONT, text = 'You beat the game!\nBut did you find the easter egg?', tags = "board1")
    board.move(text, 150, 150)

    tagCollector()

    #adding appropriate objects to lists for collision

def board5():
    global currentBoard
    currentBoard = 5
    global blueKey

    gateReset()

    #borders
    topLeftBlock = board.create_rectangle(0, 0, 150, 20, fill = 'darkblue', tags = ("board5", "top"))
    topRightBlock = board.create_rectangle(500, 0, 350, 20, fill = 'darkblue', tags = ("board5", "top"))
    rightBlock = board.create_rectangle(480, 0, 500, 500, fill = 'darkblue', tags = ("board5", "right"))
    leftBlock = board.create_rectangle(0, 0, 20, 500, fill = 'darkblue', tags = ("board5", "left"))

    #castle
    castleLeft = board.create_rectangle(150, 0, 130, 150, fill = 'darkblue', tags = ("board5", "right"))
    castleRight = board.create_rectangle(370, 0, 350, 150, fill = 'darkblue', tags = ("board5", "left"))

    #gate and key check
    if blueKey == 0:
        castleGate = board.create_rectangle(150, 150, 350, 140, fill = 'blue', tags = ("board5", "top", "bgate"))
        blueKeyObj = board.create_rectangle(200, 300, 210, 310, fill = 'blue', tags = ("board5", "blueKeyObj"))

    #screen changer
    changerUp = board.create_rectangle(150, 0, 350, 10, fill = 'white', tags = ("board5", "changer51"))
    changerDown = board.create_rectangle(20, 500, 480, 490, fill = 'white', tags = ("board5", "changer59"))

    tagCollector()

def board9():
    global currentBoard
    currentBoard = 9

    gateReset()

    #borders
    topRightBlock = board.create_rectangle(480, 0, 500, 20, fill = 'darkblue', tags = ("board5", "right"))
    bottomRightBlock = board.create_rectangle(480, 500, 500, 480, fill = 'darkblue', tags = ("board5", "right"))
    leftBlock = board.create_rectangle(0, 0, 20, 500, fill = 'darkblue', tags = ("board5", "left"))

    #screen changer
    changerUp = board.create_rectangle(20, 0, 480, 10, fill = 'white', tags = ("board5", "changer", "changer95"))
    changerDown = board.create_rectangle(20, 500, 480, 490, fill = 'white', tags = ("board5", "changer", "changer913"))

    tagCollector()

board9()
checkCollision()

#runs the program
main.mainloop()

AP Comp sci ATARI Adventure/adventure pt2.pyw


#!/usr/bin/env python3
#
# Copyright (c) 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

import os
import unittest

from .lib import testcase

@testcase.eden_repo_test
class PersistenceTest:
    def populate_repo(self):
        self.repo.write_file('file_in_root', 'contents1')
        self.repo.write_file('subdir/file_in_subdir', 'contents2')
        self.repo.commit('Initial commit.')

    def edenfs_logging_settings(self):
        return {'eden.strace': 'DBG7', 'eden.fs.fuse': 'DBG7'}

    @unittest.skip('TODO: this is not fully implemented yet')
    def test_preserves_inode_numbers_and_timestamps_for_nonmaterialized_inodes_across_restarts(self):
        inode_paths = [
            'file_in_root',
            'subdir',  # we care about trees too
            'subdir/file_in_subdir',
        ]

        old_stats = [
            os.lstat(os.path.join(self.mount, path))
            for path in inode_paths]

        self.eden.shutdown()
        self.eden.start()

        new_stats = [
            os.lstat(os.path.join(self.mount, path))
            for path in inode_paths]

        for (path, old_stat, new_stat) in zip(inode_paths, old_stats, new_stats):
            self.assertEqual(old_stat.st_ino, new_stat.st_ino,
                             f"inode numbers must line up for path {path}")
            self.assertEqual(old_stat.st_atime, new_stat.st_atime,
                             f"atime must line up for path {path}")
            self.assertEqual(old_stat.st_mtime, new_stat.st_mtime,
                             f"mtime must line up for path {path}")
            self.assertEqual(old_stat.st_ctime, new_stat.st_ctime,
                             f"ctime must line up for path {path}")


#!/usr/bin/python3
import pygame
import numpy
from OpenGL.GL import *
from OpenGL.GLU import *
from pygame.locals import *
import tools
import gitter
import maus
import hud
import eventmanager

STARTLEVEL = 1

if __name__ == "__main__":

    font = tools.loadFont("GenBasR.ttf",(24,72))

    pygame.init()
    pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=128)

    #sounds laden:

    klick = pygame.mixer.Sound("klick.wav")
    gong = pygame.mixer.Sound("gong.wav")
    error = pygame.mixer.Sound("error.wav")

    dinfo = pygame.display.Info()
    video_flags = OPENGL | HWSURFACE | DOUBLEBUF | FULLSCREEN

    #ein paar variablen zu den seitenverhaeltnissen:
    SCREEN_RATIO = float(dinfo.current_w)/float(dinfo.current_h)  #16:9
    GITTER_RATIO = float(gitter.GITTER_W)/float(gitter.GITTER_H)

    FIELD_W_RATIO = (GITTER_RATIO*float(dinfo.current_h))/float(dinfo.current_w)

    pygame.display.set_mode((dinfo.current_w,dinfo.current_h),video_flags)
    tools.resize((dinfo.current_w,dinfo.current_h))
    tools.GlInit()
    tools.clearScreen()

    eManager = eventmanager.eventmanager()

    mausimaus = maus.maus()

    git = gitter.gitter((dinfo.current_w*FIELD_W_RATIO,dinfo.current_h),eManager,mausimaus,(klick,gong,error))

    sidebar = hud.hud((dinfo.current_w*FIELD_W_RATIO+2,2,dinfo.current_w-dinfo.current_w*FIELD_W_RATIO-4,dinfo.current_h-4),mausimaus,font)

    sidebar.setBgColor((0.0,0.0,0.5,0.1))

    clock = pygame.time.Clock()

    curLevel = STARTLEVEL

    #Hauptschleife:
    while not sidebar.isExitClicked():
        tools.clearScreen()

        ticktime = clock.tick(40)

        if sidebar.getMode() == hud.HUD_MODE_MAINMENU:

            #kleiner Effekt fuer die sidebar ;)

            x=mausimaus.getPos()[0]
            y=mausimaus.getPos()[1]

            if x > dinfo.current_w*FIELD_W_RATIO:
                x = dinfo.current_w*FIELD_W_RATIO
            r = 0.5-0.5/float(dinfo.current_w*FIELD_W_RATIO)*float(x)
            g = 0.5*float(y)/float(dinfo.current_h)
            b = float(x)/float(dinfo.current_w*FIELD_W_RATIO)

            sidebar.setBgColor((r,g,b,0.2))

            if sidebar.isPlayClicked():
                curLevel = STARTLEVEL
                sidebar.setMode(hud.HUD_MODE_PLAY)
                git.setLevel(curLevel)
                git.changeMode(gitter.MODE_SHOW)

                sidebar.setBgColor((0.0,0.0,0.3,0.2))

                sidebar.setMessage("Level " + str(curLevel))

        elif git.getMode() == gitter.MODE_SHOW:
            if git.readyToPlay():
                sidebar.setBgColor((0.3,0.0,0.1,0.2))
                git.changeMode(gitter.MODE_PLAY)
        elif git.getMode() == gitter.MODE_PLAY:
            if git.readyToShow():
                if git.madeMistake():
                    sidebar.setMode(hud.HUD_MODE_GAMEOVER)
                    sidebar.setBgColor((1.0,0.0,0.0,0.3))
                    sidebar.setMessage(str(curLevel-1) + " Level geschafft!")
                    git.changeMode(gitter.MODE_RANDOM)
                else:
                    curLevel += 1
                    if curLevel == gitter.GITTER_W*gitter.GITTER_H:
                        sidebar.setMode(hud.HUD_MODE_GAMEOVER)
                        sidebar.setMessage("alle Level geschafft!")
                        sidebar.setBgColor((0.0,1.0,0.0,0.3))
                        git.changeMode(gitter.MODE_RANDOM)
                    else:
                        git.setLevel(curLevel)
                        git.changeMode(gitter.MODE_SHOW)
                        sidebar.setBgColor((0.0,0.3,0.0,0.2))
                        sidebar.setMessage("Level " + str(curLevel))
        if sidebar.getMode() == hud.HUD_MODE_GAMEOVER:
            if sidebar.isOkClicked():
                sidebar.setMode(hud.HUD_MODE_MAINMENU)

        git.update()
        eventlist = eManager.getByType(KEYDOWN)
        for event in eventlist:
            if event.key == K_ESCAPE:
                exit()
        eManager.update()
        mausimaus.update()
        sidebar.update()

        tools.drawRect((0,0,dinfo.current_w,dinfo.current_h),0,(0,0,0,1))
        git.draw()
        sidebar.draw()

        pygame.display.flip()


# This program evaluates the running time of the mechanisms. With R changes.

import random
import math
import time
from copy import deepcopy
# Let there be 1000 users.
n = 1000
# Let the upper bound of the users' unit costs be 10.
k_max = 10.0
# Remaining tasks number is 1000.
rt = 1000
# the maximum payment to each user is 100.
Pm = 100
# Total budget of the platform is 10000.
R = 10000
# Platform utility
u_p = R
# The outputs will be stored in the text file loss_truthful_dis.txt
f = open('running_time_R.txt', 'w')
# Test samples 1000
n_test = 1000;

class SensingUser:
	'''the class for a user participating in sensing.'''
	k = 0;	# the unit cost
	upper_k = 0;	# the upper cost bound
	lower_k = 0;	# the lower cost bound
	s = 0;	# the user strategy
	n_tasks = 0;	# sensing task number of this user
	p = 0;	# payment to this user
	u = 0;	# user utility
	def __init__(self):
		# The initial s_i = kappa_i
		self.s = self.k = random.uniform(0.01, k_max)
		# additionally we have the cost bounds
		self.upper_k = self.k + random.uniform(0.01, k_max/2.0)
		self.lower_k = self.k - random.uniform(0.01, k_max/2.0)
		if self.upper_k > k_max:
			self.upper_k = k_max
		if self.lower_k < 0:
			self.lower_k = 0.01

n=100	# Initially we have 100 participating users.
R = 0
while R<10000:
	R = R + 1000;

	# our mechanism
	run_time = time.time()	# start timing...
	Pm = R/n
	remaining = rt	# remaining tasks

	for i in range(n_test):
		# Initialize the users.
		users = []
		for i in range(n):
			users.append(SensingUser())

		# Compute the d.
		d = k_max
		for user in users:
			if user.upper_k - user.lower_k < 2*d:
				d = (user.upper_k - user.lower_k)/2

		# Compute the m.
		m = 1
		while (m+1)*(m+2)*d < Pm:
			m = m+1

		# Recorrect the d
		if m*d > k_max:
			d = k_max / m

		# Let us compute the sensing time and the payment for each user.
		# Also we calculate each user utility and the platform utility.
		for user in users:
			user.n_tasks = m - math.floor(user.s / d)
			if user.n_tasks > remaining:
				user.n_tasks = 0
			if user.n_tasks < 0:
				user.n_tasks = 0
			user.p = d * user.n_tasks * (2*m + 1 - user.n_tasks) / 2.0
			user.u = user.p - user.k * user.n_tasks
			u_p = u_p - user.p
			remaining = remaining - user.n_tasks

	result1 = (time.time()-run_time)/n_test*1000

	# infocom 13 mechanism
	run_time = time.time()	# start timing...

	for i in range(n_test):
		remaining = rt	# remaining tasks
		# Initialize the users.
		users = []
		for i in range(n):
			users.append(SensingUser())

		# Let us compute the sensing time and the payment for each user.
		# Also we calculate each user utility and the platform utility.
		m = 100
		d = 0.1
		for user in users:
			sum = 0
			for k in range(n/100):
				sum = sum + users[k].s
			user.n_tasks = m - math.floor(sum / n / d*100)
			if user.n_tasks > remaining:
				user.n_tasks = 0
			if user.n_tasks < 0:
				user.n_tasks = 0
			user.p = d * user.n_tasks * (2*m + 1 - user.n_tasks) / 2.0
			user.u = user.p - user.k * user.n_tasks
			u_p = u_p - user.p
			remaining = remaining - user.n_tasks

	result2 = (time.time()-run_time)/n_test*1000

	# Output the statistical results.
	f.write('{0:f} {1:f} {2:f} \n'.format(R, result1, result2)) #ms

f.close()


#!/usr/bin/env python3

import os
import sys
import json

import steov

def clip (s, w=45):
    suffix = "..."
    if len(s) > w:
        return s[:w-len(suffix)] + suffix
    return s

def is_investment (account):
    prefixes = [
        "Fidelity",
        "ETrade",
        "Vanguard",
    ]
    return any(account.startswith(prefix) for prefix in prefixes)

transfers = [
    "Transfer",
    "Credit Card Payment",
]
income = [
    "Income",
    "Paycheck",
    "Interest Income",
]

ordering = [
    "Alliant Checking",
    "Citi 4511",
    "BofA Checking",
    "Venmo",
    "Alliant Savings",
]

def main (arg0, argv):
    global clip
    if sys.stdin.isatty():
        return "stdin is a tty. this probably isn't what you want. Try ./diff.bash"
    if argv[0] == "-v":
        verbose = True
        del argv[0]
    else:
        verbose = False
    prev, curr = argv
    if verbose:
        clip = steov.iden
    delta = 0.0
    max_name = 1
    max_amount = 1
    max_category = 1
    lines = []
    for i, line in enumerate(sys.stdin):
        if i == 0:
            lines.append((False, f"--- {prev}"))
            continue
        elif i == 1:
            lines.append((False, f"+++ {curr}"))
            continue
        line = line.rstrip("\r\n")
        transform = line.startswith("-") or line.startswith("+") or line.startswith(" ")
        if transform:
            transaction = steov.Anon({k.lower():v for k,v in json.loads(line[1:]).items() })
            if line.startswith("-"):
                delta -= transaction.amount
            elif line.startswith("+"):
                delta += transaction.amount
            transaction.prefix = line[0]
            transaction.name = clip(transaction.name)
            transaction.amount = format(transaction.amount, ",.2f")
            transaction.notes = " ".join(transaction.notes.split())
            max_name = max(max_name, len(transaction.name))
            max_amount = max(max_amount, len(transaction.amount))
            max_category = max(max_category, len(transaction.category))
            line = vars(transaction)
        lines.append((transform, line))
    for transform, line in lines:
        if transform:
            line.update(locals())
            print("{prefix}{date}  {name:{max_name}}  {amount:>{max_amount}}  {category:{max_category}}  {notes}".format(**line).rstrip())
        else:
            print(line)
    if lines:
        prefix = " "
        date = " " * len("0000-00-00")
        name = "Delta"
        amount = format(delta, ",.2f")
        category = ""
        print()
        print(f"{prefix}{date}  {name:{max_name}}  {amount:>{max_amount}}".rstrip())

if __name__ == "__main__":
    try:
        c = main(sys.argv[0], sys.argv[1:])
    except KeyboardInterrupt:
        c = 1
    except BrokenPipeError:
        c = 0
        sys.stderr.close()
    if c:
        sys.exit(c)


#!/usr/bin/env python3
"""Simulates pre-learned policy."""
import argparse
import sys

import joblib
import tensorflow as tf

from garage.sampler.utils import rollout
import gym
from gym import wrappers

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('--file', type=str,default='/home/dell/garage/examples/data/local/trpo-striker-400-dist-ctrl-touch/trpo_striker_400_dist_ctrl_touch_2020_04_17_15_58_02_0001/params.pkl', help='path to the snapshot file',)
    parser.add_argument('--max_path_length',
                        type=int,
                        default=1000,
                        help='Max length of rollout')
    parser.add_argument('--speedup', type=float, default=1, help='Speedup')
    args = parser.parse_args()
    with tf.compat.v1.Session() as sess:
        data = joblib.load(args.file)
        policy = data['algo'].policy
        #env = data['env']
        env = gym.make('Striker-v2')
        env =  wrappers.Monitor(env, "recording/striker_diff",resume=True)
        for epi in range(500):
            obs = env.reset()
            if epi%200 == 0:
                print("episode %i"%epi)
            step = 0
            while(1):
            #action = env.action_space.sample()
            # print("This is step %i"%i)
                action, _= policy.get_action(obs)
                obs, reward, done, info = env.step(action)
                if step == 0:
                    print(info)
                if done:
                    #print("done at step %i"%i)
                    #print("done")
                    break
                step+=1

    ##env.close()


from pyramid.view import (
    view_config,
    )
from pyramid.httpexceptions import (
    HTTPFound,
    )
from osipkd.models.apbd_anggaran import Tahun
from osipkd.models.base_model import App
from osipkd.views.base_view import BaseViews

########
# APP Home #
########
class vie_skpd(BaseViews):
    @view_config(route_name='skpd', renderer='templates/home.pt', permission='read')
    def view_app(self):
        session = self.request.session
        #tahun = App.get_by_kode('skpd').tahun
        #session['tahun'] = tahun
        tahun  = Tahun.get_by_tahun(session['tahun'])
        if not tahun:
            session.flash('Tahun Anggaran Belum di Set')
            return HTTPFound('ag-tahun')
        session['ag_step_id'] = tahun.status_apbd
        session['ag_step_nm'] = self._StatusAPBD(session['ag_step_id'])

        return dict(project='akuntansi')


import random

point_set = False
point = 0
break_loop = False

while not break_loop:
    die_one = random.randint(1, 6)
    die_two = random.randint(1, 6)
    die_sum = die_one + die_two
    print("I rolled " + str(die_sum))
    if not point_set:
        if die_sum in (2, 3, 12):
            print("Craps!")
            break_loop = True
        elif die_sum in (7, 11):
            print("Winner!")
            break_loop = True
        else:
            print("The point is " + str(die_sum))
            point = die_sum
            point_set = True
    else:
        if die_sum == point:
            print("Winner!")
            break_loop = True
        elif die_sum == 7:
            print("Craps!")
            break_loop = True

Programming Basics 4 Flow Control/craps.py


import logging
from argparse import ArgumentParser, Namespace
from socket import socket, AF_INET, SOCK_STREAM
from time import sleep
from contextlib import closing

from .proto import Message, Command, Status

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
TIMEOUT = 3

def connect(args: 'Namespace') -> 'socket':
    s = socket(AF_INET, SOCK_STREAM)
    s.settimeout(TIMEOUT)
    s.connect((args.address, args.port))
    return s

def send_task(args: 'Namespace', s: 'socket') -> None:
    if args.reverse:
        Message(command=Command.CS_POST_TASK_REVERSE, message=args.message).send(s)
    elif args.transposition:
        Message(command=Command.CS_POST_TASK_TRANSPOSITION, message=args.message).send(s)

def post_task_simple(args: 'Namespace') -> None:
    with closing(connect(args)) as s:
        send_task(args, s)
        task_id = Message.recv(s).task_id
    logging.info('Monitoring task with task_id {}'.format(task_id))
    while True:
        with closing(connect(args)) as s:
            Message(command=Command.CS_GET_TASK_STATUS, task_id=task_id).send(s)
            status = Message.recv(s).status
        if status == Status.NOT_FOUND:
            logging.info('Task with task_id {} not found'.format(task_id))
            return
        elif status == Status.QUEUE:
            logging.info('Task with task_id {} now in queue'.format(task_id))
        elif status == Status.PROGRESS:
            logging.info('Task with task_id {} now in progress'.format(task_id))
        elif status == Status.COMPLETED:
            logging.info('Task with task_id {} completed'.format(task_id))
            with closing(connect(args)) as s:
                Message(command=Command.CS_GET_TASK_RESULT, task_id=task_id).send(s)
                result = Message.recv(s)
            if result.status == Status.NOT_FOUND:
                logging.info('Result for task with task_id {} not found'.format(task_id))
            else:
                logging.info('Result for task with task_id {} is {}'.format(task_id, result.message))
            return
        sleep(1)

def post_task_packet(args: 'Namespace') -> None:
    with closing(connect(args)) as s:
        send_task(args, s)
        task_id = Message.recv(s).task_id
        logging.info('New task have task_id {}'.format(task_id))

def post_task(args: 'Namespace') -> None:
    """Process post new task"""
    if args.simple:
        post_task_simple(args)
    elif args.packet:
        post_task_packet(args)
    else:
        raise ValueError()

def status_task(args: 'Namespace') -> None:
    statuses = {
        Status.NOT_FOUND: 'Task with task_id {} NOT FOUND',
        Status.QUEUE: 'Task with task_id {} in QUEUE',
        Status.PROGRESS: 'Task with task_id {} in PROGRESS',
        Status.COMPLETED: 'Task with task_id {} COMPLETED',
    }
    with closing(connect(args)) as s:
        Message(command=Command.CS_GET_TASK_STATUS, task_id=args.task_id).send(s)
        status = Message.recv(s).status
        logging.info(statuses[status].format(args.task_id))

def result_task(args: 'Namespace') -> None:
    with closing(connect(args)) as s:
        Message(command=Command.CS_GET_TASK_RESULT, task_id=args.task_id).send(s)
        result = Message.recv(s)
        if result.status == Status.NOT_FOUND:
            logging.info('Result for task with task_id {} NOT FOUND'.format(args.task_id))
        else:
            logging.info('Result for task with task_id {} is {}'.format(args.task_id, result.message))

def main() -> None:
    """Show menu to user"""
    parser = ArgumentParser()

    parser.add_argument('address', help='Server IP address', metavar='IP')
    parser.add_argument('port', type=int, help='Server port', metavar='PORT')

    subparsers = parser.add_subparsers(help='Action')
    subparsers.required = True
    subparsers.metavar = 'ACTION'

    parser_post_task = subparsers.add_parser('post', help='Post new tast')
    parser_post_task.set_defaults(func=post_task)
    parser_post_task.add_argument('message', help='Message for processing', metavar='MSG')
    group_mode = parser_post_task.add_mutually_exclusive_group(required=True)
    group_mode.add_argument('--simple', action='store_true', help='Post task in simple mode')
    group_mode.add_argument('--packet', action='store_true', help='Post task in packet mode')
    group_type = parser_post_task.add_mutually_exclusive_group(required=True)
    group_type.add_argument('--reverse', action='store_true', help='Post reverse task')
    group_type.add_argument('--transposition', action='store_true', help='Post transposition task')

    parser_status_task = subparsers.add_parser('status', help='Get tast status')
    parser_status_task.set_defaults(func=status_task)
    parser_status_task.add_argument('task_id', type=int, help='Task ID for request', metavar='TASK_ID')

    parser_result_task = subparsers.add_parser('result', help='Get task result')
    parser_result_task.set_defaults(func=result_task)
    parser_result_task.add_argument('task_id', type=int, help='Task ID for request', metavar='TASK_ID')

    args = parser.parse_args()
    try:
        args.func(args)
    except Exception:
        logging.exception('main')

if __name__ == '__main__':
    main()


"""
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
"""
class Solution:
    def findMin(self, nums):
        for i in range(len(nums) - 1):
            if nums[i+1] < nums[i]:
                return nums[i+1]
        else:
             return nums[0]

寻找旋转排序数组中的最小值.py

寻找旋转排序数组中的最小值.py