#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2
import numpy as np
from scipy import ndimage
from reconocimientoPlaca import get_hog, escalar, clasificadorCaracteres
from deteccionPlaca import detectarPlaca
from Imagen import leerImagen
from imutils import contours

img = cv2.imread(r"C:\Users\xochi\OneDrive\Escritorio\UAEM\OCR2\Banco de datos\Prueba6.jpg")
#img = cv2.imread("car6.jpg")
#Esta línea regresa la placa segmentada
#placa = detectarPlaca(img)
placa = leerImagen(img)
#placa = detectarPlaca(placa)

def segmentarImagen(placa):
    placaGris = cv2.cvtColor(placa, cv2.COLOR_BGR2GRAY)
    umbral, _ = cv2.threshold(placaGris, 0, 255, cv2.THRESH_OTSU)
    mascara = np.uint8((placaGris<umbral)*255)
    num_labels, labels1,stats1,centroides = cv2.connectedComponentsWithStats(mascara, 4, cv2.CV_32S)
    valor_max_pixels = (np.max(stats1[:4][1:]))/2
    pin = np.where((stats1[:,4][1:]) > valor_max_pixels)
    pin = pin[0]+1
    mascaras = []
    mascara_final = 0
    #return stats1, pin
    #for i in range(0,len(pin)):
    #    mascara = pin[i] == labels1
    #    mascaras.append(mascara)
    #    mascara_final = mascara_final + mascaras[i]
    mascara = pin[-1] == labels1
    mascaras.append(mascara)
    mascara_final = mascara_final + mascaras[-1]
    mascarafinal2 = ndimage.binary_fill_holes(mascara_final).astype(int)
    mascarafinal2 = np.uint8(255 * mascarafinal2)
    maskObj = []
    maskConvex = []
    diferenciaArea = []

    contornos,_ = cv2.findContours(mascarafinal2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnt = contornos[0]
    hull = cv2.convexHull(cnt)
    puntosConvex = hull[:,0,:]
    m,n = mascarafinal2.shape
    aux = np.zeros((m,n))
    mascaraConvex = np.uint8(255 * cv2.fillConvexPoly(aux,puntosConvex,1))
    maskConvex.append(mascaraConvex)
    #Comparar el area del ConvexHull vs Objeto
    areaObjeto = np.sum(mascara)/255
    areaConvex = np.sum(mascaraConvex)/255
    diferenciaArea.append(np.abs(areaObjeto - areaConvex))
    maskPlaca = maskConvex[np.argmin(diferenciaArea)]
    vertices = cv2.goodFeaturesToTrack(maskPlaca, 4, 0.01, 10)

    x = vertices[:,0,0]
    #x = vertices[0]
    y = vertices[:,0,1]
    vertices = vertices[:,0,:]
    xo = np.sort(x)
    yo = np.sort(y)

    xn = np.zeros((1,4))
    yn = np.zeros((1,4))
    n = (np.max(xo)-np.min(xo))
    m = (np.max(yo)-np.min(yo))

    xn = (x == xo[2]) * n + (x == xo[3]) * n
    yn = (y == yo[2]) * m + (y == yo[3]) * m
    verticesN = np.zeros((4,2))
    verticesN[:,0] = xn
    verticesN[:,1] = yn

    vertices = np.int64(vertices)
    verticesN = np.int64(verticesN)

    h, _ = cv2.findHomography(vertices, verticesN)
    placa = cv2.warpPerspective(placa,h, (np.max(verticesN[:,0]),
                                    (np.max(verticesN[:,1]))))

    #vertices = cv2.goodFeaturesToTrack(mascara_final, 4, 0.01, 10)
    return vertices,mascarafinal2, placa, mascaraConvex

#Nueva funcion
def segmentacion2(img):
    image = img #cv2.imread('1.jpg')
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([37, 2, 0], np.uint8)
    upper = np.array([179, 255, 255], np.uint8)
    mask = cv2.inRange(hsv, lower, upper)
    #num_labels, labels1,stats1,centroides = cv2.connectedComponentsWithStats(mask, cv2.CV_32S)
    #stats_complex = stats1[2:][4:]
    # Create horizontal kernel and dilate to connect text characters
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,3))
    #kernel = np.ones((5,5),np.uint8)
    dilate = cv2.dilate(mask, kernel, iterations=5)

    # Find contours and filter using aspect ratio
    # Remove non-text contours by filling in the contour
    cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        ar = w / float(h)
        if ar < 5:
            cv2.drawContours(dilate, [c], -1, (0,255,0), -1)

    # Bitwise dilated image with mask, invert, then OCR
    result = 255 - cv2.bitwise_and(dilate, mask)
    #data = pytesseract.image_to_string(result, lang='eng',config='--psm 6')
    #print(data)
    #mascarafinal = 0
    #mascarafinal = ndimage.binary_fill_holes(result).astype(int)
    #mascarafinal = np.uint8(1 * mascarafinal)
    cv2.imshow('Mascara', mask)
    #cv2.imshow('dilate', dilate)
    #cv2.imshow('result', result)
    #cv2.imshow('mascara final', mascarafinal)
    #cv2.waitKey()
    return result

def nothing(x):
    pass

def hsv(image):
    cv2.imshow('umbral', image)
    cv2.namedWindow('image')
    cv2.createTrackbar('HMin', 'image', 0, 180, nothing)
    cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
    cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
    cv2.createTrackbar('HMax', 'image', 0, 180, nothing)
    cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
    cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

    # Set default value for Max HSV trackbars
    cv2.setTrackbarPos('HMax', 'image', 180)
    cv2.setTrackbarPos('SMax', 'image', 255)
    cv2.setTrackbarPos('VMax', 'image', 255)

    # Initialize HSV min/max values
    hMin = sMin = vMin = hMax = sMax = vMax = 0
    phMin = psMin = pvMin = phMax = psMax = pvMax = 0

    while(1):
        # Get current positions of all trackbars
        hMin = cv2.getTrackbarPos('HMin', 'image')
        sMin = cv2.getTrackbarPos('SMin', 'image')
        vMin = cv2.getTrackbarPos('VMin', 'image')
        hMax = cv2.getTrackbarPos('HMax', 'image')
        sMax = cv2.getTrackbarPos('SMax', 'image')
        vMax = cv2.getTrackbarPos('VMax', 'image')

        # Set minimum and maximum HSV values to display
        lower = np.array([hMin, sMin, vMin])
        upper = np.array([hMax, sMax, vMax])

        # Convert to HSV format and color threshold
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, lower, upper)
        result = cv2.bitwise_and(image, image, mask=mask)

        # Print if there is a change in HSV value
        if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
            print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
            phMin = hMin
            psMin = sMin
            pvMin = vMin
            phMax = hMax
            psMax = sMax
            pvMax = vMax

    # Display result image
        cv2.imshow('image', result)
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

import pytesseract

def quitarfondo(img):
    image = img #cv2.imread('image.png')
    # create grayscale
    tam_contorno = []
    gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # perform threshold
    retr , thresh = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([0, 0, 255])
    upper = np.array([179, 255, 255])
    mask = cv2.inRange(hsv, lower, upper)
    # find contours
    contours,hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # create emtpy mask
    #mask = np.zeros(image.shape[:2], dtype=image.dtype)

    # draw all contours larger than 20 on the mask
    for c in contours:
        if cv2.contourArea(c) < 500:
            x, y, w, h = cv2.boundingRect(c)
            cv2.drawContours(mask, [c], 0, (255), -1)

# apply the mask to the original image
    result = 255 - cv2.bitwise_and(image,image, mask= mask)
    #cv2.imshow("Resultadossosiso", result)
    #cv2.imshow("RRRR ", thresh)
    return result
        #if cv2.contourArea(c) > 20:
            #x, y, w, h = cv2.boundingRect(c)
            #cv2.drawContours(mask, [c], 0, (255), -1)

    """img = img #cv2.imread("py.jpg")
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    img_contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2]
    img_contours = sorted(img_contours, key=cv2.contourArea)

    for i in img_contours:

        if cv2.contourArea(i) > 100:

            break
    mask = np.zeros(img.shape[:2], np.uint8)
    cv2.drawContours(mask, [i],-1, 255, -1)
    new_img = cv2.bitwise_and(img, img, mask=mask)
    cv2.imshow("Original Image", img)
    cv2.imshow("Image with background removed", new_img)"""
    #return tam_contorno

#Comentada

def segmentacion3(img):
    image = img
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]

    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    cnts, _ = contours.sort_contours(cnts, method="left-to-right")

    ROI_number = 0
    for c in cnts:
        area = cv2.contourArea(c)
        if area > 10:
            x,y,w,h = cv2.boundingRect(c)
            ROI = 255 - image[y:y+h, x:x+w]
            cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)
            cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 1)
            ROI_number += 1
            #cv2.imshow('threshxedddd', thresh)
            #cv2.imshow('imagexdddd', image)
            #cv2.waitKey()

vertices, p1, plaquisima, mascaraConvex = segmentarImagen(placa)
placa = plaquisima
cv2.imshow("Segmentacion I", plaquisima)
placa_copia = placa.copy()

segmentacion3(placa)
#rectangulo = np.max(np.array(quitarfondo(plaquisima)))
#Easyocr
#reader = easyocr.Reader(["es"])
#resultado = reader.readtext(placa_copia)

#texto = clasificador(placa)

placaGris = cv2.cvtColor(placa, cv2.COLOR_BGR2GRAY)
umbral, _ = cv2.threshold(placaGris, 0, 255, cv2.THRESH_OTSU)

#hdeetor = cv2.cvtColor(umbralizacion_1, cv2.COLOR_BGR2HSV)
rectangulo = quitarfondo(placa)
seg2 = segmentacion2(placa) #Aqui esta la segmentacion
#hsv(placa)

_ , umbralizacion_1 = cv2.threshold(placaGris, 127, 255, cv2.THRESH_BINARY_INV+ cv2.THRESH_OTSU)

num_labelsh, labelsh,statsh,centroidesh = cv2.connectedComponentsWithStats(umbralizacion_1, 4, cv2.CV_32S)
kernelh = np.ones((5,5),np.uint8)
dilateh = cv2.dilate(umbralizacion_1, kernelh, iterations=1)
outputh = cv2.connectedComponentsWithStats(dilateh, 4, cv2.CV_32S)
cantidadObjetosh = outputh[0]
etiquetash = outputh[1]
statsh = outputh[2]
cv2.imshow("Dilatacion", dilateh)

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
#result = 255 - cv2.bitwise_and(dilate, mask)
datax = pytesseract.image_to_string(placa)

