import tkinter as tk
from PIL import ImageTk, Image

RaizComic = tk.Tk()
RaizComic.title("¡Comics!")
RaizComic.iconbitmap("Icono.ico")
RaizComic.geometry('600x600')
image2 = Image.open('marvelydc.png')
image1 = ImageTk.PhotoImage(image2)
background_Label = tk.Label(RaizComic, image=image1)
background_Label.image1 = image1
background_Label.place(x=0, y=0, height=600, width=600)

Bienvenida = tk.Label(RaizComic, text = '¡BIENVENIDOS!')
Bienvenida.place(x=150, y= 10)
Bienvenida.config(bg = 'black', fg = 'white', justify = 'right', font = ('Comic Sans', 30))

def salir():
    RaizComic.destroy()

#----------------------MARVEL.................................
def marvelbo():
    elframe = tk.Toplevel()
    elframe.geometry('790x600')
    elframe.title('Comics de Marvel')
    #w=350
    #h=460

    scrollbar = tk.Scrollbar(elframe)
    c = tk.Canvas(elframe, yscrollcommand=scrollbar.set)
    scrollbar.config(command= c.yview)
    scrollbar.pack(side= tk.RIGHT, fill= tk.Y)
    elframe = tk.Frame(c)
    c.pack(side='left', fill='both', expand= True)
    c.create_window(0,0, window= elframe, anchor= 'nw')
    imagefondo = Image.open('fondo.png')
    imagefondo1 = ImageTk.PhotoImage(imagefondo)
    background_Label = tk.Label(elframe, image=imagefondo1)
    background_Label.imagefondo1 = imagefondo1
    background_Label.place(x=0, y=0, height=1120, width=950)

    #ImagenBienvenida = tk.PhotoImage(file = 'mavellogo.png')
    #PrintBienvenida_marvel = tk.Label(elframe, image = ImagenBienvenida)
    #PrintBienvenida_marvel.grid(row=0, columnspan=2)

    ImagenBienvenida = tk.PhotoImage(file = 'marvellogo1.png')
    PrintBienvenida_marvel = tk.Label(elframe, image = ImagenBienvenida)
    PrintBienvenida_marvel.grid(row=0, column=1)

    ImagenBienvenida1 = tk.PhotoImage(file = 'marvellogo2.png')
    PrintBienvenida_marvel1 = tk.Label(elframe, image = ImagenBienvenida1)
    PrintBienvenida_marvel1.grid(row=0, column=2)

#------------------Spiderman-----------------------------
    ImagenSpiderman = tk.PhotoImage(file = 'marvel/marvel-spider.png')
    PrintSpiderman = tk.Label(elframe, image = ImagenSpiderman)
    PrintSpiderman.grid(row =1, column = 0)

    tk.Label(elframe, font=8,
        text=("Spiderman\n Amazing Fantasy #15\n"
            "Peter Parker\n"
            "Marvel Comics")).grid(row=1, column=1)

    def BotonSpiderman():
        spider_man = tk.Toplevel()
        spider_man.geometry('700x430')
        spider_man.title('¡Spider-Man!')
        spider_man.configure(background='yellow')

        def salir_ventana():
            spider_man.destroy()

        ImagenSpiderman1 = tk.PhotoImage(file = 'marvelfotos/spiderman2.png')
        PrintSpiderman1 = tk.Label(spider_man, image = ImagenSpiderman1)
        PrintSpiderman1.grid(row=0, column=0)

        tk.Label(spider_man, font=('Comic Sans', 18),
            text=("Spiderman\n Amazing Fantasy #15\n"
                "Peter Parker\n"
                "Marvel Comics\n"
                "gran fuerza\n agilidad\n"
                " Un sentido arácnido\n"
                "que le permite saber si\n"
                "un peligro se cierne sobre él\n"
                "antes de que suceda.\n")).place(x= 365, y= 30)
        botonsalir=tk.Button(spider_man, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 465, y =370)
        PrintSpiderman1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonSpiderman)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =300)

#-------------------Capitan america---------------------------------
    ImagenCapi = tk.PhotoImage(file = 'marvel/marvel-captain.png')
    PrintCapi = tk.Label(elframe,image = ImagenCapi)
    PrintCapi.grid(row = 2, column =0)

    tk.Label(elframe, font=8,
        text=("Capitan America\n Captain America Comics #1\n"
            "Steve Rogers\n"
            "Marvel Comics")).grid(row=2, column=1)

    def BotonCapi():
        capitan = tk.Toplevel()
        capitan.geometry('800x460')
        capitan.title('¡Capitan America!')
        capitan.configure(background='royal blue')

        def salir_ventana():
            capitan.destroy()

        ImagenCapi1 = tk.PhotoImage(file = 'marvelfotos/cap2.png')
        PrintCapi1 = tk.Label(capitan,image = ImagenCapi1)
        PrintCapi1.grid(row = 0, column =0)

        tk.Label(capitan, font=('Comic Sans', 18),
            text=("Capitan America\n Captain America Comics #1\n"
                "Steve Rogers\n"
                "Marvel Comics\n"
                "Gran habilidad con armas de fuego\n"
                "con el martillo Mjolnir y con su escudo\n"
                "inmune a gases y enfermedades\n"
                "Genio táctico\n"
                "acróbata experto\n")).place(x=375, y=100)
        botonsalir=tk.Button(capitan, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 530, y =390)
        PrintCapi1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonCapi)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =490)

#-------------------Iron man----------------------------------------
    ImagenIron = tk.PhotoImage(file = 'marvel/marvel-iron.png')
    PrintIron = tk.Label(elframe,image = ImagenIron)
    PrintIron.grid(row = 4, column =0)

    tk.Label(elframe, font=8,
        text=("Iron Man\n Tales of Suspense #39\n"
            "Tony Stark\n"
            "Marvel Comics")).grid(row=4, column=1)

    def BotonIron():
        iron = tk.Toplevel()
        iron.geometry('850x450')
        iron.title('¡Iron Man!')
        iron.configure(background='red4')

        def salir_ventana():
            iron.destroy()

        ImagenIron1 = tk.PhotoImage(file = 'marvelfotos/iron1.png')
        PrintIron1 = tk.Label(iron,image = ImagenIron1)
        PrintIron1.grid(row = 0, column =0)

        tk.Label(iron, font=('Comic Sans', 18),
            text=("Iron Man\n Tales of Suspense #39\n"
                "Tony Stark\n"
                "Marvel Comics\n"
                "Genio, filantropo,\n"
                "Playboy\n"
                "Repulsor de energía y misiles de proyección\n"
                "Uso de equipamiento\n"
                "Dispositivos y armamento de alta tecnología.")).place(x=350, y=80)
        botonsalir=tk.Button(iron, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 530, y =390)
        PrintIron1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonIron)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =685)

#----------------------Daredevil--------------------------------------
    ImagenDaredevil = tk.PhotoImage(file = 'marvel/marvel-daredevil.png')
    PrintDaredevil = tk.Label(elframe, image = ImagenDaredevil)
    PrintDaredevil.grid(row = 6, column = 0)

    tk.Label(elframe, font=8,
        text=("Daredevil\n Daredevil #1\n"
            "Matthew Michael Murdock\n"
            "Marvel Comics")).grid(row=6, column=1)

    def BotonDare():
        daredevil = tk.Toplevel()
        daredevil.geometry('810x485')
        daredevil.title('¡Daredevil!')
        daredevil.configure(background='indian red')

        def salir_ventana():
            daredevil.destroy()

        ImagenDaredevil1 = tk.PhotoImage(file = 'marvelfotos/daredevil1.png')
        PrintDaredevil1 = tk.Label(daredevil, image = ImagenDaredevil1)
        PrintDaredevil1.grid(row = 0, column = 0)

        tk.Label(daredevil, font=('Comic Sans', 18),
            text=("Daredevil\n Daredevil #1\n"
                "Matthew Michael Murdock\n"
                "Marvel Comics\n"
                "Ecolocalización radar cerebral\n"
                "que le permite ver a pesar de estar ciego\n"
                "Tirador de precisión perfecta\n"
                "Carencia del sentido del miedo\n")).place(x=360, y=100)
        botonsalir=tk.Button(daredevil, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 530, y =420)
        PrintDaredevil1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonDare)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =875)

#-----------------------Hulk------------------------------------------
    ImagenHulk = tk.PhotoImage(file = 'marvel/marvel-hulk.png')
    PrintHulk = tk.Label(elframe, image = ImagenHulk)
    PrintHulk.grid(row = 8, column = 0)

    tk.Label(elframe, font=8,
        text=("Hulk\n The Incredible Hulk #1\n"
            "Bruce Banner\n"
            "Marvel Comics")).grid(row=8, column=1)

    def BotonHulk():
        Hulk = tk.Toplevel()
        Hulk.geometry('800x485')
        Hulk.title('¡Hulk!')
        Hulk.configure(background='DarkOliveGreen4')

        def salir_ventana():
            Hulk.destroy()

        ImagenHulk1 = tk.PhotoImage(file = 'marvelfotos/hulk1.png')
        PrintHulk1 = tk.Label(Hulk, image = ImagenHulk1)
        PrintHulk1.grid(row = 0, column = 0)

        tk.Label(Hulk, font=('Comic Sans', 18),
            text=("Hulk\n The Incredible Hulk #1\n"
                "Bruce Banner\n"
                "Marvel Comics\n"
                "Regeneración\n"
                "Capacidad Pulmonar\n"
                "Hulk se adapta a cualquier ambiente\n"
                "Inmortalidad\n"
                " Super velocidad.\n")).place(x=380, y=100)
        botonsalir=tk.Button(Hulk, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 530, y =420)
        PrintHulk1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonHulk)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =1065)

#-----------------------Thor---------------------------------
    ImagenThor = tk.PhotoImage(file = 'marvel/marvel-thor.png')
    PrintThor = tk.Label(elframe, image = ImagenThor)
    PrintThor.grid(row = 1, column = 2)

    tk.Label(elframe, font=8,
        text=("Thor\n Journey into Myster #83\n"
            "Thor Odinson\n"
            "Marvel Comics")).grid(row=1, column=3)

    def BotonThor():
        thor = tk.Toplevel()
        thor.geometry('700x500')
        thor.title('¡Thor !')
        thor.configure(background='RoyalBlue1')

        def salir_ventana():
            thor.destroy()

        ImagenThor1 = tk.PhotoImage(file = 'marvelfotos/thor1.png')
        PrintThor1 = tk.Label(thor, image = ImagenThor1)
        PrintThor1.grid(row = 0, column = 0)

        tk.Label(thor, font=('Comic Sans', 18),
            text=("Thor\n Journey into Myster #83\n"
                "Thor Odinson\n"
                "Marvel Comics\n"
                "dios del trueno\n"
                "Fuerza sobrehumana\n"
                "velocidad\n"
                "durabilidad\n")).place(x=415, y=120)
        botonsalir=tk.Button(thor, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 490, y =440)
        PrintThor1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonThor)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 560, y =300)

