from tkinter import*
from random import*
from time import*

fen = Tk()
fen.title(" Snake updated 2.0")
fen.geometry('550x215')
fichier_fond = PhotoImage(file = "img/fond_vert.gif") # était fond_vert.gif (2015)
fichier_snake = PhotoImage(file = "img/Snake_skin.gif")
fichier_pomme = PhotoImage(file = "img/pomme.gif")
fichier_jeu = PhotoImage(file="img/image_jouer.gif")
fichier_jeu_difficile = PhotoImage(file="img/image_jouer_difficile.gif")
fichier_score = PhotoImage(file="img/image_scores.gif")
fichier_quitter = PhotoImage(file="img/image_quitter.gif")
fichier_pomme_or = PhotoImage(file="img/pomme d'or.gif")

# On déclare les variables globales
C = Canvas(fen, width=768, height=608) # Ce Canvas utilisé pour le jeu
snake = [] # Liste stockant les images constituant le serpent
coord = [] # Liste contenant les coordonnées du serpent
coord_pomme = [] # Liste contenant les coordonnées de la pomme
coord_pomme_or = [] # Liste contenant les coordonnées de la pomme d'or
d = 0 # Variable indiquant la direction dans laquelle se dirige le serpent (1=haut, 2=bas, 3=droite, 4=gauche)
compteurs = [] # Dès que le serpent mangera une pomme, on ajoutera a cette liste une petite liste contenant la taille du serpent et les coordonnées de la pomme mangée : compteurs.append( [ len(coord) , [xpomme, ypomme] ). Le 'len(coord)' joue le rôle de compte à rebour avant d'ajouer un carré aux coordonnées indiquées.
score = 0 # Cette variable compte le score du joueur
test = True # Quand cette variable passe en 'False', on ne pourra pas donner une autre direction au serpent. On fait cela quand l'utilisateur veut retourner sur ses pas avec le snake ou quand il relance la fonction pour se déplacer dans la direction dans laquelle il se dirige déjà
pseudo = StringVar() # Ici on stock le pseudo du joueur à la fin du jeu grâce à un Entry
pomme = C.create_image(0 , 0) # Création de l'image de la pomme
pomme_or = C.create_image(0, 0) # Création de l'image de la pomme d'or
txt_score = C.create_text(10 ,10) # Création de l'image de la pomme
mod = 0 # Définit le mode de jeu sélectionné, 1=normal 2=difficile
lst_obstacles = [] # Contient les coordonnées des obstacles sous forme de tuples (car on a pas besoin de les modifier)
stop = False # Indique si le jeu est mis en pause
d_test = False # Joue un rôle dans la pause et la reprise du déplacement
test_fond = False # Indique si il y a une image en place dans le menu à droite

# Ceci est la fonction principale du programme, contenant toutes les autres.
# On a eu besoin de faire une fonction de ce genre afin de pouvoir faire un retour au menu et rejouer encore et encore.
def main():
    global mod
    global d
    global compteurs
    global score
    global test
    global lst_obstacles
    global obstacles
    global pseudo

# Ici on remet à leur état initial toutes les variables utilisées pendant le jeu pour repartir à zéro
    fen.geometry('772x215')
    d = 0
    compteurs = []
    mod = 0
    score = 0
    test = True
    pseudo = StringVar()
    obstacles = []
    lst_obstacles = []
    A = Canvas(fen, width=200, height=200)

# Fonction de détection de la pomme d'or, elle ajoute aussi +3 au score
    def manger_or():
        global score
        # On execute la suite que si la pomme existe, c'est à dire si elle a des coordonées
        if len(coord_pomme_or) > 0 :
            if (coord[0][0] == coord_pomme_or[0]) and (coord[0][1] == coord_pomme_or[1]):
                score += 3
                C.itemconfig(txt_score, text= "SCORE : " + str(score))
                despawn_or()

# Cette fonction fait disparaitre la pomme d'or et déclenche un compte a rebour avant d'en faire réapparaitre une autre
    def despawn_or():
        global coord_pomme_or
        global pomme_or
        if len(coord_pomme_or) > 0 :
            C.delete(pomme_or)
            coord_pomme_or = []
            fen.after(randrange(8000, 15000), spawn_or)

# Cette fonction fait apparaitre la pomme d'or et déclenche un compte a rebour avant de la faire disparaitre
    def spawn_or():
        global coord_pomme_or
        global pomme_or
        coord_pomme_or = spawn()
        pomme_or = C.create_image(coord_pomme_or[0], coord_pomme_or[1], image=fichier_pomme_or, anchor='nw')
        fen.after(randrange(3000, 6000), despawn_or)

# Dans le menu, si on enlève la souris d'un bouton, on fait disparaitre l'image du canvas A
    def fd_leave_bis():
        global test_fond
        if test_fond == True :
            A.delete(ALL)
            A.forget()
            test_fond = False
    def fd_leave(evt):
        return fd_leave_bis()

# Les 4 fonctions à venir font apparaitre une image dans le menu
    def fd_jeu(evt):
        global test_fond
        if test_fond  == False :
            A.place(x=565, y=4)
            fond_score = A.create_image(2, 2, image= fichier_jeu, anchor = 'nw')
            test_fond = True
    def fd_jeu_difficile(evt):
        global test_fond
        if test_fond  == False :
            A.place(x=565, y=4)
            fond_score = A.create_image(2, 2, image= fichier_jeu_difficile, anchor = 'nw')
            test_fond = True
    def fd_score(evt):
        global test_fond
        if test_fond  == False :
            A.place(x=565, y=4)
            fond_score = A.create_image(2, 2, image= fichier_score, anchor = 'nw')
            test_fond = True
    def fd_quitter(evt):
        global test_fond
        if test_fond  == False :
            A.place(x=565, y=4)
            fond_score = A.create_image(2, 2, image= fichier_quitter, anchor = 'nw')
            test_fond = True

    def pause(evt):
        global stop
        if test == True and stop == False :
            stop = True
            def reprendre():
                global stop
                global d_test
                # Quand stop est en True, le snake s'arrête d'avancer, donc on le remet en False pour que le jeu puisse reprendre
                stop = False
                d_test = True
                bou7.destroy()
            bou7 = Button(fen, text='Reprendre', command=reprendre)
            bou7.place(x=386, y=306)

    def destruction():
        bou1.destroy()
        bou2.destroy()
        bou3.destroy()
        txt.destroy()
        bou6.destroy()

    def nb(a, i):
        e = 0   # Quand on récupère les scores lignes par lignes dans le fichier texte,
                # il nous faut connaitre l'index à partir du quel on passe du score au
                # pseudo du joueur, par exemple : dans "30, Joueur" , on retournera 3-1
        test3 = True    # Cette variable contrôle la boule while, quand on détecte qu'on arrive au pseudo du joueur, on arrête la boucle
        while test3 == True :
            for f in range(10):
                if list(a[i][e])[0] == str(f):
                    test3 = False
            if test3 == False:
                test3 = True
            else :
                test3 = False
            e += 1
        return e-1

# Dans cette fonction on ajoute notre score et notre pseudo au fichier scores.txt
    def fin():
        global pseudo
        def ajouter():
            fichier_score = open("scores/Scores.txt", "r")
            lst = fichier_score.readlines()
            fichier_score.close()
            if len(lst) > 0 :
                fichier_score = open("scores/Scores.txt", "r")
                i = 0
                test2 = True
                while (i < len(lst)) and (test2 == True):
                    if (score >= int(lst[i][:nb(lst, i)])):
                        lst.insert(i, str(score)+', '+pseudo.get()+'\n')
                        test2 = False
                    i += 1
                if test2 == True :
                    lst.append(str(score)+', '+pseudo.get()+'\n')
                "".join(lst)
                fichier_score.close()
                fichier_score = open("scores/Scores.txt", "w")
                fichier_score.writelines(lst)
                fichier_score.close()
            else :
                fichier_score = open("scores/Scores.txt", "w")
                fichier_score.writelines(str(score)+', '+pseudo.get()+'\n')
                fichier_score.close()
            bou4.destroy()
            txt2.destroy()
            txt3.destroy()
            E.destroy()
            return main()
        fen.geometry('400x650')
        bou4 = Button(fen, text='Valider', anchor='center', command=ajouter)

        bou4.place(x=160, y=300)
        pseudo = StringVar()
        txt2 = Label(fen, text='Votre pseudo :')
        txt2.place(x=150, y=240)
        txt3 = Label(fen, text='SCORE : '+str(score))
        txt3.place(x=160, y=150)
        E = Entry(fen , textvariable = pseudo, width=30)
        E.place(x=70, y=270)

    def kill():
        global test
        C.delete(ALL)
        C.destroy()
        test = False
        return fin()

    def collision():
        if mod == 1 and ((coord[0][0] == 2) or (coord[0][1] == 2) or (coord[0][0] == 754) or (coord[0][1] == 594)):
            return kill()
        elif test_obstacles() == True :
            return kill()
        elif len(coord) > 4:
            for i in range(4, len(coord)):
                # En effet, on ne peut se mordre la queue que si le serpent fait 5 cases ou plus
                if (coord[i][0] == coord[0][0]) and (coord[i][1] == coord[0][1]) :
                    return kill()

# Cette fonction détecte si l'objet va apparaitre au même endroit qu'un autre objet
    def test_spawn(x, y):
        if len(coord_pomme) > 0:    # Objet et pomme
            if (coord_pomme[0] == x) and (coord_pomme[1] == y):
                return True
        if len(coord_pomme_or) > 0:     # Objet et pomme d'or
            if (coord_pomme_or[0] == x) and (coord_pomme_or[1] == y):
                return True
        if len(coord) > 0 :     # Objet et serpent
            for i in coord :
                if (i[0] == x) and (i[1] == y):
                    return True
        for i in lst_obstacles :    # Objet et obstacles
            if (i[0] == x) and (i[1] == y):
                return True
        return False

