#trama corta
    #tiempo h latitud / longitud O curso / velocidad A altitud B alturaBar C tempbar D tempeSHT11 E voltajebater
#trama larga IMU
    #tiempo h latitud / longitud O curso / velocidad A altitud B alturaBar C tempbar D tempeSHT11 E voltajebater
    #f ACCx G ACCy H ACCz I GIx J GIy K GIz L Mx M My N Mz
#trama larga gases
    #tiempo h latitud / longitud O curso / velocidad A altitud B alturaBar C tempbar D tempeSHT11 E voltajebater
    #F humedadDHT11 G NH3 H CO I NO2 J C3H8 K C4H10 L Ch4 M H2 N C2H50H O tempI2C P tempADC Q presionbar

import sys
import math
import serial
import time
import subprocess
import random
import requests
import string

global MatrizD, vectorTramas, cuentatrama, cuentadesconocida

#La variable nombreArchivoTramasLeer contiene las tramas que el programa gqrx guardo al decodificar el AFSK
#La variable nombreVectorTrayectoriaGuardar es donde se guardan los vectores de trayectoria calculados por el modelo
#La variable nombreArchivoSETLeerEscribir contiene las coordenadas iniciales de la estacion y de la gondola para setear el cero relativo

nombreArchivoTramasLeer = "prueba_datos.txt"
nombreVectorTrayectoriaGuardar = "vectorpruebaSimple3.txt"
nombreArchivoSETLeerEscribir = "SET.txt"

MatrizD = []
vectorAlturaBar = []
vectorAlturaGps = []
vectorAlturaBar_ext = []
vectorAlturaGps_ext = []
sumaAlturaBar = 0
sumaAlturaGps = 0
sumaVarianzaAlturaBar = 0
sumaVarianzaAlturaGps = 0
vectorTramas = ['/0/0/0']
cuentatrama = 0
cuentadesconocida = 0
cuentaFusion = 0
arduino = serial.Serial('/dev/ttyUSB0',9600)
time.sleep(2)

def leerTrama():
    try:
        cuentaParticion = 0
        archivo = open(nombreArchivoTramasLeer,"r")
        tramaNue = archivo.readlines()
        archivo.close()
        ultimalinea = len(tramaNue)-1
        returnedValues = str(tramaNue[ultimalinea]) #Retornar solo la ultima linea del archivo
        vectorTramas.append(returnedValues)
        if len(returnedValues) < 20: # Si la longitud de la trama es exageradamente corta reportar
            return 1
        if (vectorTramas[len(vectorTramas)-1] != vectorTramas[len(vectorTramas)-2]): #Si y solo si las tramas son diferentes retorna la trama
            return returnedValues
        else:
            return 0
    except Exception as e:
        print("****ERROR LEYENDO TRAMA*****")
        print(e)

def procesarTrama(lineas,set):
    global tiempo,latitud_geo,longitud_geo,altitudGps,curso,velocidad,alturaBar,tempeSHT11,voltajebater,tempeBar,presionbar,humedadDHT11
    try:
        returnedValues = lineas
        valores = returnedValues.split("/")
        if (len(valores) == 4):
            print(returnedValues)
            tramaIMU = False
            tramaGases = False
            for i in range(len(valores[3])):
                i = i + 1
                bit = valores[3][i-1]
                if bit == "f": #Si en la trama hay una f minuscula sera una trama IMU
                    tramaIMU = True
                if bit == "F":
                    tramaGases = True
            if tramaIMU == True:
                #trama larga IMU
                #tiempo h latitud / longitud O curso / velocidad A altitud B alturaBar C tempbar D tempeSHT11 E voltajebater
                #f ACCx G ACCy H ACCz I GIx J GIy K GIz L Mx M My N Mz
                print("trama IMU")
                for i in range(len(valores[3])):
                    i = i + 1
                    bit = valores[3][i-1]
                    if bit == "B": #Si se cumple se garantiza existencia de trama hasta "B"
                        tiempo = valores[1][0:6].strip()
                        latitud = valores[1][7:15].strip()
                        longitud = valores[2][0:9].strip()
                        curso = valores[2][10:].strip()
                        velocidad = valores[3].split("A")[0].strip()
                        altitudGps = valores[3].split("A")[1].split("B")[0].strip()
                        datosTransfor = transformarTrama(latitud,longitud) #Convierte las coordenadas a decimales
                        latitud_geo = datosTransfor[0]
                        longitud_geo = datosTransfor[1]
                    if bit == "C": #Si se cumple se garantiza existencia de trama hasta "C"
                        alturaBar = valores[3].split("B")[1].split("C")[0].strip()
                        vectorAlturaBar_ext.append(alturaBar)
                        vectorAlturaGps_ext.append(altitudGps)
                        print("tiempo: " + str(float(tiempo)))
                        print("latitud_geo: " + str(float(latitud_geo)))
                        print("longitud_geo: " + str(float(longitud_geo)))
                        print("altitud_Gps: " + str(float(altitudGps)))
                        print("altura_Bar: " + str(float(alturaBar)))
                        if len(vectorAlturaBar_ext) > 1:
                            tamaño = len(vectorAlturaBar_ext)
                            deltaAlturaBar = float(vectorAlturaBar_ext[tamaño-1])-float(vectorAlturaBar_ext[tamaño-2])
                            alturaBarBias = float(vectorAlturaGps_ext[tamaño-2]) + deltaAlturaBar
                            altitudFus= fusionar(altitudGps,alturaBarBias) #Fusiona la altura del GPS y Barometro en una sola medida mas precisa
                            print("altura_FUS: " + str(float(altitudFus)))
                        datoToSetOK = True
                        print("curso: " + str(float(curso)))
                        print("velocidad: " + str(float(velocidad)))
                    if bit == "D": #Si se cumple se garantiza existencia de trama hasta "D"
                        tempeBar =  valores[3].split("C")[1].split("D")[0].strip()
                        #print("temperaturaBar: " +  str(float(tempeBar)/100))
                    if bit == "E": #Si se cumple se garantiza existencia de trama hasta "E"
                        tempeSHT11 =  valores[3].split("D")[1].split("E")[0].strip()
                        #print("temperaturaSHT11: " +  str(float(tempeSHT11)/100))
                    if bit == "f": #Si se cumple se garantiza existencia de trama hasta "f"
                        voltajebater =  valores[3].split("E")[1].split("f")[0].strip()
                        #print("voltajebater: " + str(float(voltajebater)/1000))
                    if bit == "G": #Si se cumple se garantiza existencia de trama hasta "G"
                        ACCX =  valores[3].split("f")[1].split("G")[0].strip()
                        #print("ACCX: " + str(float(ACCX)*9.8/100))
                    if bit == "H": #Si se cumple se garantiza existencia de trama hasta "H"
                        ACCY =  valores[3].split("G")[1].split("H")[0].strip()
                        #print("ACCY: " + str(float(ACCY)*9.8/100))
                    if bit == "I": #Si se cumple se garantiza existencia de trama hasta "I"
                        ACCZ =  valores[3].split("H")[1].split("I")[0].strip()
                        #print("ACCZ: " + str(float(ACCZ)*9.8/100))
                    if bit == "J": #Si se cumple se garantiza existencia de trama hasta "J"
                        GIX =  valores[3].split("I")[1].split("J")[0].strip()
                        #print("GIX: " + GIX)
                    if bit == "K": #Si se cumple se garantiza existencia de trama hasta "K"
                        GIY =  valores[3].split("J")[1].split("K")[0].strip()
                        #print("GIY: " + GIY)
                    if bit == "L": #Si se cumple se garantiza existencia de trama hasta "L"
                        GIZ =  valores[3].split("K")[1].split("L")[0].strip()
                        #print("GIZ: " + GIZ)
                    if bit == "M": #Si se cumple se garantiza existencia de trama hasta "M"
                        MX =  valores[3].split("L")[1].split("M")[0].strip()
                        #print("MX: " + MX)
                    if bit == "N": #Si se cumple se garantiza existencia de trama hasta "N"
                        MY =  valores[3].split("M")[1].split("N")[0].strip()
                        MZ =  valores[3].split("N")[1].strip()
                        #print("MY: " + MY)
                        #print("MZ: " + MZ)
                        print("trama larga IMU completa")
            elif tramaGases == True:
                #trama larga gases
                #tiempo h latitud / longitud O curso / velocidad A altitud B alturaBar C tempbar D tempeSHT11 E voltajebater
                #F humedadDHT11 G NH3 H CO I NO2 J C3H8 K C4H10 L Ch4 M H2 N C2H50H O tempI2C P tempADC Q presionbar
                print("trama Gases")
                for i in range(len(valores[3])):
                    i = i + 1
                    bit = valores[3][i-1]
                    if bit == "B": #Si se cumple se garantiza existencia de trama hasta "B"
                        tiempo = valores[1][0:6].strip()
                        latitud = valores[1][7:15].strip()
                        longitud = valores[2][0:9].strip()
                        curso = valores[2][10:].strip()
                        velocidad = valores[3].split("A")[0].strip()
                        altitudGps = valores[3].split("A")[1].split("B")[0].strip()
                        datosTransfor = transformarTrama(latitud,longitud) #Convierte las coordenadas a decimales
                        latitud_geo = datosTransfor[0]
                        longitud_geo = datosTransfor[1]
                    if bit == "C": #Si se cumple se garantiza existencia de trama hasta "C"
                        alturaBar = valores[3].split("B")[1].split("C")[0].strip()
                        vectorAlturaBar_ext.append(alturaBar)
                        vectorAlturaGps_ext.append(altitudGps)
                        print("tiempo: " + str(float(tiempo)))
                        print("latitud_geo: " + str(float(latitud_geo)))
                        print("longitud_geo: " + str(float(longitud_geo)))
                        print("altitud_Gps: " + str(float(altitudGps)))
                        print("altura_Bar: " + str(float(alturaBar)))
                        if len(vectorAlturaBar_ext) > 1:
                            tamaño = len(vectorAlturaBar_ext)
                            deltaAlturaBar = float(vectorAlturaBar_ext[tamaño-1])-float(vectorAlturaBar_ext[tamaño-2])
                            alturaBarBias = float(vectorAlturaGps_ext[tamaño-2]) + deltaAlturaBar
                            altitudFus= fusionar(altitudGps,alturaBarBias) #Fusiona la altura del GPS y Barometro en una sola medida mas precisa
                            print("altura_FUS: " + str(float(altitudFus)))
                        datoToSetOK = True
                        print("curso: " + str(float(curso)))
                        print("velocidad: " + str(float(velocidad)))
                    if bit == "D": #Si se cumple se garantiza existencia de trama hasta "D"
                        tempeBar =  valores[3].split("C")[1].split("D")[0].strip()
                        #print("temperaturaBar: " +  str(float(tempeBar)/100))
                    if bit == "E": #Si se cumple se garantiza existencia de trama hasta "E"
                        tempeSHT11 =  valores[3].split("D")[1].split("E")[0].strip()
                        #print("temperaturaSHT11: " +  str(float(tempeSHT11)/100))
                    if bit == "F": #Si se cumple se garantiza existencia de trama hasta "F"
                        voltajebater =  valores[3].split("E")[1].split("F")[0].strip()
                        #print("voltajebater: " + str(float(voltajebater)/1000))
                    if bit == "G": #Si se cumple se garantiza existencia de trama hasta "G"
                        humedadDHT11 =  valores[3].split("F")[1].split("G")[0].strip()
                        #print("humedadDHT11: " + str(humedadDHT11))
                    if bit == "H": #Si se cumple se garantiza existencia de trama hasta "H"
                        NH3 =  valores[3].split("G")[1].split("H")[0].strip()
                        #print("NH3: " + NH3)
                    if bit == "I": #Si se cumple se garantiza existencia de trama hasta "I"
                        CO =  valores[3].split("H")[1].split("I")[0].strip()
                        #print("CO: " + CO)
                    if bit == "J": #Si se cumple se garantiza existencia de trama hasta "J"
                        NO2 =  valores[3].split("I")[1].split("J")[0].strip()
                        #print("NO2: " + NO2)
                    if bit == "K": #Si se cumple se garantiza existencia de trama hasta "K"
                        C3H8 = valores[3].split("J")[1].split("K")[0].strip()
                        #print("C3H8: " + C3H8)
                    if bit == "L": #Si se cumple se garantiza existencia de trama hasta "L"
                        C4H10 = valores[3].split("K")[1].split("L")[0].strip()
                        #print("C4H10: " + C4H10)
                    if bit == "M": #Si se cumple se garantiza existencia de trama hasta "M"
                        CH4 = valores[3].split("L")[1].split("M")[0].strip()
                        #print("CH4: " + CH4)
                    if bit == "N": #Si se cumple se garantiza existencia de trama hasta "N"
                        H2 =  valores[3].split("M")[1].split("N")[0].strip()
                        #print("H2: " + H2)
                    if bit == "O": #Si se cumple se garantiza existencia de trama hasta "O"
                        C2H50H =  valores[3].split("N")[1].split("O")[0].strip()
                        #print("C2H50H: " + C2H50H)
                    if bit == "P": #Si se cumple se garantiza existencia de trama hasta "P"
                        tempI2C =  valores[3].split("O")[1].split("P")[0].strip()
                        #print("tempI2C: " + tempI2C)
                    if bit == "Q": #Si se cumple se garantiza existencia de trama hasta "Q"
                        tempADC =  valores[3].split("P")[1].split("Q")[0].strip()
                        presionbar =  valores[3].split("Q")[1].strip()
                        #print("tempADC: " + tempADC)
                        #print("presionbar: " + presionbar)
                        #print("trama larga Gases completa")
            else:
                #trama corta
                #tiempo h latitud / longitud O curso / velocidad A altitud B alturaBar C tempbar D tempeSHT11 E voltajebater
                tramalarga = False
                for i in range(len(valores[3])):
                    i = i + 1
                    bit = valores[3][i-1]
                    if bit == "B": #Si se cumple se garantiza existencia de trama hasta "B"
                        tiempo = valores[1][0:6].strip()
                        latitud = valores[1][7:15].strip()
                        longitud = valores[2][0:9].strip()
                        curso = valores[2][10:].strip()
                        velocidad = valores[3].split("A")[0].strip()
                        altitudGps = valores[3].split("A")[1].split("B")[0].strip()
                        datosTransfor = transformarTrama(latitud,longitud) #Convierte las coordenadas a decimales
                        latitud_geo = datosTransfor[0]
                        longitud_geo = datosTransfor[1]
                    if bit == "C": #Si se cumple se garantiza existencia de trama hasta "C"
                        alturaBar = valores[3].split("B")[1].split("C")[0].strip()
                        vectorAlturaBar_ext.append(alturaBar)
                        vectorAlturaGps_ext.append(altitudGps)
                        print("tiempo: " + str(float(tiempo)))
                        print("latitud_geo: " + str(float(latitud_geo)))
                        print("longitud_geo: " + str(float(longitud_geo)))
                        print("altitud_Gps: " + str(float(altitudGps)))
                        print("altura_Bar: " + str(float(alturaBar)))
                        if len(vectorAlturaBar_ext) > 1:
                            tamaño = len(vectorAlturaBar_ext)
                            deltaAlturaBar = float(vectorAlturaBar_ext[tamaño-1])-float(vectorAlturaBar_ext[tamaño-2])
                            alturaBarBias = float(vectorAlturaGps_ext[tamaño-2]) + deltaAlturaBar
                            altitudFus= fusionar(altitudGps,alturaBarBias) #Fusiona la altura del GPS y Barometro en una sola medida mas precisa
                            print("altura_FUS: " + str(float(altitudFus)))
                        datoToSetOK = True
                        print("curso: " + str(float(curso)))
                        print("velocidad: " + str(float(velocidad)))
                    if bit == "D": #Si se cumple se garantiza existencia de trama hasta "D"
                        tempeBar =  valores[3].split("C")[1].split("D")[0].strip()
                        #print("temperaturaBar: " +  str(float(tempeBar)/100))
                    if bit == "E": #Si se cumple se garantiza existencia de trama hasta "E"
                        tempeSHT11 =  valores[3].split("D")[1].split("E")[0].strip()
                        voltajebater =  valores[3].split("E")[1].strip()
                        presionbar = "0.0"
                        humedadDHT11 = "0.0"
                        #print("temperaturaSHT11: " +  str(float(tempeSHT11)/100))
                        #print("voltajebater: " + str(float(voltajebater)/1000))
                        print("trama corta completa")
            #Se debe guardar de manera recurrente las coordenadas de la estacion terrena y la gondola
            #para el caso en el que se reinicie la aplicacion y no se haya movido la estacion, poder
            #recuperar el tracking seteando nuevamente de manera automatica
            if datoToSetOK == True and set == True:
                datoToSetOK = False
                archivo3 = open(nombreArchivoSETLeerEscribir,"w")
                archivo3.write("latitudE/" + str(latitudE) + "\n")
                archivo3.write("longitudE/" + str(longitudE) + "\n")
                archivo3.write("altitudE/" + str(altitudE) + "\n")
                archivo3.write("latitudG_i/" + str(latitud_geo) + "\n")
                archivo3.write("longitudG_i/" + str(longitud_geo) + "\n")
                archivo3.write("altitudG_i/" + str(altitudGps) + "\n")
                archivo3.close()
            return [latitud_geo,longitud_geo,altitudGps]
    except Exception as e:
        print("******ERROR PROCESANDO TRAMA********")
        print(e)