#-----------------------Wolverine---------------------------------
    ImagenWolverine = tk.PhotoImage(file = 'marvel/marvel-wolverine.png')
    PrintWolverine = tk.Label(elframe, image = ImagenWolverine)
    PrintWolverine.grid(row = 2, column = 2)

    tk.Label(elframe, font=8,
        text=("Wolverine\n The Incredible Hulk #180\n"
            "James Howlett\n"
            "Marvel Comics")).grid(row=2, column=3)

    def BotonWol():
        wolve = tk.Toplevel()
        wolve.geometry('910x500')
        wolve.title('¡Wolverine!')
        wolve.configure(background='yellow3')

        def salir_ventana():
            wolve.destroy()

        ImagenWolverine1 = tk.PhotoImage(file = 'marvelfotos/wolve1_.png')
        PrintWolverine1 = tk.Label(wolve, image = ImagenWolverine1)
        PrintWolverine1.grid(row = 0, column = 0)

        tk.Label(wolve, font=('Comic Sans', 14),
            text=("Wolverine\n The Incredible Hulk #180\n"
                "James Howlett\n"
                "Marvel Comics\n"
                "Es un mutante que posee sentidos afinados a los animales\n"
                "Capacidades físicas mejoradas\n"
                "Poderosa capacidad de regeneración\n"
                "Tres garras retráctiles en cada mano.\n")).place(x=400, y=130)
        botonsalir=tk.Button(wolve, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 600, y =430)
        PrintWolverine1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonWol)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 560, y =490)

#---------------------Cyclope---------------------------------------
    ImagenCyclops = tk.PhotoImage(file = 'marvel/marvel-cyclops.png')
    PrintCyclops = tk.Label(elframe, image = ImagenCyclops)
    PrintCyclops.grid(row = 4, column = 2)

    tk.Label(elframe, font=8,
        text=("Cyclops\n X-Men #1\n"
            "Scott Summers\n"
            "Marvel Comics")).grid(row=4, column=3)

    def BotonCyclo():
        clyclo = tk.Toplevel()
        clyclo.geometry('850x460')
        clyclo.title('¡Clyclops!')
        clyclo.configure(background='bisque3')

        def salir_ventana():
            clyclo.destroy()

        ImagenCyclops1 = tk.PhotoImage(file = 'marvelfotos/cyclops.png')
        PrintCyclops1 = tk.Label(clyclo, image = ImagenCyclops1)
        PrintCyclops1.grid(row = 0, column = 0)

        tk.Label(clyclo, font=('Comic Sans', 14),
            text=("Cyclops\n X-Men #1\n"
                "Scott Summers\n"
                "Marvel Comics\n"
                "es un mutante \n"
                "con la capacidad de proyectar potentes\n"
                "explosiones de fuerza a través de sus ojos\n"
                "Es visualmente distintivo\n"
                "su visor de rubí de cuarzo,\n"
                "lo que le confiere el nombre clave de Cyclops (Cíclope).\n")).place(x=360, y=100)
        botonsalir=tk.Button(clyclo, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 560, y =390)
        PrintCyclops1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonCyclo)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 560, y =685)

#----------------------Hawkeye------------------------------------
    ImagenHawkeye = tk.PhotoImage(file = 'marvel/marvel-hawkeye.png')
    PrintHawkeye = tk.Label(elframe, image = ImagenHawkeye)
    PrintHawkeye.grid(row = 6, column = 2)

    tk.Label(elframe, font=8,
        text=("Hawkeye\n Tales of Suspense #57\n"
            "Clinton Francis Barton\n"
            "Marvel Comics")).grid(row=6, column=3)

    def BotonHaw():
        haw = tk.Toplevel()
        haw.geometry('700x380')
        haw.title('¡Hawkeye!')
        haw.configure(background='purple')

        def salir_ventana():
            haw.destroy()

        ImagenHawkeye1 = tk.PhotoImage(file = 'marvelfotos/Hawkeye.png')
        PrintHawkeye1 = tk.Label(haw, image = ImagenHawkeye1)
        PrintHawkeye1.grid(row = 0, column = 0)

        tk.Label(haw, font=('Comic Sans', 14),
            text=("Hawkeye\n Tales of Suspense #57\n"
                "Clinton Francis Barton\n"
                "Marvel Comics\n"
                "es un eximio arquero\n"
                "y suele utilizar muchas flechas con trucos\n"
                "ademas de las corrientes\n"
                "Puede apuntar una flecha con perfecta\n"
                "precision desde cualquier angulo.\n")).place(x=300, y=80)
        botonsalir=tk.Button(haw, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 420, y =320)
        PrintHawkeye1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonHaw)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 560, y =875)

#---------------------Silver surfer------------------------------
    ImagenSilver = tk.PhotoImage(file = 'marvel/marvel-silver.png')
    PrintSilver = tk.Label(elframe, image = ImagenSilver)
    PrintSilver.grid(row = 8, column = 2)

    tk.Label(elframe, font=8,
        text=("Silver Surfer\n The Fantastic Four #48\n"
            "Norrin Radd\n"
            "Marvel Comics")).grid(row=8, column=3)

    def BotonSilver():
        sil = tk.Toplevel()
        sil.geometry('700x356')
        sil.title('¡Silver Surfer!')
        sil.configure(background='gray80')

        def salir_ventana():
            sil.destroy()

        ImagenSilver1 = tk.PhotoImage(file = 'marvelfotos/Silver_Surfer.png')
        PrintSilver1 = tk.Label(sil, image = ImagenSilver1)
        PrintSilver1.grid(row = 0, column = 0)

        tk.Label(sil, font=('Comic Sans', 14),
            text=("Silver Surfer\n The Fantastic Four #48\n"
                "Norrin Radd\n"
                "Marvel Comics\n"
                "poderes cósmicos,gracias a que Galactus\n"
                "se los concedió,como heraldo \n"
                "Tiene la capacidad de reunir \n"
                "energía cósmica del ambiente\n"
                "para concentrarla en su cuerpo\n"
                "a voluntad o lanzarla violentamente.\n")).place(x=300, y=50)
        botonsalir=tk.Button(sil, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 440, y =300)
        PrintSilver1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonSilver)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 560, y =1065)

    elframe.update()
    c.config(scrollregion=c.bbox('all'))
    elframe.mainloop()

#--------------------DC----------------------------------------
def dcboton():
    elframe = tk.Toplevel()
    elframe.geometry('780x600')
    elframe.title('Comics de DC')

    scrollbar = tk.Scrollbar(elframe)
    c = tk.Canvas(elframe, yscrollcommand=scrollbar.set)
    scrollbar.config(command= c.yview)
    scrollbar.pack(side= tk.RIGHT, fill= tk.Y)
    elframe = tk.Frame(c)
    c.pack(side='left', fill='both', expand= True)
    c.create_window(0,0, window= elframe, anchor= 'nw')
    imagefondodc = Image.open('dcfondo.png')
    imagefondodc1 = ImageTk.PhotoImage(imagefondodc)
    background_Label = tk.Label(elframe, image=imagefondodc1)
    background_Label.imagefondodc1 = imagefondodc1
    background_Label.place(x=0, y=0, height=1120, width=950)

    ImagenBienvenidaDC = tk.PhotoImage(file = 'dc1.png')
    PrintBienvenida_dc = tk.Label(elframe, image = ImagenBienvenidaDC)
    PrintBienvenida_dc.grid(row=0, column=1)

    ImagenBienvenidaDC1 = tk.PhotoImage(file = 'dc2.png')
    PrintBienvenida_dc1 = tk.Label(elframe, image = ImagenBienvenidaDC1)
    PrintBienvenida_dc1.grid(row=0, column=2)

#----------------------Superman---------------------
    ImagenSuperman = tk.PhotoImage(file = 'dc/dc-superman.png')
    PrintSpiderman = tk.Label(elframe, image = ImagenSuperman)
    PrintSpiderman.grid(row =1, column = 0)

    tk.Label(elframe, font=8,
        text=("Superman\n Action Comics #1\n"
            "kal-El\n"
            "DC Comics")).grid(row=1, column=1)

    def BotonSuper():
        superman = tk.Toplevel()
        superman.geometry('700x500')
        superman.title('¡Superman!')
        superman.configure(background='black')

        def salir_ventana():
            superman.destroy()

        ImagenSuperman1 = tk.PhotoImage(file = 'dcfotos/tomsuper.png')
        PrintSuperman1 = tk.Label(superman, image = ImagenSuperman1)
        PrintSuperman1.grid(row=0, column=0)

        tk.Label(superman, font=('Comic Sans', 18),
            text=("Superman\n Action Comics #1\n"
                "kal-El\n"
                "DC Comics\n"
                "súper fuerza\n"
                "invulnerabilidad\n"
                "la capacidad de volar\n"
                "visión calorífica\n"
                "el aliento helado.\n")).place(x=410, y=100)
        botonsalir=tk.Button(superman, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 480, y =430)
        PrintSuperman1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonSuper)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =290)

#----------------Wonder woman----------------------------------
    ImagenWonder = tk.PhotoImage(file = 'dc/dc-wonder.png')
    PrintWonder = tk.Label(elframe, image = ImagenWonder)
    PrintWonder.grid(row =2, column = 0)

    tk.Label(elframe, font=8,
        text=("Wonder Woman\n All Star Comics #8\n"
            "Princess Diana\n"
            "DC Comics")).grid(row=2, column=1)

    def BotonWonder():
        wonder = tk.Toplevel()
        wonder.geometry('700x400')
        wonder.title('¡Wonder Woman!')
        wonder.configure(background='medium spring green')

        def salir_ventana():
            wonder.destroy()

        ImagenWonder1 = tk.PhotoImage(file = 'dcfotos/wonder.png')
        PrintWonder1 = tk.Label(wonder, image = ImagenWonder1)
        PrintWonder1.grid(row =0, column = 0)

        tk.Label(wonder, font=('Comic Sans', 14),
            text=("Wonder Woman\n All Star Comics #8\n"
                "Princess Diana\n"
                "DC Comics\n"
                "Invulnerabilidad al fuego\n"
                "Agilidad superhumana\n"
                "Teletransportación dimensional\n"
                "Durabilidad superhumana\n"
                "Comunicación con animales\n"
                "Multi-lenguaje.\n")).place(x=350, y=60)
        botonsalir=tk.Button(wonder, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 435, y =340)
        PrintWonder1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonWonder)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =480)