#Separar las letras de la placa con Bounding Rect
contornosh, _ = cv2.findContours(dilateh, cv2.RETR_TREE,
                                   cv2.CHAIN_APPROX_SIMPLE)
caracteresh = []
ordenh = []
placaCopiah = placa.copy()

for cnt in contornosh:
    x,y,w,h = cv2.boundingRect(cnt)
    caracteresh.append(placa[y:y+h, x:x+w,:])
    ordenh.append(x)
    cv2.rectangle(placaCopiah,(x,y),(x+w, y+h),(0,0,255),1)
    #cv2.rectangle(placaCopiah, (x,y), (x+w,y+h), (0,0,255),2)
    #cv2.imshow("Rectangulos XDDDD", placaCopiah)
#caracteresOrdenadosh = [x for _,x in sorted(zip(ordenh,caracteresh))]

mascara = np.uint8(255*(placaGris<umbral))
output = cv2.connectedComponentsWithStats(mascara, 4, cv2.CV_32S)
cantidadObjetos = output[0]
etiquetas = output[1]
stats = output[2]
stats_complex = stats[2:][4:]

"""
ret, thresh = cv2.threshold(placaGris,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# Eliminación del ruido
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

# Encuentra el área del fondo
sure_bg = cv2.dilate(opening,kernel,iterations=3)

# Encuentra el área del primer
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

# Encuentra la región desconocida (bordes)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)
# Etiquetado
ret, markers = cv2.connectedComponents(sure_fg)

# Adiciona 1 a todas las etiquetas para asegura que el fondo sea 1 en lugar de cero
markers = markers+1

# Ahora se marca la región desconocida con ceros
markers[unknown==255] = 0
markers = cv2.watershed(placa_copia,markers)
placa_copia[markers == -1] = [255,0,0]

#mascara_chida= ndimage.binary_fill_holes(markers).astype(int)
#mascara_chida = np.uint8(255 * mascara_chida)

#contornos2, _ = cv2.findContours(mascara, cv2.RETR_TREE,
                                  # cv2.CHAIN_APPROX_SIMPLE)

#cv2.drawContours(placa, contornos2, -1, (0,255,0), 3)
cv2.imshow("Contornos", placa_copia)
"""