def transformarTrama(latitud,longitud):
    try:
        longitud_geo = 0
        latitud_geo = 0
        if(len(longitud) > 8):
            grados_lo = float(longitud[1:3])
            minutos_lo = float(longitud[3:5])
            decimasMinutos_lo = float("0"+longitud[5:8])
        elif(len(longitud) > 9):
            grados_lo = float(longitud[0:2])
            minutos_lo = float(longitud[2:4])
            decimasMinutos_lo = float(longitud[4:8])
        else:
            grados_lo = float(longitud[1:2])
            minutos_lo = float(longitud[2:4])
            decimasMinutos_lo = float("0"+longitud[4:7])
        longitud_geo = (grados_lo + (minutos_lo + decimasMinutos_lo)/60)
        if(longitud[len(longitud)-1] == "W"):
            longitud_geo = longitud_geo * -1
        longitud_geo = str(longitud_geo)
        longitud_geo = longitud_geo[0:9]
        longitud_geo = longitud_geo.strip()
        if(len(latitud) == 9):
            grados_la = float(latitud[1:3])
            minutos_la = float(latitud[3:5])
            decimasMinutos_la = float("0"+latitud[5:8])
        elif(len(latitud) > 9):
            grados_la = float(latitud[0:2])
            minutos_la = float(latitud[2:4])
            decimasMinutos_la = float(latitud[4:8])
        else:
            grados_la = float(latitud[1:2])
            minutos_la = float(latitud[2:4])
            decimasMinutos_la = float("0"+latitud[4:7])
        latitud_geo = (grados_la + (minutos_la + decimasMinutos_la)/60)
        if(latitud[len(latitud)-1] == "S"):
            latitud_geo = latitud_geo * -1
        latitud_geo = str(latitud_geo)
        latitud_geo = latitud_geo[0:9]
        latitud_geo = latitud_geo.strip()
        return [latitud_geo,longitud_geo]
    except Exception as e:
        print("*****ERROR TRANSFORMANDO TRAMA*****")
        print(e)

def modelo(lati, longi, alti):
    try:
        latitudG = float(lati)
        longitudG = float(longi)
        altitudG = float(alti)
        alfaP = (3.141592653589793/180)*(latitudE)
        betaP = (3.141592653589793/180)*(longitudE)
        hP = altitudE
        alfaS = (3.141592653589793/180)*(latitudG)
        betaS = (3.141592653589793/180)*(longitudG)
        hS = altitudG
        divCero = 0
        r = 6378000.0
        P = r + hP
        S = r + hS
        Px = P*math.cos(alfaP)*math.sin(betaP)
        Py = P*math.cos(alfaP)*math.cos(betaP)
        Pz = P*math.sin(alfaP)
        Sx = S*math.cos(alfaS)*math.sin(betaS)
        Sy = S*math.cos(alfaS)*math.cos(betaS)
        Sz = S*math.sin(alfaS)
        Dxyz_1 = Sx-Px
        Dxyz_2 = Sy-Py
        Dxyz_3 = Sz-Pz
        D = math.sqrt(Dxyz_1*Dxyz_1+Dxyz_2*Dxyz_2+Dxyz_3*Dxyz_3)
        Dw_1 = math.cos(-betaP)*Dxyz_1+math.sin(-betaP)*Dxyz_2
        Dw_2 = -math.sin(-betaP)*Dxyz_1+math.cos(betaP)*Dxyz_2
        Dw_3 = Dxyz_3
        Duvw_1 = Dw_1
        Duvw_2 = math.cos(alfaP)*Dw_2+math.sin(alfaP)*Dw_3
        Duvw_3 = -math.sin(alfaP)*Dw_2+math.cos(alfaP)*Dw_3
        if abs(Duvw_1) < 1:
            Duvw_1 = 0.0
        if abs(Duvw_2) < 1:
            Duvw_2 = 0.0
        if abs(Duvw_3) < 1:
            Duvw_3 = 0.0

        vectorD = [Duvw_1,Duvw_2,Duvw_3]
        MatrizD.append(vectorD)
        try:
            archivo1 = open(nombreVectorTrayectoriaGuardar,"a")
            archivo1.write(str(vectorD) + '\n')
            archivo1.close()
        except:
            print("*** AVISO - vector no logro guardarse ***")
            print(e)

        Distancia = math.sqrt(Duvw_1*Duvw_1+Duvw_2*Duvw_2+Duvw_3*Duvw_3)
        if Distancia > 0.0:
            omega_prima = math.asin(Duvw_2/Distancia)*180/3.14159265358979
            if Duvw_1 < 0.0:
                theta_prima = -math.acos(Duvw_3/math.sqrt(Duvw_1*Duvw_1+Duvw_3*Duvw_3))*180/3.141592653589793
            elif Duvw_1 > 0.0:
                theta_prima = math.acos(Duvw_3/math.sqrt(Duvw_1*Duvw_1+Duvw_3*Duvw_3))*180/3.141592653589793
            elif Duvw_1 == 0.0 and Duvw_3 == 0.0:
                theta_prima = 0.0
            else:
                theta_prima = 0.0
            angulo_omega = omega_prima
            angulo_theta = theta_prima
            return [angulo_theta, angulo_omega]
        else:
            return[0.0, 0.0]
    except Exception as e:
        print("*** ERROR CRITICO - FALLA CALCULANDO MODELO ****")
        print(e)

