import math
import random
import time
import numpy

def main():

    bolean = True
    while bolean == True:
        print()
        print ('EP1 - MAP3121 - Métodos Numéricos e Aplicações')
        escolhido = int(input('Para Testes, digite 1, para Classificar, 2, para Sair, 3: '))
        print()

        if escolhido == 1:
            print ('1- Teste A')
            print ('2- Teste B')
            print ('3- Teste C')
            print ('4- Teste D')
            print ('5- Teste segunda tarefa')
            y = int(input('R:'))
            if y == 1:
                print(Resolve_Sistema(testeA(64,64)[0],testeA(64,64)[1],64,64))
            if y == 2:
                print(Resolve_Sistema(testeB(20,17)[0],testeB(20,17)[1],20,17))
            if y == 3:
                print(SistSimultaneos(testeC(64,64,3)[0],testeC(64,64,3)[1]))
            if y == 4:
                print(SistSimultaneos(testeD(20,17,3)[0],testeD(20,17,3)[1]))
            if y == 5:
                C = [[3/10,3/5,0],[1/2,0,1],[4/10,4/5,0]]
                W,H,d = FATORAÇÃO(C,3,3,2)
                print ('W =',W)
                print ('H =',H)
        if escolhido == 2:
            p = int(input('p:'))
            n_test = int(input('n_test:'))
            ndig_treino = int(input('ndig_treino:'))
            print()

            Teste(ndig_treino,n_test,p)
            print()
        if escolhido == 3:
              bolean = False
        else:
              None

 #_____________________________________________________________________________#

def Teste(ndig_treino,n_test,p):
    '''
    ndig_treino é com quantas imagens o dig sera testado/comparado
    n_test é quantas imagens serao comparadas
    p é quantas componentes terao Wd
    '''

    A = numpy.loadtxt('test_images.txt',usecols = range(n_test))
    Wd = TreinaDig(ndig_treino,p)[1] #TreinaDig me devolve uma linha com
    # treinei todos os digitos        # as Wd(matriz) de cada digito em cada posição
    Hd = []
    for g in range(10):
        Hdig = SistSimultaneos(Wd[g],A)
        Hd.insert(g,Hdig)

    WdigHdig =[]
    for nossa in range(10):
        WdigHdig.insert(nossa,Wd[nossa]@Hd[nossa])
        #agora tenho uma lista com matrizes resultado da multiplicação de
        # matrizes W e H para cada digito, WdigHdig é 784x784

    normas = [] #tera 2 dimensoes, digitos e erros das imagens(colunas)
    # 10xn_test
        # essa lista terá em suas linhas as informações de cada digito
        # dentro de cada linha tera as normas de cada imagem qnd comparadas
        # com cada digito, é uma matriz importante
    for dig in range(10):   # primeiro, escolhe qual digito vai ser comparado
        WHdig = WdigHdig[dig] #para dig 0, dps 1,2,3...

        for a_colunas in range(len(A[0])): # len(A[0]) == n_test
            normI = []       #pra uma imagem
            for a_linhas in range(len(A)-1):
                # esse laço coloca varias diferenças entre a imagem(coluna)
                # e a aproximaçao (WHdig) na lista normI
                normI.append(abs(A[a_linhas][a_colunas]-WHdig[a_linhas][a_colunas]))
                # normI é uma linha, calculamos a norma mesmo assim
            c = norma_euclidiana(normI)
                #uma imagem de 784 linhas é reduzida a um valor
                #AQUI CABE UMA ANALISE:
#  o valor c (norma euclidiana de normI) é a dif quadratica, um erro, entre
#   A IMAGEM REAL, E A APROXIMAÇÃO WdHd, ou seja, é o parametro
#   de comparação
            normI.append(c) #normI é quanto cada imagem se parece com o digito

        normas.append(normI)

    classific, Eassoc = analisaErro(normas,n_test)
    #sera feita a analise de todos os erros devolvendo duas matrizes, classific
    # com a classificação de cada imagem como um tal digito e Eassoc com o erro
    # de classificação associado a cada uma delas

    reais, corretas  = validacao(classific,Eassoc)

    for i in range (len(reais)):
        if reais[i] != 0:
            percent = corretas[i]*100/reais[i]
            print ('o digito %d teve %d acertos, representando %f' %(i, corretas[i], percent))
        else:
            percent = 0
            print ('o digito %d teve %d acertos, representando %f' %(i, corretas[i], percent))

    return

 #_____________________________________________________________________________#

def validacao(classific,Eassoc):
    '''
    classific é n_test X 1
    Eassoc é n_test X 1
    '''

    Real = numpy.loadtxt('test_index.txt')
    # eh uma vetor lista

    reais = []
    corretas = []

    for dig in range(10):
        deveria = 0
        acertos = 0
        for d in range (len(classific)): #==n_test
            if classific[d] == Real[d] == dig:
                acertos += 1
            elif Real[d] == dig:
                deveria +=1

        reais.append(deveria)
        corretas.append(acertos)

    return reais, corretas
 #_____________________________________________________________________________#

def analisaErro(normas,n_test):
    '''
    inicialmente A imagens é consideradas 0
    depois da verificação dos erros com os outros digitos, podem se tornar
    outros digitos
    '''

    classific = []
    Eassoc = []

    for im in range(len(normas[0])):  #pra uma imagem...  #normas[0]==n_test
        menor = 1000
        guard = 0
        for d in range (len(normas)): #procurar entre os digitos qual o menor erro
            if normas[d][im] <= menor: #d so vai de 0 a 9
                menor = normas[d][im]  # encontramos o menor erro da imagem
                guard = d
        # visto todos os erros pra uma imagem
        classific.append(guard)
        Eassoc.append(menor)
        # dois vetores linha com qual digito cada imagem representa
        # e outra com o erro (probabilidade) de ser esse digito
    return classific, Eassoc

 #_____________________________________________________________________________#
def TreinaDigUSER(dig,ndig_treino,p):

    t0 = time.process_time()

    Mat_digX = []

    print('Treinando digito', dig)

    traindig = numpy.loadtxt('train_dig'+str(dig)+'.txt',usecols = range(ndig_treino))

    Wd = FATORAÇÃO(traindig,len(traindig),len(traindig[0]),p)[0]

    Mat_digX.insert(dig,Wd)

    t1 = time.process_time()

    d = t1 - t0

    print('tempo para treinar dig',dig,':', d)

    return d, Mat_digX
 #_____________________________________________________________________________#

def TreinaDig(ndig_treino,p):
    '''
    cada imagem é uma (coluna de 784 linhas) e m colunas (n_cols, ou, ndig_treinos)
    dai forma uma matriz com a aprendizagem do digito Wd com (n=784)Xp (p escolhido)
    Guardar cada Wd

    '''
    t0 = time.process_time()
    Mat_digX = []
    for dig in range(10):
        tin = time.process_time()
        print('Treinando digito', dig)
        traindig = numpy.loadtxt('train_dig'+str(dig)+'.txt',usecols = range(ndig_treino))
        for i in range (len(traindig)):
            for j in range (len(traindig[0])):
                traindig[i][j] = traindig[i][j]/255
        Wd = FATORAÇÃO(traindig,len(traindig),len(traindig[0]),p)[0]
        Mat_digX.insert(dig,Wd)
        tout = time.process_time()
        delta = tout - tin
        print('tempo para treinar dig',dig,':', delta)
    t1 = time.process_time()
    d = t1 - t0
    return d, Mat_digX

 #_____________________________________________________________________________#

def FATORAÇÃO(A,n,m,p):
    '''A quadrado nXm
        W nXp
        H pxm
    '''
    t0 = time.process_time()
    W = matrixAleatoria255(n,p)
    Acopia = copiaMatriz(A)
    e = CalculaErro(A,W)
    it = 0
    while e > 10**-5 and it < 100:
        for col in range(len(W[0])):  # normalizando as Colunas
            s = 0
            for lin in range(len(W)):  # soma valores da coluna
                s += (W[lin][col])**2
            sq = math.sqrt(s)
            W = Normaliza_Coluna(W,col,sq) #normaliza a coluna de W

        H = numpy.array(SistSimultaneos(W,A))  # com W normalizado e A
        H = redefine(H)
        Wa = numpy.array(W)
        Ha = numpy.array(H)
        WH = Wa@Ha
        e0 = CalculaErro(A,WH)
        Ht = H.transpose()
        Acopiaa = numpy.array(Acopia)
        At = Acopiaa.transpose()
        Wt = numpy.array(SistSimultaneos(Ht,At))
        W = Wt.transpose()
        W = redefine(W)
        H = Ht.transpose()
        WH = W@H   # Multplica W por H
        e1 = CalculaErro(A,WH)

        e = abs(e0-e1)

        it += 1

    t1 = time.process_time()
    d = t1 - t0
    return W,H,d

 #_____________________________________________________________________________#

def SistSimultaneos(W,A):
    '''
    recebe uma matriz A e uma W, e devolve uma H, matriz de solução
    de todas os sistemas W com A[i]
    '''

    Wcopia = copiaMatriz(W)
    H = []
    for a_colunas in range(len(A[0])):    #formando uma matriz temporaria
        temp = []                      #com a coluna desejada para solve sist
        for a_linhas in range(len(A)):  #Destacamos uma coluna
            temp.append([A[a_linhas][a_colunas]])
            Wcopia = copiaMatriz(Wcopia)

        x = Resolve_Sistema(Wcopia,temp,len(Wcopia),len(Wcopia[0])) # matriz coluna
        x = numpy.array(x)
        x = x.transpose()       # agora matriz linha
        H.append(x[0])
    Ha = numpy.array(H)
    return Ha.transpose()

 #_____________________________________________________________________________#

def Resolve_Sistema(W,b,n,m):
    if n!= m :
        W,b = Sobredeterminada(W,b)
    m = len(W[0])
    n = len(W)
    for k in range(len(W[0])):
        for j in range(n-1,k,-1):
            i = j-1
            while W[j][k] > 10**-50:        #so chama rot_givens qnd tem que fazer operação
                if abs(W[i][k])>abs(W[i+1][k]): #caso a entrada for 0, continua procurando
                    tau = -W[i+1][k]/W[i][k]
                    c = 1/math.sqrt(1+tau**2)
                    s = c*tau
                    Rot_givens(W,n,m,i,j,c,s)
                    Rot_givens(b,n,0,i,j,c,s)
                else:
                    tau = -W[i][k]/W[i+1][k]
                    s = 1/math.sqrt(1+tau**2)
                    c = s*tau
                    Rot_givens(W,n,m,i,j,c,s)
                    Rot_givens(b,n,0,i,j,c,s)

    #agora vamos resolver o sistema com a matriz escalonada

    q = []
    if W[n-1][m-1] != 0: #ultimo valor da diagonal principal
        sol0 = (b[n-1][0])/W[n-1][m-1]     #CASO PARTICULAR DA
    else:                               # ULTIMA LINHA
        sol0 = 0
    q.append([sol0])  # uma linha eh adc ao vetor de soluções
                    #na ultima posição

    for linha in range(n-1,0,-1):   #monta a matriz x das soluçoes
        soma = 0        # loop de baixo a cima, resolvendo o sistema
        u = 0
        for j in range (linha,m):
            soma += W[linha-1][j]*q[u][0]
            u += 1

        if W[linha-1][linha-1] != 0: #caso o elemento da diag prin for 0
            soli = (b[linha-1][0]-soma)/W[linha-1][linha-1]
        else:           #caso geral
            soli = 0
        q.insert(0,[soli]) #adc na posição inicial as soluções das linhas

    return q    #devolve uma matriz coluna de soluçao

 #_____________________________________________________________________________#