maskConvex1 = []
diferenciaArea1 = []
ret, thresh = cv2.threshold(placaGris,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
contorno_p ,_ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contorno_p[0]
hull1 = cv2.convexHull(cnt)
puntosConvex1 = hull1[:,0,:]
m,n = thresh.shape
aux = np.zeros((m,n))
mascaraConvex1 = np.uint8(255 * cv2.fillConvexPoly(aux,puntosConvex1,1))
maskConvex1.append(mascaraConvex1)

#gris = cv2.cvtColor(imagen,cv2.COLOR_BGR2GRAY)
ret, binarizada = cv2.threshold(placaGris, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
caracteres3 = []
orden2 = []

contorno_c , jerarquia_c = cv2.findContours(binarizada, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

for casa in contorno_c:
    x,y,w,h = cv2.boundingRect(casa) #Calcula el punto de origen
    cv2.rectangle(placa_copia, (x,y), (x+w,y+h), (0,0,255),2)
    cv2.imshow("Rectangulos aproximados", placa_copia)

for c in contorno_c:
    #Calcular la precision del contorno calculado
    precision = 0.03 * cv2.arcLength(c, True) #Calcula el perimetro de la curva
    approx = cv2.approxPolyDP(c, precision, True) #Dibuja un poligono derecho
    x,y,w,h = cv2.boundingRect(approx)
    caracteres3.append(placa[y:y+h, x:x+w,:])
    orden2.append(x)
    cv2.drawContours(placa_copia, [approx], 0, (0,255,0), 3)
    cv2.rectangle(placa_copia,(x,y),(x+w, y+h),(255,0,0),1)
    cv2.imshow("Approx Poly", placa_copia)
#Quitar los dos primeros stats y rellenar los agujeros que queden de los demas objetos

#valor_mayor = np.max(stats_complex[:][5:])
#stats_c = [c for c in stats_complex if c[]]

#for s in stats_complex:

print("Soy el stat", len(stats_complex))
#prueba = []
#prueba2 = []
for i in range(0, len(stats_complex)):
    #print(stats_complex[i,4])
    #prueba.append(stats_complex[i,4])
    #prueba2.append(stats_complex[:,4].mean())
    if stats_complex[i,4] < stats_complex[:,4].mean()/len(stats_complex):
        etiquetas = etiquetas - i*(etiquetas == i)
#len(stats_complex)
mascara = np.uint8(255*(etiquetas > 0))

contornos, _ = cv2.findContours(mascara, cv2.RETR_TREE,
                                   cv2.CHAIN_APPROX_SIMPLE)
caracteres = []
orden = []
placaCopia = placa.copy()

for cnt in contornos:
    #x,y,w,h = cv2.boundingRect(cnt)
    #caracteres.append(placa[y:y+h, x:x+w,:])
    #orden.append(x)
    #cv2.rectangle(placaCopia,(x,y),(x+w, y+h),(0,0,255),1)
    #cv2.drawContours(placa_copia, [approx], 0, (0,255,0), 3)
    #cv2.imshow("Caracteres", placaCopia)
    x,y,w,h = cv2.boundingRect(cnt)
    caracteres.append(placa[y:y+h, x:x+w,:])
    orden.append(x)
    cv2.rectangle(placaCopia,(x,y),(x+w, y+h),(0,0,255),1)
    cv2.imshow("Caracteres", placaCopia)

palabrasSvm = datax
"""diccionario = {}
diccionario2 = {}
contador = 0
contadorx = 0
for i in orden:
    diccionario[contador] = i
    contador+= 1

for h in sorted(orden):
    diccionario2[contadorx] = h
    contadorx+=1

pruebita = sorted(list(np.array(zip(orden,caracteres)).all()))
#x9, y9 = zip(sorted(orden), sorted(caracteres))
#orde = set(orden)
ojala = []
ct = np.array(caracteres)
#pc = ct.argsort()
#xd = (sorted(np.all(zip(orden,caracteres))))
dar = np.array((list(zip(np.array(orden),np.array(caracteres)))))
tu = np.sort((dar[:,0]))
sepa = np.sort(list(zip(np.array(orden),np.array((caracteres)))), axis=0)
print("Soy la lista", np.sort(list(zip(np.array(orden),np.arange(126))), axis=0))
#caracteresOrdenados = [x for _,x in np.sort(list(zip(orden,caracteres)), axis=0)]
caracteresOrdenados = [x for _,x in np.sort(list(zip(np.array(orden),np.arange(126))), axis=0)]
#contador = 0
#for i,x in ((zip(orden,np.array(caracteres)))):
#    ojala.append([i,x])
#ojala = np.array(ojala).reshape(126,2)
#ojala2 = np.all(sorted(zip(ojala[:,0],ojala[:,1])))
#ojala = sorted(ojala)
#ojala = sorted(np.array(zip(ojala)).all())
#ojala0 = sorted(ojala[]).any()

x9 = sorted(orden)
w9 = sorted(np.array(caracteres).reshape((126,1))[2:])
print("Soy las dimensiones", np.array(caracteres).shape)
y9 = sorted(caracteres)
caracteresOrdenados = [x for _,x in sorted(zip(np.array(orden).any(axis=0),np.array(caracteres).all(axis=0)))]
"""
caracteresOrdenados = caracteres
#caracteresOrdenadosChidos = [x for _,x in sorted(zip(np.array(orden2).all(),np.array(caracteres3).all()))]

"""
Stats para contornos y rellenar los huecos de los stats encontrados del proxxy
"""

"""
for i in range(1, cantidadObjetos):
    if stats[i,4] < stats[:,4].mean()/10:
        etiquetas = etiquetas - i*(etiquetas == i)

mascara = np.uint8(255*(etiquetas > 0))

#Dilatacion de caracteres de la placa
kernel = np.ones((3,3), np.uint8)
mascara = np.uint8(255 * ndimage.binary_fill_holes
                   (cv2.dilate(mascara,kernel)))

#Separar las letras de la placa con Bounding Rect
contornos, _ = cv2.findContours(mascara, cv2.RETR_TREE,
                                   cv2.CHAIN_APPROX_SIMPLE)

#cnt = contornos[0]
#hull = cv2.convexHull(cnt)

caracteres = []
orden = []
placaCopia = placa.copy()

for cnt in contornos:
    x,y,w,h = cv2.boundingRect(cnt)
    caracteres.append(placa[y:y+h, x:x+w,:])
    orden.append(x)
    cv2.rectangle(placaCopia,(x,y),(x+w, y+h),(0,0,255),1)

pruebita = sorted(zip(orden,caracteres))
caracteresOrdenados = [x for _,x in sorted(zip(orden,caracteres))]

#contador = 0
#for i, k in zip(orden, caracteres):

#    contador += 1
listaaaaa = []
for x,y in sorted(zip(orden,caracteres)):
    listaaaaa.append(y)

#ccc = [x for _,x in (zip(sorted(orden),sorted(caracteres)))]
#y5 = sorted(orden)"""
#Fase de clasificacion
palabrasKnn = ""
palabrasSVM = ""
palabrasGnb = ""
palabrasrandomTree = ""
palabrasRedNeuronal = ""
hog = get_hog()
knn, SVM, gnb, randomTree = clasificadorCaracteres()
posiblesClases = ['0','1','2','3','4','5','6','7','8','9',
              'A','B','C','D','E','F','G','H','J','K',
              'L','M','N','P','Q','R','S','T','U','V',
              'W','X','Y','Z', 'a','b','c','d','e','f',
              'g','h','i','j','k','l','m','n','o','p',
              'r','s','t','u','v','x','y','z']

"""posiblesClases  = [ 'a','b','c','d','e','f',
                   'g','h','i','j','k','l','m','n','o','p',
                   'r','s','t','u','v','x','y','z']"""

posiblesClases = np.array(posiblesClases)
caracteresPlaca = []
#Prediction_CWA = np.expand_dims(posiblesClases, axis=0)
history = ""
for i in caracteresOrdenados:
    m,n,_ = i.shape
    imagenEscalada = escalar(i,m,n)
    caracteresPlaca.append(imagenEscalada)
    caracteristicasImagen = np.array(hog.compute(imagenEscalada))

    palabrasSVM += posiblesClases[SVM.predict([caracteristicasImagen.T])][0][0]

#print("El clasificador knn da como resultado: " + palabrasKnn)
print("El clasificador SVM da como resultado: " + palabrasSvm, end="")
#print("El clasificador Gaussian da como resultado: " + palabrasGnb)
#print("El clasificador Random Forest da como resultado: " + palabrasrandomTree)
#print("El clasificador Red Neuronal da como resultado: " + palabrasRedNeuronal)
#cv2.putText(img, "La placa es: " + palabrasKnn,
#            (10,300), cv2.FONT_HERSHEY_DUPLEX,0.8,(0,255,255),1)
cv2.putText(img, "La placa es: " + palabrasSvm,
            (10,200), cv2.FONT_HERSHEY_DUPLEX,0.8,(255,255,255),1)
#cv2.putText(img, "La placa es: " + palabrasGnb,
#            (10,100), cv2.FONT_HERSHEY_DUPLEX,0.8,(255,0,0),1)
#cv2.putText(img, "La placa es: " + palabrasrandomTree,
 #           (10,50), cv2.FONT_HERSHEY_DUPLEX,0.8,(0,0,255),1)
cv2.imshow("Recibo", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

f = open ('TextoRecibo.txt','w')
f.write(palabrasSvm)
f.close()


import torch
import torch.nn as nn
from modeling.sync_batchnorm.batchnorm import SynchronizedBatchNorm2d

#######################################
# main procedure
#######################################
"""
1. user defines a human SKELETON graph
2. convert the SKELETON graph into a 'kinematic_graph' with the format like {[[parent_ids], part_id, 'part_name'], ...}
3. build modules for every human part in the 'kinematic_graph'
"""

# Skeleton tree, each entry in a list corresponds to the parts at the same level in the tree
# (parrent ID, part ID, part name)
# This skeleton should be ascending order
SKELETON = [
    [(-1, 0, 'torso')],
    [(0, 1, 'face')],
    [(1, 2, 'hair')],
    [(0, 3, 'left_arm'), (0, 4, 'right_arm')],
    [(3, 5, 'left_hand'), (4, 6, 'right_hand')],
    [(0, 7, 'left_leg'), (0, 8, 'right_leg')],
    [(7, 9, 'left_feet'), (8, 10, 'right_feet')],
    [(-1, 11, 'accessory')]
]

class _Block_with_one_input(nn.Module):
    """Base block class takes one input which comes from the backbone"""

    def __init__(self, input_dim, BatchNorm):
        super(_Block_with_one_input, self).__init__()
        self.conv_block1 = nn.Sequential(nn.Conv2d(input_dim, 256, kernel_size=3, stride=1, padding=1, bias=False),
                                         BatchNorm(256),
                                         nn.ReLU(),
                                         nn.Dropout(0.5))
        self.conv_block2 = nn.Sequential(nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1, bias=False),
                                         BatchNorm(256),
                                         nn.ReLU(),
                                         nn.Dropout(0.1))
        self.conv2 = nn.Conv2d(256, 1, kernel_size=1, stride=1)
        # self.conv3 = nn.Conv2d(1, 48, 1, bias=False)
        self.conv3 = nn.Conv2d(1, 96, 1, bias=False)

        self._init_weight()

    def forward(self, x):
        # x = self.conv_block1(x)
        # x1 = self.conv_block2(x)
        # x = self.conv3(x1)
        x = self.conv_block1(x)
        x = self.conv_block2(x)
        x = self.conv2(x)
        x1 = self.conv3(x)
        return x, x1

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, SynchronizedBatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

class _Block_with_two_input(nn.Module):
    """Base block class takes two input, one from the backbone and one from the catenated parents input"""

    def __init__(self, input_dim, BatchNorm):
        super(_Block_with_two_input, self).__init__()
        self.conv_block1 = nn.Sequential(nn.Conv2d(input_dim, 256, kernel_size=3, stride=1, padding=1, bias=False),
                                         BatchNorm(256),
                                         nn.ReLU(),
                                         nn.Dropout(0.5))
        self.conv_block2 = nn.Sequential(nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1, bias=False),
                                         BatchNorm(256),
                                         nn.ReLU(),
                                         nn.Dropout(0.1))
        self.conv2 = nn.Conv2d(256, 1, kernel_size=1, stride=1)
        # self.conv3 = nn.Conv2d(1, 48, 1, bias=False)
        self.conv3 = nn.Conv2d(1, 96, 1, bias=False)

        self._init_weight()

    def forward(self, x, y):
        x = torch.cat((x, y), dim=1)
        # x = self.conv_block1(x)
        # x1 = self.conv_block2(x)
        # x = self.conv3(x1)
        x = self.conv_block1(x)
        x = self.conv_block2(x)
        x = self.conv2(x)
        x1 = self.conv3(x)
        return x, x1

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, SynchronizedBatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

# class SPL(nn.Module):
class Kinematic_graph(nn.Module):
    def __init__(self, BatchNorm):

        super(Kinematic_graph, self).__init__()
        # user input skeleton graph
        self.skeleton = SKELETON
        # kinematic graph, {[[parent_ids], part_id, 'part_name'], ...}
        self.kinematic_graph = dict()
        self._get_kinematic_graph()
        # one module for each human part in kinematic graph
        self.skeleton_blocks = dict()

        # build modules for every human part in the 'kinematic graph'
        self.torso = _Block_with_one_input(input_dim=304, BatchNorm=BatchNorm)
        self.face = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.hair = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.left_arm = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.right_arm = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.left_hand = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.right_hand = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.left_leg = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.right_leg = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.left_feet = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.right_feet = _Block_with_two_input(input_dim=400, BatchNorm=BatchNorm)
        self.accessory = _Block_with_one_input(input_dim=304, BatchNorm=BatchNorm)
        self.backgroud = _Block_with_one_input(input_dim=304, BatchNorm=BatchNorm)
        """
        for i in range(len(self.kinematic_graph)):
            if self.kinematic_graph[i][0]:
                temp_block = _Block_with_two_input(input_dim=512, BatchNorm=BatchNorm)
                self.skeleton_blocks[self.kinematic_graph[i][1]] = temp_block
            else:
                temp_block = _Block_with_one_input(input_dim=256, BatchNorm=BatchNorm)
                self.skeleton_blocks[self.kinematic_graph[i][1]] = temp_block
        """
        self._init_weight()

    def forward(self, x):
        """Build the forward pass of the kinematic graph by hand, maybe modified to an easier way in the future"""

        torso, torso_mid_level = self.torso(x)
        face, face_mid_level = self.face(x, torso_mid_level)
        hair, hair_mid_level = self.hair(x, face_mid_level)
        left_arm, left_arm_mid_level = self.left_arm(x, torso_mid_level)
        right_arm, right_arm_mid_level = self.right_arm(x, torso_mid_level)
        left_hand, left_hand_mid_level = self.left_hand(x, left_arm_mid_level)
        right_hand, right_hand_mid_level = self.right_hand(x, right_arm_mid_level)
        left_leg, left_leg_mid_level = self.left_leg(x, torso_mid_level)
        right_leg, right_leg_mid_level = self.right_leg(x, torso_mid_level)
        left_feet, left_feet_mid_level = self.left_feet(x, left_leg_mid_level)
        right_feet, right_feet_mid_level = self.right_feet(x, right_leg_mid_level)
        accessory, _ = self.accessory(x)
        background, _ = self.backgroud(x)

        """ Class IDs in occ5000 dataset, not same as the IDs in SKELETON
        background: 0
        hair: 1
        face: 2
        torso: 3
        left_arm: 4
        right_arm: 5
        left_hand: 6
        right_hand: 7
        left_leg: 8
        right_leg: 9
        left_foot: 10
        right_foot: 11
        accessory: 12
        """
        return torch.cat((background, hair, face, torso, left_arm, right_arm, left_hand, right_hand,
                          left_leg, right_leg, left_feet, right_feet, accessory), dim=1)

    def _get_kinematic_graph(self):
        """Get kinematic graph, {[[parent_ids], part_id, 'part_name'], ...}
        """
        indexed_skeleton = dict()
        for human_parts in self.skeleton:
            for human_part in human_parts:
                parent_list_ = [human_part[0]] if human_part[0] > -1 else []
                # This line makes sure the human par id is same as the list id
                indexed_skeleton[human_part[1]] = [parent_list_, human_part[1], human_part[2]]

        def get_all_parents(parent_list, parent_id, tree):
            if parent_id not in parent_list:
                parent_list.append(parent_id)
                for parent in tree[parent_id][0]:
                    get_all_parents(parent_list, parent, tree)

        # Get kinematic graph with all parent parts, {[[parent_ids], part_id, 'part_name'], ...}
        for i in range(len(indexed_skeleton)):
            human_part = indexed_skeleton[i]
            parent_list = list()
            if len(human_part[0]) > 0:
                get_all_parents(parent_list, human_part[0][0], indexed_skeleton)
            new_human_part = [parent_list, human_part[1], human_part[2]]
            self.kinematic_graph[i] = new_human_part

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                # n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                # m.weight.data.normal_(0, math.sqrt(2. / n))
                torch.nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, SynchronizedBatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

def build_kinematic_graph(BatchNorm):
    return Kinematic_graph(BatchNorm)

if __name__ == '__main__':
    # from tensorboardX import SummaryWriter
    from torch.utils.tensorboard import SummaryWriter

    batchnorm = nn.BatchNorm2d
    writer = SummaryWriter('/home/kidd/Documents/graph')
    kp = build_kinematic_graph(batchnorm)
    input = torch.randn(1, 304, 33, 33)
    writer.add_graph(kp, input)
    writer.close()
    output = kp(input)
    print(output.shape)


# The dataset that will be wrangled (and analyzd and visualizd)
# is the tweet archive of Twitter user @dog_rates, also known as
# WeRateDogs. WeRateDogs is a Twitter account that rates people's
# dogs with a humorous comment about the dog.

import pandas as pd
import numpy as np
import requests
import os
import tweepy
import simplejson as json

# Data Gathering
# Task 1:  load data from WeRateDogs Twitter archive
# in `twitter-archive-enhanced.csv`
archive_df = pd.read_csv('twitter-archive-enhanced.csv')

# Task 2: download online data (tweet image predictions)
# using Requests library from URL
url = 'https://d17h27t6h515a5.cloudfront.net/topher/2017/August/599fd2ad_image-predictions/image-predictions.tsv'
r = requests.get(url)

with open('image_predictions.tsv', mode='wb') as f:
    f.write(r.content)

image_df = pd.read_csv('image_predictions.tsv', sep='\t')

# Task 3: query the Twitter API for each tweet's JSON data
# using Python's Tweepy library and store each tweet's entire
# set of JSON data in a file called `tweet_json.txt`.

# create an API object
consumer_key = 'my_consumer_key'
consumer_secret = 'my_consumer_secret'
access_token = 'my_access_token'
access_secret = 'my_access_secret'

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)

api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)