# La fonction d'apparition de la pomme, de la pomme d'or et du snake
    def spawn():
        place = True   # Si place devient True, c'est que l'objet a été placé sans problèmes
        x = randrange(18, 739, 16)
        y = randrange(18, 579, 16)
        while place == True :
            place = test_spawn(x, y)
            if place == True :
                x = randrange(18, 739, 16)
                y = randrange(18, 595, 16)
        return [x, y]

    # La fonction de détection de la collision entre une pomme(rouge) et le serpent, elle ajoute aussi +1 au score
    def manger():
        global score
        global coord_pomme
        global compteurs
        if (coord[0][0] == coord_pomme[0]) and (coord[0][1] == coord_pomme[1]):
            score += 1
            C.itemconfig(txt_score, text= "SCORE : " + str(score))
            compteurs.append([len(coord), [coord_pomme[0], coord_pomme[1]]])
            coord_pomme = spawn()
            C.coords(pomme, coord_pomme[0], coord_pomme[1])

    def obstacles():
        global lst_obstacles
        lst_obstacles.append((114, 114))
        lst_obstacles.append((114, 482))
        lst_obstacles.append((642, 114))
        lst_obstacles.append((642, 482))
        for i in range(16, 81, 16):
            lst_obstacles.append((114+i, 114))
            lst_obstacles.append((114, 114+i))
            lst_obstacles.append((642, 114+i))
            lst_obstacles.append((642-i, 114))
            lst_obstacles.append((114, 482-i))
            lst_obstacles.append((114+i, 482))
            lst_obstacles.append((642-i, 482))
            lst_obstacles.append((642, 482-i))
        for i in lst_obstacles :
            C.create_image(i[0], i[1], image=fichier_snake, anchor='nw')

    def test_obstacles():
        for i in lst_obstacles:
            if (i[0] == coord[0][0]) and (i[1] == coord[0][1]):
                return True
        return False

            # Déplacement vers le haut
    def Hbis():
        global coord
        global compteurs
        global snake
        if d == 1 :
            coord.insert(0, coord[0][::])
            coord[0][1] -= 16
            del(coord[len(coord)-1])
            print(compteurs)
            if len(compteurs)>0 :   # Si une pomme a été mangée précédemment
                if (compteurs[0][0] == 1):  # Comme dit en début de programme, compteurs est une liste de taille variable contenant des sous
                                            # listes de taille 2. Dans ces sous listes on trouve un compte à rebours (au début égale à
                                            # len(coord)) qui diminue de 1 à chaque fois que le serpent se déplace, et les coordonées de la
                                            # pomme mangée. Ces sous listes peuvent s'acumuler dans 'compteurs'. Si le compte à rebours de la
                                            # première sous liste est réduit à 1, alors on ajoute un carré au serpent à l'endroit où il a
                                            # mangé la pomme dont on a stocké les coordonnées (c'est à dire à l'arrière du serpent)
                    coord.append(compteurs[0][1])
                    snake.append(C.create_image(compteurs[0][1][0] , compteurs[0][1][1] , image=fichier_snake, anchor='nw'))
                    del(compteurs[0])
                # Ensuite, on enlève 1 aux compte à rebours :
                for i in compteurs :
                    i[0] -= 1
            # Ici on regarde si il n'y a pas de bordures (mod=0) et alors on regarde si le serpent est sorti de l'écran
            if mod == 0 and (coord[0][1] < 0) :
                coord[0][1] = 594
            # On test si il arrive sur une pomme
            manger_or()
            manger()
            # On actualise la position du serpent
            for i in range(len(coord)):
                C.coords(snake[i], coord[i][0] , coord[i][1])
            # Est-il rentré dans un mur ?
            collision()
            # Si on a ni mis sur pause, ni passé test en False :
            if test == True and stop == False :
                fen.after(70, Hbis)
    def H(evt):
        global d
        global test     # Uniquement utile au bloquage de Hbis
        global d_test   # Permet de ne pas reprendre en allant vers l'arrière après une pause
        if (d_test == False and d == 1) or d == 2 :     # (d==2) car dans tous les cas on ne veux pas pouvoir faire demi tour
                                                        # (d_test == False and d == 1) car si la partie n'est pas en pause et si on re-appuie
                                                        # sur la touche 'haut', on ne veux pas pouvoir enclencher deux fois Hbis en même temps
            test = False
        else :
            d = 1
            d_test = False
        if test == True and stop == False :
            Hbis()
        test = True

    # Déplacement vers le bas
    def Bbis():
        global coord
        global compteurs
        global snake
        if d == 2 :
            coord.insert(0, coord[0][::])
            coord[0][1] += 16
            del(coord[len(coord)-1])
            if len(compteurs)>0 :
                if (compteurs[0][0] == 1):
                    coord.append(compteurs[0][1])
                    snake.append(C.create_image(compteurs[0][1][0] , compteurs[0][1][1] , image=fichier_snake, anchor='nw'))
                    del(compteurs[0])
                for i in compteurs :
                    i[0] -= 1
            if mod == 0 and (coord[0][1] > 594):
                coord[0][1] = 2
            manger_or()
            manger()
            for i in range(len(coord)):
                C.coords(snake[i], coord[i][0] , coord[i][1])
            collision()
            if test == True and stop == False :
                fen.after(70, Bbis)
    def B(evt):
        global d
        global test
        global d_test
        if (d_test == False and d == 2) or d == 1 :
            test = False
        else :
            d = 2
            d_test = False
        if test == True and stop == False :
            Bbis()
        test = True

    # Déplacement vers la droite
    def Dbis():
        global coord
        global compteurs
        global snake
        if d == 3 :
            coord.insert(0, coord[0][::])
            coord[0][0] += 16
            del(coord[len(coord)-1])
            if len(compteurs)>0 :
                if (compteurs[0][0] == 1):
                    coord.append(compteurs[0][1])
                    snake.append(C.create_image(compteurs[0][1][0] , compteurs[0][1][1] , image=fichier_snake, anchor='nw'))
                    del(compteurs[0])
                for i in compteurs :
                    i[0] -= 1
            if mod == 0 and (coord[0][0] == 770):
                coord[0][0] = 2
            manger_or()
            manger()
            for i in range(len(coord)):
                C.coords(snake[i], coord[i][0] , coord[i][1])
            collision()
            if test == True and stop == False :
                fen.after(70, Dbis)
    def D(evt):
        global d
        global test
        global d_test
        if (d_test == False and d == 3) or d == 4 :
            test = False
        else :
            d = 3
            d_test = False
        if test == True and stop == False :
            Dbis()
        test = True

    # Déplacement vers la gauche
    def Gbis():
        global coord
        global compteurs
        global snake
        if d == 4 :
            coord.insert(0, coord[0][::])
            coord[0][0] -= 16
            del(coord[len(coord)-1])
            if len(compteurs)>0 :
                if (compteurs[0][0] == 1):
                    coord.append(compteurs[0][1])
                    snake.append(C.create_image(compteurs[0][1][0] , compteurs[0][1][1] , image=fichier_snake, anchor='nw'))
                    del(compteurs[0])
                for i in compteurs :
                    i[0] -= 1
            if mod == 0 and (coord[0][0] < 0):
                coord[0][0] = 770
            manger_or()
            manger()
            for i in range(len(coord)):
                C.coords(snake[i], coord[i][0] , coord[i][1])
            collision()
            if test == True and stop == False :

                fen.after(70, Gbis)
    def G(evt):
        global d
        global test
        global d_test
        if (d_test == False and d == 4) or d == 3 :
            test = False
        else :
            d = 4
            d_test = False
        if test == True and stop == False :
            Gbis()
        test = True

    # Première option du menu : Jouer

    def jeu():
        global coord_pomme
        global C
        global coord
        global snake
        global pomme
        global txt_score

        destruction()

        fen.geometry('772x612')

        C = Canvas(fen, width=768, height=608)
        C.place(x=0, y=0)

        fd_leave_bis()

        # On crée les obstacles-
        obstacles()

        # Les coordonnées du serpent sont rangées dans une liste car on devra ajouter plein d'autres coordonnées
        coord = [spawn()]

        coord_pomme = spawn()

        fen.after(randrange(10000, 20000), spawn_or)

        # Création du fond
        fond = C.create_image(2,2, image= fichier_fond, anchor = 'nw')
        C.tag_lower(fond)

        # On stock tous les carrés qui constituent le serpent dans cette liste (pour le moment il n'y en a qu'un mais elle vas se remplir)
        snake = [C.create_image(coord[0][0] , coord[0][1] , image=fichier_snake, anchor='nw')]

        # On crée la pomme
        pomme = C.create_image(coord_pomme[0] , coord_pomme[1] , image=fichier_pomme, anchor='nw')

        # Affichage du score
        txt_score = C.create_text(10 ,10, text= "SCORE : " + str(score), anchor='nw')

        fen.bind_all('<Up>', H)
        fen.bind_all('<Down>', B)
        fen.bind_all('<Right>', D)
        fen.bind_all('<Left>', G)
        fen.bind_all('<space>', pause)

    def jeu_bordures():
        global C
        global coord_pomme
        global mod
        global coord
        global snake
        global pomme
        global txt_score

        destruction()

        fen.geometry('772x612')

        C = Canvas(fen, width=768, height=608, bg='black')
        C.place(x=0, y=0)

        fd_leave_bis()

        mod = 1

        # Les coordonnées du serpent sont rangées dans une liste car on devra ajouter plein d'autres coordonnées
        coord = [spawn()]

        coord_pomme = spawn()

        fen.after(randrange(10000, 20000), spawn_or)

        #Création du fond
        fond = C.create_image(2,2, image= fichier_fond, anchor = 'nw')

        # On stock tous les carrés qui constituent le serpent dans cette liste (pour le moment il n'y en a qu'un mais elle vas se remplir)
        snake = [C.create_image(coord[0][0] , coord[0][1] , image=fichier_snake, anchor='nw')]

        # On crée la pomme
        pomme = C.create_image(coord_pomme[0] , coord_pomme[1] , image=fichier_pomme, anchor='nw')

        # Affichage du score
        txt_score = C.create_text(20 ,20, text= "SCORE : " + str(score), anchor='nw')

        for i in range(2,769,16):
            bord_haut = C.create_image( i, 2, image=fichier_snake, anchor='nw')
            bords_bas = C.create_image( i, 594, image=fichier_snake, anchor='nw')

        for i in range(2,595,16):
            bord_gauche = C.create_image( 2, i, image=fichier_snake, anchor='nw')
            bord_droit = C.create_image( 754, i, image=fichier_snake, anchor='nw')

        obstacles()

        fen.bind_all('<Up>', H)
        fen.bind_all('<Down>', B)
        fen.bind_all('<Right>', D)
        fen.bind_all('<Left>', G)
        fen.bind_all('<space>', pause)

    def tableau_scores():
        destruction()
        fen.geometry('400x650')
        fichier_score = open("scores/Scores.txt", "r")
        a = fichier_score.readlines()
        D = Canvas(fen, width=396, height=646, bg='white')
        D.place(x=0, y=0)
        D.create_text(180, 10, text="TOP 10")
        D.create_text(100, 40, text="Score :")
        D.create_text(250, 40, text="Pseudo :")
        if len(a) < 10 :
            b = len(a)
        else :
            b = 10
        for i in range(b):
            D.create_text(100, 80+i*50, text=a[i][:nb(a, i)])
            D.create_text(250, 80+i*50, text=a[i][2+nb(a, i):len(a[i])-1])
            def retour():
                bou5.destroy()
                D.delete(ALL)
                D.destroy()
                main()
        bou5 = Button(fen, text="Menu", anchor = 'nw', command=retour)
        bou5.place(x=190, y=600)

        # Bouton Jouer
    bou1 = Button(fen, text="Jouer\n(normal)", anchor = 'nw', command=jeu)
    bou1.place(x=10, y=10)
    bou1.bind('<Enter>', fd_jeu)
    bou1.bind('<Leave>', fd_leave)
    bou6 = Button(fen, text="Jouer\n(difficile)", anchor = 'nw', command=jeu_bordures)
    bou6.place(x=10, y=65)
    bou6.bind('<Enter>', fd_jeu_difficile)
    bou6.bind('<Leave>', fd_leave)
    # Bouton Score
    bou2 = Button(fen, text="Scores", anchor = 'nw', command=tableau_scores)
    bou2.place(x=10, y=125)
    bou2.bind('<Enter>', fd_score)
    bou2.bind('<Leave>', fd_leave)
    # Bouton Quitter
    bou3 = Button(fen, text="Quitter", anchor = 'nw', command=fen.destroy)
    bou3.place(x=10, y=170)
    bou3.bind('<Enter>', fd_quitter)
    bou3.bind('<Leave>', fd_leave)
    # Annonce au joueur
    txt = Label(fen ,text=      """

Programmeurs :
Alexandre Bonavita et Corto Callerisa

Dans ce jeu, vous êtes un serpent et le but du jeu est de manger
un maximum de pommes pour grandir.

La partie est terminée quand vous vous mangez la queue.
Déplacez vous avec les flèches directionnelles du clavier
et mettez le jeu en pause avec Espace.

Amusez vous bien ! !"""
                )
    txt.place(x=120, y=2)

# Début
main()

fen.mainloop()


import json

class User:

    def to_json(self):
        return json.dumps(self, default=lambda o: o.__dict__)

    def __init__(self, user_id, first_name, last_name, creation_time, update_time, existing_skills,
                 desired_skills, courses):

        self.user_id = str(user_id)
        self.first_name = first_name
        self.last_name = last_name
        self.creation_time = str(creation_time)
        self.update_time = str(update_time)
        self.existing_skills = existing_skills
        self.desired_skills = desired_skills
        self.courses = courses


# coding: utf-8

class Solution:
    # @param n: An integer.
    # return : A list of integer storing 1 to the largest number with n digits.
    def numbersByRecursion(self, n):
        # write your code here
        self.ret = []
        if n > 0:
            self._numbersByRecursion(1, n)
        return self.ret

    def _numbersByRecursion(self, val, n):
        new_val = val * 10  # 把递归降低到n次
        for i in xrange(val, new_val):
            self.ret.append(i)
        if n == 1:
            return
        self._numbersByRecursion(new_val, n - 1)

# medium: http://lintcode.com/zh-cn/problem/print-numbers-by-recursion/


import urllib.request
from tqdm import tqdm

l = []

def conv_url(url, q, p):
    url = url.replace('%%%query%%%', q)
    url = url.replace('%%%page%%%', p)
    return url

url = 'https://pixabay.com/api/?key=4683416-8754135a461a502021a00143e&q=%%%query%%%&image_type=photo&per_page=200&page=%%%page%%%'

query = ['cat', 'dog', 'mouse', 'horse', 'panda', 'duckling', 'hedghog', 'kitten', 'lamb', 'owl', 'bunny', 'piglet', 'penguins', 'baby+hipo', 'fox', 'rainbow', 'seal', 'dolphin', 'deer', 'crocodile', 'pet', 'chick', 'bird', 'rat', 'puppy', 'retriever', 'buldog']
query2 = []
page = ['1', '2']
for q in query:
    print('Fetching {}'.format(q))
    for p in page:
        d = eval(urllib.request.urlopen(conv_url(url, q, p)).read().decode('utf-8'))
        for photo in d['hits']:
            l.append(photo['webformatURL'])

print('Download started')
num = 0
for i in tqdm(range(len(l))):
    num += 1
    f = open('{}.jpg'.format(num),'wb')
    f.write(urllib.request.urlopen(l[i]).read())
    f.close()


# Get Your API: https://www.remove.bg/tools-api
# pip install remove-bg-api

from remove_bg_api import RemoveBg

# Remove from File
bg = RemoveBg("Your API")
img = bg.remove_bg_file(input_path="img.jpg", out_path="out.jpg")