def Rot_givens(W,n,m,i,j,c,s):

    if m == 0:  #RotGivens pra matriz coluna
        aux = c*W[i][0]-s*W[j][0]
        W[j][0] = s*W[i][0]+c*W[j][0]
        W[i][0] = aux

    else:   #RotGivens pra matriz a ser escalonada
        for k in range (0,m):
            aux = c*W[i][k]-s*W[j][k]
            W[j][k] = s*W[i][k]+c*W[j][k]
            W[i][k] = aux

    return W

 #_____________________________________________________________________________#

def Sobredeterminada(W,b):
    Wa = numpy.array(W)
    ba = numpy.array(b)
    Wt = Wa.transpose()
    R = Wt@W
    b = Wt@ba
                #daqui sai a matriz R quadrada
    return R,b #b so é corrigida pela multip. de matrizes

 #_____________________________________________________________________________#

def Normaliza_Coluna(W,col,sq):
    for lin in range(len(W)):  # normaliza todas as entradas dessa coluna
        if sq == 0:
            W[lin][col] = 0.0
        else:
            W[lin][col] = W[lin][col]/sq

    return W

 #_____________________________________________________________________________#

def copiaMatriz(W):
    Wcop = []
    for i in range(len(W)):
        Wcop.append([])
        for j in range(len(W[i])):
            Wcop[i].append(W[i][j])  #adiciona todas as entradas de uma coluna
                                    # numa linha
    return Wcop

 #_____________________________________________________________________________#

def matrixAleatoria9(n,m):
    E = []
    for a_linhas in range(n):
        temp = []
        for a_colunas in range(m):
            x = random.randrange(0,9)
            temp.append(x)
        E.append(temp)

    return E

 #_____________________________________________________________________________#

def matrixAleatoria255(n,m):
    E = []
    for a_linhas in range(n):
        temp = []
        for a_colunas in range(m):
            x = random.randrange(0,255)
            temp.append(x)
        E.append(temp)

    return E

 #_____________________________________________________________________________#

def CalculaErro(A,WH): #A - WH

    E =[]
    for linhas in range(len(WH)):  #nesse passo A e WH tem mesma dimensao
        for colunas in range(len(WH[0])):
            Etemp = (A[linhas][colunas]-WH[linhas][colunas])**2 #variavel
            E.append(Etemp) # coloca as pequenas diferencas na lista
    erro = math.sqrt(sum(E))

    return erro

 #_____________________________________________________________________________#

def redefine(M):
    for a_linhas in range(len(M)):
        for a_colunas in range(len(M[0])):
            if M[a_linhas][a_colunas] <= 0:
                M[a_linhas][a_colunas] = 0
    return M

 #_____________________________________________________________________________#

def norma_euclidiana(A):
    E = numpy.linalg.norm(A)
    return E

 #_____________________________________________________________________________#

def testeA(n,m):
    W=[]
    for i in range (n):
        linhai= []
        for j in range (m):
            if i == j:
                linhai.append(2)
            elif abs(i-j) == 1:
                linhai.append(1)
            elif abs(i-j) > 1:
                linhai.append(0)

        W.append(linhai)

    b = []
    for i in range (0,n):
        b.append([1])

    return W,b

 #_____________________________________________________________________________#

def testeB(n,m):
    W=[]
    for i in range (0,n):
        linhai= []
        for j in range (0,m):
            if abs(i-j) <=4:
                if i+j-1 == 0:
                    linhai.append(0)
                else:
                    linhai.append(1/(i+j-1))
            elif abs(i-j) >4:
                linhai.append(0)

        W.append(linhai)

    b = []
    for i in range (0,n):
        b.append([i])

    return W,b

 #_____________________________________________________________________________#

def testeC(n,p,m):
    W=[]
    for i in range (n):
        linhai= []
        for j in range (p):
            if i == j:
                linhai.append(2)
            elif abs(i-j) == 1:
                linhai.append(1)
            elif abs(i-j) > 1:
                linhai.append(0)

        W.append(linhai)

    A = []
    for k in range (n):
        linhak= []
        for j in range (m+1):
            if j == 1:
                linhak.append(1)
            elif j == 2:
                linhak.append(k)
            elif j == 3:
                linhak.append(2*k-1)
        A.append(linhak)

    return W, A

 #_____________________________________________________________________________#

def testeD(n,p,m):
    W=[]
    for i in range (0,n):
        linhai= []
        for j in range (0,p):
            if abs(i-j) <=4:
                if i+j-1 == 0:
                    linhai.append(0)
                else:
                    linhai.append(1/(i+j-1))
            elif abs(i-j) >4:
                linhai.append(0)

        W.append(linhai)

    A = []
    for k in range (n):
        linhak= []
        for j in range (m+1):
            if j == 1:
                linhak.append(1)
            elif j == 2:
                linhak.append(k)
            elif j == 3:
                linhak.append(2*k-1)
        A.append(linhak)

    return W, A

main()

EP1 - MAP3121 - Métodos Numéricos e Aplicações.py


import pymysql
from pymysql.err import Error

def abrir_conexion():
    try:
        conexion = pymysql.connect(host='localhost',
                                    user='root',
                                    password='',
                                    db='abm_socios')
        print("La conexión a la base de datos fue correcta")
        return conexion
    except (Exception, Error) as error_capturado:
        print("Ocurrió el siguiente error en la conexión a la base de datos: ",
                error_capturado)

def cerrar_conexion(conexion):
    try:
        conexion.close()
        print("La conexión a la base de datos cerrada de forma correcta")
    except (Exception, Error) as error_capturado:
        print("Ocurrió el siguiente error al cerrar la conexión a la base de datos: ", error_capturado)

def buscar_socio_x_Id(id_buscar):
    try:
        conexion = abrir_conexion()
        cursor =  conexion.cursor()
        query = 'SELECT id_socio, nombres_socio, apellidos_socio, dni_socio, \
                cant_grupo_familiar, cant_menores18, cuota \
                FROM socios WHERE id_socio = %s;'
        cursor.execute(query, id_buscar)
        socio = cursor.fetchone()
        return socio
    except:
        return False
    finally:
        cerrar_conexion(conexion)

def modificacion_socio(socio):
    try:
        conexion = abrir_conexion()
        cursor =  conexion.cursor()
        query = 'UPDATE socios SET nombres_socio = %s, apellidos_socio = %s, \
            dni_socio = %s, cant_grupo_familiar = %s,\
            cant_menores18 = %s, cuota = %s, menores_18 = %s WHERE id_socio = %s;'  #agregamos la columna menores_18
        values = (socio[1], socio[2], socio[3], socio[4], socio[5], socio[6], socio[7], socio[0]) #aca se le agrega el value correspondiente
        cursor.execute(query, values)
        conexion.commit()
        return True
    except:
        return False
    finally:
        cerrar_conexion(conexion)

def baja_socio(id_eliminar):
    try:
        conexion = abrir_conexion()
        cursor =  conexion.cursor()
        query = 'DELETE FROM socios WHERE id_socio = %s;'
        cursor.execute(query, id_eliminar)
        conexion.commit()
        return True
    except:
        return False
    finally:
        cerrar_conexion(conexion)

def alta_socio(socio):
    try:
        conexion = abrir_conexion()
        cursor =  conexion.cursor()
        query = 'INSERT INTO socios(nombres_socio, apellidos_socio, dni_socio,\
             cant_grupo_familiar, cant_menores18, cuota, menores_18) VALUES (%s, %s, %s, %s, %s, %s, %s);' #y por ultimo se agrega al insert el menores_18 con su respectivo value
        cursor.execute(query, socio[1:])
        conexion.commit()
        query = 'SELECT * FROM socios WHERE id_socio = \
                                (SELECT MAX(id_socio) FROM socios)'
        cursor.execute(query)
        socio = cursor.fetchone()
        return socio
    except:
        return False
    finally:
        cerrar_conexion(conexion)


#Write a program that takes a list of numbers and prints the indices of the numbers that are perfect squares
import math
import fractions
n = int(input())
lst = []
indices = []
new_lst = []
for i in range(n):
    lst.append(int(input()))
print(lst)
def is_perfect_square(num):
    if num >= 0:
        a = int(math.sqrt(num))
        return ((a*a) == num)
    return False
for k, num in enumerate(lst):
    if is_perfect_square(num):
        indices.append(k)
        new_lst.append(num)
print(list(zip(indices, new_lst)))


import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

# Define vertices for the triangle
vertices = [
    (0, 1, 0),
    (-1, -1, 0.5),
    (1, -1, 1)
]

# Define the light source position
light_position = (4, 2, 0)

# Initialize Pygame
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
glClearColor(0.0, 0.0, 0.0, 1.0)
glEnable(GL_DEPTH_TEST)

# Define the projection matrix
gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
glTranslatef(0, 0, -5)

def draw_triangle(color):
    glColor3f(color[0], color[1], color[2])
    glBegin(GL_TRIANGLES)
    for vertex in vertices:
        glVertex3fv(vertex)
    glEnd()

def draw_plane():
    glBegin(GL_QUADS)
    glColor3f(0.0, 0.0, 1.0)
    glVertex3f(-2.7, 0.7, -2.7)
    glVertex3f(2.7, 0.7, -2.7)
    glVertex3f(1.7, -1.7, 1.7)
    glVertex3f(-1.7, -1.7, 1.7)
    glEnd()

def draw_shadow():
    glDisable(GL_LIGHTING)
    glColor3f(1.0, 0.0, 0.0)
    glPushMatrix()
    glTranslatef(0, -1.01, 0)  # Slightly below the plane
    draw_triangle((0.5,0.5,0.5))
    glPopMatrix()