tweet_id_list = archive_df['tweet_id']

# Using time module to record the query process
import time
start = time.time()
# query API for info
i = 0
j = 0
for tweet_id in tweet_id_list:
    try:
        status = api.get_status(tweet_id, tweet_mode='extended')
        data = status._json
        with open('tweet_json.txt', 'a') as file:
            json.dump(data, file)
            file.write('\n')
        print('Tweet ID {} data found!'.format(tweet_id))
        i += 1
    except:
        print('Tweet ID {} data not found!!!'.format(tweet_id))
        j += 1
end = time.time()
print(end-start)

# Read the file `tweet_json.txt` and extract information of interest
df_list = []
with open('tweet_json.txt') as file:
    for line in file:
        data = json.loads(line)
        tweet_id = str(data['id'])
        retweet_count = data['retweet_count']
        favorite_count = data['favorite_count']
        text = data['full_text']
        df_list.append({'tweet_id': tweet_id, 'retweet_count': retweet_count,
                            'favorite_count': favorite_count, 'text': text})

tweet_json_df = pd.DataFrame(df_list, columns = ['tweet_id', 'retweet_count', 'favorite_count', 'text'])


import mock

from nova import db
from nova import exception
from nova.objects import flavor as flavor_obj
from nova.tests.unit.objects import test_objects

fake_flavor = {
    'created_at': None,
    'updated_at': None,
    'deleted_at': None,
    'deleted': 0,
    'id': 1,
    'name': 'm1.foo',
    'memory_mb': 1024,
    'vcpus': 4,
    'root_gb': 20,
    'ephemeral_gb': 0,
    'flavorid': 'm1.foo',
    'swap': 0,
    'rxtx_factor': 1.0,
    'vcpu_weight': 1,
    'disabled': False,
    'is_public': True,
    'extra_specs': {'foo': 'bar'},
    }

class _TestFlavor(object):
    @staticmethod
    def _compare(test, db, obj):
        for field, value in db.items():
            test.assertEqual(db[field], obj[field])

    def test_get_by_id(self):
        with mock.patch.object(db, 'flavor_get') as get:
            get.return_value = fake_flavor
            flavor = flavor_obj.Flavor.get_by_id(self.context, 1)
            self._compare(self, fake_flavor, flavor)

    def test_get_by_name(self):
        with mock.patch.object(db, 'flavor_get_by_name') as get_by_name:
            get_by_name.return_value = fake_flavor
            flavor = flavor_obj.Flavor.get_by_name(self.context, 'm1.foo')
            self._compare(self, fake_flavor, flavor)

    def test_get_by_flavor_id(self):
        with mock.patch.object(db, 'flavor_get_by_flavor_id') as get_by_id:
            get_by_id.return_value = fake_flavor
            flavor = flavor_obj.Flavor.get_by_flavor_id(self.context,
                                                        'm1.foo')
            self._compare(self, fake_flavor, flavor)

    def test_add_access(self):
        elevated = self.context.elevated()
        flavor = flavor_obj.Flavor(context=elevated, flavorid='123')
        with mock.patch.object(db, 'flavor_access_add') as add:
            flavor.add_access('456')
            add.assert_called_once_with(elevated, '123', '456')

    def test_add_access_with_dirty_projects(self):
        flavor = flavor_obj.Flavor(context=self.context, projects=['1'])
        self.assertRaises(exception.ObjectActionError,
                          flavor.add_access, '2')

    def test_remove_access(self):
        elevated = self.context.elevated()
        flavor = flavor_obj.Flavor(context=elevated, flavorid='123')
        with mock.patch.object(db, 'flavor_access_remove') as remove:
            flavor.remove_access('456')
            remove.assert_called_once_with(elevated, '123', '456')

    def test_create(self):
        flavor = flavor_obj.Flavor(context=self.context)
        flavor.name = 'm1.foo'
        flavor.extra_specs = fake_flavor['extra_specs']

        with mock.patch.object(db, 'flavor_create') as create:
            create.return_value = fake_flavor
            flavor.create()

        self.assertEqual(self.context, flavor._context)
        # NOTE(danms): Orphan this to avoid lazy-loads
        flavor._context = None
        self._compare(self, fake_flavor, flavor)

    def test_create_with_projects(self):
        context = self.context.elevated()
        flavor = flavor_obj.Flavor(context=context)
        flavor.name = 'm1.foo'
        flavor.extra_specs = fake_flavor['extra_specs']
        flavor.projects = ['project-1', 'project-2']

        db_flavor = dict(fake_flavor, projects=list(flavor.projects))

        with mock.patch.multiple(db, flavor_create=mock.DEFAULT,
                                 flavor_access_get_by_flavor_id=mock.DEFAULT
                                 ) as methods:
            methods['flavor_create'].return_value = db_flavor
            methods['flavor_access_get_by_flavor_id'].return_value = [
                {'project_id': 'project-1'},
                {'project_id': 'project-2'}]
            flavor.create()
            methods['flavor_create'].assert_called_once_with(
                context,
                {'name': 'm1.foo',
                 'extra_specs': fake_flavor['extra_specs']},
                projects=['project-1', 'project-2'])

        self.assertEqual(context, flavor._context)
        # NOTE(danms): Orphan this to avoid lazy-loads
        flavor._context = None
        self._compare(self, fake_flavor, flavor)
        self.assertEqual(['project-1', 'project-2'], flavor.projects)

    def test_create_with_id(self):
        flavor = flavor_obj.Flavor(id=123)
        self.assertRaises(exception.ObjectActionError, flavor.create,
                          self.context)

    @mock.patch('nova.db.flavor_access_add')
    @mock.patch('nova.db.flavor_access_remove')
    @mock.patch('nova.db.flavor_extra_specs_delete')
    @mock.patch('nova.db.flavor_extra_specs_update_or_create')
    def test_save(self, mock_update, mock_delete, mock_remove, mock_add):
        ctxt = self.context.elevated()
        extra_specs = {'key1': 'value1', 'key2': 'value2'}
        projects = ['project-1', 'project-2']
        flavor = flavor_obj.Flavor(context=ctxt, flavorid='foo',
                                   extra_specs=extra_specs, projects=projects)
        flavor.obj_reset_changes()

        # Test deleting an extra_specs key and project
        del flavor.extra_specs['key1']
        del flavor.projects[-1]
        self.assertEqual(set(['extra_specs', 'projects']),
                         flavor.obj_what_changed())
        flavor.save()
        self.assertEqual({'key2': 'value2'}, flavor.extra_specs)
        mock_delete.assert_called_once_with(ctxt, 'foo', 'key1')
        self.assertEqual(['project-1'], flavor.projects)
        mock_remove.assert_called_once_with(ctxt, 'foo', 'project-2')

        # Test updating an extra_specs key value
        flavor.extra_specs['key2'] = 'foobar'
        self.assertEqual(set(['extra_specs']), flavor.obj_what_changed())
        flavor.save()
        self.assertEqual({'key2': 'foobar'}, flavor.extra_specs)
        mock_update.assert_called_with(ctxt, 'foo', {'key2': 'foobar'})

        # Test adding an extra_specs and project
        flavor.extra_specs['key3'] = 'value3'
        flavor.projects.append('project-3')
        self.assertEqual(set(['extra_specs', 'projects']),
                         flavor.obj_what_changed())
        flavor.save()
        self.assertEqual({'key2': 'foobar', 'key3': 'value3'},
                         flavor.extra_specs)
        mock_update.assert_called_with(ctxt, 'foo', {'key2': 'foobar',
                                                     'key3': 'value3'})
        self.assertEqual(['project-1', 'project-3'], flavor.projects)
        mock_add.assert_called_once_with(ctxt, 'foo', 'project-3')

    @mock.patch('nova.db.flavor_create')
    @mock.patch('nova.db.flavor_extra_specs_delete')
    @mock.patch('nova.db.flavor_extra_specs_update_or_create')
    def test_save_deleted_extra_specs(self, mock_update, mock_delete,
                                      mock_create):
        mock_create.return_value = dict(fake_flavor,
                                        extra_specs={'key1': 'value1'})
        ctxt = self.context.elevated()
        flavor = flavor_obj.Flavor(context=ctxt)
        flavor.flavorid = 'test'
        flavor.extra_specs = {'key1': 'value1'}
        flavor.create()
        flavor.extra_specs = {}
        flavor.save()
        mock_delete.assert_called_once_with(ctxt, flavor.flavorid,
                                            'key1')
        self.assertFalse(mock_update.called)

    def test_save_invalid_fields(self):
        flavor = flavor_obj.Flavor(id=123)
        self.assertRaises(exception.ObjectActionError, flavor.save)

    def test_destroy(self):
        flavor = flavor_obj.Flavor(context=self.context, id=123, name='foo')
        with mock.patch.object(db, 'flavor_destroy') as destroy:
            flavor.destroy()
            destroy.assert_called_once_with(self.context, flavor.name)

    def test_load_projects(self):
        flavor = flavor_obj.Flavor(context=self.context, flavorid='foo')
        with mock.patch.object(db, 'flavor_access_get_by_flavor_id') as get:
            get.return_value = [{'project_id': 'project-1'}]
            projects = flavor.projects

        self.assertEqual(['project-1'], projects)
        self.assertNotIn('projects', flavor.obj_what_changed())

    def test_load_anything_else(self):
        flavor = flavor_obj.Flavor()
        self.assertRaises(exception.ObjectActionError,
                          getattr, flavor, 'name')

class TestFlavor(test_objects._LocalTest, _TestFlavor):
    pass

class TestFlavorRemote(test_objects._RemoteTest, _TestFlavor):
    pass

class _TestFlavorList(object):
    def test_get_all(self):
        with mock.patch.object(db, 'flavor_get_all') as get_all:
            get_all.return_value = [fake_flavor]
            filters = {'min_memory_mb': 4096}
            flavors = flavor_obj.FlavorList.get_all(self.context,
                                                    inactive=False,
                                                    filters=filters,
                                                    sort_key='id',
                                                    sort_dir='asc')
            self.assertEqual(1, len(flavors))
            _TestFlavor._compare(self, fake_flavor, flavors[0])
            get_all.assert_called_once_with(self.context, inactive=False,
                                            filters=filters, sort_key='id',
                                            sort_dir='asc', limit=None,
                                            marker=None)

class TestFlavorList(test_objects._LocalTest, _TestFlavorList):
    pass

class TestFlavorListRemote(test_objects._RemoteTest, _TestFlavorList):
    pass


import numpy as np
import os
import sys
import torch