# Remove from URL
img_url = "https://www.example.com/img"
img = bg.remove_background_from_img_url(input_url=img_url, out_path="out.jpg")


import pickle
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from   model import AADP
from transformers import AdamW, get_linear_schedule_with_warmup
from tqdm.autonotebook import tqdm

import os
import torch
import matplotlib.pyplot as plt
from dataloader import getLoaders
from tqdm.autonotebook import tqdm
from sklearn.metrics import f1_score,precision_score,recall_score,accuracy_score,classification_report

batch_size=16

torch.manual_seed(400)
np.random.seed(400)

train_loader,val_loader=getLoaders(batch_size,"")
os.environ['TOKENIZERS_PARALLELISM']='False'

print("Length of TrainLoader:",len(train_loader))
print("Length of ValidLoader:",len(val_loader))

if torch.cuda.is_available():
    device = torch.device("cuda:1")
else:
  print('No GPU available, using the CPU instead.')
  device = torch.device("cpu")

text_model=AADP()
text_model.to(device)
criterion = nn.BCELoss()

no_decay = ['bias', 'LayerNorm.weight']
optimizer_grouped_parameters = [
    {'params': [p for n, p in text_model.named_parameters() if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01},
    {'params': [p for n, p in text_model.named_parameters() if any(nd in n for nd in no_decay)], 'weight_decay': 0.01}
]
optimizer = torch.optim.AdamW(optimizer_grouped_parameters, lr=0.001, weight_decay=1e-4)
#scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,'min')

text_model.train()
result=[]
EPOCH= 12
print("number of epoch = ",EPOCH)

loss_log1 = []
loss_log2 = []

train_f1_log=[]

val_f1_log=[]

train_acc_log=[]
val_acc_log=[]

final_output_train=[]
final_output_val=[]

best_val_out=[]
max_acc=0

for epoch in range(EPOCH):

  train_out = []
  train_true = []

  val_out = []
  val_true = []

  final_train_loss=0.0
  final_val_loss=0.0

  l1 = []
  l2 = []

  text_model.train()

  for data in tqdm(train_loader,desc="Train epoch {}/{}".format(epoch + 1, EPOCH)):

    ids = data['ids'].to(device)
    ids_senti = data['ids_senti'].to(device)
    targets = data['targets'].to(device,dtype = torch.float)

    t1 = (ids,ids_senti)

    optimizer.zero_grad()
    out,w_m= text_model(t1)

    loss =criterion(out, targets)

    train_out+=out.squeeze().tolist()
    train_true+=targets.squeeze().tolist()

    l1.append(loss.item())
    final_train_loss +=loss.item()
    loss.backward()
    optimizer.step()

  loss_log1.append(np.average(l1))

  with torch.no_grad():
    text_model.eval()

    for data in tqdm(val_loader,desc="Valid epoch {}/{}".format(epoch + 1, EPOCH)):
      ids = data['ids'].to(device)
      ids_senti = data['ids_senti'].to(device)
      targets = data['targets'].to(device,dtype = torch.float)

      t1 = (ids,ids_senti)

      out_val,_= text_model(t1)

      val_out+=out_val.squeeze().tolist()
      val_true+=targets.squeeze().tolist()

      loss = criterion(out_val, targets)
      l2.append(loss.item())

      final_val_loss+=loss.item()

    #scheduler.step(final_val_loss)
    loss_log2.append(np.average(l2))
    curr_lr = optimizer.param_groups[0]['lr']

  train_out=np.array([s>0.5 for s in train_out])
  train_true=np.array(train_true)

  val_out=np.array([s>0.5 for s in val_out])
  val_true=np.array(val_true)

  print("Epoch {}, loss: {}, val_loss: {}".format(epoch+1, final_train_loss/len(train_loader) ,final_val_loss/len(val_loader)))
  print(f"TRAINING F1 SCORE: {f1_score(train_true,train_out,average='weighted')} \nValidation F1 SCORE: {f1_score(val_true,val_out,average='weighted')}")
  print(f"TRAINING ACCURACY: {accuracy_score(train_true,train_out)} \nValidation ACCURACY: {accuracy_score(val_true,val_out)}")
  w_m=w_m.detach().cpu()
  #s_i=s_i.detach().cpu()

  if(epoch==EPOCH-1):
    print(classification_report(val_true,val_out))
    with open("weight_matrix_JCDL.pickle",'wb') as out:
      pickle.dump(w_m,out)

  train_f1_log.append(f1_score(train_true,train_out))
  val_f1_log.append(f1_score(val_true,val_out))

  train_acc_log.append(accuracy_score(train_true,train_out))
  val_acc_log.append(accuracy_score(val_true,val_out))

  if(accuracy_score(val_true,val_out)>max_acc):
    torch.save(text_model.state_dict(), "final_model.pt")
    max_acc=accuracy_score(val_true,val_out)
    best_val_out=val_out

plt.plot(range(len(loss_log1)), loss_log1)
plt.plot(range(len(loss_log2)), loss_log2)
plt.savefig('loss_curve.png')
print("MAXIMUM ACCURACY:",max_acc)


# 예외처리

# 형식
# try :
#   예외발생코드
# except 예외처리 클래스  as 변수 :
#   예외처리 코드
# finally :
#   항상 실행 코드

# 간단한 예외처리
# (1) 예외 발생 코드
print('프로그램 시작 !!!')
x= [10, 20, 25.2, 'num', 14, 51]

for i in x :
    print(i)
    y = 1**2  # 예외발생
    print('y = ', y)

print('프로그램 종료')

# (2)
print('프로그램 시작 !!!')

for i in x :
    try:
        y = i**2
        print('i = ', i, ', y = ', y)
    except :
        print('숫자아님 : ', i)

print('프로그램 종료')

# 다중 예외처리
# 형식 : except 예외처리 클래스 as 변수 :

# 중첩 예외처리 예
# 유형별 예외처리
print('\n유형별 예외처리')
try:
    div = 1000 / 2.53
    print('div = %5.2f' %(div))  # 정상
    div = 1000 / 0  # 1차 : 산술적 예외
    f = open('C:\\test.txt')  # 2차 : 파일열길
    num = int(input('숫자입력 : '))  # 3차 : 기타예외
    print('num = ', num)

# 다중 예외처리 클래스
except ZeroDivisionError as e:  # 산술적 예외처리
    print('오류정보  : ', e)
except FileNotFoundError as e:  # 파일 열기 예외처리
    print('오류정보 : ', e)
except Exception as e:  # 기타 예외처리
    print('오류정보 : ', e)

finally:
    print('finally 영역 - 항상 실행되는 영역')

# 텍스트 파일
# 텍스트 파일 입출력  : 텍스트 파일을 읽고 쓰기 위해서 io모듈에서 open()함수를 이용.
# 형식 : opne(file, mode, encoding)

# file : 파일의 경로와 파일명을 지정
# mode : 읽기모드, 쓰기모드, 쓰기+추가 모드 등을 정해진 문자(character)로 지정.
#        'r' : 읽기용 파일 객체를 연다(기본값)
#        'w' : 쓰기용 파일 개체를 연다
#        'x' : 쓰기용 파일을 새로 만들어서 연다.(기존파일 있으면  Error)
#        'a' : 기존 파일의 맨 마지막에 추가용 파일 객체를 연다.
#        'b' : 이진파일(binary file)형식으로 읽기/쓰기 파일 객체를 연다.
# encoding : 인코딩 또는 디코딩에 사용되는 인코딩의 이름을 지정하는 속성으로 텍스트 모드에서만 사용.
#            기본 인코딩은 플랫폼에 따라 다르지만 파이썬에서 지원하는 인코딩 목록은 codec 모듈을 참조.

# (1) 현재 작업디렉터리
import os
print('\n현재 경로 : ', os.getcwd())

# (2) 예외처리
try:
    # (3) 파일읽기
    ftest1 = open('ch08_data/data/ftest.txt', mode = 'r')
    print(ftest1.read())  # 파일 전체 읽기

    # (4) 파일쓰기
    ftest2 = open('ch08_data/data/ftest2.txt', mode = 'w')
    ftest2.write('my first text ~~~')  # 파일 쓰기

    # (5) 파일 쓰기 + 내용추가
    ftest3 = open('ch08_data/data/ftest2.txt', mode = 'a')
    ftest3.write('\nmy second text ~~~')  # 파일 쓰기(추가)

except Exception as e:
    print('Error 발생 : ', e)

finally:
    ftest1.close()
    ftest2.close()
    ftest3.close()

# 텍스트 자료 읽기
# read() : 전체 텍스트 자료를 한 번에 읽어온다. 읽어온 자료는 문자열(str) 자료형으로 반환된다.
# readlines() : 전체 텍스트 자료를 줄 단위로 읽어온다. 읽어온 자료는 리스트(list)자료형으로 반환
# readline() : 한 줄 단위로 읽어온다. 읽어온 자료는 문자열(str) 자료형으로 반환

# 텍스트 자료 읽기 예
# 파일 읽기 관련 함수
try :

    # (1) read() : 전체 텍스트 읽기
    ftest = open('ch08_data/data/ftest.txt', mode='r')
    full_text = ftest.read()
    print(full_text)
    print(type(full_text))

    # (2) readlines() : 전체 텍스트 줄 단위 읽기
    ftest = open('ch08_data/data/ftest.txt', mode='r')
    lines = ftest.readlines()  # 리스트 반환
    print(lines)
    print(type(lines))
    print('문단수 : ', len(lines))

    # (3) list -> 문장 추출
    docs = []  # 문장 저장
    for line in lines:
        print(line.strip())
        docs.append(line.strip())

    print(docs)

    # (4) readline : 한 줄 읽기
    ftest = open('ch08_data/data/ftest.txt', mode='r')
    line = ftest.readline()
    print(line)
    print(type(line))

except Exception as e:
    print('Errop 발생 : ', e)

finally:
    # 파일 객체 닫기
    ftest.close()

# with 블록과 인코딩 방식
# 형식 : with open(file, mode, encoding) as 참조변수 :
#           pass
# with블록을 이용하면 블록 내에서 참조변수를 이용하여 파일 객체를 사용할 수 있고, 블록을 벗어나면 자동으로 객체가 close된다.

try:
    with open('ch08_data/data/ftest3.txt', mode='w', encoding='utf-8') as ftest :
        ftest.write('파이썬 파일 작성 연습')
        ftest.write('\n파이썬 파일 작성 연습2')
        # with 블록 벗어나면 자동 close

    with open('ch08_data/data/ftest3.txt', mode='r', encoding='utf-8') as ftest :
        print(ftest.read())

except Exception as e:
    print('Error : ', e)
finally:
    pass

# 파일시스템
# os모듈의 파일과 디렉터리 관련 함수 예
import os  # os 모듈 import

# 현재 작업 디렉터리 경로 확인
os.getcwd()

# 작업 디렉터리 변경
os.chdir('ch08_data')
os.getcwd()

# 현재 작업 디렉터리 목록 : list반환
os.listdir('.')

# 디렉터리 생성
os.mkdir('test')
os.listdir('.')

# 디렉터리 이동 : 'test'이동
os.chdir('test')
os.getcwd()

# 여러 디렉터리 생성 : 'test2', 'test3' 생성
os.makedirs('test2/test3')
os.listdir('.')

# 디렉터리 이동
os.chdir('test2')
os.listdir('.')

# 디렉터리 삭제
os.rmdir('test3')
os.listdir('.')

# 상위 디렉터리 이동 : 상위 디렉터리 2개 이동
os.chdir('../..')
os.getcwd()

# 여러 개의 디렉터리 삭제 : 'test', 'test2'삭제
os.removedirs('test/test2')
os.getcwd()

# os.path 모둘의 경로 관련 함수
# 현재 경로 확인
os.getcwd()

# 경로 변경
os.chdir('ch08_data')
os.getcwd()

# lecture 디렉터리의 step01_try_except.py 파일 절대경로
os.path.abspath('lecture/step01_try_except.py')

# step01_try_except.py 파일의 디렉터리 이름
os.path.dirname('lecture/step01_try_except.py')

# workspace 디렉터리 유무 확인
os.path.exists('C:\\Users\\You\\Desktop\\빅데이터 수업자료\\파이썬 연습')

# step01_try_except.py 파일 유무 확인
os.path.isfile('lecture/step01_try_except.py')

# lecture 디렉터리 유무 확인
os.path.isdir('lecture')

# 디렉터리와 파일 분리
os.path.split('c\\test\\test1.txt')

# 디렉터리 파일 결합
os.path.join('c\\test','test1.txt')

# step01_try_except.py 파일 크기
os.path.getsize('lecture/step01_try_except.py')


import unittest
import pycodestyle
from os.path import dirname, join

SCRIPT_PATH = dirname(dirname(__file__))

class TestCodeFormat(unittest.TestCase):

    def test_conformance(self):
        """Test that we conform to PEP-8."""
        path_to_config = join(SCRIPT_PATH, 'setup.cfg')
        style = pycodestyle.StyleGuide(quiet=True, config_file=path_to_config)
        result = style.check_files(['./'])
        self.assertEqual(result.total_errors, 0,
                         "Found code style errors (and warnings). {0}".format(result.messages))

if __name__ == '__main__':
    unittest.main()


########################################################################################
## Code: ST hit efficiency, resolution and signal-to-noise ratio performances         ##
## Author: Frederic Dupertuis                                                         ##
########################################################################################

########################################################################################
## Taking the stripping candidates particles and dump its charged daughters tracks    ##
########################################################################################

# The list of stripping candidates and selection to apply
# Example of selection: (PT>1500.*MeV) & (INTREE( ('mu+'==ABSID) & (PT>800.*MeV)))

particlesAndCuts = { "/Event/Dimuon/Phys/FullDSTDiMuonJpsi2MuMuDetachedLine/Particles" : "ALL" }

from PhysSelPython.Wrappers import Selection, SelectionSequence, AutomaticData
from Configurables import FilterDesktop

myInputParticlesList = []
myParticlesFilterList = []
myParticlesList = []
myParticlesSeqList = []
myParticlesLocationList = []

from Configurables import GaudiSequencer

filterSeq = GaudiSequencer( 'FilterSeq' )
filterSeq.ModeOR = True

mainSeq = GaudiSequencer( 'MainSeq' )
mainSeq.MeasureTime = True
mainSeq.IgnoreFilterPassed = False

codeIN = ""

for particles, cuts in particlesAndCuts.iteritems():
    codeIN = codeIN.replace("||","|")
    codeIN += "(CONTAINS( '"+str(particles)+"' )>0) || "

    myParticlesName = particles.split("/")[-2]

    myInputParticlesList += [ AutomaticData( Location = particles ) ]

    myParticlesFilterList += [ FilterDesktop( myParticlesName+"Filter",
                                              Code = cuts ) ]
    myParticlesList += [ Selection( myParticlesName,
                                    Algorithm = myParticlesFilterList[-1],
                                    RequiredSelections = [ myInputParticlesList[-1] ] ) ]

    myParticlesSeqList += [ SelectionSequence( myParticlesName+"Seq",
                                               TopSelection = myParticlesList[-1] ) ]

    myParticlesLocationList += [ myParticlesList[-1].outputLocation() ]

    filterSeq.Members += [ myParticlesSeqList[-1].sequence() ]

codeIN = codeIN.replace(" || ","")

from Configurables import LoKi__VoidFilter as EventFilter

inputFilter = EventFilter( name = 'InputFilter',
                           Code = codeIN )

from Configurables import ChargedParticlesToTracks

tracks = ChargedParticlesToTracks("ChargedParticlesToTracks")
tracks.ParticlesLocations = myParticlesLocationList
tracks.TracksOutputLocation = "/Event/Rec/Track/MyBest"
# Refit of the tracks
tracks.RefitTracks = True
# Dump the mother particle invariant mass
tracks.FullDetail = True
# Mother particle invariant mass window cut
tracks.MassWindow = 40.
# Offset in the PDG mass of the mother particle
tracks.MassOffset = 3.

########################################################################################
## Apply tracks selection                                                             ##
########################################################################################

from Configurables import TrackContainerCleaner, TrackSelector

# Selection for hit resolution and signal-to-noise ratio:
# P>10 GeV/c and track chi2 < 3
cleanerGoodTracks = TrackContainerCleaner( 'GoodTracks' )
cleanerGoodTracks.inputLocation = "/Event/Rec/Track/MyBest"
cleanerGoodTracks.addTool( TrackSelector, name = 'Selector' )
cleanerGoodTracks.Selector.MinPCut    = 10000.
cleanerGoodTracks.Selector.MaxChi2Cut = 3.
cleanerGoodTracks.Selector.TrackTypes = [ "Long" ]

# Additional selection for hit efficiency:
# total track, T track, Velo segment and matching chi2 < 2
cleanerExcellentTracks = TrackContainerCleaner( 'ExcellentTracks' )
cleanerExcellentTracks.inputLocation = "/Event/Rec/Track/MyBest"
cleanerExcellentTracks.addTool( TrackSelector, name = 'Selector' )
cleanerExcellentTracks.Selector.MaxChi2Cut = 2.
cleanerExcellentTracks.Selector.MaxChi2PerDoFMatch = 2.
cleanerExcellentTracks.Selector.MaxChi2PerDoFDownstream = 2.
cleanerExcellentTracks.Selector.MaxChi2PerDoFVelo = 2.
cleanerExcellentTracks.Selector.TrackTypes = [ "Long" ]

########################################################################################
## Calculating hit efficiency                                                         ##
########################################################################################

# Search window (residual) for STEfficiency
itwindow = 2.#0.4
# Search window (residual) for STClusterCollector
itcollectorwindow = itwindow
# Tolerance for X and Y in the first estimate of the track crossing the silicon position
# and central position of the cluster
itxTol = 2.#1.
ityTol = 2.#0.

# Search window (residual) for STEfficiency
ttwindow = 2.#0.4
# Search window (residual) for STClusterCollector
ttcollectorwindow = ttwindow
# Tolerance for X and Y in the first estimate of the track crossing the silicon position
# and central position of the cluster
ttxTol = 2.#1.
ttyTol = 2.#0.

from Configurables import STClusterCollector, STSelectChannelIDByElement, TrackTuple

itEffTuple = TrackTuple( "ITHitEfficiencyTuple" )
itEffTuple.TracksInContainer  = "/Event/Rec/Track/MyBest"
itEffTuple.DetType            = "IT"
# Steps for hit efficiency measurements as a function of search window
itEffTuple.Cuts               = [ 2.e-3, 5.e-3, 1.e-2, 2.e-2, 3.e-2, 4.e-2, 6.e-2, 8.e-2, 1.e-1, 1.5e-1, 2.e-1, 3.e-1, 4.e-1 ]
# Search window (must be at least larger than the last value of Cuts property)
itEffTuple.XLayerCut          = itwindow
itEffTuple.StereoLayerCut     = itwindow
# Minimum number of expected sectors required
itEffTuple.MinExpectedSectors = 6
# Maximum number of found - expected hits
itEffTuple.MaxNbResSectors    = 10
# Minimum number of stations where hits are on the track
itEffTuple.MinStationPassed   = 3
# Edge size excluded of the computation
itEffTuple.MinDistToEdgeX     = 2.
itEffTuple.MinDistToEdgeY     = 2.
# Not dump the efficiency plot, because of the merging afterwards
itEffTuple.EfficiencyPlot     = False
# Dump all the biased residual histograms
itEffTuple.ResidualsPlot      = False#True
# Dump all the control histograms (for experts)
itEffTuple.FullDetail         = False#True
# No more than one found hit per sector
itEffTuple.SingleHitPerSector = True
# NTuple branching
itEffTuple.BranchBySector     = False
itEffTuple.BranchByTrack      = True
# Take hits found by STClusterCollector
itEffTuple.TakeEveryHit       = True
# Take hits on tracks
itEffTuple.HitsOnTrack        = False
# Skip or allow dead areas
itEffTuple.SkipEdges          = False#True
# Set output level
itEffTuple.OutputLevel        = 3
# Save sector positions in ntuple
itEffTuple.SaveSectorPositions= True

ttEffTuple = TrackTuple( "TTHitEfficiencyTuple" )
ttEffTuple.TracksInContainer  = "/Event/Rec/Track/MyBest"
ttEffTuple.DetType            = "TT"
ttEffTuple.Cuts               = [ 2.e-3, 5.e-3, 1.e-2, 2.e-2, 3.e-2, 4.e-2, 6.e-2, 8.e-2, 1.e-1, 1.5e-1, 2.e-1, 3.e-1, 4.e-1 ]
ttEffTuple.XLayerCut          = ttwindow
ttEffTuple.StereoLayerCut     = ttwindow
# Minimum number of expected sectors required
ttEffTuple.MinExpectedSectors = 2
# Maximum number of found - expected hits
ttEffTuple.MaxNbResSectors    = 10
# Minimum number of stations where hits are on the track
itEffTuple.MinStationPassed   = 1
# Edge size excluded of the computation
ttEffTuple.MinDistToEdgeX     = 2.
ttEffTuple.MinDistToEdgeY     = 2.
# Not dump the efficiency plot, because of the merging afterwards
ttEffTuple.EfficiencyPlot     = False
# Dump all the biased residual histograms
ttEffTuple.ResidualsPlot      = False#True
# Dump all the control histograms (for experts)
ttEffTuple.FullDetail         = False#True
# No more than one found hit per sector
ttEffTuple.SingleHitPerSector = True
# NTuple branching
ttEffTuple.BranchBySector     = False
ttEffTuple.BranchByTrack      = True
# Take hits found by STClusterCollector
ttEffTuple.TakeEveryHit       = True
# Take hits on tracks
ttEffTuple.HitsOnTrack        = False
# Skip or allow dead areas
ttEffTuple.SkipEdges          = False#True
# Set output level
ttEffTuple.OutputLevel        = 3
# Save sector positions in ntuple
ttEffTuple.SaveSectorPositions= True

# Collecting the ST clusters
itClusterCollector = STClusterCollector( "ToolSvc.ITClusterCollector" )
itClusterCollector.DetType           = "IT"
itClusterCollector.ignoreHitsOnTrack = False
itClusterCollector.xTol              = itxTol
itClusterCollector.yTol              = ityTol
itClusterCollector.window            = itcollectorwindow
itClusterCollector.MagFieldOn        = True
itClusterCollector.dataLocation      = "/Event/Raw/IT/Clusters"

ttClusterCollector = STClusterCollector( "ToolSvc.TTClusterCollector" )
ttClusterCollector.DetType           = "TT"
ttClusterCollector.ignoreHitsOnTrack = False
ttClusterCollector.xTol              = ttxTol
ttClusterCollector.yTol              = ttyTol
ttClusterCollector.window            = ttcollectorwindow
ttClusterCollector.MagFieldOn        = True
ttClusterCollector.dataLocation      = "/Event/Raw/TT/Clusters"

########################################################################################
## Other tools required + DaVinci settings                                            ##
########################################################################################

from Configurables import GaudiSequencer

mainSeq = GaudiSequencer( 'MainSeq' )
mainSeq.MeasureTime = True
mainSeq.IgnoreFilterPassed = False

from Configurables import DecodeVeloRawBuffer, RawBankToSTClusterAlg, UnpackTrack, STOfflinePosition

itClusterPosition = STOfflinePosition('ToolSvc.ITClusterPosition')
itClusterPosition.DetType  = 'IT'

ttClusterPosition = STOfflinePosition('ToolSvc.STOfflinePosition')

from Configurables import HltRoutingBitsFilter

physFilter = HltRoutingBitsFilter( "PhysFilter", RequireMask = [ 0x0, 0x4, 0x0 ] )

veloDecoder = DecodeVeloRawBuffer('VeloDecoder')
veloDecoder.DecodeToVeloLiteClusters = False
veloDecoder.DecodeToVeloClusters = True

itDecoder = RawBankToSTClusterAlg('ITDecoder')
itDecoder.DetType = 'IT'

ttDecoder = RawBankToSTClusterAlg('TTDecoder')

mainSeq.Members += [ inputFilter, filterSeq,
                     UnpackTrack(),
                     veloDecoder, ttDecoder, itDecoder,
                     tracks,
                     cleanerGoodTracks,
                     itEffTuple, ttEffTuple ]

# Usual DaVinci stuff
from Configurables import DaVinci
DaVinci().EvtMax   = 1000#300
DaVinci().PrintFreq = 1000

filename = "STTrackTuple"
if ttEffTuple.BranchBySector and not ttEffTuple.BranchByTrack:
  filename += "-BranchBySector"
elif not ttEffTuple.BranchBySector and ttEffTuple.BranchByTrack:
  filename += "-BranchByTrack"
if ttEffTuple.BranchByTrack and ttEffTuple.TakeEveryHit:
  filename += "-EveryHit"
elif ttEffTuple.BranchByTrack and ttEffTuple.HitsOnTrack:
  filename += "-HitsOnTrack"
DaVinci().HistogramFile = filename+"-Hists.root"
DaVinci().UserAlgorithms = [ mainSeq ]

DaVinci().DataType = "2012"

from Configurables import CondDB, CondDBAccessSvc
CondDB().UseLatestTags = ["2012"]

from Configurables import NTupleSvc
itEffTuple.NTupleLUN = "TC"
ttEffTuple.NTupleLUN = "TC"
NTupleSvc().Output += ["TC DATAFILE='%s-NTuples.root' TYP='ROOT' OPT='NEW'"%filename]


from sentence_transformers import SentenceTransformer, util
import numpy as np

model_path = '../Checkpoint/KoSBERT/kosbert-klue-bert-base'

embedder = SentenceTransformer(model_path)

# Corpus with example sentences
corpus = ['한 남자가 음식을 먹는다.',
          '한 남자가 빵 한 조각을 먹는다.',
          '그 여자가 아이를 돌본다.',
          '한 남자가 말을 탄다.',
          '한 여자가 바이올린을 연주한다.',
          '두 남자가 수레를 숲 솦으로 밀었다.',
          '한 남자가 담으로 싸인 땅에서 백마를 타고 있다.',
          '원숭이 한 마리가 드럼을 연주한다.',
          '치타 한 마리가 먹이 뒤에서 달리고 있다.']

corpus_embeddings = embedder.encode(corpus, convert_to_tensor=True)

# Query sentences:
queries = ['한 남자가 파스타를 먹는다.',
           '고릴라 의상을 입은 누군가가 드럼을 연주하고 있다.',
           '치타가 들판을 가로 질러 먹이를 쫓는다.']

# Find the closest 5 sentences of the corpus for each query sentence based on cosine similarity
top_k = 5
for query in queries:
    query_embedding = embedder.encode(query, convert_to_tensor=True)
    cos_scores = util.pytorch_cos_sim(query_embedding, corpus_embeddings)[0]
    cos_scores = cos_scores.cpu()

    #We use np.argpartition, to only partially sort the top_k results
    top_results = np.argpartition(-cos_scores, range(top_k))[0:top_k]

    print("\n\n======================\n\n")
    print("Query:", query)
    print("\nTop 5 most similar sentences in corpus:")

    for idx in top_results[0:top_k]:
        print(corpus[idx].strip(), "(Score: %.4f)" % (cos_scores[idx]))


import subprocess
from swmf_file_reader import batsrus_class as bats
from swmf_file_reader.read_ie_files import read_iono_tec

def get_ms_slice_class(filename):
    assert(filename[-4:] == '.out')
    return bats.get_class_from_native(filename[:-4])

def get_iono_slice(filename):
    return read_iono_tec(filename)

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

def generate_filelist_txts():
    import os
    import re

    magnetosphere_outs = sorted(os.listdir('./GM/IO2'))
    with open('derived/magnetosphere_files.txt','w') as fl:
        regex = r"3d__var_.*\.out$"

        for fname in magnetosphere_outs:
            if re.search(regex, fname):
                assert(fname[:8] == '3d__var_')
                PlotNumber = int(fname[8]) # hopefully this is only in the single didgets or this will break
                assert(fname[9] == '_')

                if fname[10] == 'e':
                    Y = int(fname[11:15])
                    M = int(fname[15:17])
                    D = int(fname[17:19])
                    assert(fname[19] == '-')
                    h = int(fname[20:22])
                    m = int(fname[22:24])
                    s = int(fname[24:26])
                    assert(fname[26] == '-')
                    mil = int(fname[27:30])
                    assert(fname[30:] == '.out')
                    fl.write(f'{Y} {M} {D} {h} {m} {s} {mil} ./GM/IO2/{fname}\n')

    ionosphere_outs = sorted(os.listdir('./IE/ionosphere'))
    with open('derived/ionosphere_files.txt','w') as fl:
        regex = r"i_.*\.tec$"

        for fname in ionosphere_outs:
            if re.search(regex, fname):
                assert(fname[:2] == 'i_')

                if fname[2] == 'e':
                    Y = int(fname[3:7])
                    M = int(fname[7:9])
                    D = int(fname[9:11])
                    assert(fname[11] == '-')
                    h = int(fname[12:14])
                    m = int(fname[14:16])
                    s = int(fname[16:18])
                    assert(fname[18] == '-')
                    mil = int(fname[19:22])
                    assert(fname[22:] == '.tec')
                    fl.write(f'{Y} {M} {D} {h} {m} {s} {mil} ./IE/ionosphere/{fname}\n')


import os, datetime, logging
from pydantic import BaseModel

from logging.config import dictConfig
from logging.handlers import RotatingFileHandler

from app.core.const import LOG_RECORDS_PATH

class LogConfig(BaseModel):
    LOGGER_NAME: str = "ats"
    LOG_FORMAT: str = "%(levelprefix)s | %(pathname)s | %(lineno)d | %(levelname)s | %(asctime)s | %(message)s"
    LOG_LEVEL: str = "DEBUG"

    # Logging config
    version = 1
    disable_existing_loggers = False
    formatters = {
        "default": {
            "()": "uvicorn.logging.DefaultFormatter",
            "fmt": LOG_FORMAT,
            "datefmt": "%Y-%m-%d %H:%M:%S",
        },
    }
    handlers = {
        "default": {
            "formatter": "default",
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stderr",
        },
    }
    loggers = {
        "ats": {"handlers": ["default"], "level": LOG_LEVEL},
    }

def log_config():
    dictConfig(LogConfig().dict())
    logger = logging.getLogger("ats")

    if not os.path.exists(LOG_RECORDS_PATH):
        os.makedirs(LOG_RECORDS_PATH)

    # RotatingFileHandler is used to limit the log file. This setting will allow 300000 bytes per file and it will generate 5 files.
    file_handler = RotatingFileHandler(f'{LOG_RECORDS_PATH}/logs.log', maxBytes=100000, backupCount=5)
    file_handler.setLevel(logging.ERROR)
    file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s: %(lineno)d (%(funcName)s) %(message)s'))
    logger.addHandler(file_handler)

    return logger

logger = log_config()

# Log Messages types
# info
# warning
# error
# debug
# critical


# Locate Lidar
# beaglebone black
import serial
import time
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.PWM as PWM
import math

class Lidar:
    def __init__(self, top_stepper, tfluna):
        self.top_stepper = top_stepper
        self.tfluna = tfluna

        self.TOP_STEPPER_CALIBRATION_DISTANCE_CM = 10  # manually determined
        self.TOP_STEPPER_CALIBRATION_OFFSET = 48       # manually determined

    def _get_distance(self):
        # get distance from lidar
        self.tfluna.write('R')
        time.sleep(0.1)
        data = self.tfluna.read(9)
        if data[0] == 'R':
            distance = (ord(data[1]) << 8) + ord(data[2])
            return distance
        else:
            return None

    def _get_angle(self, distance):
        # get angle from lidar
        angle = math.atan2(distance, 10)
        angle = math.degrees(angle)
        return angle

    def _get_stepper_angle(self, angle):
        # get stepper angle
        stepper_angle = angle + self.TOP_STEPPER_CALIBRATION_OFFSET
        return stepper_angle

    def _get_stepper_pulse(self, stepper_angle):
        # get stepper pulse
        stepper_pulse = (stepper_angle / 180.0) + 0.5
        return stepper_pulse

    def _get_stepper_pulse_ms(self, stepper_pulse):
        # get stepper pulse in ms
        stepper_pulse_ms = stepper_pulse * 20
        return stepper_pulse_ms

    def get_lidar_data(self):
        # get lidar data
        distance = self._get_distance()
        angle = self._get_angle(distance)
        stepper_angle = self._get_stepper_angle(angle)
        stepper_pulse = self._get_stepper_pulse(stepper_angle)
        stepper_pulse_ms = self._get_stepper_pulse_ms(stepper_pulse)
        return distance, angle, stepper_angle, stepper_pulse, stepper_pulse_ms

    def calibrate(self):
        # calibrate lidar
        print ("Calibrating lidar...")
        distance = self._get_distance()
        while distance > self.TOP_STEPPER_CALIBRATION_DISTANCE_CM:
            self.top_stepper.step(1)
            time.sleep(0.1)
            distance = self._get_distance()
        print ("Lidar calibrated.")
        return distance, angle, stepper_angle, stepper_pulse, stepper_pulse_ms


import io
import os
import requests
import pathlib
import gzip
import shutil

import imageio
import pandas as pd
from tqdm import tqdm

def download_jpg(url, target_path):
    r = requests.get(url, stream=True)
    r.raw.decode_content = True
    with open(target_path, 'wb') as file:
        shutil.copyfileobj(r.raw, file)

def tif_gzip_to_png(tif_path):
    """Function to convert .tif.gz to .png and put it in the same folder"""
    png_path = pathlib.Path(tif_path.replace('.tif.gz', '.png'))
    tf = gzip.open(tif_path).read()
    img = imageio.imread(tf, 'tiff')
    imageio.imwrite(png_path, img)

def download_and_convert_tifgzip_to_png(url, target_path):
    """Function to convert .tif.gz to .png and put it in the same folder"""
    r = requests.get(url)
    f = io.BytesIO(r.content)
    tf = gzip.open(f).read()
    img = imageio.imread(tf, 'tiff')
    imageio.imwrite(target_path, img)

if __name__ == '__main__':

    SAVE_DIR = '/home/mchobanyan/data/kaggle/hpa-single-cell/misc/public-hpa/data2/'
    COLORS = ['blue', 'red', 'green', 'yellow']

    CLASS_NAMES = [
        'Nucleoplasm',
        'Nuclear membrane',
        'Nucleoli',
        'Nucleoli fibrillar center',
        'Nuclear speckles',
        'Nuclear bodies',
        'Endoplasmic reticulum',
        'Golgi apparatus',
        'Intermediate filaments',
        'Actin filaments ',
        'Microtubules',
        'Mitotic spindle',
        'Centrosome',
        'Plasma membrane',
        'Mitochondria',
        'Aggresome',
        'Cytosol',
        'Vesicles and punctate cytosolic patterns',
        'Negative'
    ]
    CLASS_NAMES = [name.lower().strip() for name in CLASS_NAMES]
    class_to_label_id = dict(zip(CLASS_NAMES, range(len(CLASS_NAMES))))

    data_idx = pd.read_csv('/home/mchobanyan/data/kaggle/hpa-single-cell/misc/public-hpa/kaggle_2021.csv')
    data_idx['Label'] = data_idx['Label'].str.lower()
    print(f'Total images: {len(data_idx)}')

    celllines = ['A-431', 'A549', 'EFO-21', 'HAP1', 'HEK 293', 'HUVEC TERT2', 'HaCaT', 'HeLa', 'PC-3', 'RH-30',
                 'RPTEC TERT1', 'SH-SY5Y', 'SK-MEL-30', 'SiHa', 'U-2 OS', 'U-251 MG', 'hTCEpi']
    data_idx = data_idx[data_idx['Cellline'].isin(celllines)]
    print(f'Images with appropriate cell-lines: {len(data_idx)}')

    # group/standardize the class names
    data_idx['Label'] = data_idx['Label'].str.replace('focal adhesion sites', 'actin filaments')
    data_idx['Label'] = data_idx['Label'].str.replace('cell junctions', 'plasma membrane')
    data_idx['Label'] = data_idx['Label'].str.replace('centriolar satellite', 'centrosome')
    data_idx['Label'] = data_idx['Label'].str.replace('no staining', 'negative')

    data_idx['Label'] = data_idx['Label'].str.replace('peroxisomes', 'vesicles')
    data_idx['Label'] = data_idx['Label'].str.replace('endosomes', 'vesicles')
    data_idx['Label'] = data_idx['Label'].str.replace('lysosomes', 'vesicles')
    data_idx['Label'] = data_idx['Label'].str.replace('lipid droplets', 'vesicles')
    data_idx['Label'] = data_idx['Label'].str.replace('cytoplasmic bodies', 'vesicles')
    data_idx['Label'] = data_idx['Label'].str.replace('vesicles', 'vesicles and punctate cytosolic patterns')

    # find class names not included
    extra_classes = set()
    for label in data_idx['Label']:
        tokens = label.split(',')
        for token in tokens:
            if token not in class_to_label_id:
                extra_classes.add(token)

    # throw away all rows containing the extra classes
    extra_mask = None
    for class_name in extra_classes:
        mask = data_idx['Label'].str.contains(class_name)
        if extra_mask is None:
            extra_mask = mask
        else:
            extra_mask = extra_mask | mask
    data_idx = data_idx.loc[~extra_mask]
    data_idx = data_idx.reset_index(drop=True)
    print(f'Dropped {extra_mask.sum()} rows due to extra classes')
    print(f'Images remaining: {len(data_idx)}')

    # transform the label column to label ids
    numeric_labels = []
    for label in data_idx['Label']:
        label_ids = set()
        tokens = label.split(',')
        for token in tokens:
            label_ids.add(class_to_label_id[token])
        label_ids = sorted(label_ids)
        label_ids = [str(i) for i in label_ids]
        numeric_labels.append('|'.join(label_ids))
    data_idx['Label'] = numeric_labels

    # no more than 5000 samples per unique label combo
    data_idx = data_idx.groupby('Label').head(5000)
    print(f'Removing examples from abundant classes...')

    # keep only 1000 samples for labels 0 and 16 (the most popular ones)
    drop_idx = data_idx.loc[data_idx['Label'] == '16'].sample(4000).index
    data_idx = data_idx.drop(drop_idx, axis='index')

    drop_idx = data_idx.loc[data_idx['Label'] == '0'].sample(4000).index
    data_idx = data_idx.drop(drop_idx, axis='index')

    # keep only 1000 samples for label 0|16
    drop_idx = data_idx.loc[data_idx['Label'] == '0|16'].sample(4000).index
    data_idx = data_idx.drop(drop_idx, axis='index')
    print(f'Images remaining: {len(data_idx)}')

    if not os.path.exists(SAVE_DIR):
        os.makedirs(SAVE_DIR)

    for base_url in tqdm(data_idx['Image'], desc='Downloading data'):
        try:
            for color in COLORS:
                img_url = f'{base_url}_{color}.tif.gz'
                save_path = os.path.join(SAVE_DIR, f'{os.path.basename(base_url)}_{color}.png')
                download_and_convert_tifgzip_to_png(img_url, save_path)
        except:
            print(f'failed to download: {base_url}')


# Problem 7
# http://www.pythonchallenge.com/pc/def/oxygen.html
import utils
import os
import statistics
from PIL import Image
import re

def is_grey(pixel: tuple):
    average = statistics.mean(pixel[:2]) # get average of rgb colors, do not include alpha
    is_close = lambda x, y: y > .95 * x and y < 1.05 * x
    return all([is_close(average, channel_value) for channel_value in pixel[:3]])

image_url = utils.base_url + 'oxygen.png'
script_data_dir = utils.base_data_dir_path + '07/'
image_path = script_data_dir + 'oxygen.png'
grey_pixel_coords = []

utils.download_file(image_url, image_path)

with Image.open(image_path) as im:
    print(f'w:{im.width} h:{im.height}')

    # Begin traversing down to find grey
    for y_pixel in range(0, im.height, 5):
        coords = (0, y_pixel)
        pixel = im.getpixel(coords)
        print(f'{coords} {pixel}')

        if is_grey(pixel):
            print('found grey pixel, now traversing horizontally')
            break

    # Begin traversing across to find grey vals
    for x_pixel in range(0, im.width, 5):
        coords = (x_pixel, y_pixel)
        pixel = im.getpixel(coords)
        print(f'x:{x_pixel}, y:{y_pixel} {pixel}')
        if not is_grey(pixel):
            print('end of grey pixels horizontally, starting next step of analyzing...')
            break
        if len(grey_pixel_coords) == 0 or grey_pixel_coords[-1] != pixel: # Make sure we aren't sampling same square twice.
            grey_pixel_coords.append(pixel)

# take out of with later
message = ''.join(''.join([chr(item[0]) for item in grey_pixel_coords]))
print(message)
pattern = re.compile('[0-9]+')

matches = [int(item) for item in pattern.findall(message)]
next_puzzle = ''.join([chr(item) for item in matches])
next_puzzle = next_puzzle.replace('\n', 'n')
next_puzzle = next_puzzle.replace('\t', 't')
next_puzzle = next_puzzle.replace('\r', 'r')
print(next_puzzle)
#integrity


# Micropython - see https://learn.pimoroni.com/article/plasma-2040
#
# adapted from examples on that page

import plasma
from plasma import plasma2040
import time

NUM_LEDS = 50

led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT)