#--------------------Robin nightwing-----------------------
    ImagenRobin = tk.PhotoImage(file = 'dc/dc-robin.png')
    PrintRobin = tk.Label(elframe, image = ImagenRobin)
    PrintRobin.grid(row =4, column = 0)

    tk.Label(elframe, font=8,
        text=("Robin/Nightwing\n Detective Comics #38\n"
            "Dick Grayson\n"
            "DC Comics")).grid(row=4, column=1)

    def BotonRobin():
        robin = tk.Toplevel()
        robin.geometry('800x506')
        robin.title('¡Robin/Nightwing!')
        robin.configure(background='honeydew4')

        def salir_ventana():
            robin.destroy()

        ImagenRobin1 = tk.PhotoImage(file = 'dcfotos/robin.png')
        PrintRobin1 = tk.Label(robin, image = ImagenRobin1)
        PrintRobin1.grid(row =0, column = 0)

        tk.Label(robin, font=('Comic Sans', 18),
            text=("Robin/Nightwing\n Detective Comics #38\n"
                "Dick Grayson\n"
                "DC Comics\n"
                "es experto en las artes marciales\n"
                "crea armas simples\n")).place(x=425, y=150)
        botonsalir=tk.Button(robin, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 550, y =430)
        PrintRobin1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonRobin)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =675)

#-----------------Flash---------------------------
    ImagenFlash = tk.PhotoImage(file = 'dc/dc-flash.png')
    PrintFlash = tk.Label(elframe, image = ImagenFlash)
    PrintFlash.grid(row =6, column = 0)

    tk.Label(elframe, font=8,
        text=("Flash\n Flash Comics #1\n"
            "Barry Allen\n"
            "DC Comics")).grid(row=6, column=1)

    def BotonFlash():
        flash = tk.Toplevel()
        flash.geometry('840x455')
        flash.title('¡Flash!')
        flash.configure(background='firebrick2')

        def salir_ventana():
            flash.destroy()

        ImagenFlash1 = tk.PhotoImage(file = 'dcfotos/flashba.png')
        PrintFlash1 = tk.Label(flash, image = ImagenFlash1)
        PrintFlash1.grid(row =0, column = 0)

        tk.Label(flash, font=('Comic Sans', 16),
            text=("Flash\n Flash Comics #1\n"
                "Barry Allen\n"
                "DC Comics\n"
                "pensar y reaccionar a velocidad luz\n"
                "además de tener una resistencia sobrehumana\n"
                "que les permite recorrer distancias increíbles.\n")).place(x=380, y=150)
        botonsalir=tk.Button(flash, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 555, y =390)
        PrintFlash1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonFlash)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =870)

#--------------Linterna verde--------------------------
    ImagenVerde = tk.PhotoImage(file = 'dc/dc-green.png')
    PrintVerde = tk.Label(elframe, image = ImagenVerde)
    PrintVerde.grid(row =8, column = 0)

    tk.Label(elframe, font=8,
        text=("Green Lantern\n All-American Comics #16\n"
            "Alan Scott\n"
            "DC Comics")).grid(row=8, column=1)

    def BotonVerde():
        verde = tk.Toplevel()
        verde.geometry('800x545')
        verde.title('¡Green Lantern!')
        verde.configure(background='forest green')

        def salir_ventana():
            verde.destroy()

        ImagenVerde1 = tk.PhotoImage(file = 'dcfotos/linver.png')
        PrintVerde1 = tk.Label(verde, image = ImagenVerde1)
        PrintVerde1.grid(row =0, column = 0)

        tk.Label(verde, font=('Comic Sans', 16),
            text=("Green Lantern\n All-American Comics #16\n"
                "Alan Scott\n"
                "DC Comics\n"
                "se caracterizan por un anillo de poder\n"
                "y la capacidad de crear manifestaciones\n"
                "de luz sólida con los susodichos anillos.\n")).place(x=390, y=180)
        botonsalir=tk.Button(verde, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 520, y =470)
        PrintVerde1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonVerde)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 150, y =1065)

#--------------Flecha verde-----------------------
    ImagenFlecha = tk.PhotoImage(file = 'dc/dc-arrow.png')
    PrintFlecha = tk.Label(elframe, image = ImagenFlecha)
    PrintFlecha.grid(row =1, column = 2)

    tk.Label(elframe, font=8,
        text=("Green Arrow\n More Fun Comics #73\n"
            "Oliver Queen\n"
            "DC Comics")).grid(row=1, column=3)

    def BotonFlecha():
        flecha = tk.Toplevel()
        flecha.geometry('740x505')
        flecha.title('¡Green Arrow!')
        flecha.configure(background='royal blue')

        def salir_ventana():
            flecha.destroy()

        ImagenFlecha1 = tk.PhotoImage(file = 'dcfotos/flechaoli.png')
        PrintFlecha1 = tk.Label(flecha, image = ImagenFlecha1)
        PrintFlecha1.grid(row =0, column = 0)

        tk.Label(flecha, font=('Comic Sans', 16),
            text=("Green Arrow\n More Fun Comics #73\n"
                "Oliver Queen\n"
                "DC Comics\n"
                "Posee una gran habilidad como arquero\n"
                "y tiene un amplio arsenal de flechas\n"
                "Excelente rastreador\n"
                "manejo de armas y piloto aviador.\n")).place(x=350, y=150)
        botonsalir=tk.Button(flecha, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 490, y =440)
        PrintFlecha1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonFlecha)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 550, y =290)

#-----------------Martian Manhunter------------------------
    ImagenMartin = tk.PhotoImage(file = 'dc/dc-martian.png')
    PrintMartin = tk.Label(elframe, image = ImagenMartin)
    PrintMartin.grid(row = 2, column = 2)

    tk.Label(elframe, font=8,
        text=("Martian Manhunter\n Detective Comics #225\n"
            "Martian Manhunter\n"
            "DC Comics")).grid(row=2, column=3)

    def BotonMartin():
        martin = tk.Toplevel()
        martin.geometry('700x510')
        martin.title('¡Martian Manhunter!')
        martin.configure(background='RoyalBlue4')

        def salir_ventana():
            martin.destroy()

        ImagenMartin1 = tk.PhotoImage(file = 'dcfotos/martian.png')
        PrintMartin1 = tk.Label(martin, image = ImagenMartin1)
        PrintMartin1.grid(row = 0, column = 0)

        tk.Label(martin, font=('Comic Sans', 18),
            text=("Martian Manhunter\n Detective Comics #225\n"
                "Martian Manhunter\n"
                "DC Comics\n"
                "Superfuerza Velocidad \n"
                "Telepatía Telekinesis\n"
                "Cambio de forma\n"
                "Nueve sentidos\n")).place(x=390, y=140)
        botonsalir=tk.Button(martin, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 465, y =440)
        PrintMartin1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonMartin)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 550, y =480)

#-------------Blue Beetle------------------------
    ImagenBlue = tk.PhotoImage(file = 'dc/dc-blue.png')
    PrintBlue = tk.Label(elframe, image = ImagenBlue)
    PrintBlue.grid(row = 4, column = 2)

    tk.Label(elframe, font=8,
        text=("Blue Beetle\n Mystery Men Comics #1\n"
            "Dan Garret\n"
            "DC Comics")).grid(row=4, column=3)

    def BotonBlue():
        blue = tk.Toplevel()
        blue.geometry('700x505')
        blue.title('¡Blue Beetle!')
        blue.configure(background='SteelBlue4')

        def salir_ventana():
            blue.destroy()

        ImagenBlue1 = tk.PhotoImage(file = 'dcfotos/bluebe.png')
        PrintBlue1 = tk.Label(blue, image = ImagenBlue1)
        PrintBlue1.grid(row = 0, column = 0)

        tk.Label(blue, font=('Comic Sans', 18),
            text=("Blue Beetle\n Mystery Men Comics #1\n"
                "Dan Garret\n"
                "DC Comics\n"
                "capacidad de volar\n"
                "superfuerza y luminosidad\n")).place(x=370, y=160)
        botonsalir=tk.Button(blue, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.place(x = 465, y =430)
        PrintBlue1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonBlue)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 550, y =675)

#----------------Black Canary------------------
    ImagenBlack = tk.PhotoImage(file = 'dc/dc-black.png')
    PrintBlack = tk.Label(elframe, image = ImagenBlack)
    PrintBlack.grid(row = 6, column = 2)

    tk.Label(elframe, font=8,
        text=("Black Canary\n Flash Comics #86\n"
            "Dinah Drake\n"
            "DC Comics")).grid(row=6, column=3)

    def BotonBlack():
        black = tk.Toplevel()
        black.geometry('1050x550')
        black.title('¡Black Canary!')
        black.configure(background='orchid2')

        def salir_ventana():
            black.destroy()

        ImagenBlack1 = tk.PhotoImage(file = 'dcfotos/blackca.png')
        PrintBlack1 = tk.Label(black, image = ImagenBlack1)
        PrintBlack1.grid(row = 0, column = 0)

        tk.Label(black, font=('Comic Sans', 16),
            text=("Black Canary\n Flash Comics #86\n"
                "Dinah Drake\n"
                "DC Comics\n"
                "Su superpoder más conocido es el grito del canario\n"
                "Un chillido ultrasónico que le permite aturdir a sus enemigos\n"
                "E incluso destruir objetos\n")).place(x=480, y=180)
        botonsalir=tk.Button(black, text = "RETROCEDER", command = salir_ventana,fg = 'red', padx = 10, pady = 10)
        botonsalir.config(width=12, height=0)
        botonsalir.place(x = 720, y =480)
        PrintBlack1.mainloop()

    boton_1 = tk.Button(elframe, text = "Más", command = BotonBlack)
    boton_1.config(width=8, height=0)
    boton_1.place(x = 550, y =870)

    elframe.update()
    c.config(scrollregion=c.bbox('all'))
    elframe.mainloop()