from botorch.acquisition import PosteriorMean
from botorch import fit_gpytorch_model

torch.set_default_dtype(torch.float64)

script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
project_path = script_dir[:-12]
sys.path.append(project_path)
data_folder = project_path + "/experiments/animation_data/"

from src.models.pairwise_kernel_variational_gp import PairwiseKernelVariationalGP
from src.utils import optimize_acqf_and_get_suggested_query

datapoints = np.loadtxt(data_folder + "datapoints.txt")
comparisons = np.loadtxt(data_folder + "responses.txt")
datapoints[:, 1] = (datapoints[:, 1] + 2.0) / 4.0
datapoints[:, 2] = datapoints[:, 2] / 4.0
datapoints[:, 3] = (datapoints[:, 3] - 5.0) / 20.0
datapoints[:, 4] = datapoints[:, 4] - 1.0
np.savetxt(data_folder + "datapoints_norm.txt", datapoints)
n_queries = comparisons.shape[0]
queries = []
responses = []

for i in range(n_queries):
    queries.append(datapoints[2 * i : 2 * (i + 1), :])
    responses.append(0 if comparisons[i, 0] < comparisons[i, 1] else 1)

queries = torch.tensor(queries)
responses = torch.tensor(responses)
datapoints = torch.tensor(datapoints)
test_random_points = torch.rand(size=datapoints.size())

save_surrogate = True
if save_surrogate:
    model = PairwiseKernelVariationalGP(queries, responses)
    print(queries[:5, ...])
    print(responses[:5, ...])
    print(model(datapoints).mean[:10, ...])
    print(model(test_random_points).mean[:5, ...])

    torch.save(model.aux_model.state_dict(), "animation_surrogate_state_dict2")

print(model.aux_model.state_dict())
print(e)
aux_model = PairwiseKernelVariationalGP(queries, responses, fit_aux_model_flag=False)
animation_surrogate_state_dict = torch.load("animation_surrogate_state_dict2")
aux_model.aux_model.load_state_dict(animation_surrogate_state_dict)
aux_model.aux_model(aux_model.aux_model.train_inputs[0])
aux_model.aux_model.eval()
print(aux_model(test_random_points).mean[:5, ...])

input_dim = 5
standard_bounds = torch.tensor([[0.0] * input_dim, [1.0] * input_dim])
num_restarts = 6 * input_dim
raw_samples = 180 * input_dim

post_mean_func = PosteriorMean(model=aux_model)
max_post_mean_func = optimize_acqf_and_get_suggested_query(
    acq_func=post_mean_func,
    bounds=standard_bounds,
    batch_size=1,
    num_restarts=num_restarts,
    raw_samples=raw_samples,
)
print(max_post_mean_func)
print(post_mean_func(max_post_mean_func).item())


"""
Unit tests for featurebyte.core.timedelta
"""
import pytest

from featurebyte.core.timedelta import to_timedelta
from featurebyte.enum import DBVarType
from featurebyte.query_graph.enum import NodeType
from tests.util.helper import get_node

@pytest.mark.parametrize(
    "unit",
    [
        "day",
        "hour",
        "minute",
        "second",
        "millisecond",
        "microsecond",
    ],
)
def test_to_timedelta(int_series, unit):
    """Test to_timedelta() can construct a timedelta Series"""
    timedelta_series = to_timedelta(int_series, unit=unit)
    assert timedelta_series.dtype == DBVarType.TIMEDELTA
    series_dict = timedelta_series.dict()
    assert series_dict["node_name"] == "timedelta_1"
    timedelta_node = get_node(series_dict["graph"], "timedelta_1")
    assert timedelta_node == {
        "name": "timedelta_1",
        "output_type": "series",
        "parameters": {"unit": unit},
        "type": NodeType.TIMEDELTA,
    }

def test_to_timedelta__unsupported_unit(int_series):
    """Test to_timedelta() with a non-supported time unit"""
    with pytest.raises(TypeError) as exc:
        _ = to_timedelta(int_series, unit="month")
    assert 'the value of argument "unit" must be one of' in str(exc.value)

def test_to_timedelta__not_int(float_series):
    """Test to_timedelta() rejects non-INT Series"""
    with pytest.raises(ValueError) as exc:
        _ = to_timedelta(float_series, unit="second")
    assert str(exc.value) == "to_timedelta only supports INT type series; got FLOAT"


"""
:Author: Theodor A. Dumitrescu
:Date: 03/06/20
:Version: 0.0.1
"""
from __future__ import print_function

import logging

import scanner as lex

NULLTOKEN = -1

LITERAL = 0

NOT = 30
AND = 31
OR = 32
IMP = 33
EQ = 34

LPAREN = 50
RPAREN = 51

ATOM = 1000
UNARY = 1001
BINARY = 1002

u_operators = (NOT,)
b_operators = (AND, OR, IMP, EQ,)

FIRST = (LITERAL, LPAREN, NOT, )

rules = ([
    ('SPACES', r'\s+'),

    (AND, r'and'),
    (OR, r'or'),
    (NOT, r'not'),
    (IMP, r'=>'),
    (EQ, r'<=>'),

    (LITERAL, r'[a-zA-Z][a-zA-Z0-9]*'),

    (LPAREN, r'\('),
    (RPAREN, r'\)'),

    (NULLTOKEN, r'null_token')
])

def isUnitary(op):
    return op in u_operators

def isBinary(op):
    return op in b_operators

def isOperator(op):
    return isBinary(op) or isUnitary(op)

class TokenizerException(Exception):
    pass

class ParserException(Exception):
    def __init__(self, str):
        super(Exception, self).__init__('ParserException: ' + str)

class Exp(object):
    """
    The pars tree of an expression.
    A node could be of two forms unitary or binary.
    If the operation is binary, the related information is stored in the left and right attributes.
    If the operation is unitary the related information is stored in the child attribute.
    """
    __hash__ = None

    def __init__(self, str_exp=None, kind=None, scanner=None):
        """
        Generate the tree from the tokenized expression.
        If the expression is specified then it will create an empty node.
        """
        self.kind = None
        self.name = 'undef'
        self.attr = None
        self.child = None
        self.left = None
        self.right = None
        self.code = None

        if str_exp is not None:
            logging.debug('========== EXP in init(NODE): SEXP = [' + str_exp + ']')
            scanner = lex.Scanner(rules)
            scanner.setString(str_exp)

        if kind is not None:  # create an empty node
            self.kind = kind
            return

        if scanner is None:
            raise Exception('Fatal Error: scanner not defined')

        while scanner.curToken().type in FIRST:

            if scanner.curToken().type == LITERAL:
                self.name = scanner.curToken().name
                self.code = LITERAL
                self.kind = ATOM
                scanner.move()

            elif scanner.curToken().type == LPAREN:
                scanner.move()  # skip the parentheses

                tmp = Exp(scanner=scanner)  # tree of the expression between parentheses
                self.kind = tmp.kind
                self.attr = tmp.attr
                self.name = tmp.name
                self.left = tmp.left
                self.right = tmp.right
                self.child = tmp.child

                if scanner.curToken().type != RPAREN:
                    raise ParserException("')' expected")
                scanner.move()

            elif isUnitary(scanner.curToken().type):
                self.kind = UNARY
                self.name = scanner.curToken().name
                self.code = scanner.curToken().type

                # if token_type == ATTRIB # this is for existence and foreach

                scanner.move()
                self.child = Exp(scanner=scanner)

            # the scanner has been moved to a successive token
            if scanner.curToken().type == NULLTOKEN:
                break

            # check for infix operators
            if isBinary(scanner.curToken().type):
                operator_name = scanner.curToken().name
                operator_type = scanner.curToken().type
                scanner.move()

                # move the current node to the left of the tree
                lnode = Exp(kind=self.kind)
                lnode.name = self.name
                lnode.attr = self.attr
                lnode.child = self.child
                lnode.left = self.left
                lnode.right = self.right
                lnode.code = self.code

                # this node became the handler aka the binary operator
                self.code = operator_type
                self.name = operator_name
                self.kind = BINARY
                self.left = lnode
                # lookup the second child of the operator
                self.right = Exp(scanner=scanner)

    def __str__(self):
        if self.code == LITERAL:
            return self.name
        elif self.kind == UNARY:
            return self.name + " (" + self.child.__str__() + ")"
        elif self.kind == BINARY:
            le = self.left.__str__()
            re = self.right.__str__()

            return le + ' ' + self.name + ' ' + re

if __name__ == "__main__":
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)

    # create formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # add formatter to ch
    ch.setFormatter(formatter)

    # add ch to logger
    logger.addHandler(ch)
    s = '(A <=> not B)'
    exp = Exp(str_exp=s)
    print(exp)

'''
s = lex.Scanner(rules)
s.setString('A and B')

while s.curToken().type != NULLTOKEN:
    print('TOKEN =', str(s.curToken()))
    s.getToken()
'''


import logging

import jinja2

import container
import logrotate

logger = logging.getLogger(__name__)

CHARMED_MYSQL_COMMON_DIRECTORY = "/var/snap/charmed-mysql/common"
SYSTEM_USER = "snap_daemon"
ROOT_USER = "root"

class LogRotate(logrotate.LogRotate):
    """logrotate cron configuration"""

    def __init__(self, *, container_: container.Container):
        super().__init__(container_=container_)
        self._logrotate_config = self._container.path("/etc/logrotate.d/flush_mysqlrouter_logs")
        self._cron_file = self._container.path("/etc/cron.d/flush_mysqlrouter_logs")

    def enable(self) -> None:
        logger.debug("Creating logrotate config file")

        template = jinja2.Template(self._container.path("templates/logrotate.j2").read_text())

        log_file_path = self._container.path("/var/log/mysqlrouter/mysqlrouter.log")
        rendered = template.render(
            log_file_path=str(log_file_path),
            system_user=SYSTEM_USER,
        )
        self._logrotate_config.write_text(rendered)

        logger.debug("Created logrotate config file")
        logger.debug("Adding cron job for logrotate")

        # cron needs the file to be owned by root
        self._cron_file.write_text(
            "* * * * * snap_daemon logrotate -f -s /tmp/logrotate.status /etc/logrotate.d/flush_mysqlrouter_logs\n\n",
            user=ROOT_USER,
            group=ROOT_USER,
        )

        logger.debug("Added cron job for logrotate")

    def disable(self) -> None:
        logger.debug("Removing cron job for log rotation of mysqlrouter")
        self._logrotate_config.unlink()
        self._cron_file.unlink()
        logger.debug("Removed cron job for log rotation of mysqlrouter")