def enviarArduino(angulo_theta, angulo_omega, state):
    try:
        SET = state
        #Python le pregunta al arduino si puede recibir datos
        arduino.write(str("ESTALISTO0000090909").encode())
        print("arduino listo?")
        time.sleep(0.1)
        datoRecibido = ''
        while True:
            datoRecibido = str(arduino.readline().decode().splitlines())
            if datoRecibido == "['listo']":
                print(datoRecibido)
                break
            time.sleep(0.01)
        #Solo cuando el arduino responda el programa continua
        datoRecibido = ''

        omega_prima = angulo_omega
        theta_prima = angulo_theta

        #Se hace un acarreo de los datos a enviar al arduino y garantizar que no hay perdida de datos
        if omega_prima < 0:
            signo_omega = "-"
            acarreo_signo_omega = 45
        else:
            signo_omega = "+"
            acarreo_signo_omega = 43

        if theta_prima < 0:
            signo_theta = "-"
            acarreo_signo_theta = 45
        else:
            signo_theta = "+"
            acarreo_signo_theta= 43

        suma = (acarreo_signo_theta
            + acarreo_signo_omega
            + 84 + 79
            + int(abs(theta_prima*100))
            + int(abs(omega_prima*100)))
        if suma > 10000:
            ajusteSum = "";
        if 1000 < suma and suma < 10000:
            ajusteSum = "0";
        if 100 < suma and suma < 1000:
            ajusteSum = "00";
        if 10 < suma and suma < 100:
            ajusteSum = "000";
        if suma < 10:
            ajusteSum = "0000";

        print("theta_prima: " + str(theta_prima))
        print("omega_prima: " + str(omega_prima))

        if abs(theta_prima) > 100:
            ajusteT = ""
        if 10 < abs(theta_prima) and abs(theta_prima) < 100:
            ajusteT = "0"
        if 1 < abs(theta_prima) and abs(theta_prima) < 10:
            ajusteT = "00"
        if 0.1 < abs(theta_prima) and abs(theta_prima) < 1:
            ajusteT = "000"
        if abs(theta_prima) < 0.1:
            ajusteT = "0000"

        if abs(omega_prima) > 100:
            ajusteO = "";
        if 10 < abs(omega_prima) and abs(omega_prima) < 100:
            ajusteO = "0";
        if 1 < abs(omega_prima) and abs(omega_prima) < 10:
            ajusteO = "00";
        if 0.1 < abs(omega_prima) and abs(omega_prima) < 1:
            ajusteO = "000";
        if abs(omega_prima) < 0.1:
            ajusteO = "0000";

        #Si SET es true el arduino comprendera que las coordenadas enviadas son el SET y alli configurara su posicion inicial
        if SET == False:
            print(str("T").encode() + str(signo_theta).encode() + str(ajusteT).encode() + str(int(abs(theta_prima*100))).encode()
                  + str("O").encode() + str(signo_omega).encode() + str(ajusteO).encode() + str(int(abs(omega_prima*100))).encode()
                  + str(ajusteSum).encode() + str(suma).encode())
            arduino.write(str("T").encode() + str(signo_theta).encode() + str(ajusteT).encode() + str(int(abs(theta_prima*100))).encode()
                  + str("O").encode() + str(signo_omega).encode() + str(ajusteO).encode() + str(int(abs(omega_prima*100))).encode()
                  + str(ajusteSum).encode() + str(suma).encode())
        else:
            print(str("T").encode() + str(signo_theta).encode() + str(ajusteT).encode() + str(int(abs(theta_prima*100))).encode()
                  + str("O").encode() + str(signo_omega).encode() + str(ajusteO).encode() + str(int(abs(omega_prima*100))).encode()
                  + str("99999").encode())
            arduino.write(str("T").encode() + str(signo_theta).encode() + str(ajusteT).encode() + str(int(abs(theta_prima*100))).encode()
                  + str("O").encode() + str(signo_omega).encode() + str(ajusteO).encode() + str(int(abs(omega_prima*100))).encode()
                  + str("99999").encode())
        time.sleep(0.1)

        datoRecibido = ''
        #Python le pregunta al arduino si entendio el dato que le fue enviado
        while True:
            datoRecibido = str(arduino.readline().decode().splitlines())
            print("angulo entendido? ")
            if datoRecibido == "['entendido']":
                print(datoRecibido)
                break
            if datoRecibido == "['SET']":
                print(datoRecibido)
                break
            time.sleep(0.01)
        #Si el arduino responde el programa continua
        datoRecibido = ''
    except Exception as e:
        print("******ERROR ENVIANDO A ARDUINO*****")
        print(e)

#SETEAR POSICIONES INICIALES GONDOLA Y ESTACION
while(1):
    continuar = 0
    try:
        trama = leerTrama()
        if trama != 0 and trama != 1:
            print(trama)
            for line in sys.stdin:
                if str(line).encode() == b'\n':
                    break
                if line.strip() == "SET-ESTACION":
                    coordenadas = procesarTrama(trama,False)
                    latitudE_set = coordenadas[0]
                    longitudE_set = coordenadas[1]
                    altitudE_set = coordenadas[2]
                    print("**** SET-ESTACION OK ****")
                    continuar = continuar + 1
                    break
                if line.strip() == "SET-GONDOLA":
                    coordenadas = procesarTrama(trama,False)
                    latitudG_i_set = coordenadas[0]
                    longitudG_i_set = coordenadas[1]
                    altitudG_i_set = coordenadas[2]
                    print("**** SET-GONDOLA OK ****")
                    continuar = continuar + 1
                    break
        if continuar == 2:
            archivo3 = open(nombreArchivoSETLeerEscribir,"w")
            archivo3.write("latitudE/" + str(latitudE_set) + "\n")
            archivo3.write("longitudE/" + str(longitudE_set) + "\n")
            archivo3.write("altitudE/" + str(altitudE_set) + "\n")
            archivo3.write("latitudG_i/" + str(latitudG_i_set) + "\n")
            archivo3.write("longitudG_i/" + str(longitudG_i_set) + "\n")
            archivo3.write("altitudG_i/" + str(altitudG_i_set) + "\n")
            archivo3.close()
            break
            print("_________________")
        time.sleep(0.1)

        archivo2 = open(nombreArchivoSETLeerEscribir,"r")
        datoSET = archivo2.readlines()
        latitudE = float(datoSET[0].split("/")[1])
        longitudE = float(datoSET[1].split("/")[1])
        altitudE = float(datoSET[2].split("/")[1])
        latitudG_i = float(datoSET[3].split("/")[1])
        longitudG_i = float(datoSET[4].split("/")[1])
        altitudG_i = float(datoSET[5].split("/")[1])
        angulosSET = modelo(latitudG_i,longitudG_i,altitudG_i)
        thetaSET = angulosSET[0]
        omegaSET = angulosSET[1]
        archivo2.close()
        enviarArduino(thetaSET,omegaSET,True)
        print("__________________________________________")
    except Exception as e:
        print("****ERROR GENERANDO SET***")
        print(e)
        time.sleep(1)

time.sleep(2)

#FLUJO PRINCIPAL
while (1):
    try:
        trama = leerTrama()
        if trama != 0 and trama != 1:
            cuentatrama = 0
            cuentadesconocida = 0
            coordenadas = procesarTrama(trama,True)
            angulos = modelo(coordenadas[0],coordenadas[1],coordenadas[2])
            #print("theta_prima: " + str(angulos[0]))
            #print("omega_prima: " + str(angulos[1]))
            enviarArduino(angulos[0],angulos[1],False) #theta,omega
            if len(MatrizD) > 1: #Estimacion
                #estimacion()
                continue
            print("__________________________________________")
        if trama == 0:
            if cuentatrama < 1:
                print("Esperando trama nueva.....")
                print("__________________________________________")
                cuentatrama = cuentatrama + 1
        if trama == 1:
            if cuentadesconocida < 1:
                print("Trama leida desconocida")
                print("__________________________________________")
                cuentadesconocida = cuentadesconocida + 1
        time.sleep(0.1) #leer archivo tramas cada 100 milisegundos
    except:
        print("******** ERROR DE EJECUCION ***********")


#####################################################################
#
# audio.py
#
# Copyright (c) 2015, Eran Egozy
#
# Released under the MIT License (http://opensource.org/licenses/MIT)
#
#####################################################################

import sys

try:
    from common.core import register_terminate_func
except:
    # if import failed, we are most likely running from command line (python audio.py)
    # to print out audio devices. In that case, we don't need anything from common.core anyway
    pass

import pyaudio
import numpy as np
import time

class Audio(object):
    """
    Audio input and output stream manager. Only one `Audio` object should be created. Audio output
    (sent to speakers) is supplied by setting an audio Generator class. Audio input (from microphone) is
    provided via a callback function. You can also "tap into" the output audio using a callback.

    :param num_channels: Number of output channels. Can be 1 (mono) or 2 (stereo)

    :param listen_func: if provided, call with audio buffer about to be sent out to speaker with
        parameters ``(audio, num_channels)``

    :param input_func: if provided, input streaming is enabled, and function will be called when
        input data is available with parameters ``(audio, num_channels)``

    :param num_input_channels: stream 1 (mono) or 2 (stereo) input channels. Note that some devices
        may not support stereo input.

    The following parameters are class-parameters and can be set before creating the Audio class:

    :param Audio.sample_rate: Audio sample rate to use. Defaults to 44100.

    :param Audio.buffer_size: Internal buffer size. A smaller buffer will lower latency, at the risk of buffer underrun.
        Default is 512.

    :param Audio.out_dev: Can specify a non-default audio output device (via integer index).
        See :meth:`print_audio_devices`. Default is None, which chooses the default output device.

    :param Audio.in_dev: Can specify a non-default audio input device (via integer index).
        See :meth:`print_audio_devices`. Default is None, which chooses the default input device.

    .. note::
        On Windows, if ASIO drivers are installed, you can run the whole python app with
        command-line-args `-asio`. That will cause ASIO drivers to be used instead of the default in/out
        devices. ASIO typically has much lower latency than the built-in Windows drivers.

        Example: ``python myapp.py -asio``

    """

    # audio configuration parameters:
    sample_rate = 44100
    buffer_size = 512
    out_dev = None
    in_dev = None

    def __init__(self, num_channels, listen_func = None, input_func = None, num_input_channels = 1):
        super(Audio, self).__init__()

        assert(num_channels == 1 or num_channels == 2)
        self.num_channels = num_channels
        self.listen_func = listen_func
        self.input_func = input_func
        self.audio = pyaudio.PyAudio()

        self.num_input_channels = num_input_channels

        # on windows, if '-asio' found in command-line-args, use ASIO drivers
        if '-asio' in sys.argv:
            Audio.out_dev, Audio.in_dev = self._find_asio_devices()

        print('using audio params:')
        print('  samplerate: {}\n  buffersize: {}\n  outputdevice: {}\n  inputdevice: {}'.format(
            Audio.sample_rate, Audio.buffer_size, Audio.out_dev, Audio.in_dev))

        # create output stream
        self.stream = self.audio.open(format = pyaudio.paFloat32,
                                      channels = num_channels,
                                      frames_per_buffer = Audio.buffer_size,
                                      rate = Audio.sample_rate,
                                      output = True,
                                      input = False,
                                      output_device_index = Audio.out_dev)

        # create input stream
        self.input_stream = None
        if input_func:
            self.input_stream = self.audio.open(format = pyaudio.paFloat32,
                                                channels = self.num_input_channels,
                                                frames_per_buffer = Audio.buffer_size,
                                                rate = Audio.sample_rate,
                                                output = False,
                                                input = True,
                                                input_device_index = Audio.in_dev)

        self.generator = None
        self.cpu_time = 0
        register_terminate_func(self._close)

    def set_generator(self, gen):
        """
        Sets a Generator object that must supply audio data to Audio. Generator must define the
        method ``generate(num_frames, num_channels)``, which returns a numpy array of
        length *(num_frames * num_channels)*.

        :param gen: The generator object. May be `None`.

        """
        self.generator = gen

    def get_cpu_load(self):
        """
        :returns: Time spent (in milliseconds) processing audio input and output.
            Returned value is smoothed out somewhat. If value is too high (above 16ms), then too much time
            is being spent calculating audio.
        """
        return 1000 * self.cpu_time

    def on_update(self):
        """
        Must be called by the app (`MainWidget`) very often - usually 60 times per second. Typically,
        Audio.on_update() should be called from MainWidget.on_update().
        """

        t_start = time.time()

        # get input audio if desired
        if self.input_stream:
            try:
                num_frames = self.input_stream.get_read_available() # number of frames to ask for
                if num_frames:
                    data_str = self.input_stream.read(num_frames, False)
                    data_np = np.fromstring(data_str, dtype=np.float32)
                    self.input_func(data_np, self.num_input_channels)
            except IOError as e:
                print('got error', e)

        # Ask the generator to generate some audio samples.
        num_frames = self.stream.get_write_available() # number of frames to supply
        if self.generator and num_frames != 0:
            (data, continue_flag) = self.generator.generate(num_frames, self.num_channels)

            # make sure we got the correct number of frames that we requested
            assert len(data) == num_frames * self.num_channels, \
                "asked for (%d * %d) frames but got %d" % (num_frames, self.num_channels, len(data))

            # convert type if needed and write to stream
            if data.dtype != np.float32:
                data = data.astype(np.float32)
            self.stream.write(data.tostring())

            # send data to listener as well
            if self.listen_func:
                self.listen_func(data, self.num_channels)

            # continue flag
            if not continue_flag:
                self.generator = None

        # how long this all took
        dt = time.time() - t_start
        a = 0.9
        self.cpu_time = a * self.cpu_time + (1-a) * dt

    def _close(self):
        self.stream.stop_stream()
        self.stream.close()
        if self.input_stream:
            self.input_stream.stop_stream()
            self.input_stream.close()

        self.audio.terminate()

    # look for the ASIO devices and return them (output, input)
    def _find_asio_devices(self):
        out_dev = in_dev = None

        cnt = self.audio.get_host_api_count()
        for i in range(cnt):
            api = self.audio.get_host_api_info_by_index(i)
            if api['type'] == pyaudio.paASIO:
                out_dev = api['defaultOutputDevice']
                in_dev = api['defaultInputDevice']
                print('Found ASIO device at index', i)

        return out_dev, in_dev