def main():
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # Setup lighting
        #glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glLightfv(GL_LIGHT0, GL_POSITION, light_position)

        # Draw the triangle
        glPushMatrix()
        glRotatef(1, 3, 1, 1)
        draw_triangle((0,1,0))
        glPopMatrix()

        # Draw the plane
        draw_plane()

        # Draw the shadow
        draw_shadow()

        pygame.display.flip()
        pygame.time.wait(10)

if __name__ == "__main__":
    main()


MODEL_GROUP_NAME = 150
MODEL_ARENA_NAME = 150
MODEL_CITY_NAME = 150
MODEL_STATS_MAX_LENGTH = 10
MODEL_USER_AVATAR = 'profile_picture'
MODEL_USER_FIRST_NAME = 30
MODEL_USER_LAST_NAME = 30
MODEL_USER_KNOWN_AS = 150
MODEL_USER_IMAGE_SIZE = (128, 128)
MODEL_USER_COUNTRIES = (
	('ND', 'Not defined'),
	('AL','Albania'),
	('AR','Argentina'),
	('AU','Australia'),
	('AT','Austria'),
	('AZ','Azerbaijan'),
	('BD','Bangladesh'),
	('BY','Belarus'),
	('BE','Belgium'),
	('BA','Bosnia And Herzegovina'),
	('BR','Brazil'),
	('IO','British Indian Ocean Territory'),
	('BG','Bulgaria'),
	('CA','Canada'),
	('CL','Chile'),
	('CN','China'),
	('CO','Colombia'),
	('CR','Costa Rica'),
	('HR','Croatia'),
	('CU','Cuba'),
	('CY','Cyprus'),
	('CZ','Czech Republic'),
	('DK','Denmark'),
	('DO','Dominican Republic'),
	('EC','Ecuador'),
	('EG','Egypt'),
	('SV','El Salvador'),
	('GQ','Equatorial Guinea'),
	('EE','Estonia'),
	('FI','Finland'),
	('FR','France'),
	('DE','Germany'),
	('GR','Greece'),
	('GL','Greenland'),
	('HK','Hong Kong'),
	('HU','Hungary'),
	('IS','Iceland'),
	('IN','India'),
	('ID','Indonesia'),
	('IE','Ireland'),
	('IL','Israel'),
	('IT','Italy'),
	('JM','Jamaica'),
	('JP','Japan'),
	('KZ','Kazakhstan'),
	('KP','Korea,Democratic Peoples Republic Of'),
	('KR','Korea,Republic Of'),
	('KW','Kuwait'),
	('LV','Latvia'),
	('LB','Lebanon'),
	('LT','Lithuania'),
	('LU','Luxembourg'),
	('MK','Macedonia,The Former Yugoslav Republic Of'),
	('MT','Malta'),
	('MX','Mexico'),
	('MD','Moldova,Republic Of'),
	('MC','Monaco'),
	('ME','Montenegro'),
	('MA','Morocco'),
	('NL','Netherlands'),
	('AN','Netherlands Antilles'),
	('NZ','New Zealand'),
	('NI','Nicaragua'),
	('NO','Norway'),
	('PY','Paraguay'),
	('PE','Peru'),
	('PL','Poland'),
	('PT','Portugal'),
	('PR','Puerto Rico'),
	('RO','Romania'),
	('RU','Russian Federation'),
	('RS','Serbia'),
	('SK','Slovakia'),
	('SI','Slovenia'),
	('ES','Spain'),
	('LK','Sri Lanka'),
	('SE','Sweden'),
	('CH','Switzerland'),
	('TW','Taiwan'),
	('TH','Thailand'),
	('TR','Turkey'),
	('UA','Ukraine'),
	('GB','United Kingdom'),
	('US','United States')
)

LOGIN_URL ='/pachangapp/login/'


import gensim
import numpy as np
import pandas as pd
from sklearn.linear_model import RidgeClassifier
from sklearn.base import ClassifierMixin, BaseEstimator
from .._types import validate_text_input
from ..base import AnySklearnEstimator

def _gensim_preprocess(X: pd.Series):
    """Lowers and splits texts"""
    X_pre = X.apply(gensim.utils.simple_preprocess).tolist()
    X_pre = [gensim.models.doc2vec.TaggedDocument(texts, [i]) for i, texts in enumerate(X_pre)]

    return X_pre

class Doc2VecClassifier(BaseEstimator, ClassifierMixin):
    """Text Classifier using Doc2Vec feateures given any Sklearn compatible estimator.

    Parameters
    ----------
    estimator : AnySklearnEstimator, default=RidgeClassifier
        Estimator to fit on TF-IDF vector. Prefer estimators with sparse vector support.

    vector_size : int, default=100
        Dimensionality of the feature vectors.

    min_count : int, default=1
        Ignores all words with total frequency lower than this.

    window : int, default=5
        The maximum distance between the current and predicted word within a sentence.

    workers : int, default=1
        Use these many worker threads to train the model (=faster training with multicore machines).

    epochs : int, default=10
        Number of iterations (epochs) over the corpus.
    """

    def __init__(self,
                 estimator: AnySklearnEstimator = RidgeClassifier(),
                 vector_size: int = 100,
                 min_count: int = 1,
                 window: int = 5,
                 epochs: int = 10,
                 workers: int = 1,
                 ):

        self.estimator = estimator
        self.vector_size = vector_size
        self.min_count = min_count
        self.window = window
        self.epochs = epochs
        self.workers = workers

        self.vectorizer = gensim.models.doc2vec.Doc2Vec(
            vector_size=self.vector_size,
            min_count=self.min_count,
            window=self.window,
            epochs=self.epochs,
            workers=self.workers,
        )
        self.is_prefit = False

    def prefit(
        self,
        X: pd.Series,
        y=None
    ):
        """Prefit Doc2Vec vectorizer with unlabeled text data.

        Parameters
        ----------
        X : pd.Series
            Pandas series containing texts.

        y : None
             This parameter is not needed.

        Returns
        -------
        self : object
            Fitted estimator.
        """

        validate_text_input(X)

        if self.is_prefit:
            print("Overwriting previous prefit.")

        train_corpus = _gensim_preprocess(X)

        self.vectorizer.build_vocab(train_corpus)
        self.vectorizer.train(train_corpus, total_examples=self.vectorizer.corpus_count, epochs=self.vectorizer.epochs)

        self.is_prefit = True

    def fit(
        self,
        X: pd.Series,
        y: pd.Series
    ):
        """Build Doc2Vec vectors from training set and fit the provided estimator.

        Parameters
        ----------
        X : pd.Series
            Pandas text series containing texts.

        y : pd.Series
            Pandas text series containing targets.

        Returns
        -------
        self : object
            Fitted estimator.
        """
        validate_text_input(X)

        if self.is_prefit:
            X_pre = _gensim_preprocess(X)
            vectors = [self.vectorizer.infer_vector(doc.words) for doc in X_pre]
            X_vec = pd.DataFrame(np.stack(vectors))
        else:
            train_corpus = _gensim_preprocess(X)
            self.vectorizer.build_vocab(train_corpus)
            self.vectorizer.train(train_corpus, total_examples=self.vectorizer.corpus_count, epochs=self.vectorizer.epochs)

            vectors = [self.vectorizer.infer_vector(doc.words) for doc in train_corpus]
            X_vec = pd.DataFrame(np.stack(vectors))

        self.estimator.fit(X_vec, y)

        return self

    def predict(
        self,
        X: pd.Series
    ):
        """Predict class labels for samples in `X`.

        Parameters
        ----------
        X : pd.Series
            Pandas text series containing texts.

        Returns
        -------
        y_pred : ndarray of shape (n_samples,) or (n_samples, n_outputs)
            Vector or matrix containing the predictions.
        """
        validate_text_input(X)

        X_pre = _gensim_preprocess(X)
        vectors = [self.vectorizer.infer_vector(doc.words) for doc in X_pre]
        X_vec = pd.DataFrame(np.stack(vectors))

        return self.estimator.predict(X_vec)

    def predict_proba(
        self,
        X: pd.Series
    ):
        """Probability estimates.

        Parameters
        ----------
        X : pd.Series
            Pandas text series containing texts.

        Returns
        -------
        y_prob : ndarray of shape (n_samples, n_classes)
            The predicted probability of the sample for each class in the
            model, where classes are ordered as they are in `self.classes_`.
        """
        validate_text_input(X)

        if not hasattr(self.estimator, "predict_proba"):
            raise AttributeError(f"{self.estimator} does not have a predict_proba method.")

        X_pre = _gensim_preprocess(X)
        vectors = [self.vectorizer.infer_vector(doc.words) for doc in X_pre]
        X_vec = pd.DataFrame(np.stack(vectors))

        return self.estimator.predict_proba(X_vec)


import time
import logging
import re
import torch
from torch.utils.data import Dataset, DataLoader
from transformers import T5ForConditionalGeneration, T5Tokenizer, AdamW
import pytorch_lightning as pl

from transformers import AutoTokenizer, AutoModelWithLMHead

tokenizer = AutoTokenizer.from_pretrained("deep-learning-analytics/triviaqa-t5-base")

# tokenizer = T5Tokenizer.from_pretrained('t5-base')

class QADataset(Dataset):
    def __init__(
            self,
            data, #:pd.DataFrame
            source_max_token_len: int = 396,
            target_max_token_len: int = 32,
        ):
        self.data =  data
        self.source_max_token_len =  source_max_token_len
        self.target_max_token_len =  target_max_token_len
        self.tokenizer = tokenizer

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index: int):
        data_row = self.data.iloc[index]
        source_encoding = self.tokenizer(
            data_row['question'],
            data_row['context'],
            max_length=self.source_max_token_len,
            padding='max_length',
            truncation="only_second",
            return_attention_mask=True,
            add_special_tokens=True,
            return_tensors="pt"
            )
        target_encoding = self.tokenizer(
            data_row['answer_text'],
            max_length=self.target_max_token_len,
            padding='max_length',
            truncation=True,
            return_attention_mask=True,
            add_special_tokens=True,
            return_tensors="pt"
            )
        labels = target_encoding['input_ids']
        labels[labels==0] = -100
        return dict(
            question=data_row['question'],
            context=data_row['context'],
            answer_text=data_row['answer_text'],
            input_ids=source_encoding["input_ids"].flatten(),
            attention_mask=source_encoding['attention_mask'].flatten(),
            labels=labels.flatten()
        )