from TravelingSalesmanProblem import TSP
from deap import tools, base, algorithms, creator
import array, random
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from eaSimple_withElitism import eaSimpleWithElitism

TSP_NAME = "bayg29"
tsp = TSP(TSP_NAME)

# Genetic Constants
MAX_GENERATION = 250
POPULATION = 500
P_CROSSOVER = 0.9
P_MUTATION = 0.1
HALL_OF_FAME_NUMBER = 50

# Define the fitness strategy
creator.create("FitnessMin", base.Fitness, weights=(-1.,))

# Creating the chromosome

creator.create("Individual", array.array, typecode="i", fitness=creator.FitnessMin)

toolbox = base.Toolbox()

toolbox.register("randomOrder", random.sample, range(len(tsp)), len(tsp))
toolbox.register("IndividualCreator", tools.initIterate, creator.Individual, toolbox.randomOrder)
toolbox.register("populationCreator", tools.initRepeat, list, toolbox.IndividualCreator)

def tspDistance(individual):
    return (tsp.getTotalDistance(individual),)

toolbox.register("evaluate", tspDistance)

# register three genetic operators : Select, mate, mutate

toolbox.register("select", tools.selTournament, tournsize=2)
toolbox.register("mate", tools.cxOrdered)
toolbox.register("mutate", tools.mutShuffleIndexes, indpb=1. / len(tsp))

def main():
    population = toolbox.populationCreator(n=POPULATION)
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("MIN", np.min)
    stats.register("MEAN", np.mean)
    hof = tools.HallOfFame(HALL_OF_FAME_NUMBER)

    population, logbook = eaSimpleWithElitism(population=population,
                                              toolbox=toolbox,
                                              cxpb=P_CROSSOVER,
                                              mutpb=P_MUTATION,
                                              ngen=MAX_GENERATION,
                                              halloffame=hof,
                                              stats=stats,
                                              verbose=True)

    maxFitnessValues, meanFitnessValues = logbook.select("MIN", "MEAN")
    sns.set_style("whitegrid")
    plt.plot(maxFitnessValues, color='red')
    plt.plot(meanFitnessValues, color='green')
    plt.title("Traveling Salesman Problem")
    plt.ylabel("Max/Mean Values")
    plt.xlabel("Generations")
    plt.legend(["MIN", "MEAN"])
    plt.show()

    print(f"--Best ever individual: {hof.items[0]}")
    print(f"--Best ever fitness: {hof.items[0].fitness.values[0]}")
    plot = tsp.plotData(hof.items[0])
    plot.show()

if __name__ == '__main__':
    main()


from django.test import TestCase
from decimal import Decimal
from jimi.price import fields

# All this is needed for temporary testing models
from django.conf import settings
from django.core.management import call_command
from django.db.models import loading

from models import TestModel

class CurrencyTest(TestCase):
    def test_default_currency(self):
        """Testing if default currency and __eq__() work."""
        self.currency1 = fields.Currency()
        self.currency2 = fields.Currency(fields.DEFAULT_CURRENCY)
        self.assertEqual(self.currency1, self.currency2)

    def test_init(self):
        """Testing if __init__ is sufficiently intelligent."""
        invalid = "ZZZ"
        self.assertRaisesRegexp(ValueError,
                                'Currency %s not defined.' % invalid,
                                fields.Currency,
                                invalid)
        self.assertRaisesRegexp(ValueError,
                                'Currency %s not defined.' % invalid,
                                fields.Currency,
                                code=invalid)

    def test_code_mapping(self):
        """Testing if mapping code to name works"""
        self.currency = fields.Currency()
        self.name = str(self.currency)
        self.assertEqual(self.name, fields.CURRENCIES[fields.DEFAULT_CURRENCY]["code"])

class MoneyTest(TestCase):
    def test_init_without_currency(self):
        """Testing if initialization without currency gives DEFAULT_CURRENCY."""
        self.price = fields.Money(amount=3.14)
        self.currency = fields.Currency()
        self.assertEqual(self.price.currency, self.currency)

    def test_str(self):
        pass  # TODO string conversion

    def test_equality(self):
        """Testing if == works"""
        self.price1 = fields.Money(amount=3.14, currency="USD")
        self.price2 = fields.Money(amount=3.14, currency="USD")
        self.assertEqual(self.price1, self.price2)

    def test_inequality_amount(self):
        """Testing if != works with differing amounts"""
        self.price1 = fields.Money(amount=3.14, currency="USD")
        self.price2 = fields.Money(amount=4.14, currency="USD")
        self.assertNotEqual(self.price1, self.price2)

    def test_inequality_currency(self):
        """Testing if != works with differing currencies"""
        self.price1 = fields.Money(amount=3.14, currency="USD")
        self.price2 = fields.Money(amount=3.14, currency="EUR")
        self.assertNotEqual(self.price1, self.price2)

    def test_pos(self):
        """Testing if __pos__ works"""
        amount = 100
        self.price1 = fields.Money(amount=amount)
        self.price2 = fields.Money(amount=amount)
        self.assertEqual(self.price1, +self.price2)

    def test_neg(self):
        """Testing if __neg__ works"""
        amount = 100
        self.price1 = fields.Money(amount=amount)
        self.price2 = fields.Money(amount=-amount)
        self.assertEqual(self.price1, -self.price2)

    def test_add(self):
        """Testing if __add__ works"""
        amount1 = Decimal("100.01")
        amount2 = Decimal("20000000.01")
        self.price1 = fields.Money(amount=amount1)
        self.price2 = fields.Money(amount=amount2)
        self.assertEqual(self.price1 + self.price2, fields.Money(amount1 + amount2))
        self.price3 = fields.Money()
        self.price3 += self.price1
        self.assertEqual(self.price3, self.price1)

    def test_sub(self):
        """Testing if __sub__ works"""
        amount1 = Decimal("100.01")
        amount2 = Decimal("20000000.01")
        self.price1 = fields.Money(amount=amount1)
        self.price2 = fields.Money(amount=amount2)
        self.assertEqual(self.price1 - self.price2, fields.Money(amount1 - amount2))

    def test_mul(self):
        """Testing if __mul__ works"""
        amount1 = Decimal("100.01")
        self.price1 = fields.Money(amount=amount1)
        self.assertEqual(self.price1 * 100, fields.Money(amount1 * Decimal(100)))
        self.assertEqual(100.23 * self.price1, fields.Money(amount1 * Decimal(100.23)))

    def test_div(self):
        """Testing if __div__ works"""
        amount1 = Decimal("100.01")
        self.price1 = fields.Money(amount=amount1)
        self.assertEqual(self.price1 / "100", fields.Money(amount1 / Decimal("100")))
        self.assertEqual(100.23 / self.price1, fields.Money(amount1 / Decimal(100.23)))

    def test_percentage(self):
        r"""Testing if percentage operator % works"""
        self.price = fields.Money(200)
        self.assertAlmostEqual(5 % self.price, fields.Money(amount=10))

    def test_float(self):
        """Testing if casting to float works"""
        amount = 1000000.01
        self.price = fields.Money(amount=amount)
        self.assertAlmostEqual(float(self.price), amount)

    def test_lt(self):
        """Testing if __lt__() works"""
        amount1 = Decimal("1")
        amount2 = Decimal("2")
        self.price1 = fields.Money(amount=amount1)
        self.price2 = fields.Money(amount=amount2)
        self.assertTrue(self.price1 < self.price2)

    def test_lt_different_currencies(self):
        """Testing if __lt__() works with differing currencies"""
        def run_test(price1, price2):
            return price1 < price2

        amount = Decimal("1")
        self.price1 = fields.Money(amount=amount, currency="USD")
        self.price2 = fields.Money(amount=amount, currency="EUR")
        self.assertRaisesRegexp(TypeError,
                                'Cannot compare Money with different currencies.',
                                run_test,
                                price1=self.price1, price2=self.price2)

    def test_gt(self):
        """Testing if __gt__() works"""
        amount1 = Decimal("2")
        amount2 = Decimal("1")
        self.price1 = fields.Money(amount=amount1)
        self.price2 = fields.Money(amount=amount2)
        self.assertTrue(self.price1 > self.price2)

    def test_gt_different_currencies(self):
        """Testing if __gt__() works with differing currencies"""
        def run_test(price1, price2):
            return price1 > price2

        amount = Decimal("1")
        self.price1 = fields.Money(amount=amount, currency="USD")
        self.price2 = fields.Money(amount=amount, currency="EUR")
        self.assertRaisesRegexp(TypeError,
                                'Cannot compare Money with different currencies.',
                                run_test,
                                price1=self.price1, price2=self.price2)

    def test_le(self):
        """Testing if __le__() works"""
        amount1 = Decimal("1")
        amount2 = Decimal("2")
        self.price1 = fields.Money(amount=amount1)
        self.price2 = fields.Money(amount=amount2)
        self.assertTrue(self.price1 <= self.price1)
        self.assertTrue(self.price1 <= self.price2)

    def test_ge(self):
        """Testing if __ge__() works"""
        amount1 = Decimal("2")
        amount2 = Decimal("1")
        self.price1 = fields.Money(amount=amount1)
        self.price2 = fields.Money(amount=amount2)
        self.assertTrue(self.price1 >= self.price1)
        self.assertTrue(self.price1 >= self.price2)

    def test_hash(self):
        pass  # TODO hashing

class MoneyFieldTest(TestCase):
    apps = ("jimi.price.tests",)

    def _pre_setup(self):
        # Add the models to the db.
        self._original_installed_apps = list(settings.INSTALLED_APPS)
        for app in self.apps:
            settings.INSTALLED_APPS += (app,)
        loading.cache.loaded = False
        call_command('syncdb', interactive=False, migrate=False, verbose=0)
        # Call the original method that does the fixtures etc.
        super(MoneyFieldTest, self)._pre_setup()

    def _post_teardown(self):
        # Call the original method.
        super(MoneyFieldTest, self)._post_teardown()
        # Restore the settings.
        settings.INSTALLED_APPS = self._original_installed_apps
        loading.cache.loaded = False

    def setUp(self):
        a = TestModel(ident=1, price=fields.Money(amount="11.11", currency="USD"))
        a.save()
        b = TestModel(ident=2, price=fields.Money(amount="200.02", currency="USD"))
        b.save()

    def test_filter_price(self):
#        res = TestModel.objects.get(price__gt=fields.Money(amount=100, currency="USD"))
        res = TestModel.objects.filter(ident__exact=1)
        self.assertEqual(res[0].price, fields.Money("11.11", "USD"))


import numpy as np
from scipy.stats import chisquare
import matplotlib.pyplot as plt
from lmfit import Model
from matplotlib import colors, ticker, cm