def get_audio_devices():
    """
    :returns: Available input and output devices as `{ 'input': <list>, 'output': <list> }`.
        `<list>` is a list of device descriptors, each being a dictionary:
        `{'index': <integer>, 'name': <string>, 'latency': (low, high), 'channels': <max # of channels>`.
    """

    def add_device(arr, io_type, dev):
        info = {}
        info['index'] = dev['index']
        info['name'] = dev['name']
        info['latency'] = (dev['defaultLow' + io_type + 'Latency'],
                           dev['defaultHigh' + io_type + 'Latency'])
        info['channels'] = dev['max' + io_type + 'Channels']
        arr.append(info)

    audio = pyaudio.PyAudio()

    out_devs = [{'index':'None', 'name':'Default', 'channels':0, 'latency':(0,0)}]
    in_devs  = [{'index':'None', 'name':'Default', 'channels':0, 'latency':(0,0)}]

    cnt = audio.get_device_count()
    for i in range(cnt):
        dev = audio.get_device_info_by_index(i)

        if dev['maxOutputChannels'] > 0:
            add_device(out_devs, 'Output', dev)

        if dev['maxInputChannels'] > 0:
            add_device(in_devs, 'Input', dev)

    audio.terminate()
    return {'output': out_devs, 'input': in_devs}

def print_audio_devices():
    """
    Prints the list of accessible input and output audio devices. This easiest way to see
    these results is to run ``python audio.py``, which just calls this function.
    """

    devs = get_audio_devices()

    print("\nOutput Devices")
    print('{:>5}: {:<40} {:<6} {}'.format('idx', 'name', 'chans', 'latency'))
    for d in devs['output']:
        print('{index:>5}: {name:<40} {channels:<6} {latency[0]:.3f} - {latency[1]:.3f}'.format(**d))

    print("\nInput Devices")
    print('{:>5}: {:<40} {:<6} {}'.format('idx', 'name', 'chans', 'latency'))
    for d in devs['input']:
        print('{index:>5}: {name:<40} {channels:<6} {latency[0]:.3f} - {latency[1]:.3f}'.format(**d))

if __name__ == "__main__":
    print_audio_devices()


import httpx
import json

async def get_image(key:str):
    '''
    根据关键词提取image的url
    '''
    # 推荐使用此方法
    # 调取表情包链接api
    # async with httpx.AsyncClient() as client:
    #     resp = await client.get('https://my-json-server.typicode.com/sliefamily/bdg-bot/db')
    #     json_data = resp.json()['bqb']

    # 读取本地json文件
    with open('/home/bdg-bot/db.json','r',encoding='utf8')as fp:
        json_data = json.load(fp)['bqb']

    for i in range(0,len(json_data)):
        if json_data[i]["key"] == key:
            return json_data[i]["url"]
    return None


# coding: utf-8

__author__ = 'Mário Antunes'
__version__ = '0.1'
__email__ = 'mariolpantunes@gmail.com'
__status__ = 'Development'

import typing
import logging
import numpy as np
import knee.knee_ranking as ranking
import matplotlib.pyplot as plt

logger = logging.getLogger(__name__)

def filter_worst_knees(points: np.ndarray, knees: np.ndarray) -> np.ndarray:
    """
    Filter the worst knees points.

    A worst knee is a knee that is higher (at y axis) than a previous knee.

    Args:
        points (np.ndarray): numpy array with the points (x, y)
        knees (np.ndarray): knees indexes

    Returns:
        np.ndarray: the filtered knees
    """

    filtered_knees = []

    filtered_knees.append(knees[0])
    h_min = points[knees[0]][1]

    for i in range(1, len(knees)):
        h = points[knees[i]][1]
        if h <= h_min:
            filtered_knees.append(knees[i])
            h_min = h

    return np.array(filtered_knees)

def filter_clustring(points: np.ndarray, knees: np.ndarray,
clustering: typing.Callable[[np.ndarray, float], np.ndarray], t: float = 0.01,
method: ranking.ClusterRanking = ranking.ClusterRanking.linear) -> np.ndarray:
    """
    Filter the knee points based on clustering.

    For each cluster a single point is selected based on the ranking.
    The ranking is computed based on the slope and the improvement (on the y axis).

    Args:
        points (np.ndarray): numpy array with the points (x, y)
        knees (np.ndarray): knees indexes
        clustering (typing.Callable[[np.ndarray, float]): the clustering function
        t (float): the threshold for merging (in percentage, default 0.01)
        method (ranking.ClusterRanking): represents the direction of the ranking within a cluster (default ranking.ClusterRanking.linear)

    Returns:
        np.ndarray: the filtered knees
    """

    knee_points = points[knees]
    clusters = clustering(knee_points, t)
    max_cluster = clusters.max()
    filtered_knees = []
    for i in range(0, max_cluster+1):
        current_cluster = knees[clusters == i]

        if len(current_cluster) > 1:
            rankings = ranking.cluster_ranking(points, current_cluster, method)
            #logger.info('Rankings: %s', rankings)
            idx = np.argmax(rankings)
            best_knee = knees[clusters == i][idx]
        else:
            #logger.info('Rankings: [1.0]')
            best_knee = knees[clusters == i][0]
        filtered_knees.append(best_knee)

        # plot cluster
        # if plot:
        #    xpoints = points[:,0]
        #    ypoints = points[:,1]
        #    plt.plot(xpoints, ypoints)
        #    plt.plot(xpoints[current_cluster], ypoints[current_cluster], marker='x', markersize=3, color='green')
        #    plt.plot(xpoints[best_knee], ypoints[best_knee], marker='o', markersize=5, color='red')
        #    plt.show()
    return np.array(filtered_knees)


from flask import Flask, render_template
import pandas as pd

app = Flask(__name__)

stations = pd.read_csv("data_small/stations.txt", skiprows=17)
stations = stations[["STAID","STANAME                                 "]]

@app.route("/")
def home():
    return render_template("home.html", data=stations.to_html())

@app.route("/api/v1/<station>/<date>")
def about(station, date):
    filename = "data_small/TG_STAID" + str(station).zfill(6) + ".txt"
    df = pd.read_csv(filename, skiprows=20, parse_dates=["    DATE"])
    temperature = df.loc[df['    DATE'] == date]['   TG'].squeeze() / 10
    return {"station": station,
            "date": date,
            "temperature": temperature}

@app.route("/api/v1/<station>")
def all_data(station):
    filename = "data_small/TG_STAID" + str(station).zfill(6) + ".txt"
    df = pd.read_csv(filename, skiprows=20, parse_dates=["    DATE"])
    result = df.to_dict(orient="records")
    return result

@app.route("/api/v1/yearly/<station>/<year>")
def yearly(station, year):
    filename = "data_small/TG_STAID" + str(station).zfill(6) + ".txt"
    df = pd.read_csv(filename, skiprows=20)
    df["    DATE"] = df["    DATE"].astype(str)
    result = df[df["    DATE"].str.startswith(str(year))].to_dict(orient="records")
    return result

if __name__ == "__main__":
    app.run(debug=True, port=5000)


# -*- coding: utf-8 -*-

import os.path
import sqlite3
import csv

class BooksDao:

    # constructor
    def __init__(self, db):
        def dict_factory(cursor, row):
            d = {}
            for idx, col in enumerate(cursor.description):
                d[col[0]] = row[idx]
            return d

        self.db = db
        self.con = sqlite3.connect(self.db)
        # self.con = sqlite3.connect(db)
        self.con.row_factory = dict_factory
        self.cur = self.con.cursor()
        # ñapa para que funcione el iterador
        self.cur_iter = self.con.cursor()

    def __iter__(self):
        query = '''select *
                from books
                where 1 == 1
                order by isbn13 ;'''

        self.cur_iter.execute(query)
        return self

    def __next__(self):

        data = self.cur_iter.fetchone()

        if data:
            return data
        else:
            raise StopIteration

    def create(self):
        """ Creación de la base de datos con una única tabla BOOKS """
        self.cur.execute('drop table IF EXISTS books;')
        self.cur.execute('''create table books
                                (authors, first_name, last_name, title,
                                description, rating, review_date, review,
                                status, began_date, completed_date, tags,
                                notes, groups, copies, created,
                                publisher, publish_date, pages, price,
                                isbn10, isbn13);''')

    def read(self, isbn13):
        q = ("""select * from books where isbn13 = '{}'""").format(isbn13)

        self.cur.execute(q)

        # solo devuelve 1, es PK
        return self.cur.fetchone()

    def exist(self, book):
        """ Revisar si un book (un dict) existe en base de datos """
        isbn13 = book.get('isbn13')

        q = ("""select count(*) total
                from books where isbn13 = '{}'""").format(isbn13)

        self.cur.execute(q)

        return self.cur.fetchone().get('total') > 0

    def insert(self, book):
        """ Inserta un libro en base de datos, únicamente si no existe """
        if self.exist(book):
            print("The book already exists, will be updated")
            self.update(book)
        else:
            t = {}
            # Buscamos y dejamos a '' los valores None
            for key in book.keys():
                if book.get(key):
                    t[key] = book.get(key)

            # en dos pasos
            keys = "'" + "', '".join(t.keys()) + "'"
            values = "'" + "', '".join(t.values()) + "'"
            q = "insert into books ({}) values ({})".format(keys, values)
            self.cur.execute(q)
            self.con.commit()

    def update(self, book):
        """ Actualizamos un libro """
        if self.exist(book):
            sets = ''
            for key in book.keys():
                # evitamos que los valores sin datos se actualicen
                if book.get(key):
                    value = str(book.get(key))
                    # tratamiento de nulos es especial
                    if value.upper() == 'NULL':
                        sets = sets + '"' + key + '" = ' + value + ', '
                    else:
                        sets = sets + '"' + key + '" = "' + value + '", '

            # eliminamos el último ", "
            sets = sets[0:len(sets) - 2]

            where = ("isbn13 = '{}'").format(book.get('isbn13'))

            q = ("""update books set {} where {}""").format(sets, where)

            self.cur.execute(q)
            self.con.commit()

        else:
            print('There is no book to update')

    def delete(self, book):
        """ Revisar si un book (un dict) existe en base de datos """
        isbn13 = book.get('isbn13')

        q = ("""delete from books where isbn13 = '{}'""").format(isbn13)

        self.cur.execute(q)
        self.con.commit()

    def load_csv(self, csvdata):
        """ Carga un fichero CSV a la tabla BOOKS """

        with open(csvdata, 'rt', encoding='utf8') as csvfile:
            # cabecera
            dr = csv.DictReader(csvfile)
            to_db = [(i['authors'], i['first_name'], i['last_name'],
                     i['title'], i['description'], i['rating'],
                     i['review_date'], i['review'], i['status'],
                     i['began_date'], i['completed_date'], i['tags'],
                     i['notes'], i['groups'], i['copies'],
                     i['created'], i['publisher'], i['publish_date'],
                     i['pages'], i['price'], i['isbn10'],
                     i['isbn13'])
                     for i in dr]

            self.cur.executemany('''insert into books
                                    (authors, first_name, last_name,
                                    title, description, rating,
                                    review_date, review, status,
                                    began_date, completed_date, tags,
                                    notes, groups, copies,
                                    created, publisher, publish_date,
                                    pages, price, isbn10,
                                    isbn13)
                            values
                            (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);''',
                                 to_db)
        self.con.commit()

    def executefile(self, sqlfile):
        """ Ejecuta un fichero SQL """
        if os.path.isfile(sqlfile):
            with open(sqlfile, 'rt', encoding='utf8') as sqls:
                # cur.executescript(sql.readlines())
                for sql in sqls:
                    self.cur.execute(sql)
        self.con.commit()

    def execute(self, query):
        """ Ejecuta una sentencia SQL """
        for sql in query:
            self.cur.execute(sql)
        self.con.commit()

    def select(self, query='select * from books order by isbn13'):

        self.cur.execute(query)
        return self.cur.fetchall()

    # def list_by(self, column='', value=''):
    def list_by(self, keys='*', by=None):
        """ List by """

        # Dangerous default value {} as argument
        by = {} if not by else by

        select = 'select ' + ', '.join(keys)

        fromm = ' from books where 1 = 1 '

        where = ''
        for key in by:

            # napeando los acentos
            kaccents = """replace(replace(replace(replace(replace(replace(
                            replace(replace(replace(replace(replace(
                            lower({}),
                                'á','a'), 'ã','a'), 'â','a'),
                                'é','e'), 'ê','e'),
                                'í','i'),
                                'ó','o') ,'õ','o') ,'ô','o'),
                                'ú','u'),
                                'ç','c')""".format(key)

            where = where + " and {} like '%{}%' ".format(kaccents, by[key])

        order = ' order by completed_date '

        query = select + fromm + where + order

        self.cur.execute(query)
        return self.cur.fetchall()

    def stats(self):
        """ Books stats """

        query = ''' select case status when '' then 'No status'
                    else status end as status,
                    count(*) total
                from books
                group by status'''

        self.cur.execute(query)
        return self.cur.fetchall()


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.distributions.bernoulli import Bernoulli

