#!BPY

# Une cyclide de Dupin C3, format fil de fer, avec les quatres droites. En couleur...
# chaque cercle est un seul mesh
# on isole le cas des cercles complets, plutot que de trainer des si alors sinon compliques
# 10/11/2014 : mesh ok, on rajoute les couleurs
# et les quatre droites
__author__ = "francesco de comite"
__version__ = "1.0 2014/11/05"
__url__="Website, www.lifl.fr/decomite"

##############################################################
# load the modules used in the script
import bpy
import math
import mathutils
from mathutils import *

from math import *
##############################################################
# une sphere
# R : rayon
# n : nombre de meridiens
# p : nombre de paralleles

def sphere(R,n,p):
    me=bpy.data.meshes.new('sphere')
    coords=[[0,0,0] for i in range(n*p+2)]
    faces=[]

    # Les points
    for i in range(p): #les points sur un parallele
        zc=pi/2-(i+1)*pi/(p+1)
        for j in range(n):
            coords[j+i*n]=[R*cos(2*j*pi/n)*cos(zc),R*sin(2*j*pi/n)*cos(zc),R*sin(zc)]
    coords[n*p]=[0,0,R]
    coords[n*p+1]=[0,0,-R]

    #les faces
    # Calottes
    for i in range(n):
        faces.append([i,(i+1)%n,n*p])
        faces.append([i+(p-1)*n,n*p+1,(i+1)%n+(p-1)*n])

    # relier un parallele au suivant
    for i in range(p-1):
        for j in range(n):
            faces.append([(j+1)%n+n*i,j+n*i,j+n*(i+1)])
            faces.append([(j+1)%n+n*i,j+n*(i+1),(j+1)%n+n*(i+1)])

    me.from_pydata(coords,[],faces)
    me.update(calc_edges=True)
    return me

#un tore
# R : grand rayon
# r : petit rayon
# n : nombre de sections
# p : nombre de points sur une section
def tore(R,r,n,p):
    me=bpy.data.meshes.new('tore')
    coords=[[0,0,0] for i in range(n*p)]
    faces=[]
    for i in range(n):
        for j in range(p):
                coords[i*p+j]=[(R+r*cos(2*j*pi/p))*cos(2*i*pi/n),(R+r*cos(2*j*pi/p))*sin(2*i*pi/n),r*sin(2*j*pi/p)]
    for i in range(n):
        #relier la couronne numero i a la couronne (i+1)%n
        depart=i*p
        arrivee=((i+1)*p)%(n*p)
        for j in range(p):
            faces.append([depart+j,arrivee+j,depart+(j+1)%p])
            faces.append([depart+(j+1)%p,arrivee+j,arrivee+(j+1)%p])

    me.from_pydata(coords,[],faces)
    me.update(calc_edges=True)
    return me

# un cylindre
def cylindre(r,nbFaces,l):

 me=bpy.data.meshes.new('cylindre')
 coords=[[0,0,0] for i in range(2*nbFaces+2)]
 faces=[]

 coords[2*nbFaces]=[0,0,0]
 coords[2*nbFaces+1]=[0,l,0]

 for i in range(0,nbFaces):
     coords[i]=[r*cos(2*i*pi/nbFaces),0,r*sin(2*i*pi/nbFaces)]
     coords[i+nbFaces]=[r*cos(2*i*pi/nbFaces),l,r*sin(2*i*pi/nbFaces)]

 for i in range(0,nbFaces):
     faces.append([i,(i+1)%nbFaces,2*nbFaces])
     faces.append([i+nbFaces,2*nbFaces+1,nbFaces+(i+1)%nbFaces])
     faces.append([(i+1)%nbFaces,i,i+nbFaces])
     faces.append([i+nbFaces,nbFaces+(i+1)%nbFaces,(i+1)%nbFaces])

 me.from_pydata(coords,[],faces)   # edges or faces should be [], or you ask for problems
 me.update(calc_edges=True)
 return me

# construit un cylindre et l'oriente dans l'espace
def cylindreOriente(p1,p2,rayon,nbFaces):

 # use the class constructors from Blender to form vectors for p1 and p2
 p1 = Vector(p1)
 p2 = Vector(p2)
 # form a vector that points in the direction from p1 to p2
 dir = p2-p1
 # get the length of the line we want that goes from p1 to p2
 length = dir.length
 me=cylindre(rayon,nbFaces,length)
 dir.normalize()
 u = dir
 uu = Vector([0,1.0,0])
 if abs(u.angle(uu))>1e-6:
  v=u.cross(uu)
  A=Matrix.Rotation(-u.angle(uu),4,v)
 else:
  A = Matrix((
    (1,0,0,0),
    (0,1,0,0),
    (0,0,1,0),
    (0,0,0,1)))

 # apply the transform to the cylinder

 me.transform(A)
 trans=mathutils.Matrix.Translation(p1)
 me.transform(trans)
 return me

#Construit une couronne de points
def couronneOrientee(p1,p2,rayon,nbFaces):
     # use the class constructors from Blender to form vectors for p1 and p2
     p1 = Vector(p1)
     p2 = Vector(p2)
     # form a vector that points in the direction from p1 to p2
     dir = p2-p1
     # get the length of the line we want that goes from p1 to p2
     length = dir.length
     me=[[0,0,0] for i in range(nbFaces)]
     for i in range(nbFaces):
         me[i]=[rayon*cos(2*i*pi/nbFaces),0,rayon*sin(2*i*pi/nbFaces)]
     dir.normalize()
     u = dir
     uu = Vector([0,1.0,0])
     if abs(u.angle(uu))>1e-6:
      v=u.cross(uu)
      A=Matrix.Rotation(-u.angle(uu),4,v)
     else:
      A = Matrix((
        (1,0,0,0),
        (0,1,0,0),
        (0,0,1,0),
        (0,0,0,1)))

     # apply the transform to the cylinder
     trans=mathutils.Matrix.Translation(p1)
     for i in range(nbFaces):
         vecti=Vector((me[i][0],me[i][1],me[i][2]))
         vecti.rotate(A)
         vecti=vecti+p1
         me[i]=[vecti.x,vecti.y,vecti.z]
     return me

maxbox=15
rayon=0.135

nbAlpha=48 # forcement multiple de 4...
nbTheta=400
nbFaces=10
indice=0
memoire=[[0,0,0] for i in range(2*nbAlpha)]

# les parametres de la cyclide
p=2
q=-9
omega=q-sqrt(q*q-p*q)
k=p*p-p*q
xOmega=(2*q*q-(p+2*q)*sqrt(q*q-p*q))/(2*q)
r=abs((q-p+sqrt(q*q-p*q))/2);
R=abs((q-p)*(q+sqrt(q*q-p*q))/(2*q));
Rr=sqrt(R*R-r*r);
k=p*p-p*q;

# les sous programmes auxiliaires (cf L. Garnier)

def den1(ct,theta,epsilon):
    global xOmega,r,R,omega
    valeur=xOmega*xOmega+R*R+r*r+omega*omega-2*xOmega*omega+2*R*r*cos(ct)-2*xOmega*epsilon*r*sin(theta)
    return valeur

def den2(ct,theta,epsilon):
    global xOmega,Rr,r,omega
    valeur=-2*xOmega*cos(theta)*sin(ct)*Rr+2*epsilon*r*omega*sin(theta)+2*omega*cos(theta)*sin(ct)*Rr
    return valeur

def den3(ct,theta,epsilon):
    global xOmega,R,omega
    valeur=-2*xOmega*R*epsilon*cos(ct)*sin(theta)+2*R*epsilon*omega*cos(ct)*sin(theta)
    return valeur

def denom(ct,theta,epsilon):
    global k
    valeur=den1(ct,theta,epsilon)+den2(ct,theta,epsilon)+den3(ct,theta,epsilon)

    return k/valeur

def valX(ct,theta,epsilon):
    global xOmega,omega,Rr,r,R
    f1=xOmega
    f2=epsilon*r*sin(theta)
    f3=omega
    f4=Rr*cos(theta)*sin(ct)
    f5=epsilon*R*cos(ct)*sin(theta)
    total=f1-f2-f3-f4-f5
    return omega+total*denom(ct,theta,epsilon)

def valY(ct,theta,epsilon):
    global R,r
    f1=epsilon*R*cos(ct)*cos(theta)
    f2=epsilon*r*cos(theta)
    f3=Rr*sin(ct)*sin(theta)
    total=-f1-f2+f3
    return (-total*denom(ct,theta,epsilon))

def valZ(ct,theta,epsilon):
    global r
    total=r*sin(ct);
    return total*denom(ct,theta,epsilon)

# Pour arreter les cylindres aux frontieres de la sphere englobante
def modifCoef(v1,v2,rayon):
    vA=v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]
    vB=v2[0]*v2[0]+v2[1]*v2[1]+v2[2]*v2[2]
    vC=v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]
    delta=(vC-vB)*(vC-vB)-(vA+vB-2*vC)*(vB-rayon*rayon)
    alpha0=(-(vC-vB)-sqrt(delta))/(vA+vB-2*vC)
    alpha1=(-(vC-vB)+sqrt(delta))/(vA+vB-2*vC)
    if (alpha0>=0)and(alpha0<=1):
        return alpha0
    else:
        return alpha1

def distance(t1,t2):
    ax=t1[0]-t2[0]
    ax=ax*ax
    ay=t1[1]-t2[1]
    ay=ay*ay
    az=t1[2]-t2[2]
    az=az*az
    return sqrt(ax+ay+az)

#quand tous les point du cercle sont dans la sphere, on fait un tore clos.
def makeSimiliTorus(path,rayon,nbFaces):
    coords=[]
    faces=[]
    me=bpy.data.meshes.new('victor')
    for i in range(len(path)):
        tably=couronneOrientee(path[i],path[(i+1)%len(path)],rayon,nbFaces)
        for j in range(len(tably)):
            coords.append(tably[j])

    # Construire les faces
    for i in range(len(path)):
        # calculer le decalage pour eviter les etranglements
        # ca ne marche pas vraiment TODO
        temoin=coords[i*nbFaces]
        indice_challenger=((i+1)%len(path))*nbFaces
        decalageMin=0

        challenger=coords[indice_challenger]
        distMin=distance(temoin,challenger)
        # TODO : pas tres au point, et pas utile
        for decalage in range(nbFaces):
            challenger=coords[indice_challenger+decalage]
            distCourante=distance(temoin,challenger)
            if(distCourante<distMin):
                decalageMin=decalage
                distMin=distCourante

        decalageMin=0

        for j in range(nbFaces):  # Normales en cours
            #faces.append([i*nbFaces+j,i*nbFaces+((j+1)%nbFaces),((i+1)%len(path))*nbFaces+(j+decalageMin)%nbFaces])
            faces.append([i*nbFaces+((j+1)%nbFaces),i*nbFaces+j,((i+1)%len(path))*nbFaces+(j+decalageMin)%nbFaces])

            faces.append([((i+1)%len(path))*nbFaces+(j+decalageMin)%nbFaces,((i+1)%len(path))*nbFaces+((j+1+decalageMin)%nbFaces),i*nbFaces+(j+1)%nbFaces])
    me.from_pydata(coords,[],faces)
    me.update(calc_edges=True)
    return me
  # fin de makeSimiliTorus