from itertools import chain
import scipy.interpolate

def gaussian(x, amp, cen, wid):
    "1-d gaussian: gaussian(x, amp, cen, wid)"
    return (amp/(np.sqrt(2*np.pi)*wid)) * np.exp(-(x-cen)**2 /(2*wid**2))

def get_normed_histo(data, bins, rang):
    hist, bin_edges = np.histogram(data, bins, range=rang)
    hist = np.divide(hist, np.sum(hist))
    return hist, bin_edges

def get_gauss_fit(hist, edges):
    gmodel = Model(gaussian)
    result = gmodel.fit(hist, x=edges[:-1], amp=1, cen=0, wid=2)
    return result

plt.style.use('./mythesis.mplstyle')
rnge = [-1.5, 1.5]
stp = 0.5
rng_x = np.linspace(rnge[0], rnge[1], 7)
xrange, yrange = np.meshgrid(rng_x, rng_x)

width_xz = np.zeros(xrange.shape).flatten()
idx = 0
dz = 0

rng_hist = [-4, 4]
for dx, dy in zip(xrange.flatten(), yrange.flatten()):
    frame = "-x_{:.1f}".format(dx) + "_y_{:.1f}".format(dz) + "_z_{:.1f}".format(dy)

    print(dx, dy, dz)
    df = np.load('output/cross_dist/dist{}.npz'.format(frame))

    dist_d = df['d']
    hist, bin_edges = get_normed_histo(dist_d, 2*20 + 1, rng_hist)
    result = get_gauss_fit(hist, bin_edges)

    # plotting individual histograms
    #plt.bar(bin_edges[:-1], hist, width=(bin_edges[1]-bin_edges[0]), label='full set')
    #plt.plot(bin_edges[:-1], result.best_fit, 'purple', label='best fit', alpha=0.5)
    #plt.show()

    amp = result.params['amp']
    cen = result.params['cen']
    wid = result.params['wid']
    print(result.redchi)
    width_xz[idx] = wid

    idx += 1
    del result

width_xz = width_xz.reshape(xrange.shape)
plt.contourf(xrange, yrange, width_xz, cmap=cm.viridis, interpolation='bicubic')
cbar = plt.colorbar()
plt.xlabel("$\Delta x[cm]$")
plt.ylabel("$\Delta z[cm]$")
cbar.set_label("width [cm]")

plt.show()


'''

    Toute amelioration du spcrit sera la BIENVENU
    N'hesite a envoyer vos remaque a cette adresse kouyatosten@gmail.com

    description : ce script peut se diver en 2 partir

        - Recuperer des Donners
        - Formatage des Donners

'''

from json import dump
from bs4 import BeautifulSoup as be
from requests import get
#  from repertoire import effter ce module n'est pas encore disponible
from optparse import OptionParser
from threading import Thread
from sys import argv
from os.path import isfile
from page import page

# aller chercher les donner
def req():
    url = 'https://hors-frontieres.fr/liste-des-capitales-de-tous-les-pays-du-monde/'
    return get(url).text

# recuperation de
def recu():
    r = req()
    b = be(r,features='html.parser')
    return b.findAll('td')

'''

    formatage de donner recuperer sous la forme { pays : capital }

'''

# ajout des pays dans le dictionnaire
def addP():
    data = {}
    st = recu()
    for i in st:
        j = ""
        if int(i['width']) >= 200:
            data[i.text] = ''
    return data

# ajout des capital dans le dictionnaire
def addC(af = False):
    n= 0
    data = addP();st = recu()
    for i,j in data.items():
        c = 0
        for z in st[n:]:
            c +=1
            if 150< int(z['width']) <= 200:
                data[i]  = z.text.strip()
                n += c
                break
    if af== True:
        for i,j in data.items(): print(f'pays {i} | {j} capital')
    return data

# enredistrement des donner dans un fichier json formatage = { pays : capital }
def enr(ch = False,format= ''):
    data = addC()
    if ch in [False,'false']: ch = 'data.'+format

    if format == 'json':
        with open(ch,"w") as file:
            dump(data,file)
            print(f'enregistrer dans le fichier \\{ch}')
    elif format == 'txt':
        with open(ch,"w") as file:
            for i,j in data.items(): file.write(f'{i}:{j}\n')
            print(f'enregistrer dans le fichier \\{ch}')
    else:
        page(data,ch)

name = 'main.py'
info = f'''{"mode d'emploi":-^55}
    Usage :
            {name} -e (json/txt/html) format d'enregistrement des donner
            {name} -a affichage des donner (true/false)
            {name} -n nom du fichier d'enregistrement par defaut c'est data.json
            {name} -f forcer l'enregistrement dans un fichier exitant

    Exemple : {name} -e json -n index -f _
              {name} -a false -n data -f _
              {name} -e txt -a true -n enregistrement

'''
def print_info():
    print(p.usage)
    exit()
# parametrage des option
p = OptionParser(info)
p.add_option('-e',dest='erg',type='string',help='enregistrement json/txt')
p.add_option('-a',dest='af',type='string',help='affichage {pays : capital} ')
p.add_option('-n',dest='name',type='string',help='nom du fichier')
p.add_option('-f',dest='df',type='string',help='nom du fichier')

# recuperation des option
res,null = p.parse_args()
erg, aff,name = res.erg,res.af,res.name
force = True if '-f' in argv else False

# dispositif de preparation de l'option -a
t = Thread(target=addC,args=[True])
def _a():
    t.start()
    t.join()

# cet fonction permet de verifier si le nom du fichier indiquer existe
def veri_fch(name,erg):
    if name != False:
        if isfile(name+'.'+erg):

            if force == True:enr(ch=name+'.'+erg,format=erg)
            else:
                verifi = input(f'le fichier {name}.{erg} existe déja voulez vous le réecrire o/n ? ')
                enr(ch=name+'.'+erg,format=erg) if verifi.lower() == 'o' else print_info()
        else:enr(ch=name+'.'+erg,format=erg)
    else :
        if isfile('data.'+erg):

            if force == True:enr(ch=name+'.'+erg,format=erg)
            else:
                verifi = input(f'le data.{erg} existe déja voulez vous le réecrire o/n ? ')
                enr(format=erg) if verifi.lower() == 'o' else print_info()
        else:enr(format=erg)

# ---------------------------traitement------------------------------------
try :
    if (name or erg or aff):

        erg = erg if type(erg) != type(None) else 'false'
        aff = aff if type(aff) != type(None) else 'false'
        name = name if type(name) != type(None) else False

        if erg.lower() in ['html','json','txt']:

            if aff.lower() =='true':

                if name != False:
                    veri_fch(name,erg)
                    _a()
                else:
                    veri_fch('data',erg)
                    _a()

            else: veri_fch(name,erg)

        else:
            if aff.lower() =='true':
                if name != False:
                    veri_fch(name,erg = 'txt')
                    _a()
                else: _a()
            else:
                if name != False: veri_fch(name,erg = 'txt')

    else :print_info()

except : print('''Vous avez un probleme que faire D'abord
    - Verifier votre connection internet
    - Allons jetter un coup d'oeil a la documentation sur 'https://github.com/Tostenn/country_capital'
    - Si le probleme persiste n'hesite pas a me contacter a cette adresse kouyatosten@gmail.com
''')


###########################################
    # DEPENDENCIES AND SETUP
###########################################
from flask import Flask, render_template, redirect, jsonify, request
import os
import requests
import json
import time
# Import our pymongo library, which lets us connect our Flask app to our Mongo database.
from flask_pymongo import pymongo
import pandas as pd
# Importing "starter.py" which is used for loading data to mongodb
import starter

##########################################
    # FLASK SETUP
##########################################
# Create an instance of our Flask app.
app = Flask(__name__)

##########################################
    # MONGO DB CONNECTION
##########################################
# Use flask_pymongo to set up mongo db connection
conn = "mongodb://localhost:27017"
client = pymongo.MongoClient(conn)
mongo = client.UFO

#########################################
    # CREATING ROUTES USING FLASK
#########################################

# before_first_request_function
# Registers a function to be run before the first request to this instance of the application.
#The function will be called without any arguments and its return value is ignored.
@app.before_first_request
def import_csvfile():
    starter

@app.route("/")
def index():
    # write a statement that finds all the items in the db and sets it to a variable

# render an index.html template and pass it the data you retrieved from the database
    return render_template("index.html")

    # Redirect back to home page
    return redirect("/")

@app.route("/alien_data")
def data():
    alien_collection = mongo.db.alien_data.find({}).limit(3251)
    alien_data_json = []
    for json in alien_collection:
        alien_data_dict = {}
        alien_data_dict.update({
            "state_long": json["state_long"],
            "state_short": json["state_short"],
            "city_state": json["city_state"],
            "mj_legal": json["mj_legal"],
            "lat": json["lat"],
            "long" : json["long"],
            "sighting_date" : json["sighting_date"]

        })

        alien_data_json.append(alien_data_dict)

    return jsonify(alien_data_json)

time.sleep(1)

@app.route("/military")
def military():
    military_basescollection = mongo.db.military_bases.find({}).limit(700)
    military_bases_json = []
    for json in military_basescollection:
        military_bases_dict = {}
        military_bases_dict.update({
            "state_long": json["state_long"],
            "state_short": json["state_short"],
            "mil_base_name" : json["mil_base_name" ],
            "component" : json["component"],
            "lat": json["lat"],
            "long" : json["long"],
            "country": json["country"]
        })
        military_bases_json.append(military_bases_dict)
    return jsonify(military_bases_json)

@app.route("/sightings")
def sightings():
    sightings_collection = mongo.db.sightings_count.find({})
    sightings_json = []
    for json in sightings_collection:
        sightings_dict = {}
        sightings_dict.update({
            "state_long": json["state_long"],
            "state_short": json["state_short"],
            "sightings_total" : json["sightings_total"],
            "Jan" : json["Jan"],
            "Feb" : json["Feb"],
            "Mar" : json["Mar"],
            "Apr" : json["Apr"],
            "May" : json["May"],
            "Jun" : json["Jun"],
            "Jul" : json["Jul"],
            "Aug" : json["Aug"],
            "Sep" : json["Sep"],
            "Oct" : json["Oct"],
            "Nov" : json["Nov"],
            "Dec" : json["Dec"],
        })
        sightings_json.append(sightings_dict)
    return jsonify(sightings_json)

time.sleep(1)

@app.route("/word_cloudusatotals")
def word():
    word_collection = mongo.db.word_cloud_usatotals.find({})
    word_json = []
    for json in word_collection:
        word_dict = {}
        word_dict.update({
            "word": json["word"],
            "count": json["count"] })
        word_json.append(word_dict)
    return jsonify(word_json)