class DataModule(pl.LightningDataModule):

    def __init__(
            self,
            train_df,
            test_df,
            batch_size: int = 8,
            source_max_token_len: int = 396,
            target_max_token_len: int = 32,
        ):
        super().__init__()
        self.train_df = train_df
        self.test_df = test_df
        self.batch_size = batch_size
        self.source_max_token_len = source_max_token_len
        self.target_max_token_len = target_max_token_len

    def setup(self):
        self.train_dataset = QADataset(
            self.train_df,
            self.source_max_token_len,
            self.target_max_token_len
        )
        self.test_dataset = QADataset(
            self.test_df,
            self.source_max_token_len,
            self.target_max_token_len
        )

    def train_dataloader(self):
        return DataLoader(
            self.train_dataset,
            batch_size=self.batch_size,
            shuffle=True,
            num_workers=4
        )

    def val_dataloader(self):
        return DataLoader(
            self.test_dataset,
            batch_size=self.batch_size,
            num_workers=4
        )

    def test_dataloader(self):
        return DataLoader(
            self.test_dataset,
            batch_size=1,
            num_workers=4
        )

class QAModel(pl.LightningModule):

    def __init__(self):
        super().__init__()
        # self.model = T5ForConditionalGeneration.from_pretrained('t5-base', return_dict=True)
        self.model = AutoModelWithLMHead.from_pretrained("deep-learning-analytics/triviaqa-t5-base", return_dict=True)

    def forward(self, input_ids, attention_mask, labels=None):
        output = self.model(
            input_ids,
            attention_mask=attention_mask,
            labels=labels)
        return output.loss, output.logits

    def training_step(self, batch, batch_idx):
        input_ids = batch['input_ids']
        attention_mask=batch['attention_mask']
        labels = batch['labels']
        loss, outputs = self(input_ids, attention_mask, labels)
        self.log("train_loss", loss, prog_bar=True, logger=True)
        return {
            "loss": loss,
            "predictions":outputs,
            "labels": labels
        }

    def validation_step(self, batch, batch_idx):
        input_ids = batch['input_ids']
        attention_mask=batch['attention_mask']
        labels = batch['labels']
        loss, outputs = self(input_ids, attention_mask, labels)
        self.log("val_loss", loss, prog_bar=True, logger=True)
        return loss

    def test_step(self, batch, batch_idx):
        input_ids = batch['input_ids']
        attention_mask=batch['attention_mask']
        labels = batch['labels']
        loss, outputs = self(input_ids, attention_mask, labels)
        self.log("test_loss", loss, prog_bar=True, logger=True)
        return loss

    def configure_optimizers(self):
        optimizer = AdamW(self.parameters(), lr=0.0001)
        return optimizer

def generate_answer(question, trained_model):
    source_encoding = tokenizer(
        question["question"],
        question['context'],
        max_length = 396,
        padding="max_length",
        truncation="only_second",
        return_attention_mask=True,
        add_special_tokens=True,
        return_tensors="pt"
    )
    generated_ids = trained_model.model.generate(
        input_ids=source_encoding["input_ids"],
        attention_mask=source_encoding["attention_mask"],
        num_beams=10,  # greedy search
        max_length=20,
        repetition_penalty=2.5,
        early_stopping=True,
        use_cache=True)
    preds = [
            tokenizer.decode(generated_id, skip_special_tokens=True, clean_up_tokenization_spaces=True)
            for generated_id in generated_ids
    ]
    return "".join(preds)


import os.path
import shutil

import fixtures
import stubout

from glance.api.middleware import context
from glance.common import config
from glance.tests import utils as test_utils

class TestPasteApp(test_utils.BaseTestCase):

    def setUp(self):
        super(TestPasteApp, self).setUp()
        self.stubs = stubout.StubOutForTesting()
        self.addCleanup(self.stubs.UnsetAll)

    def _do_test_load_paste_app(self,
                                expected_app_type,
                                make_paste_file=True,
                                paste_flavor=None,
                                paste_config_file=None,
                                paste_append=None):

        def _writeto(path, str):
            with open(path, 'wb') as f:
                f.write(str or '')
                f.flush()

        def _appendto(orig, copy, str):
            shutil.copy(orig, copy)
            with open(copy, 'ab') as f:
                f.write(str or '')
                f.flush()

        self.config(flavor=paste_flavor,
                    config_file=paste_config_file,
                    group='paste_deploy')

        temp_dir = self.useFixture(fixtures.TempDir()).path
        temp_file = os.path.join(temp_dir, 'testcfg.conf')

        _writeto(temp_file, '[DEFAULT]\n')

        config.parse_args(['--config-file', temp_file])

        paste_to = temp_file.replace('.conf', '-paste.ini')
        if not paste_config_file and make_paste_file:
            paste_from = os.path.join(os.getcwd(),
                                      'etc/glance-registry-paste.ini')
            _appendto(paste_from, paste_to, paste_append)

        app = config.load_paste_app('glance-registry')

        self.assertEquals(expected_app_type, type(app))

    def test_load_paste_app(self):
        expected_middleware = context.UnauthenticatedContextMiddleware
        self._do_test_load_paste_app(expected_middleware)

    def test_load_paste_app_paste_config_not_found(self):
        expected_middleware = context.UnauthenticatedContextMiddleware
        self.assertRaises(RuntimeError, self._do_test_load_paste_app,
                          expected_middleware, make_paste_file=False)

    def test_load_paste_app_with_paste_flavor(self):
        pipeline = ('[pipeline:glance-registry-incomplete]\n'
                    'pipeline = context registryapp')
        expected_middleware = context.ContextMiddleware
        self._do_test_load_paste_app(expected_middleware,
                                     paste_flavor='incomplete',
                                     paste_append=pipeline)

    def test_load_paste_app_with_paste_config_file(self):
        paste_config_file = os.path.join(os.getcwd(),
                                         'etc/glance-registry-paste.ini')
        expected_middleware = context.UnauthenticatedContextMiddleware
        self._do_test_load_paste_app(expected_middleware,
                                     paste_config_file=paste_config_file)


from optparse import OptionParser
import os, shutil
from pkg_resources import Requirement, resource_filename
import plugboard

class CreateCommand(object):
    def __init__(self, main):
        self.main = main
        self.skeleton_path = resource_filename(Requirement.parse('PlugBoard'), 'plugboard/skeleton')
        self.setup_tmpl = """from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages

setup(
    name="%(project_title)s",
    version="0.1",
    description="Project description",
    author="Project author",
    packages=find_packages(),
    entry_points=\"\"\"
    [%(project_name)s.plugins]

    \"\"\",
    install_requires=["PlugBoard>=%(plugboard_version)s"],
    )
"""

    def run(self, options, args):
        if not args:
            self.main.parser.error('You must specify the name of the project to create')
        project_name = args[0]
        shutil.copytree(self.skeleton_path, project_name)
        project_path = os.path.abspath(project_name)
        os.rename(os.path.join(project_path, '_app_'), os.path.join(project_path, project_name.lower()))
        setup_py = self.setup_tmpl % {'project_name': project_name,
                                      'project_title': project_name.title(),
                                      'plugboard_version': plugboard.__version__}
        setup = file(os.path.join(project_path, 'setup.py'), 'w')
        setup.write(setup_py)
        setup.close()
        os.unlink(os.path.join(project_path, '__init__.py'))
        for curdir, dirs, files in os.walk(project_path):
            for filename in files:
                if filename.endswith('.pyc'):
                    os.unlink(os.path.join(curdir, filename))
            if '.svn' in dirs:
                shutil.rmtree(os.path.join(curdir, '.svn'))

class Main(object):
    def __init__(self):
        self.parser = OptionParser()
        self.commands = {
            'CREATE': CreateCommand(self),
        }

    def run(self):
        options, args = self.parser.parse_args()
        if not args:
            self.parser.error('You must specify one of the following commands: CREATE')
        command = args[0].upper()
        if not self.commands.has_key(command):
            self.parser.error('Command %r not found' % command)
            sys.exit(-1)
        self.commands[command].run(options, args[1:])

if __name__ == '__main__':
    Main().run()


menu = [
        ["egg", "bacon"],
        ["egg", "sausage", "bacon"],
        ["egg", "spam"],
        ["egg", "bacon", "spam"],
        ["spam", "spam", "spamegg"],
        ]
for meal in menu :
    if "spam" not in meal :
        print(meal)
        for item in meal :
            print(item)
    else :
        print("{0} has spam score of {1}".format(meal, meal.count("spam")))


'''
Input: Unsorted array a[1]...a[n]
Output: 1 if a[1]..a[n] has #inversions = 1.
        0 if #inversions = 0
        1 if #inversions = -1
'''

import math

# Challenge Implementation
def isSorted(a):
    return all( a[i] < a[i+1] for i in range(len(a)-1))