from absl import logging
from embed_regularize import embedded_dropout
from locked_dropout import LockedDropout
from weight_drop import WeightDrop
from sparsemax import row_wise_sparsemax,Sparsemax

logging.set_verbosity(logging.INFO)

class RNNModel(nn.Module):
    """Container module with an encoder, a recurrent module, and a decoder."""

    def __init__(self, rnn_type, ntoken, ninp, nhid, nlayers, dropout=0.5,
                 dropouth=0.5, dropouti=0.5, dropoute=0.1, wdrop=0, tie_weights=False,
                 num_features=0, feature_dim=0, feature_relu_bias=2.0):
        super(RNNModel, self).__init__()
        self.lockdrop = LockedDropout()
        self.idrop = nn.Dropout(dropouti)
        self.hdrop = nn.Dropout(dropouth)
        self.drop = nn.Dropout(dropout)
        self.num_features = num_features
        self.feature_dims = feature_dim
        if self.num_features == 0:
            # self.encoder = nn.Embedding(ntoken, ninp)
            self.encoder = nn.Parameter(torch.FloatTensor(ntoken, ninp))
        else:
            self.word_emb = nn.Parameter(torch.FloatTensor(ntoken, feature_dim))
            self.feature_emb = nn.Parameter(torch.FloatTensor(num_features, feature_dim))
            self.feature_relu_bias = nn.Parameter(torch.FloatTensor([feature_relu_bias]),requires_grad=False)
            self.encoder = nn.Parameter(torch.FloatTensor(num_features, ninp))
            self.word_emb_cache = None
            self.feature_emb_cache = None

        assert rnn_type in ['LSTM', 'QRNN', 'GRU'], 'RNN type is not supported'
        if rnn_type == 'LSTM':
            self.rnns = [torch.nn.LSTM(ninp if l == 0 else nhid, nhid if l != nlayers - 1 else (ninp if tie_weights else nhid), 1, dropout=0) for l in range(nlayers)]
            if wdrop:
                self.rnns = [WeightDrop(rnn, ['weight_hh_l0'], dropout=wdrop) for rnn in self.rnns]
        if rnn_type == 'GRU':
            self.rnns = [torch.nn.GRU(ninp if l == 0 else nhid, nhid if l != nlayers - 1 else ninp, 1, dropout=0) for l in range(nlayers)]
            if wdrop:
                self.rnns = [WeightDrop(rnn, ['weight_hh_l0'], dropout=wdrop) for rnn in self.rnns]
        elif rnn_type == 'QRNN':
            from torchqrnn import QRNNLayer
            self.rnns = [QRNNLayer(input_size=ninp if l == 0 else nhid, hidden_size=nhid if l != nlayers - 1 else (ninp if tie_weights else nhid), save_prev_x=True, zoneout=0, window=2 if l == 0 else 1, output_gate=True) for l in range(nlayers)]
            for rnn in self.rnns:
                rnn.linear = WeightDrop(rnn.linear, ['weight'], dropout=wdrop)
        logging.info(self.rnns)
        self.rnns = torch.nn.ModuleList(self.rnns)
        self.decoder = nn.Linear(nhid, ntoken)

        # Optionally tie weights as in:
        # "Using the Output Embedding to Improve Language Models" (Press & Wolf 2016)
        # https://arxiv.org/abs/1608.05859
        # and
        # "Tying Word Vectors and Word Classifiers: A Loss Framework for Language Modeling" (Inan et al. 2016)
        # https://arxiv.org/abs/1611.01462
        if tie_weights:
            assert self.num_features == 0, "Its not supported to tie weights and use feature models right now."
            #if nhid != ninp:
            #    raise ValueError('When using the tied flag, nhid must be equal to emsize')
            self.decoder.weight = self.encoder

        self.init_weights()

        self.rnn_type = rnn_type
        self.ninp = ninp
        self.nhid = nhid
        self.nlayers = nlayers
        self.dropout = dropout
        self.dropouti = dropouti
        self.dropouth = dropouth
        self.dropoute = dropoute
        self.tie_weights = tie_weights

        if self.num_features == 0:
            logging.info('Using normal encoder model')
            self._input_layer_fn = self.normal_encoder
        else:
            logging.info('Using feature encoder model %s %s', self.num_features, self.feature_dims)
            self._input_layer_fn = self.feature_encoder

    def comp_fn(self, child, parent):
        pass

    def cache_emb(self):
        self.word_emb_cache = self.word_emb.clone().detach()
        self.feature_emb_cache = self.feature_emb.clone().detach()

    def input_layer(self):
        return self._input_layer_fn()

    def normal_encoder(self):
        return self.encoder

    def feature_encoder(self):
        # Z = F.relu(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)) - self.feature_relu_bias)
        Z = self.compute_z()
        emb = torch.matmul(Z, self.encoder)
        return emb

    def reset(self):
        if self.rnn_type == 'QRNN': [r.reset() for r in self.rnns]

    def init_weights(self):
        initrange = 0.1
        # self.encoder.weight.data.uniform_(-initrange, initrange)
        self.encoder.data.uniform_(-initrange, initrange)
        self.decoder.bias.data.fill_(0)
        self.decoder.weight.data.uniform_(-initrange, initrange)
        if self.num_features > 0:
            self.word_emb.data.uniform_(-initrange, initrange)
            self.feature_emb.data.uniform_(-initrange, initrange)

    def compute_z(self):
        # Z = F.relu(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)) - self.feature_relu_bias)
        # Z = F.relu(F.softmax(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)), dim=1) - self.feature_relu_bias)
        # Z = row_wise_sparsemax.apply(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)))
        Z = F.softmax(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)), dim=1)
        # z = F.relu(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)) - self.feature_relu_bias)
        # b = Bernoulli(F.sigmoid(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0))))
        # Z = b.rsample()
        return Z

    def feature_model_sparsity_loss(self, lambda1, lambda2, avg1, avg2):
        if avg1:
            word_l2_dist = torch.mean(torch.pow(self.word_emb - self.word_emb_cache, 2))
            feat_l2_dist = torch.mean(torch.pow(self.feature_emb - self.feature_emb_cache, 2))
        else:
            word_l2_dist = torch.sum(torch.pow(self.word_emb - self.word_emb_cache, 2))
            feat_l2_dist = torch.sum(torch.pow(self.feature_emb - self.feature_emb_cache, 2))
        # z = F.relu(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0)) - self.feature_relu_bias)
        # b = Bernoulli(F.sigmoid(torch.matmul(self.word_emb, torch.transpose(self.feature_emb, 1, 0))))
        # z = b.sample()
        z = self.compute_z()
        z_sum = z.sum()
        # z_gt_0 = torch.zeros_like(z)
        z_gt_0 = torch.sign(z)
        z_gt_0_sum = z_gt_0.sum()
        if avg2:
            z_sparse = z_sum.sum()
        else:
            z_sparse = z_sum.sum(dim=1).mean()

        loss = lambda1 * word_l2_dist + lambda1 * feat_l2_dist + lambda2 * z_sparse
        logging.log_every_n(logging.INFO, 'loss %s | word %s | feat %s | z %s | z_sum %s | z > 0 %s',
                            100, loss.cpu().detach().numpy(), word_l2_dist.cpu().detach().numpy(), feat_l2_dist.cpu().detach().numpy(), z_sparse.cpu().detach().numpy(), z_sum.cpu().detach().numpy(), z_gt_0_sum.cpu().detach().numpy())
        # logging.info('z.sum() = %s, (z > 0).sum() = %s bias = %s', z.sum(), (z > 0).sum(), self.feature_relu_bias)
        return loss

    def forward(self, input, hidden, return_h=False):
        emb = embedded_dropout(self.input_layer(), input, dropout=self.dropoute if self.training else 0)
        #emb = self.idrop(emb)

        emb = self.lockdrop(emb, self.dropouti)

        raw_output = emb
        new_hidden = []
        #raw_output, hidden = self.rnn(emb, hidden)
        raw_outputs = []
        outputs = []
        for l, rnn in enumerate(self.rnns):
            current_input = raw_output
            raw_output, new_h = rnn(raw_output, hidden[l])
            new_hidden.append(new_h)
            raw_outputs.append(raw_output)
            if l != self.nlayers - 1:
                #self.hdrop(raw_output)
                raw_output = self.lockdrop(raw_output, self.dropouth)
                outputs.append(raw_output)
        hidden = new_hidden

        output = self.lockdrop(raw_output, self.dropout)
        outputs.append(output)

        result = output.view(output.size(0)*output.size(1), output.size(2))
        if return_h:
            return result, hidden, raw_outputs, outputs
        return result, hidden

    def init_hidden(self, bsz):
        weight = next(self.parameters()).data
        if self.rnn_type == 'LSTM':
            return [(weight.new(1, bsz, self.nhid if l != self.nlayers - 1 else (self.ninp if self.tie_weights else self.nhid)).zero_(),
                    weight.new(1, bsz, self.nhid if l != self.nlayers - 1 else (self.ninp if self.tie_weights else self.nhid)).zero_())
                    for l in range(self.nlayers)]
        elif self.rnn_type == 'QRNN' or self.rnn_type == 'GRU':
            return [weight.new(1, bsz, self.nhid if l != self.nlayers - 1 else (self.ninp if self.tie_weights else self.nhid)).zero_()
                    for l in range(self.nlayers)]


#coding=utf-8

import xlwt
# 创建一个Workbook对象，这就相当于创建了一个Excel文件
book = xlwt.Workbook(encoding='utf-8',style_compression=0)
'''
Workbook类初始化时有encoding和style_compression参数
encoding:设置字符编码，一般要这样设置：w = Workbook(encoding='utf-8')，就可以在excel中输出中文了。
默认是ascii。当然要记得在文件头部添加：
#!/usr/bin/env python
# -*- coding: utf-8 -*-
style_compression:表示是否压缩，不常用。
'''
sheet = book.add_sheet('test',cell_overwrite_ok=True)
# 其中的test是这张表的名字,cell_overwrite_ok，表示是否可以覆盖单元格，其实是Worksheet实例化的一个参数，默认值是False
#像test表中添加数据
sheet.write(0,0,'EnglishName')
sheet.write(1,0,'Marcovaldo')
txt1 = '中文名字'
sheet.write(0,1,txt1.decode('utf-8'))
txt2 = '马可波罗'
sheet.write(1,1,txt2.decode('utf-8'))

book.save(r'test1.xls')


import cv2
import numpy as np

nomeArquivo = input("Informe o nome do arquivo: ")

imagem = cv2.imread(nomeArquivo)

if imagem is None:
	print("Nome da imagem incorreto\n")