#--------------BOTONES-----------
BotonMarvel = tk.Button(RaizComic, text = 'MARVEL', command = marvelbo, fg = 'RED', padx = 40, pady = 5)
BotonMarvel.place(x=100, y=80)
botonsalir = tk.Button(RaizComic, text = 'SALIR', command= salir, padx = 10, pady = 10)
botonsalir.place(x=275, y= 500)
BotonDC = tk.Button(RaizComic, text= 'DC', command= dcboton, fg = 'BLUE', padx = 50, pady = 5)
BotonDC.place(x=380, y=80)
#botonbuscar = tk.Button(RaizComic, text= 'BUSCAR', padx = 10, pady = 5)
#botonbuscar.place(x=275,y=80)

RaizComic.mainloop()


import pyro
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from copy import deepcopy
from pyro.optim import Adam
from pyro.infer import SVI, Trace_ELBO
from pyro.nn import PyroModule, PyroSample
from pyro.distributions import constraints
from pyro.distributions.transforms import Radial, Planar
from pyro.infer.autoguide import AutoMultivariateNormal
from pyro.distributions import Normal, MultivariateNormal, TransformedDistribution

class RegressionModel(nn.Module):
    """Simple neural network regression model with one hidden layer"""

    def __init__(self, n_features, noise_var=1, device='cuda'):
        super().__init__()
        self.n_features = n_features
        self.noise_var = noise_var
        self.device = device

        self.fc_1 = nn.Linear(in_features=self.n_features, out_features=25)
        self.fc_2 = nn.Linear(in_features=25, out_features=1)

        self.ordered_modules = nn.ModuleList([
            self.fc_1,
            nn.ReLU(),
            self.fc_2
        ])

        self.noise_scale = torch.sqrt(
            torch.tensor(self.noise_var, dtype=torch.float, device=self.device)
        )
        self.to(self.device)

    def forward(self, x):
        for module in self.ordered_modules:
            x = module(x)
        return x

    def loss(self, model_output, target):
        log_likelihood = Normal(
            loc=model_output, scale=self.noise_scale).log_prob(target).sum()
        return -log_likelihood

    def optimizer(self, lr=1e-3, weight_decay=0):
        return optim.Adam(self.parameters(), lr=lr, weight_decay=weight_decay)

class BayesianLastLayer:
    """Neural network with Bayesian last layer."""
    def __init__(self, base_model, noise_var=1):
        self.base_model = base_model
        self.noise_var = noise_var
        self.device = base_model.device

        # Feature extractor
        self.feature_extractor = nn.Sequential(
            *self.base_model.ordered_modules[:-1]
        )
        # Properties of last layer (assumed to be linear)
        self.in_features = self.base_model.ordered_modules[-1].in_features
        self.out_features = self.base_model.ordered_modules[-1].out_features
        self.n_weight = self.base_model.ordered_modules[-1].weight.numel()
        self.n_bias = self.base_model.ordered_modules[-1].bias.numel()

         # Distribution over parameters in last layer
        self.base_mean = torch.zeros(
            self.n_weight + self.n_bias, device=self.device
        )
        self.base_scale_tril = torch.eye(
            self.n_weight + self.n_bias, device=self.device
        )
        self.base_dist = MultivariateNormal(
            loc=self.base_mean,
            scale_tril=self.base_scale_tril
        )

        self.noise_scale = torch.sqrt(
            torch.tensor(self.noise_var, dtype=torch.float, device=self.device)
        )

    def model(self, x, y=None):
        # Sample parameters
        parameters = pyro.sample('parameters', self.base_dist)
        parameters = parameters.squeeze()

        # Extract weight and biases
        weight = parameters[...,:self.n_weight]
        weight = weight.reshape(
            *weight.shape[:-1], self.out_features, self.in_features
        )
        bias = parameters[...,self.n_weight:]

        # Compute model output
        x_encoded = self.feature_extractor(x)
        model_output = x_encoded @ weight.transpose(-2,-1) + bias.unsqueeze(-2)
        model_output = model_output.squeeze()

        with pyro.plate('data', size=len(x)):
            obs = pyro.sample(
                    'obs',
                    Normal(loc=model_output, scale=self.noise_scale),
                    obs=y
                )
            return model_output

    def guide_mvn(self, x, y=None):
        scale = pyro.param(
            'scale',
            0.1*torch.ones(self.n_weight + self.n_bias, device=self.device),
            constraint=constraints.softplus_positive
        )
        scale_tril = pyro.param(
            'scale_tril',
            torch.eye(self.n_weight + self.n_bias, device=self.device),
            constraint=constraints.unit_lower_cholesky
        )
        loc = pyro.param(
            'loc',
            torch.zeros(self.n_weight + self.n_bias, device=self.device),
        )

        parameters = pyro.sample(
            'parameters',
            MultivariateNormal(loc=loc, scale_tril=scale[..., None]*scale_tril)
        )

    def guide_nf(self, x,  y=None):
        num_flows = 5
        flows = [Planar(self.n_weight + self.n_bias) for _ in range(num_flows)]
        for i, flow in enumerate(flows):
            flow.to(self.device)
            pyro.module(f'flow_{i}', flow)

        parameters = pyro.sample(
            'parameters',
            TransformedDistribution(self.base_dist, flows)
        )

def set_seed(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    pyro.set_rng_seed(seed)

def train_bayesian_last_layer(X, y, model, num_particles, vectorize_particles):
    pyro.clear_param_store()
    print(f'Num particles: {num_particles}; vectorized: {vectorize_particles}')
    set_seed(0)
    for name, param in pyro.get_param_store().named_parameters():
        print(name, param)

    # Make last layer Bayesian
    model = deepcopy(model)
    model_bll = BayesianLastLayer(model)
    #guide = AutoMultivariateNormal(model_bll.model)

    elbo = Trace_ELBO(
        num_particles=num_particles, vectorize_particles=vectorize_particles
    )
    svi = SVI(
        model_bll.model,
        model_bll.guide_nf,
        Adam({"lr": 1e-4}),
        elbo
    )

    n_svi_steps = 10000
    for step in range(n_svi_steps):
        loss = svi.step(X, y)
        if step % 100 == 0:
            print(f'SVI step: {step}, Loss: {loss}')

    for name, param in pyro.get_param_store().named_parameters():
        print(name, param)

    print('\n')

# Data
set_seed(0)
device = 'cuda'
N, M = 1000, 15
X = torch.randn(N, M, device=device)
w = torch.randn(M, 1, device=device)
y = X @ w + torch.randn(N, 1, device=device)
y = y.squeeze(-1)
print(X.shape, y.shape)

# Train initial neural network
n_train_steps = 10000
model = RegressionModel(n_features=M, device=device)
optimizer = model.optimizer()
for step in range(n_train_steps):
    model_output = model(X)
    loss = model.loss(model_output, y)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if step % 100 == 0:
        print(f'Train step: {step}; Loss: {loss.detach().item()}')
print('\n')

# Seems to work
train_bayesian_last_layer(
    X, y, model, num_particles=100, vectorize_particles=True
)

""""
# Not sure if this works, loss don't seem to decrease much
train_bayesian_last_layer(
    X, y, model, num_particles=1, vectorize_particles=True
)

# Seems to work
train_bayesian_last_layer(
    X, y, model, num_particles=7, vectorize_particles=False
)

# Does not seem to work, loss increases a lot
train_bayesian_last_layer(
    X, y, model, num_particles=7, vectorize_particles=True
)
"""


#

import pygame
import random

class Hero(object):
    def __init__(self, x, y):
        self.image = pygame.image.load('chgirl.png').convert_alpha()
        self.x = x
        self.y = y
        self.bullets = []
        self.frame = 0
        self.velocity = 0

    def draw(self, screen):
        screen.blit(self.image, (self.x, self.y))
        for bullet in self.bullets:
            pygame.draw.circle(screen, (255, 255, 255),
                               (bullet[0], bullet[1]), 6)

    def update(self, screen):
        # Update frame counter
        self.frame += 1

        remove = False
        # Move any existing bullets
        for bullet in self.bullets:
            bullet[0] += 1
            if bullet[0] > screen.get_width():
                remove = True

        # Delete any offscreen bullets
        if remove:
            del self.bullets[0]

        # Move hero
        self.y += self.velocity
        if self.y > screen.get_height() and self.velocity > 0:
            self.y = -self.image.get_height() + 70   # -101
        if self.y < -self.image.get_height() and self.velocity < 0:
            self.y = screen.get_height() - 70

    def shoot(self):
        if len(self.bullets) < 9:
            y_loc = self.y + 100
            self.bullets.append([170, y_loc])
            self.bullets.append([150, y_loc])
            self.bullets.append([130, y_loc])

    def move_down(self):
        self.velocity = 3

    def move_up(self):
        self.velocity = -3

class Villain(object):
    def __init__(self, x, y):
        self.image = pygame.image.load('pkgirl.png').convert_alpha()
        self.x = x
        self.y = y
        self.bullets = []
        self.frame = 0
        self.velocity = 0

    def draw(self, screen):
        screen.blit(self.image, (self.x, self.y))
        for bullet in self.bullets:
            pygame.draw.circle(screen, (192, 192, 192),
                               (bullet[0], bullet[1]), 6)

    def update(self, screen):
        if random.randint(1, 60) == 1:
            self.shoot()
        if random.randint(1, 100) == 1:
            self.velocity *= -1

        # Update frame counter
        self.frame += 1

        remove = False
        # Move any existing bullets
        for bullet in self.bullets:
            bullet[0] -= 1
            if bullet[0] < 0:
                remove = True

        # Delete any offscreen bullets
        if remove:
            del self.bullets[0]

        # Move hero
        self.y += self.velocity
        if self.y > screen.get_height() and self.velocity > 0:
            self.y = -self.image.get_height() + 70   # -101
        if self.y < -self.image.get_height() and self.velocity < 0:
            self.y = screen.get_height() - 70

    def shoot(self):
        if len(self.bullets) < 15:
            y_loc = self.y + 100
            self.bullets.append([self.x - 110, y_loc])
            self.bullets.append([self.x - 90, y_loc])
            self.bullets.append([self.x - 70, y_loc])

    def move_down(self):
        self.velocity = 3

    def move_up(self):
        self.velocity = -3

def init():
    width, height = 800, 600
    pygame.init()
    # Screen
    return pygame.display.set_mode((width, height))

def main(screen):
    clock = pygame.time.Clock()
    hero = Hero(60, 100)
    villain = Villain(640, 400)
    villain.move_up()
    running = True
    while running:
        screen.fill((0, 0, 0))          # Redraw background
        hero.draw(screen)
        villain.draw(screen)
        pygame.display.flip()           # Display screen in window
        hero.update(screen)
        villain.update(screen)

        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_q):
                # exit()
                running = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    hero.shoot()
                if event.key == pygame.K_s:
                    hero.move_down()
                if event.key == pygame.K_w:
                    hero.move_up()
        clock.tick(40)