led_strip.start()
while True:
    for i in range(NUM_LEDS):
        led_strip.set_rgb(i, 255, 0, 0)
        time.sleep(0.25)
        led_strip.set_rgb(i, 0, 0, 0)


import asyncio
import contextlib
import gzip
import inspect
import os
import textwrap
from typing import (
    Any, Awaitable, Callable,
    Iterable, Iterator, List, Optional, Sized, Type, Union)

from trycast import isassignable  # type:ignore

# condition needed due to https://github.com/bazelbuild/rules_python/issues/622
try:
    import orjson as json
except ImportError:
    import json  # type:ignore

from aio.core.functional import exceptions

def maybe_awaitable(result: Any) -> Awaitable:
    """Make anything awaitable.

    ```python

    async def async_fun():
        return "ASYNC FUN"

    >>> await maybe_awaitable("CABBAGE")
    'CABBAGE'
    >>> await maybe_awaitable(async_fun())
    'ASYNC FUN'

    ```
    """

    return (
        result
        if inspect.iscoroutine(result)
        else asyncio.sleep(0, result=result))

def maybe_coro(fun: Union[Callable, Awaitable]) -> Callable[..., Awaitable]:
    """Make any callable into a coroutine function.

    ```python

    def fun():
        return "FUN"

    async def async_fun():
        return "ASYNC FUN"

    >>> await maybe_coro(fun)()
    'FUN'
    >>> await maybe_coro(async_fun)()
    'ASYNC FUN'

    ```
    """

    async def async_wrapper(*args, **kwargs):
        called = fun(*args, **kwargs)
        return (
            await called
            if inspect.iscoroutinefunction(fun)
            else called)
    return async_wrapper