else:

	print("tamanho da imagem" , imagem.shape)
	tamanho = imagem.shape
	tamX = tamanho[1]
	tamY = tamanho[0]
	cv2.imshow('aberta', imagem)
	print(imagem)

	print(imagem[10,10,0])

	print(imagem[10,10,1])

	print(imagem[10,10,2])
	cv2.waitKey(0)
	cv2.destroyAllWindows()
	cv2.imwrite("saida"+ext, imagem)

	#stri = "Atenção chegou chatuba, hein Atenção chegou chatuba, hein Vâmo esculachá, hein Máquina de sexo Eu transo igual a um animal A Chatuba de Mesquita Do bonde sexo anal Moleque playboy Funkeiro sexo anal A Chatuba de Mesquita Come as mina de geral"


import pandas as pd

import requests

import re
import math
import random
import time
import sys, urllib

# 商品字段列表
products_columns = ['itemid', 'itemname', 'shopid', 'shopname', 'area', 'areaname',
                    'author', 'press', 'price', 'binding', 'bindingname', 'pubdate', 'quality', 'qualityname',
                    'bigimgurl', 'smallimgurl', 'biztype', 'catid', 'class', 'importantdesc', 'isrelatedisbn',
                    'nickname', 'addtime', 'newaddtime', 'updatetime', 'years', 'years2', 'yearsgroup']

# 图书条目字段列表
items_columns = ['bookid', 'bookname', 'author', 'binding', 'bindingname', 'press',
                 'price', 'prodnum', 'newminprice', 'newprodnum', 'oldminprice', 'oldprodnum',
                'pubdate', 'qualityname', 'bigimgurl', 'smallimgurl', 'subtitle', 'updatetime']

# 获取搜索结果函数
def search(key, unit='product', status=0, mode='isfuzzy', order=0, page=1, **kwargs):
    '''
        根据关键词搜索孔夫子旧书网所有商品
        @param key: search keywords, str
        @param unit: commodity units, str, default 'product'
        @param status: product status, int, default 0
        @param mode: search mode, str, default 'isfuzzy'
        @param order: sorting method, int, default 0
        @param page: page num, int, default=1
        @param kwargs: other conditions, Dict
        @return result: search results, Dict
    '''
    encode_key = urllib.parse.quote(key)

    # 搜索条件
    search_conditions = 'select=0&' + 'key=' + encode_key + '&status=' + str(status)
    for key, value in kwargs.items():
        value = value.encode('unicode_escape').decode()
        pattern = re.compile(r'\\u')
        encode_value  = re.sub(pattern, 'k', value)
        search_conditions += '&' + key
        if key=='author' or key=='press':
            search_conditions += '=h' + str(encode_value)
        else:
            search_conditions += '=' + str(encode_value)
    if unit=='product':
        search_conditions += '&' + mode + '=1'
    search_conditions += '&order=' + str(order)
    if page != 1:
        search_conditions += '&pagenum=' + str(page)

    #  Request URL
    request_url = 'http://search.kongfz.com/' + unit + '_result/?' + search_conditions + '&type=1' + '&ajaxdata=1' + '&_=' + str(round(time.time() * 1000))

    # Request Headers
    my_headers = {
        'Host': 'search.kongfz.com',
        'Referer': 'http://search.kongfz.com/' + unit + '_result/?' + search_conditions,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest',
    }

    res = requests.post(url=request_url, headers = my_headers)
    res.raise_for_status()
    res.encoding = 'utf-8'

    # 得到包含搜索结果的字典
    result = res.json()
    return result

# 解析商品信息函数
def getPageInfo(unit, product_list, columns):
    '''
        对一个网页的商品信息进行解析，返回结果列表
        @param unit: commodity units, str, default 'product'
        @param product_list: product list, List
        @param columns: columns list, List
        @return page_info_list: result list, List
    '''
    page_info_list = []

    for item in product_list:
        product_info = []
        for col in columns:
            try:
                product_info.append(item[col])
            except:
                product_info.append(None)
        if unit=='product':
            product_info.append('http://book.kongfz.com/' + item['shopid'] + '/' + item['itemid'] + '/')
        elif unit=='item':
            product_info.append('http://item.kongfz.com/book/' + item['bookid'] + '.html')
        page_info_list.append(product_info)

    return page_info_list

# 爬取搜索结果列表数据函数
def kongfzSearchSpider(key, unit='product', status=0, mode='isfuzzy', order=0, page=1, **kwargs):
    '''
        爬取孔夫子商品搜索结果列表数据，最多返回 5000 条搜索结果
        @param key: search keywords, str
        @param unit: commodity units, str, default 'product'
        @param status: product status, int, default 0;
        @param mode: search mode, str, default 'isfuzzy'
        @param order: sorting method, int, default 0
        @param page: page num, int, default=1
        @param kwargs: other conditions, Dict
    '''
    # 先爬取第一页，得到搜索结果的总记录数和总页数
    result_dict = search(key, unit, status, mode, order, page=1, **kwargs)
    total_found = result_dict['other']['total_found'] #获取总记录数
    page_num = result_dict['other']['page_count'] #获取总页数
    print('商品总数：{0}，总页数：{1}'.format(total_found, page_num))
    time.sleep(30)

    if unit=='product':
        columns = products_columns
    elif unit=='item':
        columns = items_columns

    # 对每个网页读取JSON, 获取每页数据
    total_info = []
    for n in range(1, page_num+1):
        result_dict = search(key, unit, status, mode, order, page=n, **kwargs)
        item_list = result_dict['data']['itemList']
        page_info = getPageInfo(unit, item_list, columns)
        total_info += page_info
        print('第 {0}/{1} 页爬取完成'.format(n, page_num))
        time.sleep(random.randint(20, 40))

    #将所有数据转化为 DataFrame再输出
    columns.append('detail_url')
    df = pd.DataFrame(data=total_info, columns=columns)
    data_output = 'output\\' + key + '_' + str(round(time.time())) + '.csv'
    df.to_csv(data_output, index = False)
    print('爬虫结束')
    return df


from django.db import models

class PostCategory(models.Model):
    title = models.CharField(
        max_length=255,
        verbose_name='Название'
    )

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'Категория постов'
        verbose_name_plural = 'Категории постов'


import sys
#from PyQt4.QtWidgets import *
#from PyQt4.QtCore import *
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtWidgets, QtGui
import numpy as np
import cv2
import math
import os

VERSION = (0, 2, 0)