time.sleep(1)

@app.route("/mapping_data")
def data_new():

    # Select columns 'state_long'  and 'mj_legal' from 'alien_data' collection where 'state_long' not equal to ""
    # adding _id:0 to remove _id from the dataframe.Then removing duplicates from dataframe.
    mj_legal_df = pd.DataFrame(list(mongo.db.alien_data.find( { "state_long": { "$ne": "" } }, { "_id":0, "state_long": 1, "mj_legal": 1 } )))
    mj_legal_df_unique = mj_legal_df.drop_duplicates()

    # Select columns 'state_long' and 'operational_status' from 'military_bases' collection where 'state_long' not equal to "" and 'operational_status' is equal to active.
    # adding _id:0 to remove _id from the dataframe. Do groupby based on column 'state_long' and take count.
    miltary_bases_df = pd.DataFrame(list(mongo.db.military_bases.find( { "state_long": { "$ne": "" }, "operational_status": "Active" },{ "_id":0, "state_long": 1, "operational_status": 1 } )))
    miltary_bases_count = miltary_bases_df.groupby("state_long").count()

    # sightings_count_df = pd.DataFrame(list(mongo.db.sightings_count.find( { "state_long": { "$ne": "USA" } }, { "_id":0, "state_long": 1, "sightings_total": 1 } )))
    # Select columns 'state_long', 'state_short' and 'sighings_total' from 'sightings_count' collection where 'state_long' not equal to 'USA'
    sightings_count_df = pd.DataFrame(list(mongo.db.sightings_count.find( { "state_long": { "$ne": "USA" } }, { "_id":0, "state_long": 1, "state_short":1, "sightings_total": 1 } )))
    # combining dataframes 'miltary_bases_count' and 'sightings_count_df'
    combined_1_df = pd.merge(miltary_bases_count,sightings_count_df, on='state_long')
    # combining dataframe 'combined_1_df' and 'mj_legal_df_unique'
    combined_df = pd.merge(combined_1_df,mj_legal_df_unique, on='state_long')
    #print(combined_df)
    #print(type(combined_df))
    # converting dataframe to json(but it was in string format)
    combined_df_json = combined_df.to_json(orient='records')
    #print(combined_df_json)
    #print(type(combined_df_json))
    # string to json
    combined_df_json_final = json.loads(combined_df_json)
    #print(combined_df_json_final)

    return jsonify(combined_df_json_final)

# Calling functions
if __name__ == "__main__":
    app.run(debug=True)


import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn

import torchvision
import torchvision.transforms as transforms

from models import *
#from advertorch.attacks import LinfPGDAttack
from autoattack import AutoAttack
from tqdm import tqdm
import argparse

parser = argparse.ArgumentParser(
    description="Test the trained model with AutoAttack (l-inf, eps = 8/255)."
)
parser.add_argument(
    "file_name",
    type=str,
    help="the model to be tested"
)
parser.add_argument(
    "checkpoint_dir",
    type=str,
    help="directory of the model"
)

args = parser.parse_args()

#file_name = 'pgd_adversarial_training'
file_name = args.file_name
checkpoint_dir = args.checkpoint_dir
device = 'cuda' if torch.cuda.is_available() else 'cpu'

transform_test = transforms.Compose([
    transforms.ToTensor(),
])

test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=100, shuffle=False, num_workers=4)

net = ResNet18()
net = net.to(device)
net = torch.nn.DataParallel(net)
cudnn.benchmark = True
checkpoint = torch.load('./' + checkpoint_dir + '/' + file_name)
#print('model loaded successfully.')
#print('device:',device)
net.load_state_dict(checkpoint['net'])

#adversary = LinfPGDAttack(net, loss_fn=nn.CrossEntropyLoss(), eps=0.0314, nb_iter=7, eps_iter=0.00784, rand_init=True, clip_min=0.0, clip_max=1.0, targeted=False)
adversary = AutoAttack(net,norm='Linf',eps=8/255,version='standard')
criterion = nn.CrossEntropyLoss()

def test():
    print('\n[ Test Start ]')
    net.eval()
    benign_loss = 0
    adv_loss = 0
    benign_correct = 0
    adv_correct = 0
    #print('net.eval() works fine')
    total = 0
    pbar = tqdm(test_loader)
    for inputs, targets in pbar:
        inputs, targets = inputs.to(device), targets.to(device)
        total += targets.size(0)

        outputs = net(inputs)
        loss = criterion(outputs, targets)
        benign_loss += loss.item()

        _, predicted = outputs.max(1)
        benign_correct += predicted.eq(targets).sum().item()

        batch_size = len(targets)
        #adv = adversary.perturb(inputs, targets)
        x_adv = adversary.run_standard_evaluation(inputs,targets,bs=batch_size)
        adv_outputs = net(x_adv)
        loss_adv = criterion(adv_outputs, targets)
        adv_loss += loss_adv.item()

        _, adv_predicted = adv_outputs.max(1)
        adv_correct += adv_predicted.eq(targets).sum().item()
        pbar.set_postfix({'benign test accuracy:': predicted.eq(targets).sum().item() / targets.size(0), 'benign test loss': loss.item(), 'adversary test accuracy': adv_predicted.eq(targets).sum().item() / targets.size(0), 'adversary test loss': loss_adv.item()})

    print('\nTotal benign test accuarcy:', 100. * benign_correct / total)
    print('Total adversarial test Accuarcy:', 100. * adv_correct / total)
    print('Total benign test loss:', benign_loss)
    print('Total adversarial test loss:', adv_loss)

test()


import arcpy
from arcpy import env
import arcpy.mapping
#from arcpy.sa import *

# Set workspace
env.overwriteOutput = True
work_space = r"C:\Users\erentschlar\Desktop\ToDelete"
# arcpy.env.workspace = arcpy.GetParameterAsText(0)
env.workspace = work_space

# Script arguments
sde_GIS_ADMIN_COB_WATER_HYDRANTS = arcpy.GetParameterAsText(0)
if sde_GIS_ADMIN_COB_WATER_HYDRANTS == '#' or not sde_GIS_ADMIN_COB_WATER_HYDRANTS:
    sde_GIS_ADMIN_COB_WATER_HYDRANTS = "sde.GIS_ADMIN.COB_WATER_HYDRANTS" # provide a default value if unspecified

BRYAN__CITY_LIMITS = arcpy.GetParameterAsText(1)
if BRYAN__CITY_LIMITS == '#' or not BRYAN__CITY_LIMITS:
    BRYAN__CITY_LIMITS = "BRYAN  CITY LIMITS" # provide a default value if unspecified

# Local variables:
COB_Hydrants_shp = sde_GIS_ADMIN_COB_WATER_HYDRANTS
ThiessenPolygon_shp = COB_Hydrants_shp
ThiessenPolygon_shp__3_ = ThiessenPolygon_shp
ThiessenPolygon_shp__5_ = ThiessenPolygon_shp__3_
ThiessenPolygon_shp__4_ = ThiessenPolygon_shp__5_
FireFlow_shp = ThiessenPolygon_shp__4_

# Process: Select
arcpy.Select_analysis(sde_GIS_ADMIN_COB_WATER_HYDRANTS, COB_Hydrants_shp, "PITOT_GPM > 0 AND CCN_ENTITY = 'COB'")

# Process: Create Thiessen Polygons
arcpy.CreateThiessenPolygons_analysis(COB_Hydrants_shp, ThiessenPolygon_shp, "ALL")

# Process: Add Field
arcpy.AddField_management(ThiessenPolygon_shp, "GPM_Range", "TEXT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Calculate Field
arcpy.CalculateField_management(ThiessenPolygon_shp__3_, "GPM_Range", "[PITOT_GPM]", "VB", "")

# Process: Calculate Field (2)
arcpy.CalculateField_management(ThiessenPolygon_shp__5_, "GPM_Range", "Reclass(!GPM_Range!)", "PYTHON_9.3", "def Reclass(GPM_Range):\\n    if (int(GPM_Range)<=499):\\n        return \"0-499\"\\n    elif (int(GPM_Range)>=500 and int(GPM_Range)<=999):\\n        return \"500-999\"\\n    elif (int(GPM_Range)>=1000 and int(GPM_Range)<=1499):\\n        return \"1000-1499\"\\n    elif (int(GPM_Range)>=1500):\\n        return \"1500-2000\"")

# Process: Clip
arcpy.Clip_analysis(ThiessenPolygon_shp__4_, BRYAN__CITY_LIMITS, FireFlow_shp, "")

mapdoc = arcpy.mapping.MapDocument(r"G:\GIS_PROJECTS\WATER_SERVICES\Hydrants\FireFlow.mxd")

#Data Frame
listdf = arcpy.mapping.ListDataFrames(mapdoc)
data_frame = listdf[0]
listdf[0].scale = 90000

#Paths to the Layers and Shapefiles
#LyrCL = arcpy.mapping.Layer(r"G:\4_LAYERS\COB_CITY_LIMITS.lyr")
#LyrFF = arcpy.mapping.Layer(r"G:\GIS_PROJECTS\WATER_SERVICES\Hydrants\FireFlowSymbology.lyr")
#LyrST = arcpy.mapping.Layer(r"G:\4_LAYERS\COB_STREET_HISTORY_1996-2014.lyr")

# Adding the relevant layers
#arcpy.mapping.AddLayer( data_frame ,LyrST,"TOP")
#arcpy.mapping.AddLayer( data_frame ,LyrCL,"BOTTOM")
#arcpy.mapping.AddLayer( data_frame ,LyrFF,"BOTTOM")

## Page Layout Elements
# Date for Title
import datetime
mydate = datetime.datetime.now()
month = mydate.strftime("%B")
year = mydate.strftime("%Y")

# Set Title Text
title = arcpy.mapping.ListLayoutElements(mapdoc, "TEXT_ELEMENT")[0]
title.text = "Analysis of Measured Fire Flow (Pitot GPM) " + month + " " + year

# May not be necessary
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
mapdoc.save()

# Create PDF
pdf = r"G:\GIS_PROJECTS\WATER_SERVICES\Hydrants\FireFlow" +month + year + ".pdf"
arcpy.mapping.ExportToPDF(mapdoc, pdf )
#"PAGE_LAYOUT", , ,300, "BEST", "RGB", 1,"ADAPTIVE", "RASTERIZE_BITMAP",0,1,"LAYERS_ONLY",1,80
#arcpy.ApplySymbologyFromLayer_management()

# Finishing

del mapdoc