screen = init()
main(screen)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 14 10:20:12 2023

@author: emgordy
"""

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import sys

sys.path.append('functions/')

# custom modules, les miennes
import experiment_settings
import metricplots
import importlib as imp
imp.reload(metricplots)

mpl.rcParams['figure.facecolor'] = 'white'
mpl.rcParams['figure.dpi']= 150
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = ['Helvetica']
mpl.rcParams['font.size'] = 12

params = {"ytick.color" : "k",
          "xtick.color" : "k",
          "axes.labelcolor" : "k",
          "axes.edgecolor" : "k"}
plt.rcParams.update(params)

experiment_name = "predictSST_terciles20202050_singlelocation_nobias_betterpreprocessing"

# experiment_name = "predictT2M_terciles20202050_singlelocation"
experiment_dict = experiment_settings.get_experiment_settings(experiment_name)
filefront = experiment_dict["filename"]

#%%
lat = np.arange(-60,70,10)+5
lon = np.arange(0,360,10)+5

nlat = len(lat)
nlon = len(lon)

#%%

file = "metricsfiles/" + filefront + "test_2050.npz"
test_2050=np.load(file)

#%%

acc = test_2050["acc"]
acc = acc[:,:,0,:]

shuffle = test_2050["shuffleacc"]
shuffle = shuffle[:,:,0,:]

shuffle90 = test_2050["shuffle90"]
shuffle90 = shuffle90[:,:,0,:]

metricplots.compareaccuracy_IV_sig(acc,shuffle,lon,lat,shuffle90)
metricplots.compareaccuracy_IVSDP50_sig(acc,shuffle,lon,lat,shuffle90)
metricplots.compareaccuracy_IVSDP_sig(acc,shuffle,lon,lat,shuffle90)
metricplots.compareaccuracy_SDP_allish(acc,lon,lat)


from typing import Callable, Tuple

from einops import rearrange
import torch
from torch import Tensor

DEBUG = False  # activate debug mode when needed

def hardest_triplet(
    triplet: Tuple[Tensor, Tensor, Tensor],
    label: Tuple[Tensor, Tensor, Tensor],
    distance: Callable[[Tensor, Tensor], Tensor],
    mode: str = "min",
) -> Tuple[Tensor, Tensor]:
    """Return hardest negative distance of a batch for each anchor

    Args:
        triplet: the triplet input embedding (anchor, positive, negative) of
            shape (B, C) where C is embedding dimension
        label: the corresponding triplet of label, each of shape (B)
        distance: the distance to be used
        mode: if "min" hardest negative are supposed to have minimal distance
            to anchor, else maximum distance

    Returns:
        positive_distance: the distance between anchor and positive samples
            (shape B)
        hardest_negative_distance: the hardest distance between anchor and
            any other sample not belonging to the same label group
    """
    # triplet is a 3-tuple of anchor, positive, negative samples
    # with shape (B, C) and corresponding labels have shape (B)
    anchor = triplet[0]
    anchor_label = label[0]
    triplet = torch.cat(triplet)  # shape (3B, C)
    label = torch.cat(label)  # shape (3B)

    # compute pairwise distance between anchor and triplet
    anchor = rearrange(anchor, "b c -> b c 1")
    triplet = rearrange(triplet, "n c -> 1 c n")  # N == 3B
    dist = distance(anchor, triplet)  # shape (B, 3B)

    # compute pairwise positive distance
    positive_distance = torch.diag(
        rearrange(dist, "b (t b1) -> b t b1", t=3)[:, 1]  # B1 == B
    )

    # compute pairwise boolean for identifying samples belonging to same group
    anchor_label = rearrange(anchor_label, "b -> b 1")
    label = rearrange(label, "n -> 1 n")  # N == 3B
    same_label = anchor_label == label  # shape (B, 3B)

    # find hardest negative distance
    inf = torch.tensor(float("inf")).to(anchor.device)
    if mode == "min":
        updated_distance = torch.where(same_label, inf, dist)
        hardest_negative_distance = torch.min(updated_distance, dim=1)[0]
    else:
        updated_distance = torch.where(same_label, -inf, dist)
        hardest_negative_distance = torch.max(updated_distance, dim=1)[0]

    # used for checking
    if DEBUG:
        print(f"Original distance:\n{dist}")
        print(f"Distance after filtering positives:\n{updated_distance}")
        print(f"Positive distance:\n{positive_distance}")
        print(f"Hardest negative distance:\n{hardest_negative_distance}")

    return positive_distance, hardest_negative_distance

if __name__ == "__main__":
    # check return values on a simple case
    import torch.nn.functional as F

    device = "cuda" if torch.cuda.is_available() else "cpu"
    DEBUG = True

    B = 2
    C = 256
    triplet = tuple(torch.randn((B, C)).to(device) for i in range(3))
    label = tuple(
        torch.tensor(_label).to(device) for _label in [[0, 1], [0, 1], [2, 0]]
    )
    distance = lambda x, y: 1 - F.cosine_similarity(x, y)

    hardest_triplet(triplet, label, distance, mode="min")


from __future__ import absolute_import, unicode_literals

from django.utils import six
from django.db import models
from django.apps import apps

try:
    from django.channels import Channel
except ImportError:
    from channels import Channel

stratus_app = apps.get_app_config('stratus')
VM = stratus_app.get_model('VM')

GAZON_STATUS_ENUM = [ (u'WAITING', u'Gazon entry need complementary info'),
                      (u'TO_CREATE', u'Gazon entry need to be created'),
                      (u'TO_DELETE', u'Gazon entry need to be deleted'),
                      (u'CREATED', u'Gazon is created for the VM'),
                      (u'DELETED', u'Gazon is deleted for the VM'),
                      (u'NONE', u'None has to been done for gazon. Ever'), ]

class GazonEntry(models.Model):

    vm = models.OneToOneField(VM, default=None)

    gazon_status = models.CharField(choices=GAZON_STATUS_ENUM, default='WAITING', max_length=100)
    gazon_error = models.CharField(blank=True, max_length=100)

    def delete_vm(self):
        if self.gazon_status in [u'CREATED', u'TO_CREATE']:
            self.gazon_status = u'TO_DELETE'
            Channel(u'gazonentry').send({})
            self.save()


import pandas as pd
import mlflow
import os

# Setting the MLflow tracking server
#mlflow.set_tracking_uri('http://training.itu.dk:5000/')

# Setting the requried environment variables
# os.environ['MLFLOW_S3_ENDPOINT_URL'] = 'http://130.226.140.28:5000'
# os.environ['AWS_ACCESS_KEY_ID'] = 'training-bucket-access-key'
# os.environ['AWS_SECRET_ACCESS_KEY'] = 'tqvdSsEDnBWTDuGkZYVsRKnTeu'

#mlflow.set_experiment("<gebu> - a2")
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.svm import SVR
from sklearn.model_selection import train_test_split, TimeSeriesSplit
from sklearn.metrics import r2_score
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import GridSearchCV
import json
import shutil
import warnings

def run(search, name):
    with mlflow.start_run(run_name= name) as run:
        df = pd.read_json("./dataset.json", orient="split")
        df = df.dropna()

        transformer = ColumnTransformer([
                ('standard_scaler', StandardScaler(), ['Speed']), #scales the data to mean 0 and std 1
                ('num_features', PolynomialFeatures(degree= 1), ['Speed']),
                ('Categorical', OneHotEncoder(), ['Direction'])
                ])

        pipeline = Pipeline(steps = [
                ('transformers', transformer),
                ('model', GradientBoostingRegressor())])

        X = df[["Speed","Direction"]]
        y = df["Total"]

        number_of_splits = 5

        #Splitting data intro training and test data
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle= False)

        tscv = TimeSeriesSplit(n_splits=5)
        grid = GridSearchCV(pipeline, search, scoring= 'r2',verbose=1, cv=tscv)
        pipe = grid.fit(X_train, y_train)
        r2_score_test = pipe.score(X_test, y_test)
        r2_score = pipe.best_score_
        params = pipe.best_params_
        mlflow.log_metric('r2', r2_score_test)
        mlflow.log_params(params)

        artifact_path= f"mlruns/1/{run.info.run_id}"
        mlflow.sklearn.log_model(pipe, artifact_path=artifact_path)

#Updating best model

        try:
          with open("best_regressor.json", "r") as f:
            best_model = json.loads(f.read())

          if r2_score_test > best_model["score"]:
            shutil.rmtree('best_model')
            print(f"New model outperforms old model")
            mlflow.sklearn.save_model(
                pipe, path = 'best_model', conda_env="conda.yml")

            model_details = {
                "model_name": name,
                "score": r2_score_test,
                }
            with open("best_regressor.json", "w") as f:
              json.dump(model_details, f)
          else:
            print(f"Model {name} does not perform better than current saved one")

        except:
          print(f"There is no model saved yet. Let's save model: {name}")
          mlflow.sklearn.save_model(
              pipe, path = 'best_model', conda_env="conda.yml")

          model_details = {
              "model_name": name,
              "score": r2_score_test,
              }
          with open("best_regressor.json", "w") as f:
            json.dump(model_details, f)

def main():
        warnings.filterwarnings("ignore")
        svr = [{'model': [SVR()],
         'model__gamma': ['scale', 'auto'],
         'model__C': [1,5,10]}]
        rfr = [{'model': [RandomForestRegressor()],
         'model__max_depth': [i for i in range(1,8)]}]
        gbr = [{'model': [GradientBoostingRegressor()],
         'model__learning_rate': [0.1,0.2,0.3],
         'model__n_estimators': [100,200,300]}]
        run(svr, 'SVR')
        run(rfr, 'RFR')
        run(gbr,'GBR')

if __name__ == "__main__":
  main()


"""
Unittest for File class