# Pour faire le contour ferme
def makeSimiliTorus2(path,rayon,nbFaces):
    coords=[]
    faces=[]
    me=bpy.data.meshes.new('victor')
    for i in range(len(path)):
        tably=couronneOrientee(path[i],path[(i+1)%len(path)],rayon,nbFaces)
        for j in range(len(tably)):
            coords.append(tably[j])

    # Construire les faces
    for i in range(len(path)):
        # calculer le decalage pour eviter les etranglements
        temoin=coords[i*nbFaces]
        indice_challenger=((i+1)%len(path))*nbFaces
        decalageMin=0

        challenger=coords[indice_challenger]

        # TODO : pas tres au point, et pas utile (en fait, vaut mieux laisser un decalage de zero...
        #14/11/2014 : on refait le decalage
        # toujours pas tres efficace : il semble que les deux derniers doivent etre tournes de nbFaces/2
        d1min=0
        d2min=0
        distMin=distance(temoin,challenger)
        for decalage1 in range(nbFaces):
            surCercle1=coords[i*nbFaces+decalage1]
            debut2=coords[indice_challenger]
            for decalage2 in range(nbFaces):
                # distance entre i+d1min et j+d2min
                surCercle2=coords[indice_challenger+decalage2]
                distCourante=distance(surCercle1,surCercle2)
                if(distCourante<distMin):
                    distMin=distCourante
                    d1min=decalage1
                    d2min=decalage2
        decalageMin=(d2min-d1min+nbFaces)%nbFaces
        print(i," ",d1min," ",d2min," ",decalageMin)

        if(i<len(path)-2):
            for j in range(nbFaces):
                #faces.append([i*nbFaces+j,i*nbFaces+((j+1)%nbFaces),((i+1)%len(path))*nbFaces+(j+decalageMin)%nbFaces]) #originale
                faces.append([i*nbFaces+((j+1)%nbFaces),i*nbFaces+j,((i+1)%len(path))*nbFaces+(j+decalageMin)%nbFaces])
                faces.append([((i+1)%len(path))*nbFaces+(j+decalageMin)%nbFaces,((i+1)%len(path))*nbFaces+((j+1+decalageMin)%nbFaces),i*nbFaces+(j+1)%nbFaces]) #originale
        #traitement particulier pour les deux derniers segments...
        if(i==len(path)-2):
            decalage=decalageMin-1
            for j in range(nbFaces):  # Normales OK
                #faces.append([i*nbFaces+j,i*nbFaces+((j+1)%nbFaces),((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces]) #originale
                faces.append([i*nbFaces+((j+1)%nbFaces),i*nbFaces+j,((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces])
                faces.append([((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces,((i+1)%len(path))*nbFaces+((nbFaces-j-1-1+decalage)%nbFaces),i*nbFaces+(j+1)%nbFaces]) #originale
                #faces.append([((i+1)%len(path))*nbFaces+((nbFaces-j-1-1+decalage)%nbFaces),((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces,i*nbFaces+(j+1)%nbFaces])
        if(i==len(path)-1):
            decalage=decalageMin-1
            for j in range(nbFaces): # Normales OK
                faces.append([i*nbFaces+j,i*nbFaces+((j+1)%nbFaces),((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces]) #originale
                #faces.append([i*nbFaces+((j+1)%nbFaces),i*nbFaces+j,((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces])
                #faces.append([((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces,((i+1)%len(path))*nbFaces+((nbFaces-j-1-1+decalage)%nbFaces),i*nbFaces+(j+1)%nbFaces]) #originale
                faces.append([((i+1)%len(path))*nbFaces+((nbFaces-j-1-1+decalage)%nbFaces),((i+1)%len(path))*nbFaces+(nbFaces-j-1+decalage)%nbFaces,i*nbFaces+(j+1)%nbFaces])
    me.from_pydata(coords,[],faces)
    me.update(calc_edges=True)
    return me
  # fin de makeSimiliTorus2

# construire un tube a partir d'un tableau de points
# aussitot qu'on repere que tous les points sont presents, on pass la main a un autre programme
def makeMesh(path,radio,nbFaces,alpha,epsilon):
    global nbTheta,maxbox,memoire,indice
    coords=[]
    faces=[]

    me=bpy.data.meshes.new('myMesh')
    fin=len(path)-1
    complet=1
    # A quel angle theta=2*indiceDepart*pi/nbTheta correspond la premiere valeur du tableau
    indiceDepart=0
    # Purger le tableau
    nbZero=0
    for i in range(len(path)):
        if(path[i].length==0):
             nbZero=nbZero+1
    if(nbZero==len(path)):
        print("rien dans le tableau")
        return

    if(nbZero==0):
        return makeSimiliTorus(path,radio,nbFaces)

    # cas  des cercles incomplets

    # tableau avec des trous
    complet=0
    # tant qu'il y a des zeros a gauche, decaler a gauche
    while(path[0].length==0):
        #decaler le tableau vers la gauche
        indiceDepart=indiceDepart+1
        tmp=path[0]
        for i in range(len(path)-1):
            path[i]=path[i+1]
        path[len(path)-1]=tmp
    #tant qu'il y a quelque chose a droite, decaler a droite
    while(path[len(path)-1].length!=0):
        indiceDepart=indiceDepart-1
        tmp=path[len(path)-1]
        for i in range(len(path)-1):
            j=len(path)-i-1
            path[j]=path[j-1]
        path[0]=tmp
    while(path[fin].length==0):
        fin=fin-1
    # de l'indice zero  a l'indice fin (inclus), la liste des points du tube
    # pour des angles theta=2*(indiceDepart)*pi/nbTheta jusqu'a theta=2*(indiceDepart+fin)*pi/nbTheta
    # todo : si le tube n'est pas ferme, rajouter des bouts de tube pour arriver au bord, memoriser la position de cette extremite...

    #rajouter un point a la fin

    theta1=2*(indiceDepart+fin)*pi/nbTheta
    theta2=2*(1+indiceDepart+fin)*pi/nbTheta
    vx=valX(theta1,alpha,epsilon)
    vy=valY(theta1,alpha,epsilon)
    vz=valZ(theta1,alpha,epsilon)
    point1=Vector((vx,vy,vz))

    vx=valX(theta2,alpha,epsilon)
    vy=valY(theta2,alpha,epsilon)
    vz=valZ(theta2,alpha,epsilon)
    point2=Vector((vx,vy,vz))
    valcoef=modifCoef(point1,point2,maxbox)
    fin=fin+1
    path[fin]=valcoef*point1+(1-valcoef)*point2
    memoire[indice]=path[fin]
    indice=indice+1

    #rajouter un point au debut
    # todo que faire quand on ne peu pas ???
    if(nbZero!=1):
        theta1=2*(indiceDepart-1)*pi/nbTheta
        theta2=2*(indiceDepart)*pi/nbTheta
        vx=valX(theta1,alpha,epsilon)
        vy=valY(theta1,alpha,epsilon)
        vz=valZ(theta1,alpha,epsilon)
        point1=Vector((vx,vy,vz))

        vx=valX(theta2,alpha,epsilon)
        vy=valY(theta2,alpha,epsilon)
        vz=valZ(theta2,alpha,epsilon)
        point2=Vector((vx,vy,vz))
        valcoef=modifCoef(point1,point2,maxbox)
        for i in reversed(range(fin+1)):
            path[i+1]=path[i]
        path[0]=valcoef*point1+(1-valcoef)*point2
        memoire[indice]=path[0]
        indice=indice+1
        fin=fin+1

    for i in range(fin):

        tably=couronneOrientee(path[i],path[i+1],radio,nbFaces)
        for j in range(len(tably)):
            coords.append(tably[j])

    # la derniere couronne (a l'envers)
    tably=couronneOrientee(path[fin],path[fin-1],radio,nbFaces)
    for j in reversed(range(len(tably))):
            coords.append(tably[j])
    # Construire les faces
    for i in range(fin):
        # calculer le decalage pour eviter les etranglements
        temoin=coords[i*nbFaces]
        indice_challenger=(i+1)*nbFaces
        decalageMin=0
        challenger=coords[indice_challenger]
        distMin=distance(temoin,challenger)
        for decalage in range(nbFaces):
            challenger=coords[indice_challenger+decalage]
            distCourante=distance(temoin,challenger)
            if(distCourante<distMin):
                decalageMin=decalage
                distMin=distCourante

        if(i!=fin-1):
            decalageMin=0
            for j in range(nbFaces):
                #faces.append([i*nbFaces+j,i*nbFaces+((j+1)%nbFaces),(i+1)*nbFaces+(j+decalageMin)%nbFaces])  # originale
                faces.append([i*nbFaces+((j+1)%nbFaces),i*nbFaces+j,(i+1)*nbFaces+(j+decalageMin)%nbFaces])
                faces.append([(i+1)*nbFaces+(j+decalageMin)%nbFaces,(i+1)*nbFaces+((j+1+decalageMin)%nbFaces),i*nbFaces+(j+1)%nbFaces])  #originale
        else:
            #print("decalage :",decalageMin)
            for j in range(nbFaces):  # Normales OK
                #faces.append([i*nbFaces+j,i*nbFaces+((j+1)%nbFaces),(i+1)*nbFaces+(j+decalageMin)%nbFaces])# originale
                faces.append([i*nbFaces+((j+1)%nbFaces),i*nbFaces+j,(i+1)*nbFaces+(j+decalageMin)%nbFaces])
                faces.append([(i+1)*nbFaces+(j+decalageMin)%nbFaces,(i+1)*nbFaces+((j+1+decalageMin)%nbFaces),i*nbFaces+(j+1)%nbFaces])      #originale

    # toutes les faces sont finies sauf les couvercles

    coords.append([path[0][0],path[0][1],path[0][2]]) # de numero (fin+1)*nbFaces
    coords.append([path[fin][0],path[fin][1],path[fin][2]])    # de numero (fin+1)*nbFaces+1
    for j in range(nbFaces):
        # fabriquer des triangles pour les couvercles
        faces.append([j,(j+1)%nbFaces,(fin+1)*nbFaces])
        faces.append([j+fin*nbFaces,(j+1)%nbFaces+fin*nbFaces,(fin+1)*nbFaces+1])

    me.from_pydata(coords,[],faces)
    me.update(calc_edges=True)
    return me

def ordonner(tableau,indice):
    for i in range(indice):
        for j in range(indice-1):
            valj=atan2(tableau[j][1],tableau[j][2])
            valjp1=atan2(tableau[j+1][1],tableau[j+1][2])
            if(valj>valjp1):
                tmp=tableau[j]
                tableau[j]=tableau[j+1]
                tableau[j+1]=tmp
    return

def colorize(myMesh,myColor):
     # Create a single Material that respect Vertex Color
    mat = bpy.data.materials.new('VertexMat')
    mat.use_vertex_color_paint = True
    mat.use_vertex_color_light = True

    # Create new 'Col' Vertex Color Layer
    myMesh.vertex_colors.new()

    # Vertex colour data
    vertexColor = myMesh.vertex_colors[0].data
    faces = myMesh.polygons

    # Assign colours to verts (loop every faces)
    # Script Snippet from Blender Artist
    #Fixer la couleur de tous les sommets d'une meme lunule
    j = 0
    for face in faces:
     for idx in face.loop_indices:
      vertexColor[j].color = myColor
      j += 1
    return
# fin de colorize

#test
print("debut/n")

scn=bpy.context.scene

couleurFamille1=[0,0,1] # bleu
couleurFamille2=[1,165/255,0] #orange
couleurDroiteP=[0,1,0] # vert
couleurDroiteQ=[1,1,0] # jaune
couleurContour=[0.5,0,0] # marron

first=1
numero=0

catenaName='velo'

# Memoriser tous les points de coupure, pour les ordonner et les relier a la fin
memoire=[0 for i in range(800)]
indice=0

for ind2 in range(nbAlpha):

    alphy=2*ind2*pi/nbAlpha
    #le cas des droites
    if alphy==pi/2:
        alphy=0.9999*alphy
    if alphy==3*pi/2:
        alphy=0.9999*alphy
    # memoriser tous les points d'un cercle de Villarceau, 0 si on sort des bornes
    cheminDirect=[Vector((0,0,0)) for i in range(nbTheta)]
    cheminInverse=[Vector((0,0,0))  for i in range(nbTheta)]

    for index in range(nbTheta):
        theta=2*index*pi/nbTheta
        vx=valX(theta,alphy,1)
        vy=valY(theta,alphy,1)
        vz=valZ(theta,alphy,1)

        depart=Vector((vx,vy,vz))

        if depart.length<=maxbox:
            cheminDirect[index]=depart

        # deuxieme cercle pour le meme alpha
        vx=valX(theta,alphy,-1)
        vy=valY(theta,alphy,-1)
        vz=valZ(theta,alphy,-1)

        thetaS=theta+2*pi/nbTheta
        vxS=valX(thetaS,alphy,-1)
        vyS=valY(thetaS,alphy,-1)
        vzS=valZ(thetaS,alphy,-1)

        depart=Vector((vx,vy,vz))

        if (depart.length<=maxbox):
            cheminInverse[index]=depart

    # On a cree deux chemins, pas forcement complets, on les transforme en tubes fermes aux extremites

    if(ind2!=(nbAlpha//4)):
        cercle1=makeMesh(cheminDirect,rayon,nbFaces,alphy,1)
    else:
        cercle1=makeMesh(cheminDirect,2*rayon,nbFaces,alphy,1)

    colorize(cercle1,couleurFamille1)

    if(first==1):
        ob=bpy.data.objects.new(catenaName+str(numero),cercle1)
        bpy.context.scene.objects.link(ob)
        bpy.context.scene.objects.active = ob
        numero+=1
        first=0
    else:
        localOb=bpy.data.objects.new(catenaName+str(numero),cercle1)
        numero+=1
        scn.objects.link(localOb)

    if(ind2!=(3*nbAlpha//4)):
        cercle2=makeMesh(cheminInverse,rayon,nbFaces,alphy,-1)
    else:
        cercle2=makeMesh(cheminInverse,2*rayon,nbFaces,alphy,-1)

    colorize(cercle2,couleurFamille2)

    if(first==1):
        ob=bpy.data.objects.new(catenaName+str(numero),cercle2)
        bpy.context.scene.objects.link(ob)
        bpy.context.scene.objects.active = ob
        numero+=1
        first=0
    else:
        localOb=bpy.data.objects.new(catenaName+str(numero),cercle2)
        numero+=1
        scn.objects.link(localOb)

#for index in range(indice):
    #print(index," ",memoire[index]," ",atan2(memoire[index][1],memoire[index][2]))

ordonner(memoire,indice)

# On a besoin de ça pour avoir un tableau de la bonne taille : il y a surement une meilleure solution...
newMemoire=[[0,0,0] for i in range(indice)]

for index in range(indice):
    #print(index," ",memoire[index]," ",atan2(memoire[index][1],memoire[index][2]))
    newMemoire[index]=memoire[index]

contour=makeSimiliTorus2(newMemoire,rayon*1.2,nbFaces)
colorize(contour,couleurContour)
localOb=bpy.data.objects.new(catenaName+str(numero),contour)
numero+=1
scn.objects.link(localOb)

# les deux droites p et q
# Droite P
extremiteMoinsP=Vector((p,0,-maxbox+rayon))
extremitePlusP=Vector((p,0,maxbox-rayon))
droiteP=cylindreOriente(extremiteMoinsP,extremitePlusP,2*rayon,nbFaces)
colorize(droiteP,couleurDroiteP)
localOb=bpy.data.objects.new(catenaName+str(numero),droiteP)
numero+=1
scn.objects.link(localOb)

# Droite Q
extremiteMoinsQ=Vector((q,-24.23/2+rayon,0))
extremitePlusQ=Vector((q,24.23/2-rayon,0))
droiteQ=cylindreOriente(extremiteMoinsQ,extremitePlusQ,2*rayon,nbFaces)
colorize(droiteQ,couleurDroiteQ)
localOb=bpy.data.objects.new(catenaName+str(numero),droiteQ)
numero+=1
scn.objects.link(localOb)

bpy.ops.object.select_pattern(extend=False, pattern=catenaName+'*', case_sensitive=False)
bpy.ops.object.join()


# pip install beautifulsoup4
# pip install lxml

from bs4 import BeautifulSoup

with open("sample.html", "r") as html_file:
    content = html_file.read()
    soup = BeautifulSoup(content, 'lxml')
    course_cards = soup.findAll("div", class_="card")
    for course in course_cards:
        course_name = course.h5.text
        course_price = course.a.text.split()[-1]
        print(f"{course_name} costs {course_price}")

# headers = {"User-Agent": "Mozilla/5.0"}
# content is bytes, text is text - content is better
# find, find_all
# select_one, select
# # id
# . class
# tag
# find and .get("attr")

# bs4.element
# bs4.element.ResultSet

# str.ljust(30)

# string="xx"

# find_parents
# find_parent
# .get_text(strip=True)

# ul
# ol
# li

# table
# tr
# th/td

# div section span input a p

# find_next_sibling/s
# find_previous_sibling/s

# find_next()
# find_all_next()

# find_previous()
# find_all_previous()


import argparse
from PIL import Image

from vietocr.tool.predictor import Predictor
from vietocr.tool.config import Cfg
import sys
sys.path.insert(0, './')
from char import character
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--img', required=True, help='foo help')
    parser.add_argument('--config', required=True, help='foo help')

    args = parser.parse_args()
    config_base = Cfg.load_config_from_file("config/base.yml")
    config = Cfg.load_config_from_file(args.config)
    config_base.update(config)
    config = config_base

    config['vocab'] = character

    detector = Predictor(config)

    img = Image.open(args.img)
    s = detector.predict(img)

    print(s)

if __name__ == '__main__':
    main()


r"""
Download resources used for various purposes.

Usage:
    python download_resources.py \
        --game_num 5961 \
        --data_root path/to/folder/containing/all/game/data/ \
        --purpose calibration
"""

import argparse
import os

from src.util import s3_util

def download_spotlight_resources(game_num, local_game_folder):
    """
    Download resources used for running spotlight.

    Args:
        game_num            Game number
        local_game_folder   Path to folder containing game resources
    """
    s3_util.download_calibration_folder(game_num, local_game_folder)
    s3_util.download_color_classification_folder(game_num, local_game_folder)
    s3_util.download_object_detector_folder_no_videos(
        game_num, local_game_folder)
    s3_util.download_object_tracker_folder(game_num, local_game_folder)
    s3_util.download_results_folder(game_num, local_game_folder)
    s3_util.download_spotlight_folder(game_num, local_game_folder)
    s3_util.download_stitch_folder_no_videos(game_num, local_game_folder)

def download_calibration_resources(game_num, local_game_folder):
    """
    Download resources used for calibration.

    Args:
        game_num            Game number
        local_game_folder   Path to folder containing game resources
    """
    s3_util.download_calibration_folder(game_num, local_game_folder)
    s3_util.download_results_folder(game_num, local_game_folder)
    s3_util.download_stitch_folder_no_videos(game_num, local_game_folder)

if __name__ == "__main__":

    ap = argparse.ArgumentParser()
    ap.add_argument(
        "--game_num", required=True, type=int,
        help="Game number to use")
    ap.add_argument(
        "--data_root", required=True, type=str,
        help="Folder containing game data")
    ap.add_argument(
        "--purpose", required=True, type=str,
        choices=["calibration", "spotlight"])
    args = vars(ap.parse_args())
    game_num = args["game_num"]
    data_root = args["data_root"]
    purpose = args["purpose"]

    assert os.path.isdir(data_root)

    local_game_folder = os.path.join(data_root, "game_{0}".format(game_num))

    if purpose == "calibration":
        download_calibration_resources(game_num, local_game_folder)
    elif purpose == "spotlight":
        download_spotlight_resources(game_num, local_game_folder)


# coding: UTF-8

import numpy as np
import cv2
from matplotlib import pyplot as plt

#img = cv2.imread('simple.jpg',0)
img = cv2.imread('simple2.jpg',0)

#まずデフォルト値でFASTオブジェクトを作る
fast = cv2.FastFeatureDetector_create()

# キーポイントを求めて描画する
kp = fast.detect(img,None)
img2 = cv2.drawKeypoints(img, kp,None,color=(255,0,0))

# デフォルトのパラメタをすべて表示
print("Threshold: ", fast.getThreshold())   #閾値の設定
print("nonmaxSuppression: ", fast.getNonmaxSuppression()) #最大値抑制を適用するか
print("neighborhood: ", fast.getType())     #周辺領域の選択
print("Total Keypoints with nonmaxSuppression: ", len(kp))

#cv2.imwrite('fast_true.png',img2)
cv2.imwrite('fast_true2.png',img2)

# nonmaxSuppressionを停止
fast.setNonmaxSuppression(0)
kp = fast.detect(img,None)

print("Total Keypoints without nonmaxSuppression: ", len(kp))

img3 = cv2.drawKeypoints(img, kp,None,color=(255,0,0))

#cv2.imwrite('fast_false.png',img3)
cv2.imwrite('fast_false2.png',img3)


"""empty message

Revision ID: 40bc44aaf9dd
Revises: 201626a58dfd
Create Date: 2017-01-02 18:22:33.100981

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '40bc44aaf9dd'
down_revision = '201626a58dfd'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('last_message',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('fb_uid', sa.Integer(), nullable=True),
    sa.Column('last_user_message', sa.Unicode(), nullable=True),
    sa.Column('last_bot_response', sa.Unicode(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('last_message')
    # ### end Alembic commands ###


from inspect import stack
from pathlib import Path

def abs_path_str_from_rel_to_this_file( path : str ) :
    caller_frame = stack()[1]
    caller_file_path = caller_frame.filename
    caller_directory = Path( caller_file_path ).parent
    full_path = caller_directory / path
    abs_path = full_path.resolve()
    abs_path_str = abs_path.as_posix()
    return abs_path_str


#!/usr/bin/env python3

import sys
import traceback
import time
import serial
import serial.tools.list_ports

# feature toggles
usb = False
uart = True

# if all the following are False then exit right away
local = False
competition = True
# dynamic not working properly, keep at False
dynamic = False

# note: since this program is in /usr/bin/ on the OBC
# it was necessary to also add the connection.py
# class in /usr/bin and change the following line to
# from connection import Connection
# for the startup service to work properly
from robot.comms.connection import Connection
from robot.comms.uart import Uart

# returns current time in milliseconds
current_millis = lambda: int(round(time.time() * 1000))

def get_commands_list():
    return """'q': quit\n
'w': forward\n
's': back\n
'a': left\n
'd': right\n
'i': increase throttle speed\n
'j': decrease throttle speed\n
'o': increase steering speed\n
'k': decrease steering speed\n
'l': list commands\n\n"""

# returns current time in milliseconds
current_millis = lambda: int(round(time.time() * 1000))

if len(sys.argv) == 2:
    ROVER_PORT = int(sys.argv[1])
elif len(sys.argv) >= 3:
    print(
        "too many arguments, one optional argument is the port number, otherwise default to 5010"
    )
    print("example usage: python ServerListener.py <port>")

if not local and not competition and not dynamic:
    print("local, competition and dynamic flags set to false, exiting")
    sys.exit(0)

if usb:
    # set up connection to arduino
    ports = list(serial.tools.list_ports.comports())
    is_rover = False

    if len(ports) == 1:
        print("1 USB device detected")
        port = ports[0].name
        ser = serial.Serial('/dev/' + port, 9600)

        print("clearing buffer")
        while ser.in_waiting:
            print(ser.readline().decode())

        for i in 0, 3:
            who = ""
            print("identifying MCU")
            ser.write(str.encode("who\n"))

            # CRITICAL: give time for MCU to respond
            time.sleep(1)

            while ser.in_waiting:
                who = ser.readline().decode()
                print("who: " + who)

            if who.strip() == "rover":
                print("Rover MCU identified!")
                is_rover = True
    elif len(ports) == 2:
        print("2 USB devices detected")
        port = ports[1].name
        ser = serial.Serial('/dev/' + port, 9600)

        print("clearing buffer")
        while ser.in_waiting:
            print(ser.readline().decode())

        for i in 0, 3:
            who = ""
            print("identifying MCU")
            ser.write(str.encode("who\n"))

            # CRITICAL: give time for MCU to respond
            time.sleep(1)

            while ser.in_waiting:
                who = ser.readline().decode()
                print("who: " + who)

            if who.strip() == "rover":
                print("Rover MCU identified!")
                is_rover = True

        if not is_rover:
            port = ports[0].name
            ser = serial.Serial('/dev/' + port, 9600)

            print("clearing buffer")
            while ser.in_waiting:
                print(ser.readline().decode())

            for i in 0, 3:
                who = ""
                print("identifying MCU")
                ser.write(str.encode("who\n"))

                # CRITICAL: give time for MCU to respond
                time.sleep(1)

                while ser.in_waiting:
                    who = ser.readline().decode()
                    print("who: " + who)

                if who.strip() == "rover":
                    print("Rover MCU identified!")
                    is_rover = True

    else:
        print("No USB devices recognized, exiting")
        sys.exit(0)

    if is_rover:
        print("Connected to port: " + port)
    else:
        print("Incorrect MCU connected, terminating listener")
        sys.exit(0)
elif uart:
    u = Uart("/dev/ttySAC0", 9600, timeout=1)

# for local testing
if local:
    ROVER_IP = "127.0.0.1"
    ROVER_PORT = 5020
    BASE_IP = ROVER_IP
    BASE_PORT = 5025
# for competition
elif competition:
    ROVER_IP = "172.16.1.30"
    ROVER_PORT = 5030
    BASE_IP = "172.16.1.20"
    BASE_PORT = ROVER_PORT
# attempt to get: physicial ip, which should not need connection to internet to work
#elif dynamic:
#    ROVER_IP = ni.ifaddresses(ni.interfaces()[1])[AF_INET][0]['addr']

print("ROVER_IP: " + ROVER_IP)
print("BASE_IP: " + BASE_IP)

# Create connection object to send/receive data with base-station
receiver = Connection("rover_drive_receiver", ROVER_IP, ROVER_PORT)
sender = Connection("rover_feedback_sender", BASE_IP, BASE_PORT)

print("Rover server listening on port {} \n".format(ROVER_PORT))

print("Ready for incoming drive cmds!\n")

print(get_commands_list())

key_list = ['w', 'a', 's', 'd', 'i', 'j', 'l', 'o', 'k', 'm', 'n', 't', 'b', 'q']
# Arduino sketch considers this value to be the signal for the motors to not move
REST = 49.5

# initialize throttle/steering speeds to 0
throttle_speed = 0
steering_speed = 0

# impose safety limits, theoretical limit at 49.5
MIN_THROTTLE_SPEED = 0
MAX_THROTTLE_SPEED = 25
MIN_STEERING_SPEED = 0
MAX_STEERING_SPEED = 39

# for controlling command throughput
last_cmd_sent = 0 # to keep track of the time of the last command sent
THROTTLE_TIME = 25 # time to wait before receiving next command

while True:
    #while ser.in_waiting:
    #    print(ser.readline().decode())

    try:
        # only receive commands if last command was sent
        # THROTTLE_TIME ago (in milliseconds)
        if current_millis() - last_cmd_sent > THROTTLE_TIME:

            command = receiver.receive()

            # for throttle speed, no backwards
            if command in key_list:
                print("OPERATOR command: " + command + " recognized\n")

                if command == 'w':
                    feedback = "cmd: w --> Forward\n"
                    command = str(REST + throttle_speed) + ":" + str(REST) + "\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                    last_cmd_sent = current_millis()

                elif command == 'a':
                    feedback = "cmd: a --> Left\n"
                    command = str(REST + throttle_speed) + ":" + str(REST - steering_speed) + "\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                    last_cmd_sent = current_millis()

                elif command == 's':
                    feedback = "cmd: s --> Back\n"
                    command = str(REST - throttle_speed) + ":" + str(REST) + "\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                    last_cmd_sent = current_millis()

                elif command == 'd':
                    feedback = "cmd: d --> Right"
                    command = str(REST + throttle_speed) + ":" + str(REST + steering_speed) + "\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                    last_cmd_sent = current_millis()

                elif command == 'm':
                    feedback = "cmd: m --> enable motor controls"
                    command = "activate\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                elif command == 'n':
                    feedback = "cmd: n --> disable motor controls"
                    command = "deactivate\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                # 't' --> reset to 0 on release key, otherwise motor keeps spinning
                # 45.5:45.5
                elif command == 't':
                    feedback = "cmd: t --> stop moving"
                    command = str(REST) + ":" + str(REST) + "\n"
                    feedback += "\ncommand: " + str(command)
                    print(feedback)
                    sender.send(feedback)

                    if usb:
                        ser.write(str.encode(command))
                    elif uart:
                        u.tx(command)

                    last_cmd_sent = current_millis()

                elif command == 'i':
                    feedback = "cmd: i --> Increment throttle speed"

                    if throttle_speed < MAX_THROTTLE_SPEED:
                        throttle_speed += 0.5
                        feedback += "\nthrottle speed: " + str(throttle_speed)
                    else:
                        feedback += "\nthrottle speed upper limit reached"

                    print(feedback)
                    sender.send(feedback)

                elif command == 'j':
                    feedback = "cmd: j --> Decrement throttle speed"

                    if throttle_speed > MIN_THROTTLE_SPEED:
                        throttle_speed -= 0.5
                        feedback += "\nthrottle speed: " + str(throttle_speed)
                    else:
                        feedback += "\nthrottle speed lower limit reached"

                    print(feedback)
                    sender.send(feedback)

                elif command == 'o':
                    feedback = "cmd: o --> Increment steering speed"

                    if steering_speed < MAX_STEERING_SPEED:
                        steering_speed += 0.5
                        feedback += "\nsteering speed: " + str(steering_speed)
                    else:
                        feedback += "\nsteering speed upper limit reached"

                    print(feedback)
                    sender.send(feedback)

                elif command == 'k':
                    feedback = "cmd: k --> Decrement steering speed"

                    if steering_speed > MIN_STEERING_SPEED:
                        steering_speed -= 0.5
                        feedback += "\nsteering speed: " + str(steering_speed)
                    else:
                        feedback += "\nsteering speed lower limit reached"

                    print(feedback)
                    sender.send(feedback)

                elif command == 'q':
                    feedback = "\nTerminating connection."

                    print(feedback)
                    sender.send(feedback)

                    break

                elif command == 'l':
                    print(get_commands_list())
                    sender.send(get_commands_list())

                elif command == 'b':
                    if usb:
                        data = ""
                        while ser.in_waiting:
                            data += ser.readline().decode()

                        print(data)
                        sender.send(data)
                    elif uart:
                        data = u.rx()
                        print(data)
                        sender.send(data)
            else:
                print("UNKOWN command " + command + "\n")

            if usb:
                # flush buffer to avoid overflowing it
                ser.reset_input_buffer()
                ser.reset_output_buffer()

    except Exception:
        if usb:
            ser.close()
        print("Exception in user code:")
        print("-"*60)
        traceback.print_exc(file=sys.stdout)
        print("-"*60)
        break


from django.shortcuts import render
from .models import Product, Category
from django.db.models import Q
from django.core.paginator import Paginator, InvalidPage, PageNotAnInteger, EmptyPage
from .forms import walleSearchForm
from haystack import forms
from haystack.query import SearchQuerySet

def index(request):
    clo_list = Product.objects.all()
    clo_list = get_page(request, clo_list)
    categories = Category.objects.filter(parent=None)
    search_from = walleSearchForm()
    return render(request, 'store/index.html', locals())

def get_page(request, clo_list):
    pagintor = Paginator(clo_list, 4)
    try:
        page = int(request.GET.get('page',1))
        clo_list = pagintor.page(page)
    except (EmptyPage, InvalidPage,Paginator):
        clo_list = pagintor.page(1)
    return clo_list

def product_detail(request, id):
    try:
        clo = Product.objects.get(pk=id)
    except Product.DoesNotExist:
        return render(request, 'store/error.html', {'error': '商品不存在'})
    return render(request, 'store/single_product.html', locals())

def category(request, id):
    try:
        cat = Category.objects.get(pk=id)
    except Category.DoesNotExist:
        return render(request, 'store/error.html', {'error': '分类不存在'})

    clo_list = Product.active_objects.filter(category=cat)
    clo_list= get_page(request,clo_list)
    categories = Category.objects.filter(parent=None)
    return render(request, 'store/index.html', locals())

def search(request):
    categories = Category.objects.filter(parent=None)
    search_from = walleSearchForm(request.GET)

    if search_from.is_valid():
        keyword = search_from.cleaned_data['keyword']
        query = SearchQuerySet()
        sqs = query.auto_query(keyword)
        clo_list = []
        for s in sqs:
            clo = Product.objects.get(pk=s.pk)
            if clo:
                clo_list.append(clo)
        clo_list = get_page(request,clo_list)

    return render(request, 'store/index.html', locals())


# -*- coding: utf-8 -*-
"""
Created on Wed Mar 20 18:08:07 2019

@author: skgpc
"""
import pandas as pd
import numpy as np
from itertools import chain
#%%
from features_stats import get_all_tokens
from features_stats import get_words
from features_stats import get_punct
from features_stats import average_word_length
from features_stats import average_sent_length
from features_stats import check_sarcsymbol
from features_stats import count_uppercase
from features_stats import get_verb_lemmas
from features_stats import get_punct_average
from features_stats import get_sentiment
from features_stats import get_indiv_punct
from features_stats import relative_count_wordtypes
from features_stats import get_entities
#%%
def get_average_features(dictionary):
    """Take dictionary, extract specific features (see below for full list) and
    return summary as a dataframe:
    (1) Average Word Count
    (2) Average Sentence Count
    (3) Punctuation Richness
    (4) Sarcasm Symbol
    (5) Upper-case Words
    (6) Verb Lemmas
    (7) Sentiment Classification"""

    #Get all tokens
    tokens = get_all_tokens(dictionary)

    #Get list of ONLY words (no punct)
    word_list = get_words(tokens)

    #Get list of ONLY punct (no words)
    punct_list = get_punct(tokens)

    #Create df for total, full returns for irony
    total_train= pd.DataFrame({'Ironic Comment Parsed':tokens})
    total_train["Tokens"] = word_list
    total_train["Punctuation"] = punct_list
    total_train.head()

    #(1) AVERAGE WORD LENGTH
    average_word_leng = []
    for comment in word_list:
        average_word_leng.append(average_word_length(comment))

    #Create DataFrame for Summary of Irony STATS
    summary= pd.DataFrame({"Average Word Length": average_word_leng})

    #(2) AVERAGE SENTENCE LENGTH
    average_sent_leng = []
    for x in tokens:
        average_sent_leng.append(average_sent_length(x))

    #Add to Summary of Irony STATS df
    summary["Average Sentence Length"] = average_sent_leng
    summary.head()

    #(3) AVERAGE NUMBER OF SARCASM SYMBOL (/s)
    sarcfunc = []
    for x in tokens:
        sarcfunc.append(check_sarcsymbol(x))

    sarcsymb_list = []
    for l in sarcfunc:
        if len(l) >= 1:
            sarcsymb_list.append(l)
        else:
            sarcsymb_list.append([0])

    #Remove list layer
    sarcsymb_list = list(chain.from_iterable(sarcsymb_list))

    #Add result to Ironic Summary DF
    summary["Sarcasm Symbol (/s)"] = sarcsymb_list

    #(4) AVERAGE NUMBER OF UPPER CASE WORDS (total)
    uppercase_list = []
    for b in tokens:
        uppercase_list.append((count_uppercase(b)))

    #Remove list layer
    uppercase_list = list(chain.from_iterable(uppercase_list))

    #Add result to Ironic Summary DF
    summary["Uppercase Average"] = uppercase_list
    summary.head()

    #(5) AVERAGE PUNCTUATION RICHNESS
    punct_avg = get_punct_average(punct_list, tokens)

    #Add result to Ironic Summary DF
    summary["Punctuation Richness"] = punct_avg
    summary.head()

    #(6) AVERAGE NUMBER OF LEMMAS
    lemma_list = []
    for doc in tokens:
        lemma_list.append(get_verb_lemmas(doc))

    summary["Verb Lemma Average"] = lemma_list
    summary.head()

    #(7) SENTIMENT CLASSIFICATION
    #1 = positive, -1 = negative

    sentiment = get_sentiment(dictionary)

    summary["Sentiment Classification"] = sentiment

    #replace NAN values
    summary = summary.replace(np.nan, 0)
    return summary

#%%
def get_indivpunct(dictionary):
    """Take dictionary, extract punctuation marks and return summary as a
    dataframe"""

    #Get all tokens
    tokens = get_all_tokens(dictionary)

    average_indivpunc_list = []
    for x in tokens:
        average_indivpunc_list.append(get_indiv_punct(x))

    #Create Summary DF for each individual Punctuation Mark
    summary_indivpunct = pd.DataFrame(average_indivpunc_list)
    summary_indivpunct = summary_indivpunct.replace(np.nan, 0)

    return summary_indivpunct
#%%
def get_pos(dictionary):

    #Get all tokens
    tokens = get_all_tokens(dictionary)

    average_pos_list = []
    for comment in tokens:
        average_pos_list.append(relative_count_wordtypes(comment))

    #Create Summary DF for POS
    summary_pos = pd.DataFrame(average_pos_list)

    #replace NAN values
    summary_pos = summary_pos.replace(np.nan, 0)

    return summary_pos
#%%
def get_NER(dictionary):

    #Get all tokens
    tokens = get_all_tokens(dictionary)

    #(2.10) AVERAGE FOR ALL NAMED ENTITIES
    named_entity_list = []
    for comment in tokens:
        named_entity_list.append(get_entities(comment))

    #Create Summary DF for all Named Entities
    summary_namedentity = pd.DataFrame(named_entity_list)

    #replace NAN values
    summary_namedentity = summary_namedentity.replace(np.nan, 0)

    return summary_namedentity


import os, sys, csv
import boto3, shutil
import pandas as pd
from pprint import pprint as pp

e=sys.exit
linesep	= '\n'
colsep	= ','

s3			= boto3.client('s3')
bucket 		= 'crossix-test'
file_name 	= 'cust_list2.csv'
colname 	= 'customer_name'
to_dir 	= r'N:\Analysis\unique_customers.txt'

sql_stmt = """SELECT S.%s FROM s3object S LIMIT 10"""  % colname

import tempfile

from_dir =tempfile.gettempdir()
#e()

req = s3.select_object_content(
    Bucket	= bucket,
    Key		= file_name,
    ExpressionType	= 'SQL',
    Expression		= sql_stmt,
    InputSerialization 	= {'CSV': {'FileHeaderInfo': 'USE'}},
    OutputSerialization = {'CSV': {}},
)

out=set()
if 1:
	#get usique customer names
	for event in req['Payload']:
		if 'Records' in event:
			rr=event['Records']['Payload'].decode('utf-8')
			#pp(rr)
			for rec in rr.split(linesep):
				if rec:
					row=rec.split(colsep)
					cn = row[0].strip()
					out.add(cn)

	print('Unique customer names:')
	pp(out)
	tmpfn = os.path.join(from_dir, 'unique_cn.csv')

	#write to local tmp file
	with open(tmpfn, mode='w') as fh:

		csvw = csv.writer(fh, delimiter = ',', quotechar = '"', lineterminator = '\n',  quoting=csv.QUOTE_MINIMAL)
		for cn in out:
			csvw.writerow([cn])

	assert tmpfn

	print(to_dir)
	#copy to network share
	st = shutil.copy(tmpfn, to_dir) #r'c:\tmp')

	e(0)


import socket
import threading
import os
import sys
import tkinter as tk
from tkinter import simpledialog
#import PyQt5
#from PyQt5 import QtCore, QtGui, QtWidgets
#from PyQt5.QWidgets import QApplication, QMainWindow

import emoji

#number of users in chatroom
numUsers = 0

##############
# Server
##############

class Server(threading.Thread):
    def __init__(self, host, port):
        #holds the connections of server to client
        self.connections = []
        self.host = "127.0.0.1"
        self.port = 1060
        super().__init__()

    def run(self):
        #attempt to connect socket and port
        serverSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        serverSock.bind(("127.0.0.1", 1060))
        serverSock.listen(1)
        #announce in terminal what we are listening on
        print('Connected on:', serverSock.getsockname())
        #attempt to connect user(s) to server
        while True:
            sc, sockname = serverSock.accept()
            print('user connects from {} to {}'.format(
                sc.getpeername(), sc.getsockname()))
            #new thread
            server_socket = ServerSocket(sc, sockname, self)
            server_socket.start()
            # Add thread to  connections
            self.connections.append(server_socket)
            print('Server gets messages from user from:', sc.getpeername())

    def messageSend(self, message, source):
        #sends all other users usernames message
        for connection in self.connections:
            if connection.sockname != source:
                connection.send(message)

    def remove_connection(self, connection):
        #remove connnnection from server socket
        self.connections.remove(connection)

class ServerSocket(threading.Thread):
    #support socket connection
    def __init__(self, sc, sockname, server):
        self.sc = sc
        self.sockname = sockname
        self.server = server
        super().__init__()

    def run(self):
        #return user message
        while True:
            message = self.sc.recv(1024).decode('ascii')
            if message:
                #send users message
                self.server.messageSend(message, self.sockname)
            else:
                self.sc.close()
                #server.remove_connection(self)
                return

    def send(self, message):
        #Send user message to server.
        self.sc.sendall(message.encode('ascii'))

##############
# Client
##############

class Send(threading.Thread):
    def __init__(self, socket, name):
        self.socket = socket
        self.username = name
        super().__init__()

class ClientRecieve(threading.Thread):
    #get threads from server
    def __init__(self, socket, name):
        super().__init__()
        self.socket = socket
        self.username = name
        self.messages = None

    def run(self):
        #gets messages from server and displays on GUI
        message = self.socket.recv(1024).decode('ascii')
        print("line 104: " + message)
        #check message is valid
        if message:
            if self.messages:
                self.messages.insert(tk.END, (message))
                print("line 109: " + message)
        else:
            print("ISSUE")

#GUI support for client and server

class ChatroomGUI:
    #get ports/hosts
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.username = None
        self.messages = None

    #Starting up the client server connection
    def start(self):
        #Connect host and port
        print("Connecting to " + str(self.host) + ":" + str(self.port))
        self.socket.connect((self.host, self.port))
        print(emoji.emojize("Success! :thumbs_up:"))

        #Get name from user
        self.username = simpledialog.askstring(
            "Input", "What is your name?", parent=tk.Tk())

        #threads
        send = Send(self.socket, self.username)
        receive = ClientRecieve(self.socket, self.username)
        #start thread connections
        send.start()
        receive.start()

        #announce that another user joined chatroom
        self.socket.sendall("{} has joined. Say hi!".format(
            self.username).encode("ascii"))
        print("\rNote: you can leave the chatroom by typing 'q'!\n")
        return receive

    def send(self, msgTextBox):
        #message from user written in textbox in GUI
        message = msgTextBox.get()
        #remove message from textbox after user hits send
        msgTextBox.delete(0, tk.END)
        #place message (if valid, meaning there is a message) in gui box
        print("156 message: " + message)
        if len(message) > 0:
            self.messages.insert(tk.END, "{}: {}".format(
                self.username, (message)))

        # quit classroom: user must type "q"
        if message == "q":
            #send to socket that user is leaving chat
            self.socket.sendall("{} has left the chat.".format(
                self.username).encode("ascii"))
            #close socket
            self.socket.close()
            os._exit(0)
        else:
            self.socket.sendall("{}: {}".format(
                self.username, (message)).encode("ascii"))

def main(host, port):
    #GUI of program
    client = ChatroomGUI(host, port)
    receive = client.start()

    #Create window for gui
    window = tk.Tk()

    #dimensions of window
    window.geometry("300x200")

    #Title
    window.title("Socket Server Chatroom")

    #Box of TEXT messages
    MsgBox = tk.Frame(master=window)
    messages = tk.Listbox(master=MsgBox)
    messages.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
    client.messages = messages
    receive.messages = messages
    MsgBox.grid(row=0, column=3)

    #Textbox for input
    colOne = tk.Frame(master=window)
    #accept single-line text strings from a user.
    msgTextBox = tk.Entry(master=colOne)
    msgTextBox.pack(side=tk.RIGHT, expand=True)
    #input of text message
    msgTextBox.bind("<Return>", lambda x: client.send(msgTextBox))
    colOne.grid(row=6, column=3)

    #Send button
    sendMsgButton = tk.Button(
        master=window,
        text="Send",
        width=8,
        command=lambda: client.send(msgTextBox)
    )
    sendMsgButton.grid(row=6, column=1)

    #deploy
    window.mainloop()

#start up program
if __name__ == '__main__':

    #get input from user(s)

    hosting = simpledialog.askstring(
        "Input", "Create Host connection? (yes/no)", parent=tk.Tk())
    #start up server on socket 127.0.0.1 and port 1060
    if (hosting == "yes" or hosting == "Yes" or hosting == "y"):
         (Server("127.0.0.1", int(1060))).start()

    socketValue = simpledialog.askstring(
        "Input", "Type socket value:", parent=tk.Tk())
    portValue = simpledialog.askstring(
        "Input", "Type port value:", parent=tk.Tk())
    #start main with users given socket and port values
    #main((socketValue), int(portValue))
    main("127.0.0.1", int(1060))


import json
from pprint import pprint

with open ("newsafr.json") as f:
    data = json.load(data_file)
    pprint (data)

def count_length (text):
    text_list = text.split(" ")
    text_set = set()
    for i in text_list:
        if len(i) > 6:
            text_set.add(i)
    word_value = {}
    for i in text_set:
        count = 0
        for j in text_list:
            if i == j:
                count += 1
        word_value[i] = count
    return word_value


from at import physics
import matlab
import numpy
import pytest

@pytest.mark.parametrize('dp', (0, 1e-8, 1e-7, 1e-6))
@pytest.mark.parametrize('refpts', (None, [1], [1, 2, 3]))
def test_find_orbit4(engine, ml_lattice, py_lattice, dp, refpts):
    # Matlab call
    ml_refpts = (matlab.double([]) if refpts is None else
                 matlab.double(list(r + 1 for r in refpts)))
    ml_orbit4 = engine.findorbit4(ml_lattice, dp, ml_refpts)
    py_ml_orbit4 = numpy.asarray(ml_orbit4)

    # Python call
    py_orbit4 = physics.find_orbit4(py_lattice, dp, refpts)

    numpy.testing.assert_almost_equal(py_ml_orbit4, py_orbit4.T)

@pytest.mark.parametrize('dp', (0.0, 1e-8, 1e-7, 1e-6))
@pytest.mark.parametrize('refpts', (None, [1], [1, 2, 3], [145]))
def test_find_m44(engine, ml_lattice, py_lattice, dp, refpts):
    # Matlab call
    ml_refpts = (matlab.double([]) if refpts is None else
                 matlab.double(list(r + 1 for r in refpts)))
    ml_m44, ml_mstack = engine.findm44(ml_lattice, dp, ml_refpts, nargout=2)
    py_ml_m44 = numpy.asarray(ml_m44)

    # Python call
    py_m44, py_mstack = physics.find_m44(py_lattice, dp, refpts)

    py_mstack = numpy.squeeze(py_mstack)
    # Matches to 5 d.p.
    numpy.testing.assert_almost_equal(py_ml_m44, py_m44.T, decimal=5)
    assert py_mstack.T.shape == tuple(numpy.asarray(ml_mstack).shape)
    # Matches to 5 d.p.
    numpy.testing.assert_almost_equal(py_mstack.T, numpy.asarray(ml_mstack), decimal=5)


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

import sys
sys.path.append('../../ia/')
import logging
import os

logging.basicConfig(filename=os.path.join(os.path.dirname(os.path.abspath(__file__)), "log.log"), filemode='w', level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__.split('.')[0])

import communication
from socket import *
import time
import threading

myHost = ''
myPort = 2001

#init comm
com = communication.CommunicationGlobale()
sock = socket(AF_INET, SOCK_STREAM)    # create a TCP socket
sock.bind((myHost, myPort))            # bind it to the server port
sock.listen(5)                         # allow 5 simultaneous

def update():
	if len(sys.argv) == 2:
		addr = sys.argv[1]
	else:
		addr = 2
	print("Position update on adress " + str(addr))
	while 1:
		com.sendOrderAPI(addr, 'A_GET_POS')
		ret = -1
		while ret == -1:
			ret = com.readOrdersAPI()
			time.sleep(0.01)
		data = ":".join(str(el) for el in ret[2])
		print(data)
		connection.send(bytes(data, 'utf-8'))
		time.sleep(0.1)

while 1:
	# wait for next client to connect
	print("Ready, waiting for socket connection")
	global connection
	global address
	connection, address = sock.accept()   # connection is a new socket
	print("Connection established")
	threading.Thread(target=update).start()
	while 1:
		data_rec = connection.recv(1024)  # receive up to 1K bytes
		if data_rec:
			data_rec = [data.split(':') for data in str(data_rec, 'utf-8').split('!')[:-1]] #conversion chaine en liste
			for data in data_rec:
				data[0] = int(data[0])
				#conversion data
				if data[1] == 'A_GOTOA': #deux int  un float
					data[2] = int(data[2])
					data[3] = int(data[3])
					data[4] = float(data[4])
				elif data[1] == 'A_PIDA' or data[1] == 'A_PIDD' or data[1] == 'A_ROT' or data[1] == 'A_ACCMAX': #all float
					for i in range(2,len(data)):
						data[i] = float(data[i])
				elif data[1] == 'A_GOTO': #all int
					for i in range(2,len(data)):
						data[i] = int(data[i])
				elif data[1] == 'A_PWM': #all int
					for i in range(2,len(data)):
						data[i] = int(data[i])
				elif data[1] == 'A_SET_POS': #all int
					data[2] = int(data[2])
					data[3] = int(data[3])
					data[4] = float(data[4])

				if data[1] == 'A_GOTO' or data[1] == 'A_GOTOA' or data[1] == 'A_ROT' or data[1] == 'A_PWM':
					data.insert(2, 0) #ajout id

				print('Data : ' + str(data))
				com.sendOrderAPI(data[0], data[1], *data[2:])
		else:
			break
	connection.close()              # close socket


# -*- coding: utf-8 -*-
"""
Created on Mon Sep 28 06:57:05 2020

@author: anavr
"""

import matplotlib.pyplot as plt
import pyComtrade
import numpy as np
from scipy import signal, fftpack
from tkinter import *
from tkinter import filedialog
from inspect import *

# app
#funcion para cargar

global comtradeObj
comtradeObj = pyComtrade.ComtradeRecord()

#------------------ FUNCIONES DEL PROGRAMA -------------------------------
# Para abrir archivo cfg
def abrir_cfg():

    global ar

    ar=filedialog.askopenfilename(title="Abrir cfg")#,filetypes=(("Archivos COMTRADE .cfg y .dat",".")))

    #fs=
    messagebox.showinfo("Se cargó el archivo .cfg de la siguiente dirección:\n", ar)

# Para abrir archivo dat
def abrir_dat():

    global dat

    dat=filedialog.askopenfilename(title="Abrir cfg")#,filetypes=(("Archivos COMTRADE .cfg y .dat",".")))

    #fs=
    messagebox.showinfo("Se cargó el archivo .dat de la siguiente dirección:\n", dat)

# Carga las entradas del programa
def cargar():
    global e1,e2,e3,e4,e5, ratio_V, ratio_C
    e1=en1.get()
    e2=en2.get()
    e3=en3.get()
    e4=en4.get()
    e5=en5.get()

    if e1 == "Seleccionar":
        messagebox.showerror("Error","Debe seleccionar la frecuencia de muestro del relé")
    else:
        e1 = int(e1)

    if e2=="" and e3=="":
        messagebox.showerror("Error","Debe ingresar la relación de transformación de voltaje")
    elif e2=="":
        messagebox.showerror("Error","Debe ingresar la relación de transformación del lado primario de voltaje")
    elif e3=="":
        messagebox.showerror("Error","Debe ingresar la relación de transformación del lado secundario de voltaje")
    else:
        e2 = int(e2)
        e3 = int(e3)

    if e4=="" and e5=="":
        messagebox.showerror("Error","Debe ingresar la relación de transformación de corriente")
    elif e4=="":
        messagebox.showerror("Error","Debe ingresar la relación de transformación del lado primario de corriente")
    elif e5=="":
        messagebox.showerror("Error","Debe ingresar la relación de transformación del lado secundario de corriente")
    else:
        e4 = int(e4)
        e5 = int(e5)

    if side.get() == 0:
        messagebox.showerror("Error","Debe seleccionar el lado del transformador que desea visualizar")
    elif side.get()==1:
        ratio_V = e2/e3
        ratio_C = e4/e5
    elif side.get()==2:
        ratio_V = 1
        ratio_C = 1

    DFP()

# Funciones para cada etapa
# ETAPA DE SUBMUESTREO
def subsampling(time,data,fs_comtrade,fk,fs_user_cycle):
    # time is the vector of time
    # data is the vector with the signal
    # fs_comtrade is the sample rate from the comtrade file
    # fk is the frequency of the system
    # fs_user_cycle is the sample rate given by user
    N1 = fs_user_cycle
    fs_cycle = fs_comtrade/fk
    N=np.int(fs_cycle)
    N_tot = np.int(len(data)/fs_cycle)
    new_data = [0]
    new_time = [0]
    for i in np.arange(N_tot):
        xi=data[i*N:i*N+N]
        ti=time[i*N:i*N+N]
        new_data[i*N1:i*N1+N1] = signal.resample(xi, N1)
        new_time[i*N1:i*N1+N1] = np.linspace(ti[0], ti[-1], N1, endpoint=False)

    return (new_time,new_data)

# ETAPA DE DIGITALIZACION
def quantizer(data, quantizing_bits):
    # data is the vector with the signal
    # quantizing_bits is the number of bits for the converter
    # Quantizer - S&H and ADC
    quantizing_levels   = 2 ** quantizing_bits
    quantizing_step     = (np.max(data)-np.min(data)) / quantizing_levels
    quantizing_signal   = np.round (data / quantizing_step) * quantizing_step;

    return quantizing_signal

#ETAPA DE DFT
def DFT(time, data, fk, fs_user_cycle):
    # time is the vector of time
    # data is the vector with the signal
    # fk is the frequency of the system
    # fs_user_cycle is the sample rate given by user

    N=np.int(fs_user_cycle)
    N_tot = len(data)-N
    Xc = [0]*N_tot
    Xs = [0]*N_tot
    t = [0]*N_tot

    for i in np.arange(N_tot):
        xi=data[i:i+N]
        t[i]=time[i]
        Xc_sum = 0
        Xs_sum = 0
        for k in np.arange(N):
            Xc_temp=xi[k]*np.cos(2*np.pi*k/(N))
            Xc_sum=Xc_sum+Xc_temp
            Xs_temp=xi[k]*np.sin(2*np.pi*k/(N))
            Xs_sum=Xs_sum+Xs_temp

        Xc[i]= 2/(N*np.sqrt(2))*Xc_sum
        Xs[i]= 2/(N*np.sqrt(2))* Xs_sum

    return t, Xc, Xs

# Realiza todo el proceso de DSP
def DFP():
    # Definición de variables globales para resultados
    global time, voltages, currents, time_sub, V_sub, C_sub, dig_V_sub, dig_C_sub, t, X_V, X_C, Y_V, Y_C, Xc_V, Xs_V, Xc_C, Xs_C, fs_user_cycle

    comtradeObj.read(ar,dat)
    N = comtradeObj['endsamp'][-1]
    #sampling_freq=comtradeObj['samp'][-1]
    fs_comtrade=comtradeObj['samp'][-1]
    fk = comtradeObj['line_freq']
    time = comtradeObj.get_timestamps()
    voltages = np.empty(([len(time),3]))
    currents = np.empty(([len(time),3]))
    # Reading voltaje and currents
    voltages[:,0] = comtradeObj['A'][16]['values']
    voltages[:,1] = comtradeObj['A'][17]['values']
    voltages[:,2] = comtradeObj['A'][18]['values']

    currents[:,0] = comtradeObj['A'][0]['values']
    currents[:,1] = comtradeObj['A'][1]['values']
    currents[:,2] = comtradeObj['A'][2]['values']
    for i in np.arange(6):
        if i<3:
            # voltages[:,i] = comtradeObj['A'][i]['values']
            for j in np.arange(len(voltages[:,i])):
                voltages[j,i]= voltages[j,i] * ratio_V
        else:
            # currents[:,i-3] = comtradeObj['A'][i]['values']
            for j in np.arange(len(currents[:,i-3])):
                currents[j,i-3]= currents[j,i-3] * ratio_C

    # Submuestreo
    fs_user_cycle = e1 # ESTA DATO VIENE DE LA INTERFAZ
    N_tot = np.int(N*fk/fs_comtrade)*fs_user_cycle
    V_sub = np.empty(([N_tot,3]))
    C_sub = np.empty(([N_tot,3]))
    time_sub = np.empty(([N_tot,6]))
    for i in np.arange(6):
        if i<3:
            time_sub[:,i], V_sub[:,i] = subsampling(time,voltages[:,i],fs_comtrade,fk,fs_user_cycle)
        else:
            time_sub[:,i], C_sub[:,i-3] = subsampling(time,currents[:,i-3],fs_comtrade,fk,fs_user_cycle)

    # Digitalización
    quantizing_bits_V = 12 # Valor típico: 12 (Voltaje)
    quantizing_bits_C = 16 # Valor típico: 16 (Corriente)
    dig_V_sub = np.empty(([N_tot,3]))
    dig_C_sub = np.empty(([N_tot,3]))
    for i in np.arange(6):
        if i<3:
            dig_V_sub[:,i] = quantizer(V_sub[:,i], quantizing_bits_V)
        else:
            dig_C_sub[:,i-3] = quantizer(C_sub[:,i-3], quantizing_bits_C)

    # DFT
    N_tot_DTF = np.int(N_tot-fs_user_cycle)
    Xc_V = np.empty(([N_tot_DTF,3]))
    Xs_V = np.empty(([N_tot_DTF,3]))
    Xc_C = np.empty(([N_tot_DTF,3]))
    Xs_C = np.empty(([N_tot_DTF,3]))
    X_V = np.empty(([N_tot_DTF,3]))
    Y_V = np.empty(([N_tot_DTF,3]))
    X_C = np.empty(([N_tot_DTF,3]))
    Y_C = np.empty(([N_tot_DTF,3]))
    t = np.empty(([N_tot_DTF,6]))
    for i in np.arange(6):
        if i<3:
            t[:,i], Xc_V[:,i], Xs_V[:,i] = DFT(time_sub[:,i], dig_V_sub[:,i], fk, fs_user_cycle)
            X_V[:,i] = np.sqrt(np.power(Xc_V[:,i],2)+np.power(Xs_V[:,i],2))
            ajus = np.pi
            if Xc_V[-1,i]>0 and Xs_V[-1,i]<0:
                ajus = 2*np.pi
            elif Xc_V[-1,i]>0 and Xs_V[-1,i]>0:
                ajus = 0
            Y_V[:,i] = (np.arctan(Xs_V[:,i]/Xc_V[:,i])+ajus)*180/np.pi
        else:
            t[:,i], Xc_C[:,i-3], Xs_C[:,i-3] = DFT(time_sub[:,i], dig_C_sub[:,i-3], fk, fs_user_cycle)
            X_C[:,i-3] = np.sqrt(np.power(Xc_C[:,i-3],2)+np.power(Xs_C[:,i-3],2))
            ajus = np.pi
            if Xc_C[-1,i-3]>0 and Xs_C[-1,i-3]<0:
                ajus = 2*np.pi
            elif Xc_C[-1,i-3]>0 and Xs_C[-1,i-3]>0:
                ajus = 0
            Y_C[:,i-3] = (np.arctan(Xs_C[:,i-3]/Xc_C[:,i-3])+ajus)*180/np.pi

# ------------------------- Funciones para los Botones --------------------
def seniales_COMTRADE():
    f, axarr = plt.subplots(1, 2, figsize =(16, 4))
    f.suptitle('Lectura del archivo COMTRADE', y=1, fontsize=16)

    axarr[0].plot(time, voltages[:,0], 'b-', label='Phase A')
    axarr[0].plot(time, voltages[:,1], 'r-', label='Phase B')
    axarr[0].plot(time, voltages[:,2], 'g-', label='Phase C')
    axarr[0].set_xlabel('Time [sec]')
    axarr[0].set_ylabel('Voltage [V]')
    axarr[0].grid()
    axarr[0].legend()

    axarr[1].plot(time, currents[:,0], 'b-', label='Phase A')
    axarr[1].plot(time, currents[:,1], 'r-', label='Phase B')
    axarr[1].plot(time, currents[:,2], 'g-', label='Phase C')
    axarr[1].set_xlabel('Time [sec]')
    axarr[1].set_ylabel('Current [A]')
    axarr[1].grid()
    axarr[1].legend()
    plt.show()

def submuestreo_boton():
    # PLOTING -----------------------------------------------------------------
    f, axarr = plt.subplots(3, 2, figsize =(16, 10))
    f.suptitle('Submuestreo de las señales', y=0.92, fontsize=16)

    # Plot Voltages
    axarr[0,0].plot(time, voltages[:,0], 'b-', label='Phase A')
    axarr[0,0].plot( time_sub[:,0], V_sub[:,0], 'co-', label='Phase A resampled')
    axarr[1,0].plot(time, voltages[:,1], 'r-', label='Phase B')
    axarr[1,0].plot( time_sub[:,1], V_sub[:,1], 'mo-', label='Phase B resampled')
    axarr[2,0].plot(time, voltages[:,1], 'g-', label='Phase C')
    axarr[2,0].plot( time_sub[:,2], V_sub[:,2], 'yo-', label='Phase C resampled')

    # Plot Currents
    axarr[0,1].plot(time, currents[:,0], 'b-', label='Phase A')
    axarr[0,1].plot( time_sub[:,3], C_sub[:,0], 'co-', label='Phase A resampled')
    axarr[1,1].plot(time, currents[:,1], 'r-', label='Phase B')
    axarr[1,1].plot( time_sub[:,4], C_sub[:,1], 'mo-', label='Phase B resampled')
    axarr[2,1].plot(time, currents[:,2], 'g-', label='Phase C')
    axarr[2,1].plot( time_sub[:,5], C_sub[:,2], 'yo-', label='Phase C resampled')

    for i in np.arange(3):
        axarr[i,0].set_xlabel('Time [sec]')
        axarr[i,0].set_ylabel('Voltage [V]')
        axarr[i,0].grid()
        axarr[i,0].legend()
        axarr[i,1].set_xlabel('Time [sec]')
        axarr[i,1].set_ylabel('Current [A]')
        axarr[i,1].grid()
        axarr[i,1].legend()
    plt.show()

def digitalizacion_boton():
    # PLOTING -----------------------------------------------------------------
    f, axarr = plt.subplots(3, 2, figsize =(16, 10))
    f.suptitle('Digitalización de la señal', y=0.92, fontsize=16)

    # Plot Voltages
    axarr[0,0].plot(time_sub[:,0][0:fs_user_cycle*3], V_sub[:,0][0:fs_user_cycle*3], 'b-', label='Phase A')
    axarr[0,0].plot( time_sub[:,0][0:fs_user_cycle*3], dig_V_sub[:,0][0:fs_user_cycle*3], 'c-', label='Phase A digital')
    axarr[1,0].plot(time_sub[:,1][0:fs_user_cycle*3], V_sub[:,1][0:fs_user_cycle*3], 'r-', label='Phase B')
    axarr[1,0].plot( time_sub[:,1][0:fs_user_cycle*3], dig_V_sub[:,1][0:fs_user_cycle*3], 'm-', label='Phase B digital')
    axarr[2,0].plot(time_sub[:,2][0:fs_user_cycle*3], V_sub[:,2][0:fs_user_cycle*3], 'g-', label='Phase C')
    axarr[2,0].plot( time_sub[:,2][0:fs_user_cycle*3], dig_V_sub[:,2][0:fs_user_cycle*3], 'y-', label='Phase C digital')

    # Plot Currents
    axarr[0,1].plot(time_sub[:,3][0:fs_user_cycle*3], C_sub[:,0][0:fs_user_cycle*3], 'b-', label='Phase A')
    axarr[0,1].plot( time_sub[:,3][0:fs_user_cycle*3], dig_C_sub[:,0][0:fs_user_cycle*3], 'c-', label='Phase A digital')
    axarr[1,1].plot(time_sub[:,4][0:fs_user_cycle*3], C_sub[:,1][0:fs_user_cycle*3], 'r-', label='Phase B')
    axarr[1,1].plot( time_sub[:,4][0:fs_user_cycle*3], dig_C_sub[:,1][0:fs_user_cycle*3], 'm-', label='Phase B digital')
    axarr[2,1].plot(time_sub[:,5][0:fs_user_cycle*3], C_sub[:,2][0:fs_user_cycle*3], 'g-', label='Phase C')
    axarr[2,1].plot( time_sub[:,5][0:fs_user_cycle*3], dig_C_sub[:,2][0:fs_user_cycle*3], 'y-', label='Phase C digital')

    for i in np.arange(3):
        axarr[i,0].set_xlabel('Time [sec]')
        axarr[i,0].set_ylabel('Voltage [V]')
        axarr[i,0].grid()
        axarr[i,0].legend()
        axarr[i,1].set_xlabel('Time [sec]')
        axarr[i,1].set_ylabel('Current [A]')
        axarr[i,1].grid()
        axarr[i,1].legend()

    plt.show()

def DFT_boton():
    # PLOTING -----------------------------------------------------------------
    f, axarr = plt.subplots(3, 2, figsize =(16, 10))
    f.suptitle('DFT En Magnitud', y=0.92, fontsize=16)

    # Plot Voltages
    #axarr[0,0].plot(time_sub[:,0], V_sub[:,0], 'b-', label='Phase A')
    axarr[0,0].plot( t[:,0], X_V[:,0], 'c-', label='Phase A FFT(mag)')
    #axarr[1,0].plot(time_sub[:,1], V_sub[:,1], 'r-', label='Phase B')
    axarr[1,0].plot( t[:,1], X_V[:,1], 'm-', label='Phase B FFT(mag)')
    #axarr[2,0].plot(time_sub[:,2], V_sub[:,2], label='Phase C')
    axarr[2,0].plot( t[:,2], X_V[:,2], 'y-', label='Phase C FFT(mag)')

    # Plot Currents
    #axarr[0,1].plot(time_sub[:,3], C_sub[:,0], 'b-', label='Phase A')
    axarr[0,1].plot( t[:,3], X_C[:,0], 'c-', label='Phase A FFT(mag)')
    #axarr[1,1].plot(time_sub[:,4], C_sub[:,1], 'r-', label='Phase B')
    axarr[1,1].plot( t[:,4], X_C[:,1], 'm-', label='Phase B FFT(mag)')
    #axarr[2,1].plot(time_sub[:,5], C_sub[:,2], 'g-', label='Phase C')
    axarr[2,1].plot( t[:,5], X_C[:,2], 'y-', label='Phase C FFT(mag)')

    for i in np.arange(3):
        axarr[i,0].set_xlabel('Time [sec]')
        axarr[i,0].set_ylabel('Voltage [V]')
        axarr[i,0].grid()
        axarr[i,0].legend()
        axarr[i,1].set_xlabel('Time [sec]')
        axarr[i,1].set_ylabel('Current [A]')
        axarr[i,1].grid()
        axarr[i,1].legend()

    plt.show()

    # Ploting angle
    f, axarr = plt.subplots(3, 2, figsize =(16, 10))
    f.suptitle('DFT En Fase', y=0.92, fontsize=16)

    # Plot Voltages
    #axarr[0,0].plot(time_sub[:,0], V_sub[:,0], 'b-', label='Phase A')
    axarr[0,0].plot( t[:,0], Y_V[:,0], 'c-', label='Phase A FFT[ang(rad)]')
    #axarr[1,0].plot(time_sub[:,1], V_sub[:,1], 'r-', label='Phase B')
    axarr[1,0].plot( t[:,1], Y_V[:,1], 'm-', label='Phase B FFT[ang(rad)]')
    #axarr[2,0].plot(time_sub[:,2], V_sub[:,2], label='Phase C')
    axarr[2,0].plot( t[:,2], Y_V[:,2], 'y-', label='Phase C FFT[ang(rad)]')

    # Plot Currents
    #axarr[0,1].plot(time_sub[:,3], C_sub[:,0], 'b-', label='Phase A')
    axarr[0,1].plot( t[:,3], Y_C[:,0], 'c-', label='Phase A FFT[ang(rad)]')
    #axarr[1,1].plot(time_sub[:,4], C_sub[:,1], 'r-', label='Phase B')
    axarr[1,1].plot( t[:,4], Y_C[:,1], 'm-', label='Phase B FFT[ang(rad)]')
    #axarr[2,1].plot(time_sub[:,5], C_sub[:,2], 'g-', label='Phase C')
    axarr[2,1].plot( t[:,5], Y_C[:,2], 'y-', label='Phase C FFT[ang(rad)]')

    for i in np.arange(3):
        axarr[i,0].set_xlabel('Time [sec]')
        axarr[i,0].set_ylabel('Angle (°)')
        axarr[i,0].grid()
        axarr[i,0].legend()
        axarr[i,1].set_xlabel('Time [sec]')
        axarr[i,1].set_ylabel('Angle (°)')
        axarr[i,1].grid()
        axarr[i,1].legend()
    plt.show()

def fasores_boton():
    # Creando la figura
    fig, ax = plt.subplots(1, 2, figsize =(16, 6))
    fig.suptitle('Diagrama fasorial de Voltaje y Corriente', y=0.95, fontsize=16)

    lim_axis_V = np.max([np.float(X_V[-1:,0]), np.float(X_V[-1:,1]),np.float(X_V[-1:,2])])
    lim_axis_C = np.max([np.float(X_C[-1:,0]), np.float(X_C[-1:,1]),np.float(X_C[-1:,2])])
    # Creando el punto de origen para los vectores
    x_pos = [0, 0,0]
    y_pos = [0, 0,0]

    ax[0].quiver(x_pos, y_pos, Xc_V[-1,0], Xs_V[-1,0], angles='xy', scale_units = 'xy', scale=1, color=['b'], label='Fase A')
    ax[0].quiver(x_pos, y_pos, Xc_V[-1,1], Xs_V[-1,1], angles='xy', scale_units = 'xy', scale=1, color=['r'], label='Fase B')
    ax[0].quiver(x_pos, y_pos, Xc_V[-1,2], Xs_V[-1,2], angles='xy', scale_units = 'xy', scale=1, color=['g'], label='Fase C')
    ax[0].axis([-1.2*lim_axis_V, 1.2*lim_axis_V, -1.2*lim_axis_V, 1.2*lim_axis_V])
    ax[0].set_title('Voltaje [V]')
    ax[0].legend() #<-- Se nombran las leyendas
    ax[0].grid(b=True, which='major') #<-- plot grid lines

    ax[1].quiver(x_pos, y_pos, Xc_C[-1,0], Xs_C[-1,0], angles='xy', scale_units = 'xy', scale=1, color=['b'], label='Fase A')
    ax[1].quiver(x_pos, y_pos, Xc_C[-1,1], Xs_C[-1,1], angles='xy', scale_units = 'xy', scale=1, color=['r'], label='Fase B')
    ax[1].quiver(x_pos, y_pos, Xc_C[-1,2], Xs_C[-1,2], angles='xy', scale_units = 'xy', scale=1, color=['g'], label='Fase C')
    ax[1].axis([-1.2*lim_axis_C, 1.2*lim_axis_C, -1.2*lim_axis_C, 1.2*lim_axis_C])
    ax[1].set_title('Corriente [A]')
    ax[1].legend() #<-- Se nombran las leyendas
    ax[1].grid(b=True, which='major') #<-- plot grid lines
    plt.show()

    # Mostrando las fases en la interfaz
    label_fas0.grid(row=3,column=0)
    label_fas1.config(text=['Voltaje fase A:', "{:.2f}".format(np.double(X_V[-1:,0])), 'V', "{:.2f}".format(np.double(Y_V[-1:,0])),'°'])
    label_fas1.grid(row=4,column=0)
    label_fas2.config(text=['Voltaje fase B:', "{:.2f}".format(np.double(X_V[-1:,1])), 'V', "{:.2f}".format(np.double(Y_V[-1:,1])),'°'])
    label_fas2.grid(row=5,column=0)
    label_fas3.config(text=['Voltaje fase C:', "{:.2f}".format(np.double(X_V[-1:,2])), 'V', "{:.2f}".format(np.double(Y_V[-1:,1])),'°'])
    label_fas3.grid(row=6,column=0)
    label_fas4.config(text=['Corriente fase A:', "{:.2f}".format(np.double(X_C[-1:,0])), 'A', "{:.2f}".format(np.double(Y_C[-1:,0])),'°'])
    label_fas4.grid(row=7,column=0)
    label_fas5.config(text=['Corriente fase B:', "{:.2f}".format(np.double(X_C[-1:,1])), 'A', "{:.2f}".format(np.double(Y_C[-1:,1])),'°'])
    label_fas5.grid(row=8,column=0)
    label_fas6.config(text=['Corriente fase C:', "{:.2f}".format(np.double(X_C[-1:,2])), 'A', "{:.2f}".format(np.double(Y_C[-1:,2])),'°'])
    label_fas6.grid(row=9,column=0)
#------------------------------------------------------------------
# MAIN
raiz=Tk()
raiz.title("Modulo DSP para relés")
    #raiz.geometry("650x380")
x_frame = 720
y_frame = 500
raiz.geometry("{width}x{height}".format(width=x_frame, height=y_frame))
raiz.resizable(True, True)
# mifr= Frame()
# mifr.pack(side=TOP, fill=BOTH, expand=Y)
# #mifr.config()
# mifr.config(width="650",height="380")
# mifr.config(cursor="star")
bmenu=Menu(raiz)
raiz.config(menu=bmenu)

#-------------------------------- FRAME 1 -------------------------------
frame1 = LabelFrame(raiz, text="Entradas",height= y_frame,width =x_frame,padx=5, labelanchor=N)
frame1.config(cursor="star")
frame1.pack(expand = 'no', fill = 'both')

x_frame11 = 350
frame11 = LabelFrame(frame1, text="Selección del archivo COMTRADE",fg="red",height= 100,width =x_frame11,padx=15)
frame11.grid(column=0, row=0, padx=10, pady=10)
label11 = Label(frame11, text = 'Instrucciones: Se deben seleccionar los archivos .cfg y .dat')
label11.place(x = 0, y = 5)

BotonAbrircfg = Button(frame11,text="Abrir .cfg",command=abrir_cfg)
BotonAbrircfg.place(x = x_frame11/6, y = 30)
BotonAbrirdat = Button(frame11,text="Abrir .dat",command=abrir_dat)
BotonAbrirdat.place(x = 3*x_frame11/6, y = 30)

x_frame12 = 250
frame12 = LabelFrame(frame1, text="Selección de parámetros de entrada",fg="red",height= 200,width =x_frame12,padx=15)
frame12.grid(column=1, row=0, columnspan=1, rowspan=2, padx=10, pady=10)

t1=Label(frame12,text="Seleccione la frecuencia \nde muestro del relé",fg="green")
t1.grid(row=0,column=0,sticky="w",pady="20")
en1=StringVar()
d=OptionMenu(frame12, en1, "4","8","16","32","64")
d.grid(row=0,column=1,sticky="w",padx="20",pady="20")
en1.set("Seleccionar")

frame121 = LabelFrame(frame12, text="Relación de transformadores de instrumentación",fg="Blue",height= 200,width =x_frame12,padx=15)
frame121.grid(column=0, row=1, columnspan=2, rowspan=1, padx=10, pady=10)

# Relación de transformadores de instrumentación voltaje le falta dividir entre prim y secundario
t2=Label(frame121,text="Relacion de Voltaje")
t2.grid(row=0,column=0,sticky="w")
en2=Entry(frame121, width=7)
en2.grid(row=0,column=1)
t3=Label(frame121,text=":")
t3.grid(row=0,column=2)
en3=Entry(frame121, width=7)
en3.grid(row=0,column=3)

# Relación de transformadores de instrumentación corriente le falta dividir entre prim y secundario
t21=Label(frame121,text="Relacion de Corriente")
t21.grid(row=1,column=0,sticky="w")
en4=Entry(frame121, width=7)
en4.grid(row=1,column=1)
t31=Label(frame121,text=":")
t31.grid(row=1,column=2)
en5=Entry(frame121, width=7)
en5.grid(row=1,column=3)

b1=Button(frame12,text="cargar valores",command=cargar)
b1.grid(row=2,column=0,columnspan=2, rowspan=1)

x_frame13 = 350
frame13 = LabelFrame(frame1, text="Visualización en el transformador",fg="red",height= 100,width =x_frame13,padx=15)
frame13.grid(column=0, row=1, padx=10, pady=0)
label13 = Label(frame13, text = 'Seleccione el lado que desea ver la señal del transformador')
label13.place(x = 0, y = 5)

side = IntVar()
rad_trafo1 = Radiobutton(frame13,text="Primario", variable = side, value=1)
rad_trafo1.place(x = x_frame13/6, y = 30)
rad_trafo2 = Radiobutton(frame13,text="Secundario", variable = side, value=2)
rad_trafo2.place(x = 3*x_frame13/6, y = 30)

#-------------------------------- FRAME 2 -------------------------------
frame2 = LabelFrame(raiz, text="Resultados del procesamiento",height= y_frame,width =x_frame,padx=5, labelanchor=N)
frame2.config(cursor="star")
frame2.pack(expand = 'no', fill = 'both')

x_frame21 = 350
frame21 = LabelFrame(frame2, text="Detalle por etapa",fg="red",height= 100,width =x_frame21,padx=15)
frame21.grid(column=0, row=0, padx=10, pady=10)
label21 = Label(frame21, text = 'Seleccione la etapa que desea detallar')
label21.grid(row=0,column=0,columnspan=3)

bi=Button(frame21,text="Señales de entrada",command=seniales_COMTRADE)#carga los archivos
bi.grid(row=1,column=0)
b2=Button(frame21,text="Submuestreo",command=submuestreo_boton)
b2.grid(row=1,column=1)
#etapa de mostrar señal digitalizada
b3=Button(frame21,text="Digitalizacion",command=digitalizacion_boton)
b3.grid(row=1,column=2)
#etapa de ventaneo
b3=Button(frame21,text="DFT",command=DFT_boton)
b3.grid(row=2,column=1)

x_frame22 = 250
frame22 = LabelFrame(frame2, text="Señal Procesada",fg="red",height= 100,width =x_frame22,padx=15)
frame22.grid(column=1, row=0, padx=10, pady=10)
label22 = Label(frame22, text = 'En este módulo se muestran las señales resultantes')
label22.grid(row=0,column=0)

b3=Button(frame22,text="Fasores",command=fasores_boton)
b3.grid(row=1,column=0)

label_fas0 = Label(frame22, text = 'Los fasores resultantes en rms son:')
label_fas0.grid_forget()
label_fas1 = Label(frame22, text = 'Aqui se mostrara el fasor 1',fg="blue")
label_fas1.grid_forget()
label_fas2 = Label(frame22, text = 'Aqui se mostrara el fasor 2',fg="red")
label_fas2.grid_forget()
label_fas3 = Label(frame22, text = 'Aqui se mostrara el fasor 3',fg="green")
label_fas3.grid_forget()
label_fas4 = Label(frame22, text = 'Aqui se mostrara el fasor 1',fg="blue")
label_fas4.grid_forget()
label_fas5 = Label(frame22, text = 'Aqui se mostrara el fasor 2',fg="red")
label_fas5.grid_forget()
label_fas6 = Label(frame22, text = 'Aqui se mostrara el fasor 3',fg="green")
label_fas6.grid_forget()

barchiv=Menu(bmenu,tearoff=0)
bhelp=Menu(bmenu,tearoff=0)
barchiv.add_command(label="Abrir archivo ")#carga los archivos
barchiv.add_command(label="Guardar")
bmenu.add_cascade(label="Archivo",menu=barchiv)
#help

bhelp.add_command(label="Descripción")
bmenu.add_cascade(label="Ayuda",menu=bhelp)

raiz.mainloop()