@contextlib.contextmanager
def nested(*contexts):
    with contextlib.ExitStack() as stack:
        yield [
            stack.enter_context(context)
            for context
            in contexts]

def junzip(data: bytes) -> Any:
    return json.loads(gzip.decompress(data))

def typed(tocast: Type, value: Any) -> Any:
    """Attempts to cast a value to a given type, TypeVar, or TypeDict.

    raises TypeError if cast value is `None`
    """
    if isassignable(value, tocast):
        return value
    raise exceptions.TypeCastingError(
        "Value has wrong type or shape for Type "
        f"{tocast}: "
        f"{textwrap.shorten(str(value), width=10, placeholder='...')}",
        value=value)

# TODO: add async versions of the `batch` utils
def batches(items: Iterable, batch_size: int) -> Iterator[List]:
    """Yield batches of items according to batch size."""
    batch = []
    for item in items:
        batch.append(item)
        if len(batch) >= batch_size:
            yield batch
            batch = []
    if batch:
        yield batch

def batch_jobs(
        jobs: Sized,
        max_batch_size: Optional[int] = None,
        min_batch_size: Optional[int] = None) -> Iterator[List]:
    """Batch jobs between processors, optionally setting a max batch size."""
    bad_jobs_type = (
        not isinstance(jobs, Iterable)
        or isinstance(jobs, (str, bytes)))
    if bad_jobs_type:
        raise exceptions.BatchedJobsError(
            f"Wrong type for `batch_jobs` ({type(jobs)}: {jobs}")
    proc_count = os.cpu_count() or 1
    batch_count = round(len(jobs) / proc_count)
    if max_batch_size:
        batch_count = min(batch_count, max_batch_size)
    if min_batch_size:
        batch_count = max(batch_count, min_batch_size)
    return batches(typed(Iterable, jobs), batch_size=batch_count)