"""

import unittest
import pep8
import os
from modules.read_file import read_file as rf, get_path_files

class test_read_file_docs(unittest.TestCase):
    """Testing documentation of the read_file"""

    def test_pep8_conformance_file(self):
        """Test that filre_read conforms to PEP8."""
        pep8s = pep8.StyleGuide(quiet=True)
        result = pep8s.check_files(['modules/read_file.py'])
        self.assertEqual(result.total_errors, 0,
                         "Found code style errors (and warnings).")

    def test_pep8_conformance_test_file(self):
        """Test that tests/test_read_file.py conforms to PEP8."""
        pep8s = pep8.StyleGuide(quiet=True)
        result = pep8s.check_files(['tests/test_modules/test_read_file.py'])
        self.assertEqual(result.total_errors, 0,
                         "Found code style errors (and warnings).")

class tests_read_file_functions(unittest.TestCase):
    """Testing read_files functions"""

    def test_get_path_files(self):
        """Testing function that get str and return absolute path"""
        separator = os.path.sep
        path = os.path.dirname(os.path.realpath(__file__))
        r = separator.join(path.split(separator)[:-2])
        expected = f"{r}{separator}files{separator}data.txt"
        real = get_path_files("data.txt")
        self.assertEqual(real, expected)

if __name__ == '__main__':
    """Main Unittest"""
    unittest.main()


from distutils.core import setup

try: # If we have Cython installed
    from distutils.extension import Extension
    import Cython.Distutils
    import os
    if os.name == "nt": raise OSError
    ext_modules = [Extension('forceatlas2.fa2util', ['forceatlas2/fa2util.py', 'forceatlas2/fa2util.pxd'])]
    cmdclass = {'build_ext' : Cython.Distutils.build_ext}
    cythonopts = {"ext_modules" : ext_modules,
                  "cmdclass" : cmdclass}
except ImportError:
    print("WARNING: Cython is not installed.  If you want this to be fast, install Cython and reinstall forceatlas2.")
    cythonopts = {"py_modules" : ["forceatlas2.fa2util"]}
except OSError:
    print("WARNING: Windows and Cython don't always get along, so forceatlas2 is installing without optimizations.  Feel free to fix for your computer if you know what you're doing.")
    cythonopts = {"py_modules" : ["forceatlas2.fa2util"]}

setup(
    name = 'ForceAtlas2',
    version = '1.0',
    description = 'The ForceAtlas2 algorithm for Python (and NetworkX)',
    author = 'Max Shinn',
    author_email = 'mws41@cam.ac.uk',
    packages = ['forceatlas2'],
    requires = ['numpy'],
    **cythonopts
)


import math
import numpy as np
from skimage import io
import matplotlib.pyplot as plt

def load(img_path):
    """Loads an image from a file path.

    HINT: Look up `skimage.io.imread()` function.
    HINT: Converting all pixel values to a range between 0.0 and 1.0
    (i.e. divide by 255) will make your life easier later on!

    Inputs:
        image_path: file path to the image.

    Returns:
        out: numpy array of shape(image_height, image_width, 3).
    """
    out = None
    img = io.imread(img_path)
    img = img /255
    out = img

    return out

def display(img, caption=''):
    # Show image using pyplot
    plt.figure()
    plt.imshow(img)
    plt.title(caption)
    plt.axis('off')
    plt.show()

def print_stats(image):
    """ Prints the height, width and number of channels in an image.

    Inputs:
        image: numpy array of shape(image_height, image_width, n_channels).

    Returns: none

    """

    # YOUR CODE HERE
    print('image_height: ', image.shape[0]) #height
    print('image_width: ', image.shape[1]) #width
    print('n_channels: ', image.shape[2]) #n_channels

    return None

def crop(image, start_row, start_col, num_rows, num_cols):
    """Crop an image based on the specified bounds. Use array slicing.

    Inputs:
        image: numpy array of shape(image_height, image_width, 3).
        start_row (int): The starting row index
        start_col (int): The starting column index
        num_rows (int): Number of rows in our cropped image.
        num_cols (int): Number of columns in our cropped image.

    Returns:
        out: numpy array of shape(num_rows, num_cols, 3).
    """

    out = None

    ### YOUR CODE HERE
    out = image[start_row : start_row + num_rows, start_col: start_col + num_cols]
    # print(out.shape)
    return out

def change_contrast(image, factor):
    """Change the value of every pixel by following

                        x_n = factor * (x_p - 0.5) + 0.5

    where x_n is the new value and x_p is the original value.
    Assumes pixel values between 0.0 and 1.0
    If you are using values 0-255, change 0.5 to 128.

    Inputs:
        image: numpy array of shape(image_height, image_width, 3).
        factor (float): contrast adjustment

    Returns:
        out: numpy array of shape(image_height, image_width, 3).
    """

    out = None

    ### YOUR CODE HERE
    out = factor * (image - 0.5) + 0.5

    return out

def resize(input_image, output_rows, output_cols):
    """Resize an image using the nearest neighbor method.
    i.e. for each output pixel, use the value of the nearest input pixel after scaling

    Inputs:
        input_image: RGB image stored as an array, with shape
            `(input_rows, input_cols, 3)`.
        output_rows (int): Number of rows in our desired output image.
        output_cols (int): Number of columns in our desired output image.

    Returns:
        np.ndarray: Resized image, with shape `(output_rows, output_cols, 3)`.
    """
    out = None
    # print(input_image.shape)

    height, width, channels = input_image.shape

    out = np.zeros((output_rows, output_cols, channels)) #get the empty image first

    for i in range(output_rows):
        for j in range(output_cols):
            x = int(float(i)/float(output_rows) * float(height))
            y = int(float(j)/float(output_cols) * float(width))

            out[i,j] = input_image[x, y]

    return out

def greyscale(input_image):
    """Convert a RGB image to greyscale.
    A simple method is to take the average of R, G, B at each pixel.
    Or you can look up more sophisticated methods online.

    Inputs:
        input_image: RGB image stored as an array, with shape
            `(input_rows, input_cols, 3)`.

    Returns:
        np.ndarray: Greyscale image, with shape `(output_rows, output_cols)`.
    """
    out = None
    # the average of R, G, B at each pixel
    out = (input_image[:,:,0] + input_image[:,:,1] + input_image[:,:,2] )/ 3

    return out


import json
from unittest import TestLoader, mock
from unittest.mock import MagicMock

from django.test import TestCase
from django.test.runner import DiscoverRunner

from optic_django_middleware.apps import OpticDjangoAppConfig
from optic_django_middleware.middleware import OpticMiddleware

class TestMiddleWare(TestCase):
    def setUp(self):
        self.test_runner = DiscoverRunner()

    def test_middleware_called(self):
        with mock.patch(
            "optic_django_middleware.middleware.OpticMiddleware",
            new=MagicMock(wraps=OpticMiddleware),
        ) as mocked:
            self.client.get("/url-1")
            self.assertEqual(mocked.call_count, 1)

    def test_testcase_container_one_test(self):
        class Test(TestCase):
            def test_foo(self):
                self.client.get("/url-1")
                with open(OpticDjangoAppConfig.log_path(), "r+") as f:
                    log = json.load(f)
                    self.assertEqual(log[0]["url"]["path"], "/url-1")

        self.test_runner.run_suite(
            TestLoader().loadTestsFromTestCase(testCaseClass=Test)
        )


import cv2
import numpy as np

# read and show test image
img = cv2.imread("C:/Users\Eslam.Wael\Desktop/Capture.PNG")
height, width = img.shape[:2]

# Source points
top_left = [0, 0]
top_right = [width/2, 0]
bottom_right = [width/2, height/2]
bottom_left = [0, height/2]
pts = np.array([bottom_left, bottom_right, top_right, top_left], dtype=float)

# Target points

y_off = 100  # Y offset
top_left_dst = [width/2, 0]
top_right_dst = [0, 0]
bottom_right_dst = [width/8, height/2]
bottom_left_dst = [3*width/8, height/2]
dst_pts = np.array([bottom_left_dst, bottom_right_dst, top_right_dst, top_left_dst])

# Generate a preview to show where the warped bar would end up
preview = np.copy(img)
cv2.polylines(preview, np.int32([pts]), True, (0, 255, 0), 2)
cv2.polylines(preview, np.int32([dst_pts]), True, (0, 0, 0), 2)
cv2.imshow("preview", preview)

# calculate transformation matrix
pts = np.float32(pts.tolist())
dst_pts = np.float32(dst_pts.tolist())
M = cv2.getPerspectiveTransform(pts, dst_pts)

# wrap image and draw the resulting image
image_size = (img.shape[1], img.shape[0])
warped = cv2.warpPerspective(img, M, dsize= image_size, flags= cv2.INTER_LINEAR)
cv2.imshow("warped", warped)
cv2.waitKey(0)
cv2.destroyAllWindows()

Parking detection with computer vision/Early modules/perspective.py


"""
You are a greedy stolen and you are at a store with your bag that can hold 16 pounds.
Inside the store has a lot of objects and your strategy is to stole more expensive objects that
fit inside your bag. To do that you follow the steps below:

1 - Get the more expensive item that fits inside your bag.
2 - Get the next more expensive item that fits inside your bag, and so on.

In this example the greedy algorithm doesn't work as expected. For example, supose there are 3 items
that can be stoled.

Radio    - R$ 3.000 - 13KG
Notebook - R$ 2.000 -  9KG
Guitar   - R$ 1.500 -  6KG

On the first step you stole the Radio, that is the more expensive item,
but after that no more items can fit inside your bag, it means that you
have 3 pounds of free space that can't be used anymore, because the remaing
items can't fit there.

You stole R$ 3.000, but if you had stoled the notebook and the guitar you could have R$ 3.500!