class ControlWindow(QtWidgets.QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.cap = None
        self.filename=None
        self.magnification=1

        font=QtGui.QFont()
        font.setBold(True)

        self.resize(500, 1000)
        self.setWindowTitle('Open Field analysis: Activity')

        layout = QtWidgets.QGridLayout(self)
        self.setLayout(layout)

        self.LableMag = QtWidgets.QLineEdit(self)
        self.LableMag.setEnabled(False)
        self.LableMag.setGeometry(QtCore.QRect(800, 30, 80, 20))
        self.LableMag.setFrame(False)
        self.LableMag.setText("Video mag.:")

        self.videoSize = QtWidgets.QComboBox(self)
        self.videoSize.addItem("1X")
        self.videoSize.addItem("1.5X")
        self.videoSize.addItem("2X")
        self.videoSize.addItem("3X")
        self.videoSize.addItem("4X")
        self.videoSize.setCurrentIndex(0)
        self.videoSize.setEnabled(True)
        self.videoSize.activated.connect(self.magnific)
        self.videoSize.setGeometry(QtCore.QRect(675, 30, 50, 20))

        self.LablePath = QtWidgets.QLineEdit(self)
        self.LablePath.setEnabled(False)
        self.LablePath.setGeometry(QtCore.QRect(90, 10, 641, 20))
        self.LablePath.setFrame(False)

        self.open_button = QtWidgets.QPushButton(self)
        self.open_button.setText("Open Video")
        self.open_button.clicked.connect(self.getfile)
        self.open_button.setGeometry(QtCore.QRect(9, 9, 75, 23))

        self.save_button = QtWidgets.QPushButton(self)
        self.save_button.setText("Save data")
        self.save_button.clicked.connect(self.handleSave)
        self.save_button.setGeometry(QtCore.QRect(850, 450, 80, 30))
        self.save_button.setEnabled(False)

        self.play_button = QtWidgets.QPushButton(self)
        self.play_button.setText("Analyze")
        self.play_button.clicked.connect(self.AnalyzeBtn)
        self.play_button.setGeometry(QtCore.QRect(760, 450, 80, 30))
        self.play_button.setEnabled(False)

        self.roi_button = QtWidgets.QPushButton(self)
        self.roi_button.setText("Save Roi")
        self.roi_button.clicked.connect(self.roi_box)
        self.roi_button.setGeometry(QtCore.QRect(670, 450, 80, 30))

        self.pg2_label=QtWidgets.QLineEdit(self)
        self.pg2_label.setGeometry(QtCore.QRect(650, 10, 320, 20))
        self.pg2_label.setFrame(False)
        self.pg2_label.setEnabled(False)
        self.pg2_label.setText("Tracking:")
        self.pg2_label.setFont(font)

        self.pg2 = pg.GraphicsLayoutWidget(self)
        self.pg2.setGeometry(QtCore.QRect(650, 40, 280, 200))
        self.pg2.setBackground(None)
        self.roi2= pg.RectROI([200, 200], [200, 200], pen=(0,9),
                              movable=False,centered=True, sideScalers=False)
        self.w1=self.pg2.addPlot()
        self.plot=pg.PlotDataItem(size=3,connect="all", symbolSize=3)
        self.w1.invertY()
        self.w1.addItem(self.plot)
        self.w1.addItem(self.roi2)
        self.roi3=  pg.RectROI([200, 200], [200, 200], pen=(2,9),
                              movable=False,centered=True, sideScalers=False)
        self.w1.addItem(self.roi3)

        self.Options_label=QtWidgets.QLineEdit(self)
        self.Options_label.setGeometry(QtCore.QRect(670, 270, 320, 20))
        self.Options_label.setFrame(False)
        self.Options_label.setEnabled(False)
        self.Options_label.setText("Options:")
        self.Options_label.setFont(font)

        self.proBar_label=QtWidgets.QLineEdit(self)
        self.proBar_label.setGeometry(QtCore.QRect(670, 500, 320, 20))
        self.proBar_label.setFrame(False)
        self.proBar_label.setEnabled(False)
        self.proBar_label.setText("Progress:")
        self.proBar=QtWidgets.QProgressBar(self)
        self.proBar.setGeometry(QtCore.QRect(670, 520, 280, 20))

        self.sl = QtWidgets.QSlider(self)
        self.sl.setOrientation(QtCore.Qt.Horizontal)
        self.sl.setMinimum(0)
        self.sl.setMaximum(255)
        self.sl.setValue(200)
        self.sl.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.sl.setTickInterval(10)
        self.sl.setGeometry(QtCore.QRect(750, 340, 180, 20))
        self.sl.valueChanged.connect(self.selectionchange)
        self.sl.setEnabled(False)

        self.sl_brigth = QtWidgets.QSlider(self)
        self.sl_brigth.setOrientation(QtCore.Qt.Horizontal)
        self.sl_brigth.setMinimum(0)
        self.sl_brigth.setMaximum(50)
        self.sl_brigth.setValue(10)
        self.sl_brigth.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.sl_brigth.setTickInterval(10)
        self.sl_brigth.valueChanged.connect(self.selectionchange)
        self.sl_brigth.setGeometry(QtCore.QRect(750, 370, 180, 20))

        self.sl_rotation = QtWidgets.QSlider(self)
        self.sl_rotation.setOrientation(QtCore.Qt.Horizontal)
        self.sl_rotation.setMinimum(-180)
        self.sl_rotation.setMaximum(180)
        self.sl_rotation.setValue(0)
        self.sl_rotation.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.sl_rotation.setTickInterval(20)
        self.sl_rotation.valueChanged.connect(self.selectionchange)
        self.sl_rotation.setGeometry(QtCore.QRect(750, 400, 180, 20))

        self.Inner_label = QtWidgets.QLineEdit(self)
        self.Inner_label.setEnabled(False)
        self.Inner_label.setGeometry(QtCore.QRect(670, 230, 80, 20))
        self.Inner_label.setFrame(False)
        self.Inner_label.setText("Inner box (%):")

        self.Inner = QtWidgets.QLineEdit(self)
        self.Inner.setEnabled(True)
        self.Inner.setText("45")
        self.Inner.setGeometry(QtCore.QRect(760, 230, 40, 20))
        self.Inner.setFrame(True)

        self.BoxW_label = QtWidgets.QLineEdit(self)
        self.BoxW_label.setEnabled(False)
        self.BoxW_label.setGeometry(QtCore.QRect(690, 290, 80, 20))
        self.BoxW_label.setFrame(False)
        self.BoxW_label.setText("Width (cm):")

        self.BoxW = QtWidgets.QLineEdit(self)
        self.BoxW.setEnabled(True)
        self.BoxW.setText("80")
        self.BoxW.setGeometry(QtCore.QRect(760, 290, 40, 20))
        self.BoxW.setFrame(True)

        self.BoxL_label = QtWidgets.QLineEdit(self)
        self.BoxL_label.setEnabled(False)
        self.BoxL_label.setGeometry(QtCore.QRect(830, 290, 80, 20))
        self.BoxL_label.setFrame(False)
        self.BoxL_label.setText("Long (cm):")

        self.BoxL = QtWidgets.QLineEdit(self)
        self.BoxL.setEnabled(True)
        self.BoxL.setText("100")
        self.BoxL.setGeometry(QtCore.QRect(895, 290, 40, 20))
        self.BoxL.setFrame(True)

        self.thresh_label = QtWidgets.QLineEdit(self)
        self.thresh_label.setEnabled(False)
        self.thresh_label.setGeometry(QtCore.QRect(670, 340, 80, 20))
        self.thresh_label.setFrame(False)
        self.thresh_label.setText("Set threshold:")

        self.bright_label = QtWidgets.QLineEdit(self)
        self.bright_label.setEnabled(False)
        self.bright_label.setGeometry(QtCore.QRect(670, 370, 80, 20))
        self.bright_label.setFrame(False)
        self.bright_label.setText("Set brightness:")

        self.rotation_label = QtWidgets.QLineEdit(self)
        self.rotation_label.setEnabled(False)
        self.rotation_label.setGeometry(QtCore.QRect(670, 400, 80, 20))
        self.rotation_label.setFrame(False)
        self.rotation_label.setText("Rotate image:")

        self.btn_refresh= QtWidgets.QPushButton(self)
        self.btn_refresh.setText("Live")
        self.btn_refresh.clicked.connect(self.Live)
        self.btn_refresh.setGeometry(QtCore.QRect(850, 230, 80, 23))

        layout.addWidget(self.open_button, 0,0)
        layout.addWidget(self.LableMag, 0,1)
        layout.addWidget(self.videoSize, 0,2)
        layout.addWidget(self.LablePath, 1,0)
        layout.addWidget(self.pg2_label, 2,0)
        layout.addWidget(self.pg2, 3,0,3,3)
        layout.addWidget(self.btn_refresh, 2,2)
        layout.addWidget(self.Options_label, 7,0)
        layout.addWidget(self.Inner_label, 8,1)
        layout.addWidget(self.Inner, 8,2)
        layout.addWidget(self.BoxW_label, 9,1)
        layout.addWidget(self.BoxW, 9,2)
        layout.addWidget(self.BoxL_label, 10,1)
        layout.addWidget(self.BoxL, 10,2)
        layout.addWidget(self.thresh_label, 12,0)
        layout.addWidget(self.sl, 12,1,1,2)
        layout.addWidget(self.bright_label, 13,0)
        layout.addWidget(self.sl_brigth, 13,1,1,2)
        layout.addWidget(self.rotation_label, 14,0)
        layout.addWidget(self.sl_rotation, 14,1,1,2)
        layout.addWidget(self.roi_button, 16,0)
        layout.addWidget(self.play_button, 16,1)
        layout.addWidget(self.save_button, 16,2)
        layout.addWidget(self.proBar_label, 18,0)
        layout.addWidget(self.proBar, 18,1,1,2)

        self.show()

    def startCapture(self):
        if not self.cap:
            if self.filename:
                self.cap = cv2.VideoCapture(self.filename)

                if not self.cap.isOpened():
                    print("could not open: %s" % self.filename)
                    self.getfile()
                    return

                self.length = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
                self.fps=self.cap.get(cv2.CAP_PROP_FPS)
                self.cap.set(cv2.CAP_PROP_FPS,self.fps*4)
                self.proBar.setMinimum(1)
                self.proBar.setMaximum(self.length)
                self.proBar.setValue(0)
                self.videoFrame=videoWindow(500,500, window=self)
                self.videoFrame.sl_frame.setMaximum(self.length - 1)
                self.frame_end=self.length
                self.frame_start=1
                duration=int((self.frame_end-self.frame_start)/self.fps/60)
                frames=str(self.frame_start)+"/"+str(self.frame_end)+" ("+str(duration)+" min)"
                self.videoFrame.Lableframe.setText(frames)

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.nextFrameSlot)

        self.valueX=[]
        self.valueY=[]
        self.valueNframe=[]
        self.plot.setData(x=self.valueX,y=self.valueY)

        self.t_value=self.sl.value()
        self.roi_box()

    def endCapture(self):
        self.cap.release()
        self.cap = None

    def magnific(self):
        if self.videoSize.currentText()=='1X':self.magnification=1
        if self.videoSize.currentText()=='1.5X':self.magnification=1.5
        if self.videoSize.currentText()=='2X':self.magnification=2
        if self.videoSize.currentText()=='3X':self.magnification=3
        if self.videoSize.currentText()=='4X':self.magnification=4
        self.selectionchange()

    def getfile(self):
        if self.cap:
            self.endCapture()

        filename = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file',
                        'c:\\',"Video files (*.mp4)")[0]
        if os.path.exists(filename):
            self.filename = os.path.abspath(filename)
        else:
            return

        self.startCapture()
        self.LablePath.setText(self.filename)
        self.play_button.setEnabled(False)
        self.save_button.setEnabled(False)
        self.sl.setEnabled(False)
        self.videoFrame.sl_frame.setEnabled(False)

        self.sl_rotation.setValue(0)
        self.sl.setValue(200)
        self.videoFrame.sl_frame.setValue(1)
        self.sl_brigth.setValue(10)

    def Live(self):
        if (self.btn_refresh.text()=="No live"):
            self.btn_refresh.setText("Live")
        else:
            self.btn_refresh.setText("No live")

    def adjust_gamma(self, image, gamma):
        if gamma <= 0:
            gamma = .1

        invGamma = 1.0 / gamma

        table = np.array([((i / 255.0) ** invGamma) * 255
            for i in np.arange(0, 256)]).astype("uint8")

        return cv2.LUT(image, table)

    def selectionchange(self):
        self.cap.set(cv2.CAP_PROP_POS_FRAMES,self.videoFrame.sl_frame.value())
        ret, frame = self.cap.read()

        frame= self.adjust_gamma(frame, gamma=float(self.sl_brigth.value())/10)
        frame=cv2.resize(frame,None,fx=self.magnification, fy=self.magnification, interpolation = cv2.INTER_LINEAR)

        (h, w) = frame.shape[:2]
        center = (w / 2, h / 2)
        M = cv2.getRotationMatrix2D(center, self.sl_rotation.value(), 1.0)
        frame = cv2.warpAffine(frame, M, (w, h))

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        blur = cv2.GaussianBlur(gray, (41, 41), 0)

        box_img=np.zeros((h,w), np.uint8)
        cv2.fillConvexPoly(box_img, self.pts, 1)

        blur=cv2.bitwise_and(blur, blur, mask=box_img)
        t = cv2.threshold(blur,self.t_value, 255, cv2.THRESH_BINARY)[1]
        thresh = cv2.dilate(t, None, iterations=2)
        cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                                     cv2.CHAIN_APPROX_SIMPLE)
        if cnts:
            areas = [cv2.contourArea(c) for c in cnts]
            max_index = np.argmax(areas)
            cnt=cnts[max_index]

            M = cv2.moments(cnt)
            cx = int(M['m10']/M['m00'])
            cy = int(M['m01']/M['m00'])
            cv2.circle(frame, (cx,cy), 5, (255,0,0), -1)
            cv2.drawContours(frame, cnt, -1, (0,255,0), 3)

        img = QtWidgets.QImage(frame, frame.shape[1], frame.shape[0],QtWidgets.QImage.Format_RGB888)
        pix = QtWidgets.QPixmap.fromImage(img)
        self.videoFrame.video_frame.setPixmap(pix)
        #self.video_frame.setPixmap(pix)

        self.valueX=[]
        self.valueY=[]
        self.valueNframe=[]
        self.plot.setData(x=self.valueX,y=self.valueY)
        self.t_value=self.sl.value()
        self.proBar.setValue(self.videoFrame.sl_frame.value())
        self.frame_start=self.videoFrame.sl_frame.value()
        duration=int((self.frame_end-self.frame_start)/self.fps/60)
        frames=str(self.frame_start)+"/"+str(self.frame_end)+" ("+str(duration)+" min)"
        self.videoFrame.Lableframe.setText(frames)

    def nextFrameSlot(self):
            nframe = self.proBar.value()
            self.cap.set(cv2.CAP_PROP_POS_FRAMES,nframe)
            grabbed, frame = self.cap.read()

            if not grabbed:
                self.AnalyzeBtn()
                self.proBar.setValue(self.length)
                self.btn_refresh.setText("Live")
                self.plot.setData(x=self.valueX,y=self.valueY)

            frame= self.adjust_gamma(frame, gamma=float(self.sl_brigth.value())/10)
            frame=cv2.resize(frame,None,fx=self.magnification, fy=self.magnification, interpolation = cv2.INTER_LINEAR)

            (h, w) = frame.shape[:2]
            center = (w / 2, h / 2)
            M = cv2.getRotationMatrix2D(center, self.sl_rotation.value(), 1.0)
            frame = cv2.warpAffine(frame, M, (w, h))
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            blur = cv2.GaussianBlur(gray, (41, 41), 0)

            box_img=np.zeros((h,w), np.uint8)
            cv2.fillConvexPoly(box_img, self.pts, 1)

            blur=cv2.bitwise_and(blur, blur, mask=box_img)
            t = cv2.threshold(blur,self.t_value, 255, cv2.THRESH_BINARY)[1]
            thresh = cv2.dilate(t, None, iterations=2)
            cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                                         cv2.CHAIN_APPROX_SIMPLE)
            if cnts:
                areas = [cv2.contourArea(c) for c in cnts]
                max_index = np.argmax(areas)
                cnt=cnts[max_index]

                M = cv2.moments(cnt)
                cx = int(M['m10']/M['m00'])
                cy = int(M['m01']/M['m00'])
                cv2.circle(frame, (cx,cy), 5, (255,0,0), -1)

                self.valueX.append(cx-self.Roi_points1.x())
                self.valueY.append(cy-self.Roi_points1.y())
                self.valueNframe.append(nframe+10)

            if self.btn_refresh.text() == "Live":
                self.plot.setData(x=self.valueX,y=self.valueY)
                img = QtWidgets.QImage(frame, frame.shape[1], frame.shape[0], QtWidgets.QImage.Format_RGB888)
                pix = QtWidgets.QPixmap.fromImage(img)
                self.videoFrame.video_frame.setPixmap(pix)
                self.videoFrame.sl_frame.setValue(nframe)

            if nframe < (self.frame_end - 10):
                self.proBar.setValue(nframe + 10)
            else:
                self.proBar.setValue(self.frame_end)
                self.AnalyzeBtn()

    def SlideFrame(self):
        if self.play_button.text() == "Analyze":
            self.selectionchange()

    def start(self):
        self.timer.start()

    def roi_box(self):

        self.Roi_points=self.videoFrame.roi.getSceneHandlePositions()

        self.Roi_points1=self.Roi_points[0][1]
        self.Roi_points1=self.Roi_points1.toPoint()
        self.Roi_points2=self.Roi_points[1][1]
        self.Roi_points2=self.Roi_points2.toPoint()
        self.Roi_points3=self.Roi_points[2][1]
        self.Roi_points3=self.Roi_points3.toPoint()
        self.Roi_points4=self.Roi_points[3][1]
        self.Roi_points4=self.Roi_points4.toPoint()

        self.pts = np.array([[self.Roi_points1.x(),self.Roi_points1.y()],
                              [self.Roi_points2.x(),self.Roi_points2.y()],
                               [self.Roi_points3.x(),self.Roi_points3.y()],
                                [self.Roi_points4.x(),self.Roi_points4.y()]], np.int32)
        self.pts = self.pts.reshape((-1,1,2))
        boxPixels_Y=math.sqrt((self.Roi_points1.x() - self.Roi_points2.x())**2 + (self.Roi_points1.y() - self.Roi_points2.y())**2)
        boxPixels_X=math.sqrt((self.Roi_points2.x() - self.Roi_points3.x())**2 + (self.Roi_points2.y() - self.Roi_points3.y())**2)
        self.roi2.setSize([boxPixels_X, boxPixels_Y])
        self.roi2.setPos([0,0])

        self.Innerboxdimension=float(self.Inner.text())
        self.size_x=self.roi2.size()[0]*(self.Innerboxdimension/100)
        self.size_y=self.roi2.size()[1]*(self.Innerboxdimension/100)
        self.pos_x=self.roi2.size()[0]*0.5-self.size_x*0.5
        self.pos_y=self.roi2.size()[1]*0.5-self.size_y*0.5
        self.roi3.setPos([self.pos_x, self.pos_y])
        self.roi3.setSize([self.size_x, self.size_y])
        self.roi2.setEnabled(False)
        self.roi3.setEnabled(False)

        self.selectionchange()
        self.play_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.sl.setEnabled(True)
        self.videoFrame.sl_frame.setEnabled(True)

    def AnalyzeBtn(self):
        if self.play_button.text() == "Analyze":
            self.stop()
            self.play_button.setText("Stop")
            self.start()
        else:
            self.play_button.setText("Analyze")
            self.stop()

    def frameslider(self):
        self.cap.set(cv2.CAP_PROP_POS_FRAMES,self.sl_frame.value())

    def stop(self):
        self.timer.stop()

    def setEnd(self):
        self.frame_end=self.videoFrame.sl_frame.value()
        duration=int((self.frame_end-self.frame_start)/self.fps/60)
        frames=str(self.frame_start)+"/"+str(self.frame_end)+" ("+str(duration)+" min)"
        self.videoFrame.Lableframe.setText(frames)
        self.proBar.setMaximum(self.frame_end)

    def Summary(self):
        self.distance=0
        self.Inner_distance=0
        self.Inner_frames=0
        self.duration=(self.frame_end-self.frame_start)/self.fps
        boxPixels_Y=math.sqrt((self.Roi_points1.x() - self.Roi_points2.x())**2 + (self.Roi_points1.y() - self.Roi_points2.y())**2)
        boxPixels_X=math.sqrt((self.Roi_points2.x() - self.Roi_points3.x())**2 + (self.Roi_points2.y() - self.Roi_points3.y())**2)

        if (boxPixels_X<=boxPixels_Y):
            cm_px=int(self.BoxL.text())/boxPixels_Y
        else:
            cm_px=int(self.BoxW.text())/boxPixels_Y

        roi3_xmin=self.pos_x
        roi3_xmax=self.pos_x+self.size_x
        roi3_ymin=self.pos_y
        roi3_ymax=self.pos_y+self.size_y

        for i,v in enumerate(self.valueNframe):
            if i<len(self.valueNframe)-1:
                dist = math.sqrt((self.valueX[i+1] - self.valueX[i])**2 + (self.valueY[i+1] - self.valueY[i])**2)
                self.distance=self.distance+dist
                if (self.valueX[i]>=roi3_xmin and self.valueX[i]<=roi3_xmax):
                    if (self.valueY[i]>=roi3_ymin and self.valueY[i]<=roi3_ymax):
                        self.Inner_distance=self.Inner_distance+dist
                        self.Inner_frames=self.Inner_frames+10

        self.cm_distance=self.distance*cm_px
        self.cm_Inner_distance=self.Inner_distance*cm_px
        self.Inner_time=self.Inner_frames/self.fps
        self.per_Inner_time=(self.Inner_time/self.duration)*100

    def showdialog(self):
       msg = QtWidgets.QMessageBox()
       msg.setIcon(QtWidgets.QMessageBox.Information)

       msg.setText("The files with the analysis have been created")
       msg.setWindowTitle("File Saved")
       msg.setStandardButtons(QtWidgets.QMessageBox.Ok)
       msg.exec_()

    def handleSave(self):
        self.Summary()
        s = self.filename
        end = s.find(self.filename)-4
        s[0:end]
        filename=s[0:end]
        with open(filename+".txt", "w") as text_file:
            text_file.write("Frame")
            text_file.write("\t")
            text_file.write("Raw X")
            text_file.write("\t")
            text_file.write("Raw Y")
            text_file.write("\t")
            text_file.write("X")
            text_file.write("\t")
            text_file.write("Y")
            text_file.write("\n")

            for i,v in enumerate(self.valueNframe):
                text_file.write(str(self.valueNframe[i]))
                text_file.write("\t")
                text_file.write(str(self.valueX[i]+self.Roi_points1.x()))
                text_file.write("\t")
                text_file.write(str(self.valueY[i]+self.Roi_points1.y()))
                text_file.write("\t")
                text_file.write(str(self.valueX[i]))
                text_file.write("\t")
                text_file.write(str(self.valueY[i]))
                text_file.write("\n")

        filename2=filename+"_S"
        with open(filename2+".txt", "w") as text_file:
            text_file.write("Raw Distance (px): ")
            text_file.write(str(self.distance))
            text_file.write("\n")
            text_file.write("Distance (cm): ")
            text_file.write(str(self.cm_distance))
            text_file.write("\n")
            text_file.write("Inner box dimension (%): ")
            text_file.write(str(self.Innerboxdimension))
            text_file.write("\n")
            text_file.write("Raw Inner Distance (px): ")
            text_file.write(str(self.Inner_distance))
            text_file.write("\n")
            text_file.write("Inner Distance (cm): ")
            text_file.write(str(self.cm_Inner_distance))
            text_file.write("\n")
            text_file.write("Time (s): ")
            text_file.write(str(self.duration))
            text_file.write("\n")
            text_file.write("Inner time (s): ")
            text_file.write(str(self.Inner_time))
            text_file.write("\n")
            text_file.write(" % Inner time (%): ")
            text_file.write(str(self.per_Inner_time))
        self.showdialog()