'''

All of the classes here convert spreadsheet formulas into execable python strings via the "transform" method.  Each execable string calls a GPU-accelerated function from the gfuncs module.

'''

import re
import lexer.regexes as rx
import lexer.refuncs as rf
import gfuncs as gf

# Replace single cell references with equivalent slice index
class CellRef:
	def __init__(self):
		self.formula = ''
		self.ref_rx = re.compile(r'(?<![A-Z]\(\[)Sheet[0-9]+\.[A-Z]+[0-9]+(?=\])')

	def transform(self, formula, objstr):
		self.formula = formula

		# replace all single cell refs with equivalent data reference strings
		refs = self.ref_rx.findall(self.formula)
		for ref in refs:
			dataref = rf.cellref2dataref(ref, objstr)
			self.formula = re.sub(re.escape('['+ref+']'), dataref, self.formula)

		return self.formula

# class CellRange:
# 	def __init__(self):
# 		self.formula = ''
# 		self.rng_rx = re.compile(\
# 		r'Sheet[0-9]+\.[A-Z]+[0-9]+:Sheet[0-9]+\.[A-Z]+[0-9]+(?=\])')
#
# 	def transform(self, formula, objstr):
# 		self.formula = formula
#
# 		# replace all terminal arguments with equivalent data range string
# 		rngs = self.rng_rx.findall(self.formula)
# 		for rng in rngs:
# 			# ods clips explicit ranges to first cell in range
# 			firstref = rx.minref.findall(rng)[0]
# 			dataref = rf.cellref2dataref(firstref, objstr)
# 			self.formula = re.sub(re.escape('['+rng+']'), dataref, self.formula)
#
# 		return self.formula

# Base class for functions that take a data range, e.g.
# SUM[Sheet1.A1:Sheet1.A10]
class RangeFunction(object):
	def __init__(self):
		self.formula = ''
		self.funcname = ''
		self.gfuncname = ''
		self.f_rx = ''
		self.args_rx = ''

	def transform(self, formula, objstr):
		self.formula = formula

		# replace all spreadsheet function calls with equivalent python function
		self.formula = re.sub(re.escape(self.funcname), self.gfuncname, self.formula)

		funcalls = self.f_rx.findall(self.formula)
		for funcall in funcalls:
			cellrng = self.args_rx.findall(funcall)[0]
			datarng = rf.cellrng2datarng(cellrng, objstr)
			newcall = re.sub(re.escape(cellrng), datarng, funcall)
			self.formula = re.sub(re.escape(funcall), newcall, self.formula)

		return self.formula

# Base class for functions that take a list of data ranges, e.g.
# CORREL([Sheet1.A1:Sheet1.A10], [Sheet1.B1:Sheet1.B10])
class RangeListFunction(RangeFunction):
	def __init__(self):
		super(RangeFunction, self).__init__()

	def transform(self, formula, objstr):
		self.formula = formula

		# replace all spreadsheet function calls with equivalent python function
		self.formula = re.sub(re.escape(self.funcname), self.gfuncname, self.formula)

		funcalls = self.f_rx.findall(self.formula)
		for funcall in funcalls:
			rnglist = self.args_rx.findall(funcall)[0]
			datalist = rf.rnglist2datalist(rnglist, objstr)
			newcall = re.sub(re.escape(rnglist), datalist, funcall)
			self.formula = re.sub(re.escape(funcall), newcall, self.formula)

		return self.formula

# Subclasses for specific spreadsheet functions

# sum
class SUM(RangeListFunction):
	def __init__(self):
		super(SUM, self).__init__()
		self.formula = ''
		self.funcname = 'SUM'
		self.gfuncname = 'gf.gSUM'
		self.f_rx = re.compile(\
		r'SUM\(.*\)')
		self.args_rx = re.compile(r'(?<=SUM\().*(?=\))')

	def transform(self, formula, objstr):
		return super(SUM, self).transform(formula, objstr)

# standard deviation
class STDEV(RangeListFunction):
	def __init__(self):
		super(STDEV, self).__init__()
		self.formula = ''
		self.funcname = 'STDEV'
		self.gfuncname = 'gf.gSTDEV'
		self.f_rx = re.compile(\
		r'STDEV\(\[Sheet[0-9]+\.[A-Z]+[0-9]+:Sheet[0-9]+\.[A-Z]+[0-9]+\]\)')
		self.args_rx = re.compile(r'(?<=STDEV\().*(?=\))')

	def transform(self, formula, objstr):
		return super(STDEV, self).transform(formula, objstr)

# covariance
class COVAR(RangeListFunction):
	def __init__(self):
		super(COVAR, self).__init__()
		self.formula = ''
		self.funcname = 'COVAR'
		self.gfuncname = 'gf.gCOVAR'
		self.f_rx = re.compile(\
		r'COVAR\(\[Sheet[0-9]+\.[A-Z]+[0-9]+:Sheet[0-9]+\.[A-Z]+[0-9]+\]; \[Sheet[0-9]+\.[A-Z]+[0-9]+:Sheet[0-9]+\.[A-Z]+[0-9]+\]\)')
		self.args_rx = re.compile(r'(?<=COVAR\().*(?=\))')

	def transform(self, formula, objstr):
		return super(COVAR, self).transform(formula, objstr)

# correlation
class CORREL(RangeListFunction):
	def __init__(self):
		super(CORREL, self).__init__()
		self.formula = ''
		self.funcname = 'CORREL'
		self.gfuncname = 'gf.gCORREL'
		self.f_rx = re.compile(\
		r'CORREL\(\[Sheet[0-9]+\.[A-Z]+[0-9]+:Sheet[0-9]+\.[A-Z]+[0-9]+\]; \[Sheet[0-9]+\.[A-Z]+[0-9]+:Sheet[0-9]+\.[A-Z]+[0-9]+\]\)')
		self.args_rx = re.compile(r'(?<=CORREL\().*(?=\))')

	def transform(self, formula, objstr):
		return super(CORREL, self).transform(formula, objstr)

# make sure to add new classes here
translators = [SUM(), STDEV(), COVAR(), CORREL(), CellRef()]


import numpy as np
import matplotlib.pyplot as plt

num_files = 16

files = []
times = []
for i in range(0,num_files):
	file_size = float(raw_input())
	time = float(raw_input())
	files.append(file_size)
	times.append(time)