Clearly the greedy algorithm does not offer the best strategy here, but you have an approximate solution,
and it's good!
"""

from collections import namedtuple

Item = namedtuple("Item", ["name", "price", "weight"])

bag_16kg = []
items = [
    Item(name="radio", price=3000, weight=13),
    Item(name="notebook", price=2000, weight=9),
    Item(name="guitar", price=1500, weight=6),
]

def _get_more_expensive_item_that_fit_inside_the_bag(items, remaining_weight):
    expensive_item = Item(name="fake", price=0, weight=0)
    for item in items:
        if item.price >= expensive_item.price and item.weight <= remaining_weight:
            expensive_item = item
    return expensive_item if expensive_item.name != "fake" else None

def stolen_store(items, bag_16kg):
    remaining_weight = 16
    while items:
        item = _get_more_expensive_item_that_fit_inside_the_bag(items, remaining_weight)
        if item is None:
            break

        bag_16kg.append(item.name)
        remaining_weight -= item.weight
        items.remove(item)

    return bag_16kg

stolen_bag16kg = stolen_store(items, bag_16kg)
assert stolen_bag16kg == ["radio"]


#!/usr/bin/env python
import sys
import logging
import argparse
import pymongo
from pymongo import MongoClient
from pymongo.errors import ServerSelectionTimeoutError
from .argo_config import ArgoConfig
from .common import get_config_paths
from .common import get_log_conf

log = logging.getLogger(__name__)

class ArgoMongoClient(object):

    def __init__(self, args, config, cols):
        self.args = args
        self.config = config
        self.cols = cols

    def ensure_status_indexes(self, db):
        """Checks if required indexes exist in specific argo status-related collections
        in mongodb

        Args:
            db (obj): pymongo database object

        """

        log.info("Checking required indexes in status collections...")

        def is_index_included(index_set, index):
            """gets a set of mongodb indexes and checks if specified
            mongodb index exists in this set

            Args:
                index_set (dict): pymongo mongodb index object
                index (obj): pymongo index object

            Returns:
                bool: If index exists in set return true
            """

            for name in list(index_set.keys()):
                if index_set[name]['key'] == index:
                    return True
            return False
        # Used in all status collections
        index_report_date = [("report", pymongo.ASCENDING),
                             ("date_integer", pymongo.ASCENDING)]
        # Used only in status_metrics collection
        index_date_host = [("date_integer", pymongo.ASCENDING),
                           ("report", pymongo.ASCENDING)]
        status_collections = ["status_metrics", "status_endpoints",
                              "status_services", "status_endpoint_groups"]

        index_history = [("date_integer",pymongo.DESCENDING),
                         ("id",pymongo.ASCENDING)]

        index_downtimes = [("date_integer",pymongo.DESCENDING)]

        # Check indexes in sync collections
        for col_name in ["topology_endpoints", "topology_groups", "weights"]:
            col = db[col_name]
            indexes = col.index_information()
            if not is_index_included(indexes, index_history):
                # ensure index
                col.create_index(index_history, background=True)
                log.info("Created (date_integer,id) index in %s.%s",
                         col.database.name, col.name)

        # Check for index in downtimes
        col = db["downtimes"]
        indexes = col.index_information()
        if not is_index_included(indexes, index_downtimes):
            col.create_index(index_downtimes, background=True)
            log.info("Created (date_integer) index in %s.%s",
                     col.database.name, col.name)

        # Check first for index report,date
        for status_name in status_collections:
            col = db[status_name]
            indexes = col.index_information()
            if not is_index_included(indexes, index_report_date):
                # ensure index
                col.create_index(index_report_date, background=True)
                log.info("Created (report,date) index in %s.%s",
                         col.database.name, col.name)

        # Check for index date,host in status_metrics
        col = db["status_metrics"]
        indexes = col.index_information()
        if not is_index_included(indexes, index_date_host):
            col.create_index(index_date_host, background=True)
            log.info("Created (report,date) index in %s.%s",
                     col.database.name, col.name)

    def mongo_clean_ar(self, uri, dry_run=False):
        """Gets a mongo database reference as a uri string and performs
        a/r data removal for a specific date

        Args:
            uri (str.): uri string pointing to a specific mongodb database
            dry_run (bool, optional): Optional flag that specifies if the execution is in dry mode run.
                                      If yes no data removal is performed. Defaults to False.
        """

        tenant_report = None

        # if report is given check if report exists in configuration
        if self.args.report:
            report_name = self.args.report
            tenant_group = "TENANTS:" + self.args.tenant
            if report_name in self.config.get(tenant_group, "reports"):
                tenant_report = self.config.get(
                    tenant_group, "report_"+report_name)
            else:
                log.critical("Report %s not found", report_name)
                sys.exit(1)

        # Create a date integer for use in the database queries
        date_int = int(self.args.date.replace("-", ""))

        # set up the mongo client
        try:
            log.info("Trying to connect to: " + uri.geturl())
            client = MongoClient(uri.geturl())
            # force a connection to test the client
            client.server_info()
        except ServerSelectionTimeoutError as pse:
            log.fatal(pse)
            sys.exit(1)

        # specify the db we will be using. e.g argo_TENANTA
        # from the uri, take the path, which reprents the db, and ignore the / in the begging
        db = client[uri.path[1:]]

        # iterate over the specified collections
        for col in self.cols:
            if tenant_report is not None:
                num_of_rows = db[col].find(
                    {"date": date_int, "report": tenant_report}).count()
                log.info("Collection: " + col + " -> Found " + str(
                    num_of_rows) + " entries for date: " + self.args.date + " and report: " + self.args.report)
            else:
                num_of_rows = db[col].find({"date": date_int}).count()
                log.info("Collection: " + col + " -> Found " + str(
                    num_of_rows) + " entries for date: " + self.args.date + ". No report specified!")
            if dry_run:
                log.info("Results won't be removed to dry-run mode")
            else:
                if num_of_rows > 0:
                    if tenant_report is not None:
                        # response returned from the delete operation
                        res = db[col].delete_many(
                            {"date": date_int, "report": tenant_report})
                        log.info("Collection: " + col + " -> Removed " + str(res.deleted_count) +
                                 " entries for date: " + self.args.date + " and report: " + self.args.report)
                    else:
                        # response returned from the delete operation
                        res = db[col].delete_many(
                            {"date": date_int, "report": tenant_report})
                        log.info("Collection: " + col + " -> Removed " + str(
                            res.deleted_count) + " entries for date: " + self.args.date + ". No report specified!")
                    log.info("Entries removed successfully")
                else:
                    log.info("Zero entries found. Nothing to remove.")

        # close the connection with mongo
        client.close()

    def mongo_clean_status(self, uri, dry_run=False):
        """Gets a mongo database reference as a uri string and performs
        status data removal for a specific date

        Args:
            uri (str.): uri string pointing to a specific mongodb database
            dry_run (bool, optional): Optional flag that specifies if the execution is in dry mode run.
                                      If yes no data removal is performed. Defaults to False.
        """

        tenant_report = None

        # if report is given check if report exists in configuration
        if self.args.report:
            report_name = self.args.report
            tenant_group = "TENANTS:" + self.args.tenant
            if report_name in self.config.get(tenant_group, "reports"):
                tenant_report = self.config.get(
                    tenant_group, "report_"+report_name)
            else:
                log.critical("Report %s not found", report_name)
                sys.exit(1)

        # Create a date integer for use in the database queries
        date_int = int(self.args.date.replace("-", ""))

        # set up the mongo client
        try:
            log.info("Trying to connect to: " + uri.geturl())
            client = MongoClient(uri.geturl())
            # force a connection to test the client
            client.server_info()
        except pymongo.errors.ServerSelectionTimeoutError as pse:
            log.fatal(pse)
            sys.exit(1)

        # specify the db we will be using. e.g argo_TENANTA
        # from the uri, retrieve the path section, which reprents the db, and ignore the / in the begging
        db = client[uri.path[1:]]

        # ensure indexes for status collections
        self.ensure_status_indexes(db)

        # iterate over the specified collections
        for col in self.cols:
            if tenant_report is not None:
                num_of_rows = db[col].find(
                    {"date_integer": date_int, "report": tenant_report}).count()
                log.info("Collection: " + col + " -> Found " + str(
                    num_of_rows) + " entries for date: " + self.args.date + " and report: " + self.args.report)
            else:
                num_of_rows = db[col].find({"date": date_int}).count()
                log.info("Collection: " + col + " -> Found " + str(
                    num_of_rows) + " entries for date: " + self.args.date + ". No report specified!")

            if dry_run:
                log.info("Results won't be removed to dry-run mode")
            else:
                if num_of_rows > 0:
                    if tenant_report is not None:
                        # response returned from the delete operation
                        res = db[col].delete_many(
                            {"date_integer": date_int, "report": tenant_report})
                        log.info("Collection: " + col + " -> Removed " + str(res.deleted_count) +
                                 " entries for date: " + self.args.date + " and report: " + self.args.report)
                    else:
                        # response returned from the delete operation
                        res = db[col].delete_many(
                            {"date_integer": date_int, "report": tenant_report})
                        log.info("Collection: " + col + " -> Removed " + str(
                            res.deleted_count) + " entries for date: " + self.args.Date + ". No report specified!")
                    log.info("Entries removed successfully")
                else:
                    log.info("Zero entries found. Nothing to remove.")

        # close the connection with mongo
        client.close()

def main_clean(args=None):
    # stand alone method to be used whenever we want to call the mongo_clean_status method independently

    # Get configuration paths
    conf_paths = get_config_paths(args.config)

    # Get logger config file
    get_log_conf(conf_paths['log'])

    # Get main configuration and schema
    config = ArgoConfig(conf_paths["main"], conf_paths["schema"])

    # set up the mongo uri
    section_tenant = "TENANTS:" + args.tenant
    mongo_endpoint = config.get("MONGO", "endpoint")
    mongo_uri = config.get(section_tenant, "mongo_uri").fill(
        mongo_endpoint=mongo_endpoint, tenant=args.tenant)

    if args.job == "clean_ar":
        argo_mongo_client = ArgoMongoClient(
            args, config, ["endpoint_ar", "service_ar", "endpoint_group_ar"])
        argo_mongo_client.mongo_clean_ar(mongo_uri, args.dry_run)

    elif args.job == "clean_status":
        argo_mongo_client = ArgoMongoClient(args, config, ["status_metrics", "status_endpoints", "status_services",
                                                           "status_endpoint_groups"])
        argo_mongo_client.mongo_clean_status(mongo_uri, args.dry_run)

# Provide the ability to the script, to run as a standalone module
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Mongo clean up script")
    parser.add_argument(
        "-t", "--tenant", metavar="STRING", help="Name of the tenant", required=True, dest="tenant")
    parser.add_argument(
        "-r", "--report", metavar="STRING", help="Tenant report to be used", required=True, dest="report")
    parser.add_argument(
        "-d", "--date", metavar="STRING", help="Date to run the job for", required=True, dest="date")
    parser.add_argument(
        "-c", "--config", metavar="STRING", help="Path for the config file", dest="config")
    parser.add_argument(
        "-j", "--job", metavar="STRING", help="Stand alone method we wish to run", required=True, dest="job")
    parser.add_argument("--dry-run", help="Runs in test mode without actually submitting the job",
                        action="store_true", dest="dry_run")

    # Parse the arguments
    sys.exit(main_clean(parser.parse_args()))


from __future__ import annotations
from collections.abc import Iterable, Iterator
from typing import Any, List

class AlphabeticalOrderIterator(Iterator):
    #_position stores current traversal position
    _position: int = None

    #_reverse is for what direction iterator is traversing in
    _reverse: bool = False

    def __init__(self, collection: WordsCollection, reverse: bool = False) -> None:
        self._collection = collection
        self._reverse = reverse
        self._position = -1 if reverse else 0

    def __next__(self): #returns the next item in the sequence, if it reaches the end it raises StopIteration()
        try:
            value = self._collection[self._position]
            self._position += -1 if self._reverse else 1 #depending on _reverse's value position will go forward or backwards in the sequence
        except IndexError:
            raise StopIteration()

        return value

class WordsCollection(Iterable):
    def __init__(self, collection: List[Any] = []) -> None:
        self._collection = collection

    def __iter__(self) -> AlphabeticalOrderIterator:
        return AlphabeticalOrderIterator(self._collection)

    def get_reverse_iterator(self) -> AlphabeticalOrderIterator:
        return AlphabeticalOrderIterator(self._collection, True)

    def add_item(self, item: Any):
        self._collection.append(item)

if __name__ == "__main__":
    collection = WordsCollection()
    collection.add_item("First")
    collection.add_item("Second")
    collection.add_item("Third")

    print("Straight traversal:")
    print("\n".join(collection))
    print("")

    print("Reverse traversal:")
    print("\n".join(collection.get_reverse_iterator()), end="")


import sys
import time
import sched
import random
import re
import os
import csv
import random

import argparse
import torch

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

import train
from train import Module

buttons = ["A", "B", "X", "Y", "up", "Down", "Left", "Right"]

def add_output_to_file(filename, id, buttons):
    """Buttons: boolean list, see list of buttons"""
    if not os.path.exists(filename):
        file = open(filename, 'w')
        file.write("id,A,B,X,Y,Up,Down,Left,Right\n")
        file.close()

    file = open(filename, 'a')
    file.write(str(id) + ',' + ','.join([str(button) for button in buttons]) + '\n')
    file.close()

class FileChangeHandler(FileSystemEventHandler):
    def __init__(self, data_path, model_checkpoint_folder, args):
        self.data_path = data_path
        self.model_checkpoint_folder = model_checkpoint_folder
        self.objectives = args.objectives
        self.t = args.t

        self.latest_model_file = None
        self.iter = 0
        self.dir_name = None
        self.prev_id = None
        self.model = None
        self.use_weighted_dataloader = args.use_weighted_dataloader

        #Other args
        self.reload_model_every_n_iterations = args.reload

    def load_model(self):
        model_file = train.get_latest_model(self.model_checkpoint_folder)

        if not model_file == self.latest_model_file and not model_file == None:
            model_hparams = {"t": self.t, "objectives": self.objectives}
            optimizer_hparams={"lr": 0.1}

            self.model = Module(self.objectives, data_path, model_hparams, optimizer_hparams)
            state_dict = torch.load(model_file)["state_dict"]
            self.model.load_state_dict(state_dict)
            self.latest_model_file = model_file

        print(f'Iteration {self.iter}\tLoaded model {self.latest_model_file}\tDeterministic: {self.iter % 4 >= 2}')

    def on_created(self, event):
        if event.is_directory:
            output_file = os.path.join(event.src_path, 'outputFile.csv')
            if not os.path.exists(output_file):
                file = open(output_file, 'w')
                file.write("id,A,B,X,Y,Up,Down,Left,Right\n")
                file.close()
            if self.iter % self.reload_model_every_n_iterations == 0:
                self.load_model()
            self.iter += 1
        else:
            event_dir_name = os.path.dirname(event.src_path)
            event_base_name = os.path.basename(event.src_path)

            if not event.src_path.split('.')[1] == "csv":
                id = int(re.sub("[^0-9]", "", event_base_name))
                output_file = event_dir_name + "/outputFile.csv"

                #Sometimes FIleSystemWatcher triggers twice, so check if new id is higher than previous id,
                #or if it is a new directory (in that case, reset the previous id)
                new_dir = False
                if not event_dir_name == self.dir_name:
                    new_dir = True
                    self.prev_id = 0
                self.dir_name = event_dir_name

                if id <= self.prev_id:
                    return #ignore false screenshot
                else:
                    self.prev_id = id
                if self.model:
                    #Add previous 3 frames if possible
                    input = {}
                    if not os.path.isfile(output_file): #First frame
                        input["previous_points"] = []
                        input["screenshots"] = []
                    else:
                        with open(output_file, newline='') as state_file_data:
                            reader = csv.DictReader(state_file_data, delimiter=',')
                            points = []
                            for row in reader:
                                if id - int(row["id"]) <= self.t * 10 - 10:
                                    points.append(row)
                            input["previous_points"] = points
                        input["screenshots"] = [f"{event_dir_name}/screenshot_{point['id']}.png" for point in input["previous_points"]]

                    #Add current frame
                    input["screenshots"].append(f"{event_dir_name}/screenshot_{id}.png")

                    next_inputs = train.get_next_input(self.model, input, deterministic=self.iter % 4 >= 2, objectives=self.objectives, t=self.t)

                    add_output_to_file(output_file, id, next_inputs)
                else:
                    #If no model, return random input
                    i = random.randint(0, 63)
                    next_inputs = [int(i/32)%2==1, int(i/16)%2==1, int(i/8)%2==1, int(i/4)%2==1, i%4==0, i%4==1, i%4==2, i%4==3]
                    next_inputs = [int(x) for x in next_inputs]

                    add_output_to_file(output_file, id, next_inputs)

    def on_modified(self, event):
        pass

if __name__ == "__main__":
    print('Running file watch.py')
    parser = argparse.ArgumentParser()

    # Experiment number, required!
    parser.add_argument('-e', '--experiment', type=int, required=True)
    parser.add_argument('-r', '--reload', type=int, default=2)
    parser.add_argument('-o', '--objectives', nargs='+', default=[])
    parser.add_argument('-t', type=int, default=4,
                        help='How many frames to look for in the past')

    parser.add_argument('--use_weighted_dataloader', action='store_true',
                        help='Use a dataloader weighted to get a balanced amount of x_speed values')
    parser.add_argument('--use_full_dataloader', action='store_false', dest='use_weighted_dataloader',
                        help='Use the entire dataset for the dataloader')
    parser.set_defaults(use_weighted_dataloader=False)

    args = parser.parse_args()

    if len(args.objectives) == 0:
        args.objectives = ['speed', 'death']
    print("Training objectives: ", args.objectives)

    data_path = f'experiments\\experiment_{args.experiment}\\data'
    model_checkpoint_folder = f"experiments\\experiment_{args.experiment}\\models\\lightning_logs"

    event_handler = FileChangeHandler(data_path, model_checkpoint_folder, args)
    observer = Observer()
    observer.schedule(event_handler, data_path, recursive=True)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()

    observer.join()


#! usr/bin/python3

""" Class based on Travelling Salesman Problem """

import math
from typing import Union

class ShortDistance:
    """ Full calculation of possible paths """

    def __init__(self):
        self._route = []

    @staticmethod
    def calculate_distance(origin: Union[tuple, list], destination: Union[tuple, list]):
        """
            Function that calculates the distance between two
            coordinates in Km.

            Args:
                origin (dict): Values with origin coordinates.
                destination (dict): Values with origin coordinates.

            Returns:
                The value in Km of the distance between two places.
        """

        earth_radius = 6378.7
        radians = 180/math.pi

        lat1 = origin[0] / radians
        long1 = origin[1] / radians

        lat2 = destination[0] / radians
        long2 = destination[1] / radians

        return earth_radius * math.acos(
            math.sin(lat1) * math.sin(lat2) +
            math.cos(lat1) * math.cos(lat2) *
            math.cos(long2 - long1)
        )

    def shortest_path(self, starting_point: str, destinations: dict, route=None):
        """
            Returns a list with shortest order from origin to destination.

            Args:
                starting_point (str): Initial point to be considered.
                destinations (dict): Dictionary with coordinates as keys and the
                                     place as key.
                route (list): Default None. Will handled by the Class.

            Returns:
                route (list): A list with places ordered by smallest distance.
        """

        lat_long = destinations.get(starting_point)

        if len(destinations) < 2:
            route.append({starting_point: lat_long})
            return route

        minimum = {}

        self._route.append({starting_point: lat_long})

        for i in destinations:
            if i != starting_point:
                distance = ShortDistance.calculate_distance(
                    destinations.get(starting_point),
                    destinations.get(i)
                )

                minimum[distance] = i

        closest = minimum.get(min(minimum))
        destinations.pop(starting_point)

        return self.shortest_path(
            closest,
            destinations,
            self._route
        )


# Third Party Stuff
from builtins import object
import django_filters

# Spoken Tutorial Stuff
from cms.models import News
from events.models import State, MediaTestimonials
from creation.models import FossCategory

class NewsStateFilter(django_filters.FilterSet):
    state = django_filters.ChoiceFilter(choices=State.objects.none())

    def __init__(self, *args, **kwargs):
        news_type_slug = None
        if 'news_type_slug' in kwargs:
            news_type_slug = kwargs['news_type_slug']
            kwargs.pop('news_type_slug')

        super(NewsStateFilter, self).__init__(*args, **kwargs)
        print(("news_type_slug :",news_type_slug))
        choices = None
        choices = list(State.objects.filter(id__in=News.objects.filter(news_type__slug=news_type_slug).values(
            'state_id').distinct()).order_by('name').values_list('id', 'name'))
        choices.insert(0, ('', '---------'),)
        self.filters['state'].extra.update({'choices': choices})

    class Meta(object):
        model = News
        fields = ['state']

class MediaTestimonialsFossFilter(django_filters.FilterSet):
    foss = django_filters.ChoiceFilter(choices=FossCategory.objects.none())

    def __init__(self, *args, **kwargs):
        super(MediaTestimonialsFossFilter, self).__init__(*args, **kwargs)

        choices = None
        choices = list(FossCategory.objects.filter(id__in=MediaTestimonials.objects.filter().values(
            'foss_id').distinct()).order_by('foss').values_list('id', 'foss'))
        choices.insert(0, ('', '---------'),)
        self.filters['foss'].extra.update({'choices': choices})

    class Meta:
        model = MediaTestimonials
        fields = ['foss']