class videoWindow:
        def __init__(self, w, h, window=None):
            self.window2=QtWidgets.QWidget()
            self.window2.resize(w, h)

            layout = QtWidgets.QGridLayout()
            self.window2.setLayout(layout)

            self.sl_frame = QtWidgets.QSlider()
            self.sl_frame.setOrientation(QtCore.Qt.Horizontal)
            self.sl_frame.setMinimum(1)
            self.sl_frame.setMaximum(255)
            self.sl_frame.setValue(1)
            self.sl_frame.setTickPosition(QtWidgets.QSlider.TicksBelow)
            self.sl_frame.setTickInterval(1000)
            self.sl_frame.setGeometry(QtCore.QRect(9, 530, 640, 20))
            self.sl_frame.valueChanged.connect(window.SlideFrame)
            self.sl_frame.setEnabled(False)

            self.End_button = QtWidgets.QPushButton()
            self.End_button.setText("End")
            self.End_button.clicked.connect(window.setEnd)
            self.End_button.setGeometry(QtCore.QRect(600, 530, 50, 23))

            self.Lableframe = QtWidgets.QLineEdit()
            self.Lableframe.setEnabled(False)
            self.Lableframe.setGeometry(QtCore.QRect(419, 530, 170, 20))
            self.Lableframe.setFrame(False)

            self.video_frame=QtWidgets.QLabel()
            self.video_frame.setGeometry(QtCore.QRect(10, 40, 640, 480))
            self.video_frame.setFrameShape(QtWidgets.QFrame.Box)

            self.pg1 = pg.GraphicsView()
            self.pg1.setStyleSheet("background: transparent")
            self.pg1.setGeometry(QtCore.QRect(10, 40, 640, 480))
            self.pg1.setFrameShape(QtWidgets.QFrame.Box)
            self.pg1.setBackground(None)
            self.roi=pg.PolyLineROI([[25, 25], [25, 450], [600, 450], [600, 25]], pen=(6,9), closed=True)
            self.pg1.addItem(self.roi)
            self.roi_h=self.roi.getHandles()

            layout.addWidget(self.video_frame, 0,0)
            layout.addWidget(self.pg1, 0,0)
            layout.addWidget(self.sl_frame, 1,0)
            layout.addWidget(self.End_button, 3,0)
            layout.addWidget(self.Lableframe, 2,0)
            self.window2.show()

def main():
    app = QtWidgets.QApplication(sys.argv)
    window = ControlWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()


import pygame.font

class Buttom():
    def __init__(self, ai_settings, screen, msg):
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.width, self.height = 200, 50
        self.buttom_color = (125, 125, 125)
        self.text_color = (255, 255, 255)
        self.font = pygame.font.SysFont('ubuntu', 30)
        self.rect = pygame.Rect(0, 0, self.width, self.height)
        self.rect.center = self.screen_rect.center
        self.prep_msg(msg)

    def prep_msg(self, msg):
        self.msg_image = self.font.render(msg, True, self.text_color,
                                          self.buttom_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.center = self.rect.center

    def draw_buttom(self):
        self.screen.fill(self.buttom_color, self.rect)
        self.screen.blit(self.msg_image, self.msg_image_rect)


# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: build/bdist.macosx-10.11-intel/egg/doubanfm/views/lrc_view.py
# Compiled at: 2016-06-22 17:23:26
import logging
from main_view import Win
from threading import RLock
from doubanfm.colorset.colors import color_func
from doubanfm.dal.dal_lrc import LrcDal
logger = logging.getLogger('doubanfm')
mutex = RLock()

class Lrc(Win):
    """歌词显示界面"""

    def __init__(self, data):
        super(Lrc, self).__init__(data)
        self.lrc_offset = 0

    def set_dal(self):
        dal = LrcDal(self.data, self.lrc_offset)
        self.c = dal.c
        self.set_title(dal.title)
        self.set_suffix_selected(dal.suffix_selected)
        self.set_lines(dal.lines)
        self.set_sort_lrc_dict(dal.sort_lrc_dict)

    def display(self):
        mutex.acquire()
        try:
            self.set_dal()
            self.markline = self.find_line()
            self.make_display_lines()
            print ('\n').join(self.display_lines)
        finally:
            mutex.release()

    def find_line(self):
        u"""第一次载入时查找歌词"""
        for now_time in reversed(range(self.data.time)):
            locate = [ index for index, i in enumerate(self._sort_lrc_dict) if i[0] == now_time
                     ]
            if locate:
                return locate[0] + self.lrc_offset

        return 0

    def make_display_lines(self):
        u"""通过歌词生成屏幕需要显示的内容"""
        self.screen_height, self.screen_width = self.linesnum()
        display_lines = [
         '']
        display_lines.append(self._title + '\r')
        display_lines.append('')
        scroll_line_num = self.screen_height - 6
        for linenum in range(scroll_line_num):
            if scroll_line_num / 2 - linenum > self.markline - self.topline or linenum - scroll_line_num / 2 >= len(self._lines) - self.markline:
                display_lines.append('\r')
            else:
                line = self._lines[(self.markline - (scroll_line_num / 2 - linenum))]
                line = line.strip('\n')
                l = self.center_num(line)
                flag_num = (self.screen_width - l) / 2
                if linenum == scroll_line_num / 2:
                    i = color_func(self.c['LRC']['highlight'])(line)
                    display_lines.append(' ' * flag_num + i + '\r')
                else:
                    line = color_func(self.c['LRC']['line'])(line)
                    display_lines.append(' ' * flag_num + line + '\r')

        display_lines.append('')
        display_lines.append(self.center_suffix_selected() + '\r')
        self.display_lines = display_lines

    def center_suffix_selected(self):
        song = self.data.playingsong
        tmp = (song['title'] + song['albumtitle'] + song['artist']).replace('\\', '').strip()
        l = self.center_num(tmp)
        l += 2 if song['like'] else 0
        flag_num = (self.screen_width - l - 6) / 2
        return ' ' * flag_num + self._suffix_selected + '\r'

    def up(self):
        self.lrc_offset -= 1
        self.display()

    def down(self):
        self.lrc_offset += 1
        self.display()