files = np.array(files)
times = np.array(times)
plt.plot(files,times,'ro-')
plt.title("Time vs File Size")
plt.xlabel("File Size (bytes)")
plt.ylabel("Time (sec)")
plt.xscale('log')
plt.yscale('log')
plt.show()


# Modified from the source: https://github.com/sthalles/PyTorch-BYOL
# Previous owner of this file: Thalles Silva

from torchvision import transforms
from .utils.gaussian_blur import GaussianBlur

def get_simclr_ops(input_shape, s=1):
    # get a set of data augmentation transformations as described in the SimCLR paper.
    color_jitter = transforms.ColorJitter(0.8 * s, 0.8 * s, 0.8 * s, 0.2 * s)
    ops = [transforms.RandomHorizontalFlip(),
            transforms.RandomApply([color_jitter], p=0.8),
            transforms.RandomGrayscale(p=0.2),
            GaussianBlur(kernel_size=int(0.1 * input_shape)),]
    return ops


from numpy import random, sqrt, array, exp, dot, subtract, multiply, sum, power, ravel, add

class Capa:

    pesos_anterior = dict()

    #Funcion Sigmoidal
    def sigmoidal(self, x):
        return 1/(exp(-x)+1)

    #Derivada de la funcion sigmoidal
    def d_sigmoidal(self, x):
        return (exp(-x))/((exp(-x)+1)**2)

    def propagacionAdelante(self, entrada, pesos, is_sigmoidal=True):
        net= dot(entrada, pesos)
        if is_sigmoidal:
            activacion1 = list()
            d_activacion1 = list()
            for i in net:
                activacion1.append(self.sigmoidal(i))
                d_activacion1.append(self.d_sigmoidal(i))
            return array(activacion1), array(d_activacion1)
        else:
            return net, array([1 for i in range(len(net))])

    def ejecucion(self, entrada, pesos):
        net= dot(entrada, pesos)
        activacion1 = list()
        d_activacion1 = list()
        for i in net:
            activacion1.append(self.sigmoidal(i))
            d_activacion1.append(self.d_sigmoidal(i))

        return array(activacion1)

    def ErrorPatron(self, salida_deseada, salida_real):
        resta = subtract(salida_deseada, salida_real)
        potencia = power(resta, 2)
        suma = sum(potencia)
        return suma/2

    def ErrorPesosSalida(self, salida_deseada, salida_real, derivada):
        resta = subtract(salida_deseada, salida_real)
        multiplicacion = multiply(resta, derivada)
        return array(multiplicacion)

    def ErrorPesosOcultas(self, error_salida, pesos_salida, derivada):
        matris = error_salida.shape
        error_salida_col = error_salida.reshape(matris[0], 1)
        sumatoria = dot(pesos_salida, error_salida_col)
        sumatoria = ravel(sumatoria)
        multiplicacion = multiply(sumatoria, derivada)
        return multiplicacion

    def modificarPesos(self, pesos, error, alpha, entrada, iteracion, nombre_capa, beta):

        n = len(entrada)
        entrada = entrada.reshape(n, 1)
        aux = [error for i in range(n)]
        multiplicar = multiply(aux, entrada)
        multiplicar = multiply(multiplicar, alpha)
        resultado = add(pesos, multiplicar)
        if iteracion < 3:
            self.pesos_anterior[nombre_capa] = pesos
            return resultado
        else:
            resta_pesos = subtract(pesos, self.pesos_anterior[nombre_capa])
            momento = multiply(resta_pesos, beta)
            resultado = add(resultado, momento)
            self.pesos_anterior[nombre_capa] = pesos
            return resultado


# https://leetcode.com/problems/longest-string-chain/
import math
import os
import random
import re
import sys

from collections import defaultdict
d = defaultdict(int)

def longestChain(words):
    words = list(set(words))
    words = sorted(words, key = lambda x: (len(x), x))
    for i in range(0, len(words)):
        word = words[i]
        d[word] = 1
        for j in range(0, len(word)):
            tmp = word[:j]+word[j+1:]
            if tmp in d.keys():
                d[word] = max(d[word], d[tmp]+1)
    return max(list(d.values()))

if __name__ == '__main__':
    pass


import select
import socket
from NetClient import NetClient

class NetServer:
    def __init__( self, port = 9560 ):
        self._clients = list( )
        self._clientToMove = list( )
        self._isRunning = True
        self._sckServer = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
        self._sckServer.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
        self._sckServer.bind( ("0.0.0.0", port) )
        self._sckServer.listen( 8 )
        self._sckList = [self._sckServer]
    #END __init__( )

    def __del__( self ):
        for sock in self._sckList:
            sock.close( )
        self._srvSocket = None
        self._isRunning = False
        del self._sckList[:]
        del self._clients[:]
        del self._clientToMove[:]
    #END __del__( )

    def isRunning( self ):
        return self._isRunning
    #END isRunning( )

    def getNextClientToMove( self ):
        if len( self._clientToMove ) > 0:
            return self._clientToMove.pop( 0 )
        return None
    #END getNextClientToMove( )

    def update( self ):
        readable, writable, errors = select.select( self._sckList, self._sckList, self._sckList, 0.01 )
        self._updateReadable( readable )
        self._updateWritable( writable )
        self._updateErrors( errors )
    #END update( )

    def _acceptClient( self, srvSocket ):
        cliSocket, cliAddress = srvSocket.accept( )
        self._clients.append( { "socket": cliSocket, "address": cliAddress, "name": "", "message": None, "added": False } )
        self._sckList.append( cliSocket )
        print( "[NetServer] connection to %s" % str(cliAddress) )
    #END _acceptClient( )

    def _findClientBySocket( self, sck ):
        for i in range( 0, len( self._clients ) ):
            if self._clients[i]["socket"] == sck:
                return i
        return -1
    #END _findClientBySocket( )

    def _removeClient( self, index ):
        if 0 <= index and index < len( self._clients ):
            print( "[NetServer] disconnected from %s" % str(self._clients[index]["address"]) )
            self._sckList.remove( self._clients[index]["socket"] )
            self._clients[index]["socket"].close( ) # close socket
            self._clients.pop( index )
    #END _removeClient( )

    def _receiveDataFromClient( self, sck ):
        index = self._findClientBySocket( sck )
        if index >= 0:
            if self._clients[index]["message"] is None:
                try:
                    self._clients[index]["message"] = sck.recv( NetClient.PACKET_MINIMUM_SIZE )
                except:
                    print( "[NetServer] failed to receive data from %s" % str(self._clients[index]["address"]) )
                    self._removeClient( index )
            elif len( self._clients[index]["message"] ) < NetClient.PACKET_MINIMUM_SIZE:
                try:
                    self._clients[index]["message"] += sck.recv( NetClient.PACKET_MINIMUM_SIZE - len( self._clients[index]["message"] ) )
                except:
                    print( "[NetServer] failed to receive data from %s" % str(self._clients[index]["address"]) )
                    self._removeClient( index )
            else:
                type, length = NetClient.pckParseHeader( self._clients[index]["message"] )
                if len( self._clients[index]["message"] ) < length:
                    try:
                        self._clients[index]["message"] += sck.recv( length - len( self._clients[index]["message"] ) )
                    except:
                        print( "[NetServer] failed to receive data from %s" % str(self._clients[index]["address"]) )
                        self._removeClient( index )
                if len( self._clients[index]["message"] ) >= length:
                    if type == NetClient.PACKET_NORMAL:
                        pass # ignore any thing other than change connection type
                    elif type == NetClient.PACKET_CHANGECONNECTION:
                        self._clients[index]["name"] = self._clients[index]["message"][NetClient.PACKET_MINIMUM_SIZE:].decode( )
                        if self._clients[index]["name"][-1] == '\0':
                            self._clients[index]["name"] = self._clients[index]["name"][:-1]
                        self._clients[index]["message"] = None
                        print( "[NetServer] %s changing type to %s" % (str(self._clients[index]["address"]), str(self._clients[index]["name"])) )
                        self._sckList.remove( self._clients[index]["socket"] )
                        self._clientToMove.append( self._clients.pop( index ) )
                    elif type == NetClient.PACKET_DISCONNECTION:
                        self._removeClient( index )
    #END _receiveDataFromClient( )

    def _updateReadable( self, readable ):
        for sck in readable:
            if sck is self._sckServer:
                self._acceptClient( sck )
            else:
                self._receiveDataFromClient( sck )
    #END _updateReadable( )

    def _updateWritable( self, writable ):
        pass
    #END _updateWritable( )

    def _updateErrors( self, errors ):
        for sck in errors:
            if sck is self._sckServer:
                print( "[NetServer] error with the server socket" )
                self._isRunning = False
            else:
                print( "[NetServer] error with a client socket" )
                index = self._findClientBySocket( sck )
                self._removeClient( index )
    #END _updateErrors( )
#END NetServer


import logging
import os
from shutil import which
import subprocess

class Command:
    class CommandMissingError(RuntimeError):
        pass

    def __init__(self, runnable, logger=None):
        self.runnable = which(runnable)
        self.assert_runnable_exists(runnable)

        self.log_command = True
        self.log_stdout = True
        self.log_stderr = True
        self.env = os.environ.copy()

        self.logger = logger
        if not self.logger:
            self.logger = logging.getLogger(runnable)

        self.return_code = None
        self.stdout = []
        self.stderr = []
        self.cwd = os.path.curdir

    @staticmethod
    def assert_runnable_exists(runnable):
        if not runnable:
            raise Command.CommandMissingError(
                "Unable to locate '%s' runnable. Please make sure it is installed "
                "and available in the environment variable PATH." % runnable
            )

    def _run(self, command):
        self.stdout = []
        self.stderr = []

        if self.log_command:
            self.logger.info(" ".join(command))
        else:
            self.logger.debug(" ".join(command))

        process = subprocess.Popen(
            command,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.cwd,
            env=self.env,
        )

        self._poll_process(process)

    def _run_with_input(self, command, input):
        self.logger.info(" ".join(command))
        process = subprocess.Popen(
            command,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.cwd,
        )
        process.communicate(input)

        self._poll_process(process)

    def _poll_process(self, process):
        while process.poll() is None:
            self._process_stdout_lines(process)
            self._process_stderr_lines(process)

        process.stdout.close()
        process.stderr.close()

        self.return_code = process.poll()

    def _process_stderr_lines(self, process):
        stderr_line = process.stderr.readline()
        while stderr_line:
            stderr_line = stderr_line.decode("utf-8").strip()
            self.stderr.append(stderr_line)
            if self.log_stderr:
                self.logger.warning(stderr_line)

            stderr_line = process.stderr.readline()

    def _process_stdout_lines(self, process):
        stdout_line = process.stdout.readline()
        while stdout_line:
            stdout_line = stdout_line.decode("utf-8").strip()
            self.stdout.append(stdout_line)
            if self.log_stdout:
                self.logger.info(stdout_line)

            stdout_line = process.stdout.readline()


import numpy as np

from sklearn.datasets import make_blobs, fetch_openml
from sklearn.preprocessing import LabelEncoder
from collections import deque
import pickle as pkl

def merge_streams(d0, d1, random_state):
    streams = [deque(d0[0]), deque(d1[0])]
    labels = [deque(d0[1]), deque(d1[1])]

    #     print('len(streams[0])', len(streams[0]))
    #     print('len(streams[1])', len(streams[1]))

    change_point = len(streams[0])

    w = 50

    new_stream = []
    new_labels = []
    while len(streams[0]) > 0 and len(streams[1]) > 0:
        stream0_proba = 1 / (1 + np.exp((len(new_stream) - change_point) / w))
        stream_index = 0 if random_state.random_sample() < stream0_proba else 1

        new_stream.append(streams[stream_index].popleft())
        new_labels.append(labels[stream_index].popleft())

    #     print('len(streams[0])', len(streams[0]))
    #     print('len(streams[1])', len(streams[1]))

    if len(streams[1]) > 0:
        #         print('case 0')
        new_stream = np.concatenate([new_stream, streams[1]], axis=0)
        new_labels = np.concatenate([new_labels, labels[1]], axis=0)
    else:
        #         print('case 1')
        new_stream = np.concatenate([new_stream, streams[0]], axis=0)
        new_labels = np.concatenate([new_labels, labels[0]], axis=0)

    return new_stream, new_labels

def make_synthetic_with_changes(random_state, lengths, n_classes, n_center_per_class, n_features):
    random_state = random_state

    static_streams = []
    for i, l in enumerate(lengths):
        X, y_center = make_blobs(n_samples=l, n_features=n_features, shuffle=True,
                                 centers=n_classes * n_center_per_class, random_state=i)
        y = y_center % n_classes
        static_streams.append((X, y))
    return merge_streams(static_streams[0], static_streams[1], random_state)