def swap(a,i,j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp

def oneSwap(a):
    n = len(a)
    i = 0
    j = n-1

    #Check ascending order disruptor.
    k1 = 0
    i+=1
    while i < j:
        if a[i] < a[i-1]:
            k1 = i-1
            break
        i+=1

    #Check descending ord disruptor.
    k2 = 0
    j-=1
    while j > k1:
        if a[j] > a[j+1]:
            k2 = j+1
            break
        j-=1

    swap(a,k1,k2)
    return isSorted(a)

######################################
# Driver Code
######################################
if __name__ == "__main__":
    a = [1,8,4,5,7,2,9]
    test = oneSwap(a)
    print(test)


#coding: UTF-8
from convlab2.laug.Speech_Recognition.ASR import wav2text
from convlab2.laug.Speech_Recognition.TTS import text2wav
from convlab2.laug.Speech_Recognition.multiwoz.span_detection import span_detect

import os
import time

class Speech_Recognition:
    def __init__(self,dataset='multiwoz',temp_file='temp',tld='com'):

        self.wav2text = wav2text()
        self.temp_file = temp_file
        self.tld = tld
    def aug(self,text,span_info):
        ok=0
        while ok==0:
            try:
                text2wav(text,tld=self.tld,filename=self.temp_file)
            except ValueError:
                ok=0
                print("gTTS error occur!")
            else:
                ok=1
        new_text = self.wav2text.run(self.temp_file+".wav")
        new_span_info=[]
        for span in span_info:
            new_span_info.append(span_detect(text,new_text,span))
        return new_text,new_span_info

if __name__=="__main__":
    text = "I want a train to Cambridge"
    span_info = [["Train-Inform","Dest","Cambridge",5,5]]
    SR = Speech_Recognition()
    new_text,new_span_info = SR.aug(text,span_info)
    print(new_text)
    print(new_span_info)


import Observer

class WeatherForecast(Observer.Observer):
    """forecast for tomorrow"""

    def __init__(self):
        super(WeatherForecast, self).__init__()
        self.temperatures = []
        self.humidities = []
        self.pressures = []

    def show_forecast(self):
        print()
        print('Forecast for tommorow:')
        print('temp: {}'.format(self.temperature))
        print('humidity: {}'.format(self.humidity))
        print('pressure: {}'.format(self.pressure))
        print()

    def get_average(self, parameters):
        items_count = 0
        items_sum = 0

        for param in parameters:
            items_count += 1
            items_sum += param

        return items_sum / items_count

    def collect_data(self, temperature, humidity, pressure):
        self.temperatures.append(temperature)
        self.humidities.append(humidity)
        self.pressures.append(pressure)

        if len(self.temperatures) == 10:
            self.temperature = self.get_average(self.temperatures)
            self.humidity = self.get_average(self.humidities)
            self.pressure = self.get_average(self.pressures)

            self.temperatures.clear()
            self.humidities.clear()
            self.pressures.clear()

            return True
        else:
            return False

    def update(self, temperature, humidity, pressure):
        if self.collect_data(temperature, humidity, pressure):
            self.show_forecast()


import justsayhello

justsayhello.hello()

print(justsayhello.__file__)
print(justsayhello.__name__)

def isAutomorphic(num):
    sq = num * num
    while num > 0:
        if num % 10 != sq % 10:
            return False
        num = num / 10
        sq = sq / 10
    return True

res = isAutomorphic(6)
print("is 6 automorphic", res)

res = isAutomorphic(5)
print("is 5 automorphic", res)


"""
LAST VERSION TO COMPUTE BAG OF WORDS
"""
import json
from itertools import cycle
import numpy as np
import time

from sklearn.manifold import Isomap, SpectralEmbedding, TSNE
from sklearn.metrics import silhouette_score
from cluster.hkmeans import HKMeans
import matplotlib.pyplot as plt
# from sklearn.decomposition import PCA, SparsePCA
from cluster.distance_functions import hamming

paths = []
paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s0/0_1fps')
paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s0/1_1fps')

# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s1/0_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s1/1_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s1/2_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s1/3_1fps')

# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s2/0_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s2/1_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s2/2_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s2/3_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s2/4_1fps')

# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s3/0_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s3/1_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s3/2_1fps')
# paths.append('/media/arvc/50324D7B324D6756/datasets/VIRB360/euroc/s3/3_1fps')

def read_descriptors(path):
    descriptors_input_path = path # + '/mav0/descriptors.json'
    with open(descriptors_input_path, 'r') as json_file:
        data = json.load(json_file)
        desc1 = data['descriptors_front']
        desc2 = data['descriptors_back']
        # extend list 1
        desc1.extend(desc2)
        return desc1

def flatten_list(all_descriptors):
    """
    Flattens list of descriptors: original list is of size
        n_landmarks list with [1500 x 32] in each
    """
    ret_descriptors = []
    for descriptors_image in all_descriptors:
        for desc in descriptors_image:
            ret_descriptors.append(desc)
    return ret_descriptors

# def plot_result(X, y, centroids):
#     # Plot init seeds along side sample data
#     plt.figure()
#     colors = cycle(['r', 'g', 'b', 'k', 'c', 'm', 'y'])
#     for k in set(y):
#         cluster_data = (y == k)
#         plt.scatter(X[cluster_data, 0], X[cluster_data, 1], c=next(colors), marker='.', s=50)
#         # plt.scatter(centroids[k][0], centroids[k][1], c='k', marker='.', s=200)
#     plt.title("RESULT! Data clustered")
#     plt.show()
#     return

def plot_results_projecting(X, y, centroids):
    from cluster.distance_functions import compute_hamming_distances
    # Plot init seeds along side sample data
    plt.figure()
    colors = cycle(['r', 'g', 'b', 'k', 'c', 'm', 'y'])
    on = np.unpackbits(np.array([255, 255, 255, 255, 255, 255, 255, 255,
                                 255, 255, 255, 255, 255, 255, 255, 255,
                                 255, 255, 255, 255, 255, 255, 255, 255,
                                 255, 255, 255, 255, 255, 255, 255, 255], dtype=np.uint8))
    off = np.unpackbits(np.array([0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0], dtype=np.uint8))
    for k in set(y):
        cluster_data = (y == k)
        # project all data of that cluster to to two dimensions, using two hamming distances.
        # d1 is the distance to [0  0 00 0 ]
        # d2 is the distance to [11111]
        d1 = compute_hamming_distances(X[cluster_data], on)
        d2 = compute_hamming_distances(X[cluster_data], off)
        # plt.scatter(X[cluster_data, 0], X[cluster_data, 1], c=next(colors), marker='.', s=50)
        plt.scatter(d1, d2, c=next(colors), marker='.', s=50)
        d1c = hamming(centroids[k], on)
        d2c = hamming(centroids[k], off)
        # plt.scatter(centroids[k][0], centroids[k][1], c='k', marker='.', s=200)
        plt.scatter(d1c, d2c, c=next(colors), marker='*', s=50)
        plt.annotate(str(k), (d1c, d2c))

    plt.title("RESULT! Data clustered")
    plt.show()
    return

def plot_results_isomap(X, y, centroids):
    embedding = Isomap(n_components=2, metric='manhattan', p=1)
    X_red = embedding.fit_transform(X)
    plot_results(X_red, y, title='RESULT! Data clustered. Using ISOMAP CLUSTERING TO VISUALIZE')

    # centroids_red = embedding.transform(centroids)
    # colors = cycle(['r', 'g', 'b', 'k', 'c', 'm', 'y'])
    #
    # for k in set(y):
    #     cluster_data = (y == k)
    #     plt.scatter(X_red[cluster_data, 0], X_red[cluster_data, 1], c=next(colors), marker='.', s=50)
    #     plt.scatter(centroids_red[k][0], centroids_red[k][1], c='k', marker='.', s=200)
    # plt.title("RESULT! Data clustered. Using ISOMAP TO VISUALIZE")
    # plt.show()

def plot_results_spectral(X, y, centroids):
    embedding = SpectralEmbedding(n_components=2)
    X_red = embedding.fit_transform(X)
    plot_results(X_red, y, title='RESULT! Data clustered. Using SPECTRAL CLUSTERING TO VISUALIZE')

    #
    # # centroids_red = embedding.transform(centroids)
    # colors = cycle(['r', 'g', 'b', 'k', 'c', 'm', 'y'])
    #
    # for k in set(y):
    #     cluster_data = (y == k)
    #     plt.scatter(X_red[cluster_data, 0], X_red[cluster_data, 1], c=next(colors), marker='.', s=50)
    #     # plt.scatter(centroids_red[k][0], centroids_red[k][1], c='k', marker='.', s=200)
    # plt.title("RESULT! Data clustered. Using SPECTRAL CLUSTERING TO VISUALIZE")
    # plt.show()

def plot_results_TSNE(X, y, centroids):
    embedding = TSNE(n_components=2,
                     init='pca',
                     perplexity=500)
    X_red = embedding.fit_transform(X)
    plot_results(X_red, y, title='RESULT! Data clustered. Using tsne TO VISUALIZE')

def plot_results(X, y, title):
    colors = cycle(['r', 'g', 'b', 'k', 'c', 'm', 'y'])
    markers = cycle(['.', '+', 'o', '*', '1', 'p', 's', 'x', 'X'])
    strs = []
    i = 0
    for k in set(y):
        cluster_data = (y == k)
        color = next(colors)
        marker = next(markers)
        plt.scatter(X[cluster_data, 0], X[cluster_data, 1], c=color, marker=marker, s=50)
        # plt.scatter(centroids_red[k][0], centroids_red[k][1], c='k', marker='.', s=200)
        strs.append(str(i))
        i += 1
    plt.legend(strs)
    plt.title(title)
    plt.show()

def precompute_distances(X, labels, output_size_ratio):
    idx = np.random.choice(len(X), int(len(X)*output_size_ratio), replace=False)
    X = X[idx]
    labels = labels[idx]
    # create a square distance matrix
    D = np.zeros((len(X), len(X)))
    for i in range(len(X)):
        for j in range(len(X)):
            a = X[i, :]
            b = X[j, :]
            d = hamming(a, b)
            D[i, j] = d
    return D, labels

def load_data(paths, sampling=None, max_index=None):
    all_descriptors = []
    if paths is None:
        all_descriptors = read_descriptors('../data/descriptors.json')
    else:
        # read several paths
        for path in paths:
            descriptors = read_descriptors(path + '/mav0/descriptors.json')
            all_descriptors.extend(descriptors)
    # next, flatten list in order to obtain a flat list of ORB descriptors
    all_descriptors = flatten_list(all_descriptors)
    if max_index is None:
        max_index = len(all_descriptors)
    if sampling is None:
        sampling = 1
    all_descriptors = all_descriptors[0:max_index:sampling]
    X = np.array(all_descriptors, np.uint8)
    return X

def save_bow_vectors(bow_vector, words, n_words, filename='bagofwords.json'):
    """
    Save the bag of words
    """
    data = {'bow_vector': bow_vector.tolist(),
            'words': words.tolist(),
            'n_words': n_words.tolist()}
    with open(filename, 'w') as outfile:
        json.dump(data, outfile)

if __name__ == '__main__':
    # number of samples to process
    # caution may be in the number of
    # 600000
    n_samples = 5000
    kw = 2
    lw = 9
    # load ORB DESCRIPTORS
    X = load_data(paths=paths, sampling=1, max_index=n_samples)
    # X = load_data(paths=None, sampling=1, max_index=n_samples)
    # transform to binary descriptors (length is 256 bits)
    X = np.unpackbits(X, axis=1)

    kmeans_params = {'tol': 0.001,
                     'max_iter': 300,
                     'distance_function': 'hamming',
                     'centroid_replacement': False,
                     'averaging_function': 'mean-round', # this is majority voting for binary descriptors if unpacked
                     'init_method': 'kmeans++',
                     'plot_progress': True}
    start_time = time.time()
    hk = HKMeans(kw=kw, lw=lw, kmeans_params=kmeans_params)
    hk.print_tree()
    hk.fit(X)
    elapsed_time = time.time() - start_time
    hk.print_tree()
    hk.print_words()
    # hk.plot_tree_data(X)
    print('Clustering took: ', elapsed_time, '(s)')

    print('Finding predictions via brute-force:')
    start_time = time.time()
    new_labels1, _ = hk.predict_brute_force(X)
    elapsed_time = time.time() - start_time
    print('Took: ', elapsed_time, '(s)')
    print('Done predicting brute Force. found: ', len(set(new_labels1)), ' different labels')

    print('Finding predictions via top-down:')
    start_time = time.time()
    new_labels2, _ = hk.predict_top_down(X)
    elapsed_time = time.time() - start_time
    print('Took: ', elapsed_time)
    print('Done predicting top down. found: ', len(set(new_labels2)), ' different labels')

    print("Clustered ", len(X), " n descriptors")
    print('Trained a tree with (kw, lw): ', kw, ', ', lw)
    print('Total number of nodes: ', hk.get_number_of_nodes())
    print('Total number of leaves: ', hk.get_number_of_leaves())
    print('Total number of words expected: ', hk.get_expected_number_of_words())
    print('Total number of words found: ', hk.count_number_of_words())
    print('Total cost of fit (at last hierarchy level): ', hk.get_total_cost())
    print('Number of datapoints per leaf (WORD): ', hk.get_n_datapoints_per_word())
    print('Fit time: ', elapsed_time, '(s)')
    # use 10 percent of the smaples
    # precompute distance matrix using hamming distance
    D, sampled_labels = precompute_distances(X, new_labels2, .1)
    # sil_score = silhouette_score(X, new_labels, sample_size=n_samples)
    # using precomputed distance
    sil_score = silhouette_score(D, sampled_labels, sample_size=n_samples, metric='precomputed')
    print("Silhouette Coefficient of tree classification: ", sil_score)

    # Xred = SparsePCA(n_components=2).fit_transform(X)
    # plot_results_projecting(X, new_labels2, hk.leaf_centroids)
    plot_results_isomap(X, new_labels1, hk.leaf_centroids)
    plot_results_spectral(X, new_labels1, hk.leaf_centroids)
    plot_results_TSNE(X, new_labels1, hk.leaf_centroids)

    print('Creating vocabulary object!')
    # create the vocabulary!!!
    voc = hk.create_vocabulary()
    print('Replacing centroids by true prototypes')
    # optionally, replace each original word by the closest, real, existing descripotr
    # no need to replace centroids if centroid_replacement=True
    # voc.replace_centroids(X)
    print('Saving vocabulary')
    voc.save_json('voc.json')
    print('Computing BOW vectors')
    bow_vector_st, words, n_words = voc.compute_bows(X, option='standard')
    print(bow_vector_st)
    # bow_vector_bin, words, n_words = voc.compute_bows(X, option='binary')
    # bow_vector_tfidf, words, n_words = voc.compute_bows(X, option='tfidf')

    # save bag of word vectors
    save_bow_vectors(bow_vector_st, words, n_words, 'bagofwords.json')


"""
Remove overlapping words such as *read* and *reading*...
R IY D .
R IY D IH NG .
using a trie. Because of how tries are constructed, smaller
overlapping words will become part of larger ones, and ultimately
all words will be found at nodes with an out degree of zero.

===

# Subsets and supersets/affixes
In an orthographic sense, *run* is a subset of *run*ning.
Three kinds of subsets: prefixes, suffixes, and infixes.
We already have a prefix tree
We can make a suffix tree as well (this would be a much more literal copying of the rhyme trie)
The words we then want are the leaves of the tree: in degree of one and an out degree of zero.

~Infixes require a little more elbow grease; we can find them through a function that finds any affix~
Going for infixes at this stage isn't worth it, we should just handle them during the main stage.
"""

# import nltk
# nltk.download('cmudict')

from difflib import SequenceMatcher
from typing import Iterable, List
import networkx as nx
from nltk.corpus import cmudict

def leaves(G: nx.DiGraph) -> List[str]:
	return [tuple(node.split(' ')) for node in G.nodes if G.in_degree(node) == 1 and G.out_degree(node) == 0]

def deduplicate(pronunciations: Iterable[str]) -> List[str]:
	trie = nx.DiGraph()

	for pronunciation in pronunciations:
		stages = [''] + [' '.join(pronunciation[:index]) for index in range(1, len(pronunciation) + 1)]
		for i in range(len(stages) - 1):
			trie.add_edge(stages[i], stages[i + 1], phone=pronunciation[i])

	return leaves(trie)

def is_affix(subset, superset):
	matcher = SequenceMatcher(a=subset, b=superset)
	block = matcher.find_longest_match(0, len(subset), 0, len(superset))
	return block.a == 0 and block.size == len(subset)

pronunciations = [tuple(pronunciation) for _, pronunciation in cmudict.entries()]
# 133737
# print(len(pronunciations))

unique_pronunciations = set(pronunciations)
# 114966 (14% reduction)
# print(len(unique_pronunciations))

deduplicated_pronunciations_by_prefix = deduplicate(unique_pronunciations)
# 87627 (34% reduction)
# print(len(deduplicated_pronunciations_by_prefix))

deduplicated_pronunciations_by_suffix = {
	pronunciaition[::-1]
	for pronunciaition in
	(deduplicate(pronunciation[::-1] for pronunciation in deduplicated_pronunciations_by_prefix))
}
# 81187 (39% reduction)
# print(len(deduplicated_pronunciations_by_suffix))

deduplicated_pronunciations = deduplicated_pronunciations_by_suffix


import tkinter as tk
from tkinter import ttk
from tkinter import simpledialog
from tkinter import messagebox
import configparser
import json
from prometeus_utils import PrometheusConnector
import os

config_path = list(os.listdir(PrometheusConnector().base_stack_config_path))
previous_input_path = f"{PrometheusConnector().base_stack_config_path}/prev_inp.ini"
all_stack_config_paths = [filename for filename in config_path if filename.endswith('.json')]

config = configparser.ConfigParser()
config.read(previous_input_path)

load_type_values = ['ControlPlane', 'SingleCustomer', 'MultiCustomer', 'CombinedLoad' , 'AWS_multicustomer']

prom_con_obj=None
details = {
        "nodes_file_name":[str , 's1_nodes.json'],
        "load_type": [str , "SingleCustomer"],
        "start_time_str": [str , "2023-08-12 23:08"],
        "load_duration_in_hrs": [int , 10],
        "sprint": [str , '138'],
        "build": [str , '138000'],
        "prev_sprint": [str , '137'],
        "start_margin": [int , 10],
        "end_margin": [int , 10],
        "show_gb_cores": [bool , False],
        "add_disk_space_usage":[bool , True],
        "add_screenshots":[bool , True],
        "add_kafka_topics":[bool , True],
        "make_cpu_mem_comparisions":[bool , True],
        "fetch_node_parameters_before_generating_report" : [bool , False]
        }

def create_input_form():
    global prom_con_obj,details

    for key in details:
        default = config["DEFAULT"].get(key, details[key][1])
        if details[key][0]==bool:
            if default=="True":
                default=True
            else:
                default=False
        details[key][1] = default

    def center_window(root, width, height):
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        x = (screen_width - width) // 2
        y = (screen_height - height) // 2
        root.geometry(f"{width}x{height}+{x}+{y}")

    def cancel():
        global prom_con_obj,details
        for key in details:
            details[key]=None
        prom_con_obj = None
        root.quit()

    def save_data(details):
        global prom_con_obj
        prom_con_obj = PrometheusConnector(nodes_file_name=details['nodes_file_name'] , fetch_node_parameters_before_generating_report=details['fetch_node_parameters_before_generating_report'])
        config["DEFAULT"] = details
        with open(previous_input_path, "w") as configfile:
            config.write(configfile)
        return prom_con_obj
    def submit():
        global prom_con_obj,details
        for (key,val) in details.items():
            Type , default , var = val
            details[key] = Type(var.get())
        stack = details['nodes_file_name'].split('_')[0]
        confirm = messagebox.askokcancel("Confirmation", f"Are you sure that the details mentioned are correct for generating a report for stack {str(stack).upper()} ?")
        if confirm:
            prom_con_obj = save_data(details)
            root.quit()
    try:
        1/0
        root = tk.Tk()
        root.title("Enter the load details for report generation")
        center_window(root, 520, 550)  # Center the window and set dimensions

        for id , (key,val) in enumerate(details.items()):
            Type , default = val
            label = ttk.Label(root, text=(' '.join(key.split('_'))).title() )
            label.grid(row=id, column=0)

            if Type == bool:
                var = tk.BooleanVar()  #bool
                entry = ttk.Checkbutton(root, variable=var)

            else:
                var = tk.StringVar()  #string
                if key == "load_type":
                    entry = ttk.Combobox(root, textvariable=var, values=load_type_values)
                elif key == "nodes_file_name":
                    entry = ttk.Combobox(root, textvariable=var, values=all_stack_config_paths, state="readonly")
                else:
                    entry = ttk.Entry(root, textvariable=var)

            var.set(config["DEFAULT"].get(key, default))
            entry.grid(row=id, column=1)
            details[key].append(var)

        # Function to update Previous Sprint based on Sprint
        def update_prev_sprint(*args):
            sprint_value = details['sprint'][2].get()
            try:
                prev_sprint_value = int(sprint_value) - 1
            except ValueError:
                prev_sprint_value = ""
            details['prev_sprint'][2].set(str(prev_sprint_value))
        details['sprint'][2].trace("w", update_prev_sprint)

        #submit button
        submit_button = ttk.Button(root, text="Generate", command=submit)
        submit_button.grid(row=15, column=1)

        # Cancel Button
        cancel_button = ttk.Button(root, text="Cancel", command=cancel)
        cancel_button.grid(row=15, column=0)

        root.mainloop()
        root.quit()

        return details,prom_con_obj

    except Exception as e:
        print(str(e))
        print("Looks like tkinter canvas is having an issue, do you want to continue with these previous details?")

        for key,val in details.items():
            print(f"{key} : {val[1]}")

        user_input = input("Enter 'yes' to continue, select 'no' to enter new details ... ").strip().lower()

        if user_input in ['yes' , 'no']:
            if user_input == "yes":
                print("Continuing ...")
                for key ,val in details.items():
                    details[key] = val[1]

            elif user_input == "no":
                print("Please enter your details manually to proceed...(use above details as reference)")
                for key,val in details.items():
                    Type ,_ = val
                    inp = input(f"Enter {key} :").strip()
                    if Type == bool:
                        if inp.strip() == "True":
                            inp = True
                        else:
                            inp=False
                    details[key] = Type(inp)

            prom_con_obj = save_data(details)
            return details,prom_con_obj

        else:
            print("Invalid input. Please enter either 'yes' or 'no'.")
            return None

if __name__ == "__main__":
    details = create_input_form()
    print(details)  # Print the details to verify that they are read from the configuration


from ..dba import *
from chinese_calendar import *
import os
import numpy as np
import logging
from catboost import CatBoostRegressor
from sklearn.model_selection import KFold

os.environ['NUMEXPR_MAX_THREADS'] = '16'
# 定义logger日志输出
logger = logging.getLogger(__name__)

class FactoryPredict:
    def __init__(self):
        self.predict_days = 3
        self.history_days = 35
        self.dir_path = "data/生产安排"
        self.date_col = 'DS'
        self.group_col = ['FACTORY_ID', "PRODUCT_ID"]
        self.target_col = "Y"
        self.summary_col = self.group_col + [self.date_col]
        self.plu = 'SELECT PRODUCT_ID FROM PLUVIEW WHERE PRODUCT_CATEGORY_NAME = \'散装食品\''
        self.org = "SELECT FACTORY_ID, ORGCODE STORE_ID FROM TZYORG_YH_PS_MODE"
        self.sql_holiday = """
        SELECT RPTDATE DS, FESTIVALS_NL, FESTIVALS_GL
        FROM ZCB_DAY_INFO
        ORDER BY RPTDATE
        """
        self.unit = """
        SELECT PRODUCT_STORE_ID FACTORY_ID, PRODUCT_ID, PACK_WEGIHT YH_UNIT
        FROM FACTORY_PRODUCT_ENABLE
        """

    def update_data(self, full=True):
        if full:
            date_range = pd.date_range(
                start='2019-01-01', end=datetime.datetime.now())
        else:
            from datetime import date, timedelta
            today = date.today()
            d = date(today.year, today.month, 1) - timedelta(1)
            date_range = pd.date_range(start=date(
                d.year, d.month, 1), end=datetime.datetime.now())
        df_date = pd.DataFrame(date_range, columns=["DS"])
        df_date["YEAR"] = df_date["DS"].dt.year
        df_date["MONTH"] = df_date["DS"].dt.month
        try:
            os.makedirs("data/生产安排")
        except FileExistsError:
            logger.info(f"Path exists: {self.dir_path} ")
        for (year, month), g_data in df_date.groupby(["YEAR", "MONTH"], as_index=False):
            start_date, end_date = g_data["DS"].min(), g_data["DS"].max()
            sql_ps = f"""
            SELECT ORGCODE STORE_ID,
                    PLUCODE PRODUCT_ID,
                    RPTDATE DS,
                    PLUCOUNT Y
            FROM TZYPLUPRO_PS
            WHERE RPTDATE >= TO_DATE('{start_date}','yyyy-mm-dd hh24:mi:ss') AND RPTDATE <= TO_DATE('{end_date}','yyyy-mm-dd hh24:mi:ss')
            """
            df_ps = oracle97.read(sql_ps)
            df_ps.to_feather(os.path.join(
                self.dir_path, "%04d%02d.feather" % (year, month)))

    def get_data(self):
        df_plu = oracle97.read(self.plu)
        df_org = oracle97.read(self.org)
        df_input = []
        if len(os.listdir(self.dir_path)) < 7:
            self.update_data(full=True)
        for file in os.listdir(self.dir_path):
            df_part = pd.read_feather(os.path.join(self.dir_path, file))
            df_part = df_part.merge(df_org, how="left", left_on=[
                                    "STORE_ID"], right_on=["STORE_ID"])
            df_part = df_part[df_part["PRODUCT_ID"].isin(df_plu["PRODUCT_ID"])]
            df_part = df_part.groupby(self.summary_col, as_index=False).sum()
            df_input.append(df_part)
        df_input = pd.concat(df_input, ignore_index=True, sort=False)
        df_input = df_input[df_input.groupby(
            ["FACTORY_ID", "PRODUCT_ID"]).Y.transform("mean") > 100]
        df_input = df_input[df_input.groupby(
            ["FACTORY_ID", "PRODUCT_ID"]).Y.transform("std") > 1]
        df_input = df_input.sort_values(
            by=self.summary_col).reset_index(drop=True)
        df_group = df_input.groupby(self.group_col, sort=False)
        df_input['Q10'] = df_group[self.target_col].rolling(
            self.history_days, min_periods=21).quantile(0.1).values
        df_input['Q90'] = df_group[self.target_col].rolling(
            self.history_days, min_periods=21).quantile(0.9).values
        df_input['TRUE'] = df_group[self.target_col].shift(
            -self.predict_days).values
        df_input['TRUE_STD'] = (
            df_input['TRUE'] - df_input['Q10']) / (df_input['Q90'] - df_input['Q10'])
        df_input[self.date_col] = df_input[self.date_col] + \
            datetime.timedelta(days=self.predict_days)
        return df_input

    def get_holiday(self, df_input):
        df_holiday = Oracle().read(self.sql_holiday)
        for var in ['FESTIVALS_NL', 'FESTIVALS_GL']:
            for day_num in range(-1, 2):
                if day_num > 0:
                    df_holiday["%s(t-%02d)" % (var, day_num)
                               ] = df_holiday[var].shift(day_num)
                if day_num < 0:
                    df_holiday["%s(t+%02d)" % (var, np.abs(day_num))
                               ] = df_holiday[var].shift(day_num)
        df_holiday["HOLIDAY"] = df_holiday['DS'].apply(
            is_holiday).replace([True, False], ["1", "0"])
        df_holiday["HOLIDAY_T1"] = df_holiday["HOLIDAY"].shift(-1).fillna("0")
        df_holiday["HOLIDAY_T-1"] = df_holiday["HOLIDAY"].shift(1).fillna("0")
        df_holiday["WEEK_ADJ"] = df_holiday['DS'].dt.month.astype(
            str) + df_holiday["HOLIDAY_T-1"] + df_holiday["HOLIDAY"] + df_holiday["HOLIDAY_T1"]
        df_holiday = df_holiday.drop(
            ['HOLIDAY', 'HOLIDAY_T1', 'HOLIDAY_T-1'], axis=1)

        df_input = df_input.merge(
            df_holiday, how="left", left_on=self.date_col, right_on=self.date_col)
        df_input["HOLIDAY_AFFECT"] = np.nan
        for var in df_holiday.columns[1:]:
            df_input[var] = df_input.groupby(
                self.group_col + [var], sort=False)["TRUE_STD"].transform('mean').values
            df_input[var] = df_input[var].fillna(
                df_input.groupby(self.date_col)[var].transform('mean'))
            df_input["HOLIDAY_AFFECT"] = np.where(df_input["HOLIDAY_AFFECT"].isnull(),
                                                  df_input[var].values,
                                                  df_input["HOLIDAY_AFFECT"].values)
        df_input = df_input.sort_values(
            by=self.group_col + ["WEEK_ADJ", "DS"]).reset_index(drop=True)
        for day in [1, 2, 3, 4]:
            df_input["T%02d" % day] = df_input.groupby(
                self.group_col + ["WEEK_ADJ"])["TRUE_STD"].shift(day)
        df_input = df_input.sort_values(
            by=self.summary_col).reset_index(drop=True)
        return df_input

    def predict(self, df_input):
        feature = [x for x in df_input.columns if
                   x not in self.summary_col + ['Q10', 'Q90', 'TRUE', 'TRUE_STD', 'Y']]
        df_input = df_input.replace([np.inf, np.nan])
        x = df_input.dropna(subset=["TRUE_STD"])[feature].values
        y = df_input.dropna(subset=["TRUE_STD"])['TRUE_STD'].values
        y_predict = np.zeros(len(df_input)).flatten()
        kf = KFold(5, shuffle=True, random_state=1)
        for k, (train_index, test_index) in enumerate(kf.split(x, y)):
            x_train, x_test = x[train_index], x[test_index]
            y_train, y_test = y[train_index], y[test_index]
            model = CatBoostRegressor(iterations=500,
                                      task_type="GPU",
                                      loss_function='MAE',
                                      min_data_in_leaf=10,
                                      use_best_model=True)
            model.fit(
                x_train, y_train,
                eval_set=(x, y),
                early_stopping_rounds=500,
                verbose=0
            )
            y_predict = model.predict(
                df_input[feature]).flatten() / 5 + y_predict
        # 做强输出控制
        df_input["PREDICT"] = y_predict * \
            (df_input["Q90"] - df_input["Q10"]) + df_input["Q10"]
        df_input["PREDICT"] = np.maximum(df_input["PREDICT"], 0)
        df_input["TRUE"] = df_input["TRUE_STD"] * \
            (df_input["Q90"] - df_input["Q10"]) + df_input["Q10"]
        return df_input

    def run(self):
        self.update_data(full=False)
        df_input = self.get_data()
        df_input = self.get_holiday(df_input)
        df_input = self.predict(df_input)
        df_input = df_input[["FACTORY_ID", "PRODUCT_ID",
                             "DS", "TRUE", "PREDICT", "HOLIDAY_AFFECT"]]
        df_unit = oracle97.read(self.unit)
        df_yh = df_input.merge(df_unit, how="inner",
                               left_on=self.group_col, right_on=self.group_col)
        df_yh.columns = ["FACTORY_ID", "PLUCODE", "RPTDATE",
                         "TRUE", "PREDICT", "HOLIDAY_AFFECT", "YH_UNIT"]
        df_yh = df_yh[df_yh['RPTDATE'] >
                      df_yh['RPTDATE'].max() - datetime.timedelta(days=94)]
        df_yh["SUPPORT"] = df_yh['RPTDATE'] - pd.to_datetime("1899-12-30")
        df_yh["SUPPORT"] = df_yh["SUPPORT"].dt.days
        df_yh["SUPPORT"] = df_yh["SUPPORT"].astype(str)
        df_yh["SUPPORT"] = df_yh["SUPPORT"] + df_yh["PLUCODE"].astype(str)
        df_yh['PREDICT'] = np.ceil(df_yh['PREDICT'] / df_yh['YH_UNIT'])
        df_yh['TRUE'] = np.ceil(df_yh['TRUE'] / df_yh['YH_UNIT'])
        df_yh["ERROR"] = df_yh["PREDICT"].fillna(0) - df_yh['TRUE'].fillna(0)
        df_yh["ERROR"] = np.where(df_yh['TRUE'] > 10, df_yh["ERROR"], np.nan)
        df_yh["ABS_ERROR"] = np.abs(df_yh["ERROR"])
        df_yh["ERROR_PERCENTAGE"] = df_yh["ERROR"].values / np.where(df_yh['TRUE'].values == 0,
                                                                     df_yh['TRUE'].values + 1,
                                                                     df_yh['TRUE'].values)
        df_yh["ABS_ERROR_PERCENTAGE"] = np.abs(df_yh["ERROR_PERCENTAGE"])
        df_yh["SAFE_STOCK"] = np.abs(
            df_yh.groupby(['FACTORY_ID', 'PLUCODE', 'HOLIDAY_AFFECT'])["ERROR_PERCENTAGE"].transform('mean').fillna(
                0.05))
        df_yh["SAFE_STOCK"] = np.where(
            df_yh["SAFE_STOCK"] > 0.2, 0.2, df_yh["SAFE_STOCK"])
        df_yh["SAFE_STOCK"] = np.where(
            df_yh["SAFE_STOCK"] < 0.05, 0.05, df_yh["SAFE_STOCK"])
        df_yh["SAFE_STOCK"] = df_yh["PREDICT"] / df_yh["YH_UNIT"] * df_yh["HOLIDAY_AFFECT"] * df_yh[
            "SAFE_STOCK"]  # * df_yh['YH_STORE_NUM']
        df_yh["SAFE_STOCK"] = df_yh["SAFE_STOCK"].apply(lambda x: max(x, 1))
        df_yh["SAFE_STOCK"] = 0
        df_yh["ERROR1"] = df_yh["PREDICT"].fillna(
            0) + df_yh["SAFE_STOCK"] - df_yh['TRUE'].fillna(0)
        df_yh["ERROR1"] = np.where(df_yh['TRUE'] > 1, df_yh["ERROR1"], np.nan)
        df_yh["ABS_ERROR1"] = np.abs(df_yh["ERROR1"])
        df_yh["综合波动"] = df_yh["ERROR1"].values / np.where(df_yh['TRUE'].values == 0,
                                                          df_yh['TRUE'].values + 1,
                                                          df_yh['TRUE'].values)
        df_yh = df_yh.replace([np.inf, -np.inf], [0, 0])
        df_yh['EXEDATE'] = pd.to_datetime(
            datetime.datetime.today().strftime('%Y-%m-%d'))
        df_yh = df_yh[df_yh['RPTDATE'] >
                      df_yh['RPTDATE'].max() - datetime.timedelta(days=34)]
        df_label = []
        for g_name, g_data in df_yh[(df_yh["TRUE"] > 1)].groupby(["FACTORY_ID", "PLUCODE"]):
            error_percentage = g_data["综合波动"].values
            error_percentage = np.sort(error_percentage)
            error_percentage = error_percentage[3:-3]
            count_small = np.sum(error_percentage < -0.05) / len(g_data)
            count_large = np.sum(error_percentage > 0.13) / len(g_data)
            error_sum = (np.sum(g_data["PREDICT"] + g_data["SAFE_STOCK"]) - np.sum(g_data["TRUE"])) / np.where(
                np.sum(g_data["TRUE"]) > 0, np.sum(g_data["TRUE"]), 1)
            if (count_small < 0.15) & (count_large < 0.15) & (error_sum > 0) & (error_sum < 0.1):
                label = "A"
            elif (count_small < 0.3) & (count_large < 0.3) & (error_sum > 0.1) & (error_sum < 0.2):
                label = "B"
            else:
                label = "C"
            df_label.append([g_name[0], g_name[1], label])
        df_label = pd.DataFrame(
            df_label, columns=["FACTORY_ID", "PLUCODE", "LABEL"])
        df_yh = df_yh.merge(df_label, how="left", left_on=[
                            "FACTORY_ID", "PLUCODE"], right_on=["FACTORY_ID", "PLUCODE"])
        df_yh['LABEL'] = df_yh['LABEL'].fillna("空")
        df_yh = df_yh[["FACTORY_ID", "PLUCODE", "RPTDATE", "SUPPORT", "TRUE", "PREDICT", "HOLIDAY_AFFECT", "SAFE_STOCK",
                       "EXEDATE", "ERROR", "ABS_ERROR", "ERROR_PERCENTAGE", "ABS_ERROR_PERCENTAGE", "LABEL", "综合波动",
                       "YH_UNIT"]]
        df_factory_yh = df_yh.drop("综合波动", axis=1)
        Oracle().write_dataframe(key_col=["FACTORY_ID", "PLUCODE", "RPTDATE"],
                                 table_name="ZCB_PREDICT_FACTORY_YH",
                                 df=df_factory_yh,
                                 add_ts=False)
        return df_yh


"""
Assignment 1
Rigre Garciandia

Assumptions:
    - I decided to rename the class Person detailed in the instructions to Employee for naming consistency
    - To avoid a conflict with built-in name 'id', I renamed the field in the instructions to 'emp_id'
    - If input file contains duplicate IDs, I will not ask the user to correct it, just print an error message
"""
import sys
import pathlib
import re
import pickle

class Employee:
    def __init__(self, last, first, mi, emp_id, phone):
        self.last = last
        self.first = first
        self.mi = mi
        self.emp_id = emp_id
        self.phone = phone

    def display(self):
        print("Employee id:", self.emp_id)
        print("\t", self.first, self.mi, self.last)
        print("\t", self.phone, "\n")

def gen_employees(text_in_list):
    """
    Generates Employee objects based on the input strings. Asks user for manual corrections if needed
    :param text_in_list: list of input entries
    :return: a dictionary of Employee objects generated from the input strings
    """
    if not text_in_list:
        raise Exception("input must not be empty")
    if not type(text_in_list) == list:
        raise TypeError("text_in must be a list")

    result = {}

    for line_in in text_in_list:
        # split on comma to get fields as text variables
        last, first, mi, emp_id, phone = line_in.split(",")

        # modify last name and first name fo be in Capital Case
        last = last.title()
        first = first.title()

        # modify the MI to be a single upper case letter, use 'X' as MI if one is missing
        if mi:
            mi = mi.upper()
        else:
            mi = 'X'

        # modify emp_id if necessary
        m = re.match(r'^[a-zA-Z]{2}\d{4}$', emp_id)
        while not m:
            print("ID invalid:", emp_id, "\nID is two letters followed by 4 digits")
            emp_id = input("Please enter a valid ID: ")
            m = re.match(r'^[a-zA-Z]{2}\d{4}$', emp_id)

        # modify phone number if necessary
        is_phone_in_dash_format = False
        while not is_phone_in_dash_format:
            dot_format_match = re.match(r'^[0-9]{3}\.[0-9]{3}\.[0-9]{4}$', phone)  # xxx.xxx.xxxx
            space_format_match = re.match(r'^[0-9]{3}\s[0-9]{3}\s[0-9]{4}$', phone)  # xxx xxx xxxxx
            all_together_format_match = re.match(r'^[0-9]{10}$', phone)  # xxxxxxxxxx
            dash_format_match = re.match(r'^[0-9]{3}-[0-9]{3}-[0-9]{4}$', phone)  # xxx-xxx-xxxx

            if dash_format_match:
                is_phone_in_dash_format = True
            elif dot_format_match:
                phone = re.sub(r'\.', '-', phone)
            elif space_format_match:
                phone = re.sub(r'\s', '-', phone)
            elif all_together_format_match:
                phone = phone[:3] + '-' + phone[3:6] + '-' + phone[6:]
            else:
                print("Phone", phone, "is invalid")
                print("Enter phone number in form 123-456-7890")
                phone = input("Enter phone number:")

        if emp_id not in result:
            result[emp_id] = Employee(last, first, mi, emp_id, phone)
        else:
            print("Error: ID", emp_id, "is repeated in the input file")

    return result

if __name__ == '__main__':
    # Check if the relative path was entered
    if len(sys.argv) < 2:
        print("Please enter the relative path of the data file as a system arg")
        quit()

    # Retrieve the input data in text format
    rel_path = sys.argv[1]
    with open(pathlib.Path.cwd().joinpath(rel_path), 'r') as f:
        text_in = f.read().splitlines()

    # Generate Employee objects from input data
    employees = gen_employees(text_in[1:])  # ignoring header lines

    # Pickle the employees
    pickle.dump(employees, open('employees.pickle', 'wb'))

    # read the pickle back in
    employees_in = pickle.load(open('employees.pickle', 'rb'))

    # output employees
    print("\n\nEmployee list:\n")
    for obj_id in employees_in.keys():
        employees_in[obj_id].display()


from time import time

def cmpCountIteration():
    with open('bi_aiops_mul.log', 'r') as f:
        temp1 = f.read()
        t1 = time()
        temp1.count('/api/bi/user/user_info/')
        t2 = time()
    with open('bi_aiops_mul.log', 'r') as f:
        temp2 = f.readlines()
        t3 = time()
        count = 0
        for i in temp2:
            if '/api/bi/user/user_info/' in i:
                count += 1
        t4 = time()
    print('count: %f\niteration: %f' % (t2 - t1, t4 - t3))

if __name__ == '__main__':
    cmpCountIteration()


from django.urls import path
from . import views
from watchlist import views as wlv
from exam import views as EView
from register import views as RView
from django.contrib.auth import views as auth_views

urlpatterns = [
    path("", views.home, name="home"),
    path("home/", views.home, name="home"),
    path("BuyAndSell/", views.BuyAndSell, name="BuyAndSell"),
    path('accounts/login/', auth_views.LoginView.as_view(), name='login'),
    path("log-out/", views.logout, name="log-out"),
    path("cryptoList/", views.cryptoList, name="CryptoList"),
    path("tickets/", views.tickets, name="tickets"),
    path("personal_info/", views.ViewPersonalInformation.as_view(), name="personal_info"),
    path("register/", RView.register, name="register"),
    path('FillPersonalInfo/<int:user_id>/', RView.personal_info, name='personal_info'),
    path("watchlist/", wlv.watchList, name="watchlist"),
    path("deleteItem/<int:item_id>/", wlv.deleteItem,name="deleteItem"),
    path("previousTrades", views.previousTrades, name="previousTrades"),
    path("exam/", EView.take_quiz, name="exam"),
    path ('exam/results/', EView.result, name='results'),
    path("create-ticket", views.create_ticket, name='create-ticket'),
    path('deposit_withdraw/', views.show_deposit_withdraw_form, name='deposit_withdraw'),
    path('deposit/', views.deposit, name='deposit'),
    path('withdraw/', views.withdraw, name='withdraw'),
]


import os
from time import sleep

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.IN)