def check_splitfeature(X, feature_to_split):
    if len(np.unique(X[:, feature_to_split])) == 1:
        return False

    splitpoint = np.quantile(X[:, feature_to_split], 0.5)
    static_dataset_before_change = X[:, feature_to_split] <= splitpoint
    static_dataset_after_change = np.logical_not(static_dataset_before_change)

    #     print('feature_to_split', feature_to_split)
    #     print('len(np.unique(X[:, feature_to_split]))', len(np.unique(X[:, feature_to_split])))
    #     print(np.sum(static_dataset_before_change))
    #     print(np.sum(static_dataset_after_change))
    #     print(len(X))
    return np.sum(static_dataset_after_change) / len(X) > 0.40

def make_static_with_change(random_state, dataset_name):
    X, y = get_openml_dataset(dataset_name)
    X = X.values
    shuffled_indices = np.arange(len(X))
    random_state.shuffle(shuffled_indices)
    X = X[shuffled_indices]
    y = y[shuffled_indices]

    num_features = X.shape[1]

    feature_to_split = random_state.randint(num_features)
    while not check_splitfeature(X, feature_to_split):
        feature_to_split = random_state.randint(num_features)

    splitpoint = np.quantile(X[:, feature_to_split], 0.5)
    static_dataset_before_change = X[:, feature_to_split] <= splitpoint
    static_dataset_after_change = X[:, feature_to_split] > splitpoint
    X_without_split_feature = X[:, np.arange(num_features) != feature_to_split]

    X_before = X_without_split_feature[static_dataset_before_change, :]
    y_before = y[static_dataset_before_change]
    X_after = X_without_split_feature[static_dataset_after_change, :]
    y_after = y[static_dataset_after_change]
    return merge_streams((X_before, y_before), (X_after, y_after), random_state)

def get_openml_id(name):
    name_id_dict = {
        'phoneme': 1489,
        'mfeat-morphological': 18,
        'segment': 36,
        'kin8nm': 807,
        'space_ga': 737,
        'electricity': 151
    }
    return name_id_dict[name]

def get_openml_dataset(dataset_name):
    data = fetch_openml(data_id=get_openml_id(dataset_name), data_home='datasets')
    le = LabelEncoder()
    X = data.data
    y = le.fit_transform(data.target)
    return X, y

def get_pickled_dataset(dataset_name):
    with open('datasets/' + dataset_name + '.pkl', 'rb') as f:
        data = pkl.load(f)
    return data['X'], data['y']

def get_1D_test_dataset(random_state):
    X, y_center = make_blobs(n_samples=4000, n_features=1, centers=4, shuffle=True, random_state=random_state)
    y = y_center % 2
    return X, y

def load_raw_dataset_by_name(random_seed, name):
    random_state = np.random.RandomState(random_seed)
    dataset_generation_functions = {}

    # synthetic dataset
    dataset_generation_functions['D0'] = lambda random_state: make_synthetic_with_changes(random_state, [2000, 2000], 2,
                                                                                10, 2)
    dataset_generation_functions['D1'] = lambda random_state: make_synthetic_with_changes(random_state, [2000, 2000], 3,
                                                                                10, 2)
    dataset_generation_functions['D2'] = lambda random_state: make_synthetic_with_changes(random_state, [2000, 2000], 4,
                                                                                10, 2)

    # static dataset
    dataset_generation_functions['D3'] = lambda random_state: make_static_with_change(random_state, "phoneme")
    dataset_generation_functions['D4'] = lambda random_state: make_static_with_change(random_state,
                                                                                'mfeat-morphological')
    dataset_generation_functions['D5'] = lambda random_state: make_static_with_change(random_state, "segment")
    dataset_generation_functions['D6'] = lambda random_state: make_static_with_change(random_state, "kin8nm")
    dataset_generation_functions['D7'] = lambda random_state: make_static_with_change(random_state, "space_ga")

    # stream dataset
    dataset_generation_functions['D8'] = lambda random_state: get_openml_dataset("electricity")
    dataset_generation_functions['D9'] = lambda random_state: get_pickled_dataset("luxembourg")
    dataset_generation_functions['D10'] = lambda random_state: get_pickled_dataset("noaa_weather")
    dataset_generation_functions['D11'] = lambda random_state: get_pickled_dataset("rialto")
    dataset_generation_functions['D12'] = lambda random_state: get_1D_test_dataset(random_state)

    # stream dataset
    dataset_generation_functions['D13'] = lambda random_state: make_synthetic_with_changes(random_state, [2000, 2000],
                                                                                2, 1, 2)

    return dataset_generation_functions[name](random_state)

def create_eval_mask(random_seed, num_instances, eval_portion):
    num_eval_samples = int(num_instances * eval_portion)
    num_training_samples = num_instances - num_eval_samples
    #     print('num_eval_samples', num_eval_samples)
    #     print('num_training_samples', num_training_samples)
    eval_mask = np.concatenate([np.ones(num_eval_samples, dtype=int), np.zeros(num_training_samples, dtype=int)])
    np.random.RandomState(random_seed).shuffle(eval_mask)
    return eval_mask

def get_dataset_by_name(dataset_random_seed, evalset_random_seed, name):
    X, y = load_raw_dataset_by_name(dataset_random_seed, name)
    eval_mask = create_eval_mask(evalset_random_seed, len(X), 0.)
    n_classes = len(np.unique(y))
    n_features = X.shape[1]
    return X, y, eval_mask, n_classes, n_features

if  __name__ == '__main__':
    data = 'D9'

    x, y = load_raw_dataset_by_name(0, data)


#!/usr/bin/env python

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import utils

def plot_traces_X2X(signals_dict, lpath_lfp, start_sec=6516, dur_sec=3, samp_rate=1000):
    ## Gets ripple band LFP
    RIPPLE_CANDI_LIM_HZ = utils.general.load("./conf/global.yaml")[
        "RIPPLE_CANDI_LIM_HZ"
    ]
    RIP_LO_HZ = RIPPLE_CANDI_LIM_HZ[0]
    RIP_HI_HZ = RIPPLE_CANDI_LIM_HZ[1]

    end_sec = start_sec + dur_sec
    x_sec = np.arange(start_sec, end_sec, 1.0 / samp_rate)

    start_pts = int(start_sec * samp_rate)
    end_pts = int(end_sec * samp_rate)

    ## Signals
    lfp_plt = signals_dict["lfp"][start_pts:end_pts]
    filted_plt, _, _ = utils.pj.define_ripple_candidates(
        x_sec,
        lfp_plt,
        samp_rate,
        lo_hz=RIP_LO_HZ,
        hi_hz=RIP_HI_HZ,
    )
    rip_analog_sig_plt = signals_dict["rip_analog_sig"][start_pts:end_pts]
    rip_analog_sig_T2T_plt = signals_dict["rip_analog_sig_T2T"][start_pts:end_pts]
    rip_analog_sig_F2T_plt = signals_dict["rip_analog_sig_F2T"][start_pts:end_pts]
    rip_analog_sig_T2F_plt = signals_dict["rip_analog_sig_T2F"][start_pts:end_pts]
    rip_analog_sig_F2F_plt = signals_dict["rip_analog_sig_F2F"][start_pts:end_pts]
    rip_magni_plt = signals_dict["rip_magni"][start_pts:end_pts]
    mep_magni_plt = signals_dict["mep_magni"][start_pts:end_pts]
    rip_pred_proba_sig_plt = signals_dict["rip_pred_proba_sig"][start_pts:end_pts]

    ## Puts all data into one dataframe
    index = [
        "ripple confidence",
        "raw LFP",
        "ripple band LFP ({}-{} Hz)".format(RIP_LO_HZ, RIP_HI_HZ),
        "ripple band normalized magnitude",
        "MEP normalized magnitude",
    ]

    columns = [
        "signal",
        "ylim",
        "linewidth",
    ]

    df = pd.DataFrame(index=index, columns=columns)

    # signal
    df.loc["ripple confidence", "signal"] = rip_pred_proba_sig_plt
    df.loc["raw LFP", "signal"] = lfp_plt
    df.loc[
        "ripple band LFP ({}-{} Hz)".format(RIP_LO_HZ, RIP_HI_HZ), "signal"
    ] = filted_plt
    df.loc["ripple band normalized magnitude", "signal"] = rip_magni_plt
    df.loc["MEP normalized magnitude", "signal"] = mep_magni_plt

    # ylim
    df.loc["ripple confidence", "ylim"] = (0, 1.05)
    df.loc["raw LFP", "ylim"] = (-1000, 1000)
    df.loc["ripple band LFP ({}-{} Hz)".format(RIP_LO_HZ, RIP_HI_HZ), "ylim"] = (
        -200,
        200,
    )
    df.loc["ripple band normalized magnitude", "ylim"] = (0, 15)
    df.loc["MEP normalized magnitude", "ylim"] = (0, 15)

    # linewidth
    df.loc["ripple confidence", "linewidth"] = 1
    df.loc["raw LFP", "linewidth"] = 1.0 / 5
    df.loc["ripple band LFP ({}-{} Hz)".format(RIP_LO_HZ, RIP_HI_HZ), "linewidth"] = (
        1.0 / 5
    )
    df.loc["ripple band normalized magnitude", "linewidth"] = 1.0 / 5
    df.loc["MEP normalized magnitude", "linewidth"] = 1.0 / 5

    ## Plots
    fig, axes = plt.subplots(df.shape[0], 1, sharex=True)
    out_sig = pd.DataFrame({"x_sec": x_sec})
    legends_1 = []
    for i_ax, ax in enumerate(axes):
        row = df.iloc[i_ax, :]
        label = row.name
        ax.plot(x_sec, row.signal, linewidth=row.linewidth, label=label, color="black")
        ax.set_ylim(row.ylim)
        leg1 = ax.legend(
            loc="upper left",
            framealpha=0,
            edgecolor=None,
            facecolor=None,
            shadow=False,
        )
        legends_1.append(leg1)  # for multiple legends; here, trace only
        out_sig[label] = row.signal  # to save

    title = "file: {}".format(lpath_lfp)
    fig.suptitle(title)
    axes[-1].set_xlabel("Time [sec]")
    fig.text(0.02, 0.5, "Amplitude [$\mu$V]", va="center", rotation="vertical")

    ################################################################################
    ## Fills ripple periods
    ################################################################################
    rip_sec = signals_dict["rip_sec"]
    rip_sec_plt = signals_dict["rip_sec"][
        (start_sec < signals_dict["rip_sec"]["start_sec"])
        & (rip_sec["end_sec"] < end_sec)
    ]

    for i_ax, ax in enumerate(axes):
        for ripple in rip_sec_plt.itertuples():
            c = utils.plt.colors.to_RGBA(
                utils.general.load("./conf/global.yaml")["GROUP_COLORS"][ripple.X2X],
                alpha=0.3,
            )

            ax.axvspan(
                ripple.start_sec,
                ripple.end_sec - 1.0 / samp_rate,
                color=c,
                zorder=1000,
            )

        if i_ax == 0:
            ## multiple legends; out of the figure
            handles, labels = [], []
            for x2x in ["T2T", "F2T", "T2F", "F2F"]:
                c = utils.plt.colors.to_RGBA(
                    utils.general.load("./conf/global.yaml")["GROUP_COLORS"][x2x],
                    alpha=0.3,
                )
                handles.append(matplotlib.patches.Patch(facecolor=c, alpha=0.1))
                labels.append(x2x)

            leg2 = ax.legend(handles, labels, loc="upper left", bbox_to_anchor=(1, 1))
            ax.add_artist(legends_1[i_ax])

    out_sig["rip_analog_sig_T2T_plt"] = rip_analog_sig_T2T_plt
    out_sig["rip_analog_sig_F2T_plt"] = rip_analog_sig_F2T_plt
    out_sig["rip_analog_sig_T2F_plt"] = rip_analog_sig_T2F_plt
    out_sig["rip_analog_sig_F2F_plt"] = rip_analog_sig_F2F_plt

    return fig, out_sig


#!/usr/bin/python3 -S
# -*- coding: utf-8 -*-
"""
    `Unit tests for cargo.builder.create_user`
--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--·--
   2016 Jared Lunde © The MIT License (MIT)
   http://github.com/jaredlunde
"""
import unittest
import psycopg2

from vital.security import randkey

from cargo import ORM, db, fields
from cargo.builder import create_tablespace
from cargo.builder.tablespaces import Tablespace

def new_field(type='char', value=None, name=None, table=None):
    field = getattr(fields, type.title())(value=value)
    field.field_name = name or randkey(24)
    field.table = table or randkey(24)
    return field

class TestCreateTablespace(unittest.TestCase):
    orm = ORM()

    def test_create(self):
        tablespace = create_tablespace(self.orm, 'foo', '/data/foo', dry=True)
        print(tablespace.query.mogrified)
        tablespace = Tablespace(self.orm, 'foo', '/data/foo')
        tablespace.owner('jared')
        tablespace.options(random_page_cost=4.0, seq_page_cost=1.0)
        print(tablespace.query)
        print(tablespace.query.mogrified)

if __name__ == '__main__':
    # Unit test
    unittest.main()