justEmpty = True
state = True

def speakState():
	input = "Adding." if state else "Removing."
	os.system('espeak -v en -k5 -s150 "' + input + '"')

while True:
	if not GPIO.input(4):
		if justEmpty:
			justEmpty = False
			state = not state
			speakState()
	else:
		justEmpty = True
	sleep(0.05)


from distutils.core import setup

reqs = [
    "astropy",
    "numpy",
    "scipy",
    "matplotlib",
    "psutil",
    "tqdm",
]

setup(
    name="fits_warp",
    version="2.0",
    author="Natasha Hurley-Walker and Paul Hancock",
    description="Warp catalogues and images to remove the distorting affect of the ionosphere.",
    url="https://github.com/nhurleywalker/fits_warp",
    long_description=open("README.md").read(),
    packages=["fits_warp",],
    license="Academic Free License v3.0",
    requires=reqs,
    scripts=["fits_warp/fits_warp.py"],
)


#User function Template for python3

class Solution:
    def maxSumPairWithDifferenceLessThanK(self, arr, N, K):
        arr.sort(reverse = True)

        pairs = []
        sum = 0

        i = 0
        while(i<N-1):
            diff = abs(arr[i]-arr[i+1])
            if diff<K:
                sum += arr[i]+arr[i+1]
                i+=2
            else:
                i+=1
        return sum

#{
#  Driver Code Starts
#Initial Template for Python 3

def main():

    T = int(input())

    while(T > 0):
        N = int(input())
        arr = [int(x) for x in input().strip().split()]
        K = int(input())
        ob=Solution()
        print( ob.maxSumPairWithDifferenceLessThanK(arr, N, K) )

        T -= 1

if __name__ == "__main__":
    main()

# } Driver Code Ends

Pairs with specific difference - GFG/pairs-with-specific-difference.py