#  © Shahram Talei @ 2019 The University of Alabama - All rights reserved.
#you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 3 of the License, or
#(at your option) any later version.
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import division
import yt
import numpy as np
from yt.analysis_modules.halo_finding.api import *
from yt.analysis_modules.halo_analysis.api import *
from os import environ
environ['CFLAGS'] = "-I"+np.get_include()

import pyximport; pyximport.install()
#import particle_ops
import argparse

import tempfile
import shutil
import os
import sys

from scipy.spatial.transform import Rotation as R
from numpy import linalg as LA
from operator import mul
from functools import reduce
import matplotlib.pyplot as plt
from yt.units import parsec, Msun, Mpc
from mpl_toolkits.mplot3d import Axes3D

#define an ellipsoid object in an arbitrary orientation (a,b,c,Alpha,Beta,Yamma)

unit_base0 = {'UnitLength_in_cm'         : 3.08568e+24,
             'UnitMass_in_g'            :   1.989e+43,
             'UnitVelocity_in_cm_per_s' :      100000}

unit_base1 = {'length': (1.0, 'Mpc'),
    'velocity': (1.0, 'km/s'),
    'mass': (1.0e10, 'Msun')}

class halo:
    def __init__(self,pos,R,M,pnum,id):
        self.pos=pos
        self.R=R
        self.M=M
        self.pnum=pnum
        self.id=id
class shape:
    def __init__(self,hid,Rv,Mv,R,ax):
        ax.sort()
        self.hid=hid
        self.Rv=Rv
        self.Mv=Mv
        self.R=R
        self.a=ax[2]
        self.b=ax[1]
        self.c=ax[0]
        self.b_a=ax[1]/ax[2]
        self.c_a=ax[0]/ax[2]
        self.T=(ax[2]**2.-ax[1]**2.)/(ax[2]**2.-ax[0]**2.)
class ellipsoid:
    def __init__(self,axis,orientations):#put in tuple (self,p,angle)..p.x.
        self.a=axis[0]
        self.b=axis[1]
        self.c=axis[2]
        self.axis=axis
        self.orientations=orientations
        self.A=orientations[0]
        self.B=orientations[1]
        self.C=orientations[2]
    def IsInside(self, point,R,rescale):# put in tuple p ... p.x
        #r = R.from_euler('zyx', [self.A, self.B, self.C], degrees=True)
        #point=r.apply(point)
        #print("point in is inside:")
        #print(point)
        #print(R)
        if R==0:
            return False
        t=0
        pNew=np.array([0.0,0.0,0.0])
        for i in range(0,3):
            for j in range(0,3):
                #print(point[j])
                #print(self.orientations[j,i])
                pNew[i]+=point[j]*self.orientations[j,i] # each eig vec is [:,i] comp
        #x=point[0]#-center[0]
        #y=point[1]#-center[1]
        #z=point[2]#-center[2]
        #print("point in is inside:")
        #print(pNew)
        #t=np.sum((pNew/self.axis)**2.)
        if rescale:
            factor=R/np.max(self.axis)
        else:
            factor=1

        for i in range(0,3):
            t+=(pNew[i]/(factor*self.axis[i]))**2.
        #t=(x/self.a)**2.+(y/self.b)**2.+(z/self.c)**2
        #print(t)
        if t<=1:
            return True
        else:
            return False
    def rotate(self, orientation):
        self.orientations=oriantation
    def volume(self):
        return self.axis[0]*self.axis[1]*self.axis[2]
    #    eulerrotation
    def PlotEllipsoid(self,ax,center):
        pNew=np.array([0.0,0.0,0.0])
        #for i in range(0,3):
            #for j in range(0,3):
                #print(point[j])
                #print(self.orientations[j,i])
                #pNew[i]+=point[j]*self.orientations[j,i] # each eig vec is [:,i] comp
        coefs = (np.abs(self.a),np.abs(self.b),np.abs(self.c))
        rx, ry, rz = np.sqrt(coefs)
        # Set of all spherical angles:
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        x = rx * np.outer(np.cos(u), np.sin(v))
        y = ry * np.outer(np.sin(u), np.sin(v))
        z = rz * np.outer(np.ones_like(u), np.cos(v))

        # Plot:
        ax.plot_surface(x, y, z,  rstride=4, cstride=4, color='b', alpha=0.3)

        # Adjustment of the axes, so that they all have the same span:
        max_radius = max(rx, ry, rz)
        #for axis in 'xyz':
        #    getattr(ax, 'set_{}lim'.format(axis))((-max_radius, max_radius))
    def ShapeTesnsor(self,coords,m, Rin,Rout):
        print("Started extracting the shape tensor")
        i=j=0
        c=0
        #N=2#len() use mass instead, you won't need to count!
        shape=[[0,0,0],[0,0,0],[0,0,0]]#np.array([[0,0,0,],[0,0,0,],[0,0,0]])
        s=0
        #points=coords[(coord[not IsInside()]) && ]
        #for i in range(0,3):
        #    p[i]=coords[:,i]
        #rEll=1#np.sqrt(c)Zemp 10
        #we can use IsInside to find both inside and outside
        for i in range(0,3):
            for j in range(0,3):
                c=s=0
                print("s[%d,%d]"%(i,j))
                for point in coords:
                    #print("Before=Rin:%f, Rout:%f"%(Rin,Rout))
                    #print("point before if:")
                    #print(np.sqrt(point[0]**2.+point[0]**2.+point[0]**2.))
                    #print(not(self.IsInside(point,Rin)))
                    #print(self.IsInside(point,Rout))
                    if(self.IsInside(point,Rout,True) and (not(self.IsInside(point,Rin,True)))):
                        #print("point after if:")
                        #print("After=Rin:%f, Rout:%f"%(Rin,Rout))
                        #print("point:%g"%(m*point[i]*point[j]))
                        s+=point[i]*point[j]
                        c+=1
                #s[i,j]/=(N-1)*m
                Mtot=c*m
                if c>1:
                    shape[i][j]=s/(c-1)
                print("particle count for %g<R<%g=%d"%(Rin,Rout,c))
        return shape
def CompareEllipsoids(ell1,ell2):
    AreSame=False;
    error=1.0e-3
    c=0
    inP=np.array([0,0,0])
    dRatio=np.array([0,0])
    #dax=np.abs(np.divide(ell1.axis/ell2.axis))
    for i in range(1,3):
        if(ell1.axis[0] !=0):
            dRatio[i-1]=np.abs((ell1.axis[i]/ell1.axis[0])/(ell2.axis[i]/ell2.axis[0]))
        #dRatio[i-1]=0
    #dori=np.abs(np.divide(ell1.orientations/ell2.orientations))
    d=np.sum(dRatio[(dRatio<1+error) & (dRatio>1-error)])
    if(d==0):
        for i in range(0,3):
            for j in range(0,3):
                inP[i]+=ell1.orientations[j,i]*ell2.orientations[j,i]
            if(inP[i]<((ell1.axis[i])**2.+error) and inP[i]>((ell1.axis[i])**2.-error)):
                c+=1
        if(c==3):
            AreSame=True
    return AreSame;
def GetShape(h,ds):
    FullShape=[]
    ad = ds.all_data()
    xp=ad[("all","particle_position_x")]
    yp=ad[("all","particle_position_y")]
    zp=ad[("all","particle_position_z")]
    coordsArray=np.array((xp,yp,zp))
    coordinatesDM =coordsArray.T# we need to reshape
    #print(coordinatesDM)
    #dds = halo.halo_catalog.data_ds
    #center = dds.arr([halo.quantities["particle_position_%s" % axis] \
    #for axis in "xyz"])
    c2=r2=0
    #center*=3.24078e-25
    #center=center.in_units('Mpc')
    center =h.pos# dds.arr([halo.quantities["particle_position_%s" % axis] \
    Rvir=h.R
    print("halo center (Mpc):")
    print(center)
    coordsDM=np.array(coordinatesDM)
    for i in range(0,3):
        print(coordsDM[:,i])
        print(center[i])
        coordsDM[:,i]-=center[i]
        print(coordsDM[:,i])
        #print(i)
    #print(coordinatesDM)
    for i in range(0,3):
        r2+=(coordsDM[:,i])**2.
        #c2+=(center[i])**2.
    r=np.sqrt(r2)
    print(r)
    #coords=coordinatesDM[np.abs(r-np.sqrt(c2)<Rvir)]
    coords=coordsDM[r<=Rvir]
    print("# of virialized particles:%d"%len(coords))
    print(coords)
    #coords[:,0]-=center[0]
    #coords[:,1]-=center[1]
    #coords[:,2]-=center[2]
    #print(coords[0,:])
    fig = plt.figure(figsize=plt.figaspect(1))
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(xp,yp,zp,c='black',alpha=0.1,marker='.',s=1)
    #plt.show()
    #ax.quiver(X, Y, Z, U, V, W)
    #ax.set_xlim([-1, 0.5])
    #ax.set_ylim([-1, 1.5])
    #ax.set_zlim([-1, 8])
    Pmass=ad[("all","particle_mass")].in_units('Msun')
    print("Individual particle mass: %g"%Pmass[0])
    #IDsDM = ad[("Halo","ParticleIDs")]
    #print(len(IDsDM))
    hid =h.id# halo.quantities['particle_identifier']
    #halos = HaloFinder(ds, ptype=Halo, dm_only=False, total_mass=None)
    #ind = halos[0]["particle_index"] # list of particles IDs in this halo
    #print(len(ind))
    # REMOVE
    #Rvir=10
	# Rem
    bins=4
    iteLim=2
    #convLim=5 nor need, we just compare two
    #Rbins=np.logspace(0,Rvir,bins)#(Rvir/bins,Rvir,bins)
    Rbins=np.linspace(0,Rvir,bins+1)
    print("Rbins:")
    print(Rbins)
    axis=np.array([Rbins[1],Rbins[1],Rbins[1]])
    orientation=np.identity(3)#zeros((3,3))#.array([0,0,0],[0,0,0],[0,0,0])
    a=[0]*len(Rbins)
    b=[0]*len(Rbins)
    c=[0]*len(Rbins)
    b_a=[0]*len(Rbins)
    c_a=[0]*len(Rbins)
    v0=1#ell.volume
    for i in range(0,len(Rbins)-1):
        iteration=0
        convergence=False
        conv=0
        while(not(convergence) and iteration<iteLim):
            s=np.array([[1,0,0,],[0,1,0,],[0,0,1]])
            print("halo %d -bin %d -iteration %d"% (hid,i+1, iteration+1))
            ell=ellipsoid(axis,orientation)
            s=ell.ShapeTesnsor(coords,Pmass[0],Rbins[i],Rbins[i+1])
            ell.PlotEllipsoid(ax,center)
            #plt.pause(0.05)
            if (iteration==0):
                v0=ell.volume()
            print("shape tensor:")
            print(np.array(s))
            axisNew,orientationNew=LA.eig(s)
            print("eigenvalues & eigenvectors:")
            print(axisNew)
            print(orientationNew)
            #axisNew=np.array([1,1,1]) #1 just for test
            #orientationNew=np.array([0,0,0],[0,0,0],[0,0,0])#orientationNew # 0 just for test
            #if() what if there was ne eignevalue?
            newell=ellipsoid(axisNew,orientationNew)
            if iteration>0:
                comp=CompareEllipsoids(ell,newell)
                if comp==True:
                    conv+=1
                    if conv>=1:
                        convergence=True
                else:
                    conv=0
                #if conv>=2:
                #    convergence=True#CompareEllipsoids(ell,newell)
                if(not convergence):
                    #iteration+=1  #  new_list = [x+1 for x in my_list]
                    vol=reduce(mul,axisNew)
                    norm=(v0/vol)**(1./3.)
                    axis=[ax*norm for ax in axisNew]
                    print("normalized axis:")
                    print(axis)
                    orientation=orientationNew
                if(iteration>=iteLim):
                    print("S didn't converge for halo %d"%hid)
                    convergence=True
            else:
                vol=reduce(mul,axisNew)
                print(vol)
                norm=(v0/vol)**(1./3.)
                axis=[ax*norm for ax in axisNew]
                orientation=orientationNew
                print("normalized axis:")
                print(axis)
                #if (i==0):
                #    v0=ell.volume()
            iteration+=1
        axis.sort()
        Rave=(Rbins[i]+Rbins[i+1])/2.
        FullShape.append(shape(h.id,h.R,h.M,Rave,axis))
        #a[i]=axis[0] # use max instead
        #b[i]=axis[1]
        #c[i]=axis[2] # use min instead
        #b_a[i]=b[i]/a[i]
        #c_a[i]=c[i]/a[i]
        #use the shape object instead
    #now to save these numbers somewhere
    # save halo id, center, bins, and shapes,
    print(FullShape[0].R)
    return FullShape

    #and let's plot these

#how to run: python ShapeAnalysis.py snapshot_file halo_catalog check_contamination extract_shape
#example: $python ShapeAnalysisTest.py snap_264 halos_0.0.bin 1 1

if __name__ == "__main__":
	p=4000
	UpperMass=1.0e13
	LowerMass=7.0e11

	center=np.zeros(3)
	center[0]=0
	center[1]=0
	center[2]=0
	n_particles = 20000
	h=halo(center,5.0e2,1.2e12,n_particles,0)
	ppx, ppy, ppz =1e2*np.random.normal(size=[3, n_particles])
	#np.shape(ppx))
	#ppx=range(0,10000,n_particles)
	#ppy=range(0,10000,n_particles)
	#ppz=range(0,10000,n_particles)
	ppm = np.ones(n_particles)
	data = {'particle_position_x': ppx,'particle_position_y': ppy,'particle_position_z': ppz,'particle_mass': ppm}
	bbox = 1.1*np.array([[min(ppx), max(ppx)], [min(ppy), max(ppy)], [min(ppz), max(ppz)]])
	#ds = yt.load_particles(data, length_unit=parsec, mass_unit=1e8*Msun, n_ref=256, bbox=bbox)
	ds = yt.load_particles(data, length_unit=Mpc, mass_unit=Msun, n_ref=256, bbox=bbox)
	#print(ds.field_list)
	print(ppx)

	fig2 = plt.figure(2)
	fig2.suptitle('Shapes')
	ax1 = fig2.add_subplot(221)
	ax2 = fig2.add_subplot(222)
	ax3 = fig2.add_subplot(223)
	ax4 = fig2.add_subplot(224)
	ax1.legend(loc=2)
	FinalHaloShape=[]
	print("Let's extract the shape!")
	HShape=GetShape(h,ds)
	ba=np.array(HShape[0].b_a)
	print(ba)
	pR=[]
	pb_a=[]
	pid=[]
	pc_a=[]
	pT=[]
	for s in HShape:
		#ax1.plot(s.R,s.b_a) or ax1.scatter(s.R,s.b_a,c='black', alpha=0.9, marker='.',s=15)
		#ax1.scatter( (s.R)*1000,s.b_a, alpha=0.9, marker='.',s=15)
		pR.append(s.R)
		pb_a.append(s.b_a)
		pc_a.append(s.c_a)
		pid.append(s.hid)
		pT.append(s.T)
	ax1.title.set_text('b/a')
	ax2.title.set_text('c/a')
	ax3.title.set_text('T')
	ax4.title.set_text('c/a - b/a')
	#ax2.plot(pR,pb_a,pR,pb_a,'o',label=str(pid))
	ax1.plot(pR,pb_a,label=str(pid[0]))
	ax2.plot(pR,pc_a,label=str(pid[0]))
	ax3.plot(pR,pT,label=str(pid[0]))
	ax4.plot(pc_a,pb_a,'o',label=str(pid[0]))
	ax1.legend(loc=3)
	ax2.legend(loc=3)
	ax3.legend(loc=3)
	ax4.legend(loc=4)
	fig3=plt.figure(4)
	rp=np.sqrt(ppx**2.+ppy**2.+ppz**2.)
	plt.hist(rp,bins=100)
	plt.show()


from django.contrib.auth.models import Permission
from django import forms
from .models import Proyecto, ProyectUser, RolProyecto, Sprint, UserStory, Daily
from sso.models import User
from django import forms
from django.forms.models import inlineformset_factory

class AgregarRolProyectoForm(forms.ModelForm):
    """
    Form para agregar un rol al proyecto.
    Se despliega la lista de permisos para que puedan seleccionarse los roles.
    """
    def __init__(self, *args, **kwargs):
        super(AgregarRolProyectoForm, self).__init__(*args, **kwargs)
        self.fields['permisos'] = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                                            choices=[(p.id, p.name) for p in Permission.objects.all() if
                                                                     p.codename.startswith('p_') and not p.codename.startswith('pg_') and not p.codename.startswith('p_acceder_proyecto')])
    class Meta:
        model = RolProyecto
        fields = ['nombre','permisos']

class UserAssignRolForm(forms.ModelForm):
    """
    Form para asignar un rol a los participantes del proyecto.
    """
    class Meta:
        model = RolProyecto
        fields = ['participantes']

    def __init__(self, *args, **kwargs):
        proyecto_id = kwargs.pop('pk_proy',None)
        proyecto = Proyecto.objects.get(id=proyecto_id)
        super(UserAssignRolForm, self).__init__(*args, **kwargs)
        self.fields['participantes'] = CustomUserMCF(queryset= proyecto.equipo.all(),
            widget=forms.CheckboxSelectMultiple
        )
        self.fields['participantes'].required = False

class CustomUserMCF(forms.ModelMultipleChoiceField):
    """ Un ModelMultipleChoiceField custom """
    def label_from_instance(self, member):
        return "%s" % member.first_name + " " + member.last_name

class ProyectoEditForm(forms.ModelForm):
    """
    Form de proyecto que recibe los parámetros asociados al nombre, duración del sprint, fecha de incio y fin
    y el equipo encargado del proyecto.
    """
    class Meta:
        model = Proyecto
        fields = ["nombreProyecto", "fechaInicio", "fechaFin"]

class ProyectoCreateForm(forms.ModelForm):
    """
    Form de proyecto que recibe los parámetros asociados al nombre, duración del sprint, fecha de incio y fin
    y el equipo encargado del proyecto.
    """
    class Meta:
        model = Proyecto
        fields = ["nombreProyecto", "fechaInicio", "fechaFin", "equipo"]

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user_id',None)
        user = User.objects.get(pk = user)
        super(ProyectoCreateForm,self).__init__(*args, **kwargs)
        self.fields['equipo'] = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
        choices=[(p.id, "%s" % p.first_name + " " + p.last_name) for p in User.objects.exclude(first_name__isnull=True).exclude(first_name__exact='').exclude(pk=user.pk) if p.has_perm('sso.pg_is_user')],
        required=False
    )

class ProyectoFinalizarForm(forms.ModelForm):
    """ Form para finalizar un Proyecto, no se muestran realmente campos pero el form es nescesario igual. """
    def __init__(self, *args, **kwargs):
        super(ProyectoFinalizarForm, self).__init__(*args, **kwargs)
        self.fields['estado_de_proyecto'].required = False
    class Meta:
        model = Proyecto
        fields = ["estado_de_proyecto",]

class ImportarRolProyectoForm(forms.Form):
    """
    Form para importar roles de proyecto. Se seleccionan de entre todos los proyectos existentes
    en el sistema y se extraen sus roles para desplegarse en pantalla.
    """
    class Meta:
        fields = ["roles"]

    def __init__(self, *args, **kwargs):
        proyecto_id = kwargs.pop('pk_proy',None)
        super(ImportarRolProyectoForm, self).__init__(*args, **kwargs)
        self.fields['roles'] = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
        choices=[(p.id, p.nombre) for p in RolProyecto.objects.exclude(proyecto__id=proyecto_id)]
    )

class AgregarParticipanteForm(forms.Form):
    """
    Form para agregar Participantes al Proyecto
    """
    class Meta:
        model = Proyecto
        fields = ['equipo']

    def __init__(self, *args, **kwargs):
        proyecto = kwargs.pop('instance',None)
        super().__init__(*args, **kwargs)
        self.fields['equipo'] = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
        choices=[(p.id, "%s" % p.first_name + " " + p.last_name) for p in User.objects.exclude(first_name__isnull=True).exclude(first_name__exact='').exclude(pk=proyecto.owner.pk).exclude(proyecto__id=proyecto.pk) if p.has_perm('sso.pg_is_user')]
    )

class DesarrolladorCreateForm(forms.ModelForm):
    """ Form para administrar el equipo de desarrolladores de un sprint. """

    def __init__(self, *args, **kwargs):
        proyect_id = kwargs.pop('proyecto',None)
        proyecto = Proyecto.objects.get(pk=proyect_id)
        super().__init__(*args, **kwargs)
        self.fields['usuario'] = forms.ModelChoiceField(
            empty_label="Opciones",
            queryset=proyecto.equipo.all() | User.objects.filter(pk=proyecto.owner.pk),
        )
        self.fields['horas_diarias'].required = True
        self.fields['usuario'].required = True
    class Meta:
        model = ProyectUser
        fields = ['usuario','horas_diarias']

class PermisoSolicitudForm(forms.Form):
    """ Form para solicitar más permisos al owner del proyecto. """
    asunto = forms.CharField(label='Asunto de la solitud', max_length=100, required=True)
    body = forms.CharField(widget=forms.Textarea,label='Solicitud',help_text='Especifique, que tipo de acceso o permisos necesita. Explique que acciones quiere hacer.',required=True)

class SprintCrearForm(forms.ModelForm):
    """ Form utilizado para la creación de un sprint. Se llenan los campos duración del Sprint y fechafin """
    class Meta:
        model = Sprint
        fields = ['duracionSprint']

class SprintModificarForm(forms.ModelForm):
    """ Form para modificar la duración del sprint """
    class Meta:
        model = Sprint
        fields = ['duracionSprint']

class SprintFinalizarForm(forms.ModelForm):
    """ Form para la finalización de los sprints """

    def __init__(self, *args, **kwargs):
        super(SprintFinalizarForm, self).__init__(*args, **kwargs)
        self.fields['estado_de_sprint'].required = False
    class Meta:
        model = Sprint
        fields = ['estado_de_sprint']

class UserstoryAprobarForm(forms.ModelForm):
    """ From para aprobar un user story temporal. No muestra campos pero es nescesario. """
    def __init__(self, *args, **kwargs):
        super(UserstoryAprobarForm, self).__init__(*args, **kwargs)
        self.fields['estado_aprobacion'].required = False
    class Meta:
        model = UserStory
        fields = ['estado_aprobacion']

EquipoFormset = inlineformset_factory(Sprint, ProyectUser,fields=('usuario','horas_diarias',),form=DesarrolladorCreateForm,can_delete=True)
class AgregarUserStoryForm(forms.ModelForm):
    """
    Form para crear un user story nuevo, renderiza los campos de prioridad, nombre y descripción
    """
    def __init__(self, *args, **kwargs):
        super(AgregarUserStoryForm, self).__init__(*args, **kwargs)
        self.fields['prioridad_user_story'] = forms.ChoiceField(
            widget= forms.RadioSelect,
            choices=[('B','Baja'),('A','Alta'),('M','Media'),('E','Emergencia')]
        )

    class Meta:
        model = UserStory
        fields = ['nombre','descripcion','prioridad_user_story']

class UserStoryAssingForm(forms.ModelForm):
    """ Form utilizado por el scrum master para asignar un user story a un desarrollador y estimar el tiempo de completar el user story """
    def __init__(self, *args, **kwargs):
        sprint_id = kwargs.pop('sprint_id',None)
        sprint = Sprint.objects.get(pk=sprint_id)
        super().__init__(*args, **kwargs)
        self.fields['encargado'] = forms.ModelChoiceField(
            empty_label="Desarrollador",
            queryset=sprint.sprint_team.all(),
        )
        self.fields['tiempo_estimado_scrum_master'].required = True
    class Meta:
        model = UserStory
        fields = ['tiempo_estimado_scrum_master','encargado','tiempo_estimado_dev']

class UserStoryDevForm(forms.ModelForm):
    """ Form utilizado por el encargado asignado al user story para estimar el tiempo de duración de completar el user story """
    def __init__(self, *args, **kwargs):
        sprint_id = kwargs.pop('sprint_id',None)
        super().__init__(*args, **kwargs)
    class Meta:
        model = UserStory
        fields = ['tiempo_estimado_dev']

class QaForm(forms.Form):
    """ Form de qa. Se llena con un comentario de evaluación que es requerido y que se envia posteriormente al encargado del user story """
    comentario = forms.CharField(widget=forms.Textarea,label='Comentario',help_text='De un comentario o recomendación.',required=True)

class DailyForm(forms.ModelForm):
    """
    Form para crear y modificar un Daily. Se muestran los campos de duración, del comentario de impedimientos y del comentario de progresos.
    """
    def __init__(self, *args, **kwargs):
        super(DailyForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Daily
        fields = ['fecha','duracion','impedimiento_comentario','progreso_comentario']

class ReasignarForm(forms.ModelForm):
    """ Form para reasignar un user story a otro dev del sprint. Solo se cambiará el campo encargado del user story. """
    def __init__(self, *args, **kwargs):
        sprint_id = kwargs.pop('sprint_id',None)
        sprint = Sprint.objects.get(pk=sprint_id)
        pk_proy = kwargs.pop('pk_proy',None)
        proyecto = Proyecto.objects.get(pk=pk_proy)
        user = User.objects.filter(pk=proyecto.owner.pk)
        super().__init__(*args, **kwargs)
        self.fields['encargado'] = forms.ModelChoiceField(
            empty_label="Desarrollador",
            queryset=sprint.sprint_team.all(),
        )
    class Meta:
        model = UserStory
        fields = ['encargado']

class IntercambiarDevForm(forms.ModelForm):
    """ Form para intercambiar un desarrollador de un sprint con otro asociado al proyecto. Solo se cambai el usuario para cambiar el ProyectUser. """
    def __init__(self, *args, **kwargs):
        pk_proy = kwargs.pop('pk_proy',None)
        proyecto = Proyecto.objects.get(pk=pk_proy)
        user = User.objects.filter(pk=proyecto.owner.pk)
        super().__init__(*args, **kwargs)
        self.fields['usuario'] = forms.ModelChoiceField(
            empty_label="Desarrollador",
            queryset=proyecto.equipo.all() | user,
        )
    class Meta:
        model = ProyectUser
        fields = ['usuario']


import imutils
import cv2,os
import numpy as np
from django.conf import settings
from tensorflow.keras.models import load_model

oimgPath = os.path.join(settings.BASE_DIR,"imgs/original.jpg")
pimgPath = os.path.join(settings.BASE_DIR,"imgs/processed.jpg")
fPath = os.path.join(settings.BASE_DIR,"imgs/frame.jpg")
sPath = os.path.join(settings.BASE_DIR,"imgs/mvisia.jpg")

prototxtPathFACE = os.path.join(settings.BASE_DIR, "face_detector/deploy.prototxt")
weightsPathFACE = os.path.join(settings.BASE_DIR,"face_detector/res10_300x300_ssd_iter_140000.caffemodel")
faceNet = cv2.dnn.readNet(prototxtPathFACE, weightsPathFACE)

prototxtPathAGE = os.path.join(settings.BASE_DIR, "face_detector/age_deploy.prototxt")
weightsPathAGE = os.path.join(settings.BASE_DIR,"face_detector/age_net.caffemodel")
ageNet = cv2.dnn.readNetFromCaffe(prototxtPathAGE, weightsPathAGE)

class Camera(object):
	def __init__(self):
		self.video = cv2.VideoCapture(0)

	def __del__(self):
		self.video.release()

	def stream(self):
		success, image = self.video.read()
		ret, jpeg = cv2.imencode('.jpg', image)
		cv2.imwrite(fPath,image)
		return jpeg.tobytes()

class Operacoes(object):

	def get_frame(self):
		img = cv2.imread(fPath)
		if img is None:
			img = cv2.imread(sPath)
		cv2.imwrite(oimgPath,img)
		cv2.imwrite(pimgPath,img)
		return img

	def update_process(self):
		img = cv2.imread(pimgPath)
		if img is None:
			img = cv2.imread(sPath)
		return img

	def binarize(self, b, g, r, k):
		img = cv2.imread(pimgPath)
		rows,cols,channels = img.shape
		mask = np.zeros((rows,cols, 1),np.uint8)
		for i in range(rows):
			for j in range(cols):
				if ((img[i,j,0]*int(b) + img[i,j,1]*int(g) + img[i,j,2]*int(r)) > int(k)):
					mask[i,j] = 255
				else:
					mask[i,j] = 0
		cv2.imwrite(pimgPath,mask)
		return mask

	def crop(self,x,dx,y,dy):
		pimg = cv2.imread(pimgPath)
		crop_img = pimg[int(y):int(dy), int(x):int(dx)]
		cv2.imwrite(pimgPath,crop_img)
		return crop_img

	def background_subtract(self):
		oimg = cv2.imread(oimgPath)
		cap = cv2.VideoCapture(0)
		ret, img = cap.read()
		sub = (img-oimg)
		cv2.imwrite(pimgPath,sub)
		return sub

	def detect_and_predict_age(self,frame, faceNet, ageNet):
		AGE_BUCKETS = ["(0-2)", "(4-6)", "(8-12)", "(15-20)", "(25-32)","(38-43)", "(48-53)", "(60-100)"]
		(h, w) = frame.shape[:2]
		blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300),(104.0, 177.0, 123.0))
		faceNet.setInput(blob)
		detections = faceNet.forward()

		for i in range(0, detections.shape[2]):
			confidence = detections[0, 0, i, 2]
			if confidence > 0.5:
				box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
				(startX, startY, endX, endY) = box.astype("int")
				face = frame[startY:endY, startX:endX]
				faceBlob = cv2.dnn.blobFromImage(face, 1.0, (227, 227),(78.4263377603, 87.7689143744, 114.895847746),swapRB=False)
				ageNet.setInput(faceBlob)
				preds = ageNet.forward()
				i = preds[0].argmax()
				age = AGE_BUCKETS[i]
				ageConfidence = preds[0][i]
				text = format(age)
				y = startY - 10 if startY - 10 > 10 else startY + 10
				cv2.rectangle(frame, (startX, startY), (endX, endY),(0, 0, 255), 2)
				cv2.putText(frame, text, (startX, y),
				cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
		return frame

	def detect_faces_and_lambda(self):
		frame = cv2.imread(pimgPath)
		frame = imutils.resize(frame, width=650)
		frame = self.detect_and_predict_age(frame, faceNet, ageNet)
		return frame


import torch

class SimpleBackbone(torch.nn.Module):
    def __init__(self, num_channels):
        super(SimpleBackbone, self).__init__()

        def down_layer(in_channels, out_channels):
            return torch.nn.Sequential(
                torch.nn.Conv2d(in_channels, out_channels, 4, stride=2, padding=1),
                torch.nn.BatchNorm2d(out_channels, eps=1e-3, momentum=0.03),
                torch.nn.ReLU(inplace=True),
                #torch.nn.Conv2d(out_channels, out_channels, 3, padding=1),
                #torch.nn.ReLU(inplace=True),
            )

        def up_layer(in_channels, out_channels):
            return torch.nn.Sequential(
                torch.nn.ConvTranspose2d(in_channels, out_channels, 4, stride=2, padding=1),
                torch.nn.BatchNorm2d(out_channels, eps=1e-3, momentum=0.03),
                torch.nn.ReLU(inplace=True),
            )

        self.down1 = down_layer(num_channels, 32) # -> 400x400
        self.down2 = down_layer(32, 64) # -> 200x200
        self.down3 = down_layer(64, 128) # -> 100x100
        self.down4 = down_layer(128, 256) # -> 50x50
        self.down5 = down_layer(256, 512) # -> 25x25
        self.features = torch.nn.Sequential(
            torch.nn.Conv2d(512, 512, 3, padding=1),
            torch.nn.ReLU(inplace=True),
            torch.nn.Conv2d(512, 512, 3, padding=1),
            torch.nn.ReLU(inplace=True),
            torch.nn.Conv2d(512, 512, 3, padding=1),
            torch.nn.ReLU(inplace=True),
        )
        self.up1 = up_layer(512, 256) # -> 50x50
        self.up2 = up_layer(256+256, 128) # -> 100x100
        self.out_channels = 128
        print(self)

    def forward(self, x):
        down1 = self.down1(x)
        down2 = self.down2(down1)
        down3 = self.down3(down2)
        down4 = self.down4(down3)
        down5 = self.down5(down4)
        features = self.features(down5)
        up1 = self.up1(features)
        up2 = self.up2(torch.cat([up1, down4], dim=1))
        return {'0': up2}


"""Falcon Toolkit: Console Utils.

This file contains tools to help with displaying data on the console in a user-friendly,
colourful and/or helpful way.
"""
import platform

ESC = '\033'
OSC = ESC + ']'
ST = ESC + '\\'

def build_hyperlink(target: str, text: str, link_id: str = None):
    """Build a clickable hyperlink that is compatible with modern shells."""
    if link_id:
        id_str = "id=" + link_id
    else:
        id_str = ""
    return f'{OSC}8;{id_str};{target}{ST}{text}{OSC}8;;{ST}'

def build_file_hyperlink(file_path: str, text: str, link_id: str = None):
    """Extend the build_hyperlink function to support file paths, cross-platform."""
    if platform.system() == "Windows":
        hostname = "localhost"
    else:
        hostname = platform.node()

    if file_path.startswith('/'):
        file_path = file_path[1:]

    uri_file_path = f"file://{hostname}/{file_path}"
    return build_hyperlink(uri_file_path, text, link_id)


from django.urls import reverse
from rest_framework.test import APITestCase, APIClient
from rest_framework.views import status
from .models import Politoon
from .serializers import ToonsSerializer

# tests for views

class BaseViewTest(APITestCase):
    client = APIClient()

    @staticmethod
    def create_toon(name="", majorRole="", party=""):
        if name != "" and majorRole != "" and party != "":
            Politoon.objects.create(name=name, majorRole=majorRole, party=party, dob='2012-11-11', date='2012-11-11')

    def setUp(self):
        # add test data
        self.create_toon("Ritik kumar", "President", "Republic")
        self.create_toon("yess you", "devs", "labourers")

class GetAllPolitoonTest(BaseViewTest):

    def test_get_all_Politoon(self):
        """
        This test ensures that all Politoon added in the setUp method
        exist when we make a GET request to the Politoon/ endpoint
        """
        # hit the API endpoint
        response = self.client.get(
            reverse("toons-all")
        )
        data = response.data
        print(response.status_code)
        print(data)

        # fetch the data from db
        expected = Politoon.objects.all()
        serialized = ToonsSerializer(expected, many=True)
        self.assertEqual(response.data, serialized.data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)


import torch.utils.data as data
from os import listdir
from os.path import join
from PIL import Image
from torchvision.transforms import Compose, ToTensor, Resize, RandomCrop, RandomHorizontalFlip, RandomVerticalFlip, Normalize
import PIL
import matplotlib.pyplot as plt
import numpy as np
import os
import torch
import matplotlib.cm as cm
from torchvision import transforms
import copy
import random

batch_size = 4
patch_size = 96
image_size = 320
upscale_factor = 4
save_on_disk_train = False
save_on_disk_test = False

seed = 324
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)

def is_image_file(filename):
    return any(filename.endswith(extension) for extension in [".png"])

def load_img(filepath):
    img = Image.open(filepath).convert('L')
    return img

class DatasetFromFolder(data.Dataset):
    def __init__(self, image_dir, input_transform=None, target_transform=None, bic_transform = None):
        super(DatasetFromFolder, self).__init__()
        self.image_filenames = [join(image_dir, x) for x in listdir(image_dir) if is_image_file(x)]

        self.input_transform = input_transform
        self.target_transform = target_transform
        self.bic_transform = bic_transform

        self.std_transform = Compose([
            Normalize([0.15], [0.15]),
        ])

    def __getitem__(self, index):
        input = load_img(self.image_filenames[index])
        target = copy.deepcopy(input)

        if self.target_transform:
            target = self.target_transform(target)

        input_lr = copy.deepcopy(target)
        if self.input_transform:
            input_lr = transforms.ToPILImage()(input_lr).convert("L")
            input_lr = self.input_transform(input_lr)

        bic = copy.deepcopy(input_lr)
        if self.bic_transform:
            bic = transforms.ToPILImage()(bic).convert("L")
            bic = self.bic_transform(bic)

        return input_lr, bic, target

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

def calculate_valid_crop_size(crop_size, upscale_factor):
    return crop_size - (crop_size % upscale_factor)

def input_transform(crop_size, upscale_factor):
    return Compose([
        Resize(crop_size // upscale_factor, PIL.Image.BICUBIC),
        ToTensor(),
    ])

def target_transform(crop_size):
    return Compose([
        RandomCrop(crop_size),
        RandomHorizontalFlip(0.5),
        RandomVerticalFlip(0.5),
        ToTensor(),
    ])

def bic_transform(crop_size):
    return Compose([
        Resize(crop_size, PIL.Image.BICUBIC),
        ToTensor(),
    ])

def get_training_set(upscale_factor, patch_size):
    train_dir='Subset_images/train_HR/'
    crop_size = calculate_valid_crop_size(patch_size, upscale_factor)
    return DatasetFromFolder(train_dir,
                             input_transform = input_transform(crop_size, upscale_factor),
                             target_transform = target_transform(crop_size),
                             bic_transform  = bic_transform(crop_size))

def get_test_set(upscale_factor, image_size):
    test_dir = 'Subset_images/test_HR/'
    return DatasetFromFolder(test_dir,
                             input_transform = input_transform(image_size, upscale_factor),
                             target_transform = Compose([ToTensor(),]),
                             bic_transform  = bic_transform(image_size))

def saveImage(img, epoch, batch, img_type, model, type_result):
    folder_path = "Results/" + model + "/" + type_result + "/"

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

    file_path = folder_path + str(epoch) + "_" + str(batch) + "_" + img_type + ".png"
    img = img.squeeze().cpu().detach().numpy()
    plt.imsave(file_path, img, cmap = plt.get_cmap('gray'))

def save_Crops(dataset, type_set):
    save_path = 'Subset_images/'
    lr_crops = type_set + '_LR_crops/'
    hr_crops = type_set + '_HR_crops/'
    bic_crops = type_set + '_bic_crops/'

    lr_folder_path = save_path + lr_crops
    hr_folder_path = save_path + hr_crops
    bic_folder_path = save_path + bic_crops

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

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

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

    num_images = 0

    for input_lr, bic, target in dataset:
        file = str(num_images) + '.png'
        path_lr = os.path.join(lr_folder_path, file)
        path_hr = os.path.join(hr_folder_path, file)
        path_bic = os.path.join(bic_folder_path, file)

        input_lr = np.transpose(input_lr.cpu().detach().numpy(), (1, 2, 0))
        target = np.transpose(target.cpu().detach().numpy(), (1, 2, 0))
        bic = np.transpose(bic.cpu().detach().numpy(), (1, 2, 0))

        plt.imsave(path_lr, input_lr[:, :, 0], cmap = plt.get_cmap('gray'))
        plt.imsave(path_hr, target[:, :, 0], cmap = plt.get_cmap('gray'))
        plt.imsave(path_bic, bic[:, :, 0], cmap = plt.get_cmap('gray'))
        num_images += 1

if save_on_disk_train:
    dataset_train = get_training_set(upscale_factor, patch_size)
    save_Crops(dataset_train, "train")

if save_on_disk_test:
    dataset_test = get_test_set(upscale_factor, image_size)
    save_Crops(dataset_test, "test")


import os
import cv2
import tensorflow as tf
import pathlib

#import functions from other files
from fr_utils import *
from inception_blocks_v2 import *

def triplet_loss(y_true, y_pred, alpha=0.3):
    """
    Implementation of the triplet loss as defined by formula (3)

    Arguments:
    y_pred -- python list containing three objects:
            anchor -- the encodings for the anchor images, of shape (None, 128)
            positive -- the encodings for the positive images, of shape (None, 128)
            negative -- the encodings for the negative images, of shape (None, 128)

    Returns:
    loss -- real number, value of the loss
    """

    anchor, positive, negative = y_pred[0], y_pred[1], y_pred[2]

    # Step 1: Compute the (encoding) distance between the anchor and the positive, you will need to sum over axis=-1
    pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), axis=-1)
    # Step 2: Compute the (encoding) distance between the anchor and the negative, you will need to sum over axis=-1
    neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), axis=-1)
    # Step 3: subtract the two previous distances and add alpha.
    basic_loss = tf.add(tf.subtract(pos_dist, neg_dist), alpha)
    # Step 4: Take the maximum of basic_loss and 0.0. Sum over the training examples.
    loss = tf.reduce_sum(tf.maximum(basic_loss, 0.0))

    return loss

def create_model():
    global FRmodel
    #call the function to create a face recognition model
    FRmodel = faceRecoModel(input_shape=(3, 96, 96))
    #compile the model
    FRmodel.compile(optimizer = 'adam', loss = triplet_loss, metrics = ['accuracy'])
    #load weights for the model
    load_weights_from_FaceNet(FRmodel)

def check_face(face, model):
    #Get path to my image
    myimage = Path("/images/me.jpg")
    #Get the embeding of the input image
    testembed = img_to_embedding(face, model)
    #Get embed of my image
    myembed = img_path_to_encoding(myimage, model)
    #if they match, return true
    if(testembed == myembed):
        return True
    #otherwise false
    return False

def draw_verf():
    print("Yup it matches.")

def capture_face():
    global FRmodel
#Capture video with opencv
    cam = cv2.VideoCapture(0)
#read in the frame
    ret, frame = cam.read()
#convert frame to gray
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#setup the cascade classifier
    faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#find all the faces in the image
    faces = faceCascade.detectMultiscale(frame)

#Lets pass the faces through the network
    for face in faces:
        if(check_face(face, FRmodel)):
            draw_verf(face)

def main():
    #Create the model
    create_model()
    #Run forever
    while(True):
        capture_face()

main()


import logging
import os
from typing import Any, Dict, Tuple

from kserve.errors import InferenceError
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

from model import LLM

class NLLB(LLM):
    def __init__(self, model_name: str):
        self.src_lang = os.environ.get("SRC_LANG", "eng_Latn")
        super().__init__(model_name)

    def load_tokenizer(self):
        tokenizer = AutoTokenizer.from_pretrained(
            self.model_path,
            local_files_only=True,
            src_lang=self.src_lang,
            low_cpu_mem_usage=True,
        )
        return tokenizer

    def load(self) -> Tuple[AutoModelForSeq2SeqLM, AutoTokenizer]:
        model = AutoModelForSeq2SeqLM.from_pretrained(
            self.model_path,
            local_files_only=True,
            trust_remote_code=True,
            low_cpu_mem_usage=True,
            load_in_8bit=self.quantized,
        )
        tokenizer = self.load_tokenizer()
        self.ready = True
        return model, tokenizer

    def preprocess(
        self, inputs: Dict[str, Any], headers: Dict[str, str] = None
    ) -> Dict[str, Any]:
        """
        Reading the source and the target language from the request.
        The list of available languages can be found in the paper "No Language Left Behind: Scaling Human-Centered Machine Translation"
        https://arxiv.org/pdf/2207.04672.pdf
        """

        try:
            self.check_gpu()
            prompt = inputs.get("prompt")
            tgt_lang = inputs.get("tgt_lang")
            result_length = inputs.get("result_length", 0)
            if "src_lang" in inputs:
                self.src_lang = inputs["src_lang"]
                self.tokenizer = self.load_tokenizer()
            inputs = self.tokenizer(prompt, return_tensors="pt").to(self.device)
            inputs["result_length"] = result_length + inputs["input_ids"].size()[1]
            inputs["tgt_lang"] = tgt_lang
            return inputs
        except RuntimeError:
            logging.exception("An error has occurred in preprocess.")
            raise InferenceError(
                "An error has occurred in preprocess. Please contact the ML-team "
                "if the issue persists."
            )

    def predict(
        self, request: Dict[str, Any], headers: Dict[str, str] = None
    ) -> Dict[str, Any]:
        tgt_lang = request.get("tgt_lang")
        logging.info(f"Translating from {self.src_lang} to {tgt_lang}")
        translated_tokens = self.model.generate(
            request["input_ids"],
            forced_bos_token_id=self.tokenizer.lang_code_to_id[tgt_lang],
            max_length=request["result_length"],
        )

        response = self.tokenizer.batch_decode(
            translated_tokens, skip_special_tokens=True
        )[0]
        return {"model_name": self.model_name, "response": response}


from flask import Flask,render_template,redirect,request
from mysqlconnection import connectToMySQL

# from mysqlconnection import connectToMySQL

app = Flask(__name__)

@app.route('/')
def index():
    mysql= connectToMySQL('users_db')
    users = mysql.query_db ('SELECT * FROM users;')
    print(users)
    return render_template("index.html", all_users=users)

@app.route('/create', methods=['POST'])
def add_users_to_db():
    query = "INSERT INTO users ( first_name , last_name , email, created_at, updated_at) VALUES (%(first_name)s,%(last_name)s, %(email)s,NOW(),NOW());"
    data = {
    'first_name': request.form['first_name'],
    'last_name': request.form['last_name'],
    'email': request.form['email']
    }
    bd = connectToMySQL('users_db')
    bd.query_db(query,data)
    print(bd)
    return redirect('/')

@app.route('/create_page')
def creat_page():
    return render_template('create.html')

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


import functools
import json
import os.path
from pathlib import Path
from typing import Optional, cast

import typer
from pykuda2 import Kuda, APIResponse, Mode
from typer import get_app_dir
from rich import print as rprint

APP_NAME = "kuda-cli"

CACHED_SETTINGS: Optional[dict] = None

def get_settings_path() -> Path:
    app_dir = get_app_dir(APP_NAME)
    if not os.path.isdir(app_dir):
        os.mkdir(app_dir)
    return Path(app_dir) / ".settings.json"

def get_all_settings() -> dict:
    global CACHED_SETTINGS
    if CACHED_SETTINGS:
        return CACHED_SETTINGS
    settings_path = get_settings_path()
    if not settings_path.is_file():
        with settings_path.open("w+") as f:
            f.write(json.dumps({}))
    with settings_path.open("r") as f:
        CACHED_SETTINGS = json.loads(f.read())
        return CACHED_SETTINGS

def get_settings(option: str) -> Optional[str]:
    all_settings = get_all_settings()
    return all_settings.get(option)

def update_settings(option: str, value: str):
    all_settings = get_all_settings()
    all_settings[option] = value
    settings_path = get_settings_path()
    with settings_path.open("w") as f:
        f.write(json.dumps(all_settings))

def reset_settings():
    global CACHED_SETTINGS
    CACHED_SETTINGS = None
    settings_path = get_settings_path()
    with settings_path.open("w+") as f:
        f.write(json.dumps({}))

def get_kuda_wrapper() -> "KudaSingleton":
    email = get_settings("email")
    api_key = get_settings("api_key")
    mode = get_settings("mode")
    mode = cast(Mode, mode)
    if not email:
        rprint(
            "[bold red]Error![/bold red] your email has not been configured. please run `kuda config <email> <api_key>`"
        )
        raise typer.Abort()
    if not api_key:
        rprint(
            "[bold red]Error![/bold red] your api_key as not been configured. please run `kuda config <email> <api_key>`"
        )
        raise typer.Abort()
    if not mode:
        rprint(
            "[bold red]Error![/bold red] your mode as not been configured. please run `kuda config <email> <api_key> --<mode>`"
        )
        raise typer.Abort()
    return KudaSingleton(email=email, api_key=api_key, mode=mode)

def strip_raw(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        response = func(*args, **kwargs)
        response.raw = None
        return response

    return wrapper

def override_output(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        response = func(*args, **kwargs)
        if kwargs["data_only"]:
            return response.data
        return response

    return wrapper

def colorized_print(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        response = func(*args, **kwargs)
        rprint(response)

    return wrapper

class KudaSingleton:
    instance: Optional[Kuda] = None

    def __init__(self, email: str, api_key: str, mode: Mode = Mode.DEVELOPMENT):
        ...

    def __new__(cls, *args, **kwargs):
        if not KudaSingleton.instance:
            KudaSingleton.instance = Kuda(*args, **kwargs)
        return KudaSingleton.instance

    def __getattr__(self, item):
        return getattr(self.instance, item)

    def __setattr__(self, key, value):
        return setattr(self.instance, key, value)


from rest_framework import serializers
from taggit_serializer.serializers import TagListSerializerField, TaggitSerializer

from apps.core.models import Resource, ResourceComment

class ResourceCommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = ResourceComment
        fields = [
            'id',
            'created_at',
            'last_updated_at',
            'commenter',
            'title',
            'content',
        ]
        read_only_fields = [
            'id',
            'created_at',
            'last_updated_at',
        ]

class ResourceSerializer(TaggitSerializer, serializers.ModelSerializer):
    comments = ResourceCommentSerializer(read_only=True, many=True)
    tags = TagListSerializerField()

    class Meta:
        model = Resource
        fields = [
            'id',
            'created_at',
            'last_updated_at',
            'name',
            'link',
            'creator',
            'approved',
            'comments',
            'tags',
        ]
        read_only_fields = [
            'id',
            'created_at',
            'last_updated_at',
        ]


from datetime import datetime

from pydantic import BaseModel

class TextFragment(BaseModel):
    """
    Receives a text fragment which is used for searching the documents.
    """
    text: str

    class Config:
        schema_extra = {
            'example': {
                'secret': "Text",
            }
        }

class Document(BaseModel):
    """
    The document with text from the database.
    """
    id: int
    text: str
    rubrics: list[str]
    created_date: datetime

    class Config:
        schema_extra = {
            'example': {
                'id': 1,
                'text': "Matched text",
                'rubrics': ['rubric-1', 'rubric-2'],
                'created_date': '2019-11-12T21:10:52'
            }
        }


from automata import Automata

class DFAFromNFA:

    def __init__(self, nfa):
        self.dfa = self._build_DFA(nfa)
        self.min_dfa = self._minimize_DFA()

    def get_DFA(self):
        return self.dfa

    def get_minimized_DFA(self):
        return self.min_dfa

    def _build_DFA(self, nfa: Automata):
        all_states = {}
        e_closure = {}
        count = 1

        state1 = nfa.get_e_closure(nfa.start_state)
        e_closure[nfa.start_state] = state1
        dfa = Automata(nfa.language)
        dfa.set_start_state(count)
        states = [[state1, count]]
        all_states[count] = state1
        count += 1

        while len(states):
            [state, from_index] = states.pop()
            for char in dfa.language:
                tr_states = nfa.get_transitions(state, char)
                for s in list(tr_states)[:]:
                    if s not in e_closure:
                        e_closure[s] = nfa.get_e_closure(s)
                    tr_states = tr_states.union(e_closure[s])
                if len(tr_states):
                    if tr_states not in all_states.values():
                        states.append([tr_states, count])
                        all_states[count] = tr_states
                        to_index = count
                        count += 1
                    else:
                        to_index = [k for k, v in all_states.items() if v == tr_states][0]
                    dfa.add_transitions(from_index, to_index, char)

        for value, state in all_states.items():
            if nfa.final_states[0] in state:
                dfa.add_final_states(value)

        return dfa

    def _minimize_DFA(self):
        states = list(self.dfa.states)
        n = len(states)
        unchecked = dict()
        count = 1
        distinguished = []
        equivalent = dict(zip(range(len(states)), [{s} for s in states]))
        pos = dict(zip(states, range(len(states))))

        for i in range(n - 1):
            for j in range(i + 1, n):
                if not ([states[i], states[j]] in distinguished or [states[j], states[i]] in distinguished):
                    eq = 1
                    to_append = []
                    for char in self.dfa.language:
                        s1 = self.dfa.get_transitions(states[i], char)
                        s2 = self.dfa.get_transitions(states[j], char)
                        if len(s1) != len(s2):
                            eq = 0
                            break
                        if len(s1) > 1:
                            raise BaseException("Multiple transitions detected in DFA")
                        elif len(s1) == 0:
                            continue
                        s1 = s1.pop()
                        s2 = s2.pop()
                        if s1 != s2:
                            if [s1, s2] in distinguished or [s2, s1] in distinguished:
                                eq = 0
                                break
                            else:
                                to_append.append([s1, s2, char])
                                eq = -1
                    if eq == 0:
                        distinguished.append([states[i], states[j]])
                    elif eq == -1:
                        s = [states[i], states[j]]
                        s.extend(to_append)
                        unchecked[count] = s
                        count += 1
                    else:
                        p1 = pos[states[i]]
                        p2 = pos[states[j]]
                        if p1 != p2:
                            st = equivalent.pop(p2)
                            for s in st:
                                pos[s] = p1
                            equivalent[p1] = equivalent[p1].union(st)

        new_found = True
        while new_found and len(unchecked) > 0:
            new_found = False
            for p, pair in list(unchecked.items()):
                for tr in pair[2:]:
                    if [tr[0], tr[1]] in distinguished or [tr[1], tr[0]] in distinguished:
                        unchecked.pop(p)
                        distinguished.append([pair[0], pair[1]])
                        new_found = True
                        break

        for pair in unchecked.values():
            p1 = pos[pair[0]]
            p2 = pos[pair[1]]
            if p1 != p2:
                st = equivalent.pop(p2)
                for s in st:
                    pos[s] = p1
                equivalent[p1] = equivalent[p1].union(st)

        if len(equivalent) == len(states):
            return self.dfa
        else:
            return self.dfa.build_from_equivalent_states(pos)


# **************************************************************************** #
#                                                                              #
#                                                         :::      ::::::::    #
#    visu.py                                            :+:      :+:    :+:    #
#                                                     +:+ +:+         +:+      #
#    By: tbrizon <tbrizon@student.42.fr>            +#+  +:+       +#+         #
#                                                 +#+#+#+#+#+   +#+            #
#    Created: 2019/10/25 14:10:24 by tbrizon           #+#    #+#              #
#    Updated: 2019/10/25 14:10:25 by tbrizon          ###   ########.fr        #
#                                                                              #
# **************************************************************************** #

import argparse
import matplotlib.pyplot as plt
import numpy as np
import networkx as nx
import os
from pprint import pprint
from matplotlib.animation import FuncAnimation
from reader import parse
from fourmisses import Ant
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
from matplotlib._png import read_png
import matplotlib.image as mpimg

# Colors
bg_color = '#000000'
edge_color = '#A9A9A9'
text_color = '#d4d1de'
default_node_color = '#540606'
ant_colors = ['#08d141', '#bd21bf', '#ff6f00', '#66B615']

# Node size
node_size = 1000

def highlight_node(node, highlight_color):
    node.set_color(highlight_color)
    node.set_edgecolor(edge_color)

def make_ants(pos, speed_rate, data):
    list_ants = []
    for ant_num in range(1, int(data['ants']) + 1):
        ant = Ant(ant_num)
        ant.set_path(data)
        ant.set_location(pos, data)
        ant.set_trip(pos, speed_rate, data)
        ant.color = ant_colors[ant_num % 4]
        list_ants.append(ant)

    return (list_ants)

def draw_ant(position, color, ant_img, args):

    i = 5
    ax = fig.add_subplot(111)
    ant_img = read_png('./images/Fourmisse.png')
    imagebox = OffsetImage(ant_img, zoom=.03)

    if args.images == True and i == 5:
        xy = [position[0], position[1]]
        ab = AnnotationBbox(imagebox, xy,
            xycoords='data',
            boxcoords="offset points")
        ax.add_artist(ab)
    else:
        ant = plt.plot([position[0]], [position[1]], color=color, marker='.', markersize=40.0)
        return (ant)

def draw_node(node_name, node_color, node_size, edge_color):
    node_list = []
    node_list.append(node_name)
    node = nx.draw_networkx_nodes(
        G,
        pos,
        nodelist=node_list,
        node_color=node_color,
        node_size=node_size)
    node.set_edgecolor(edge_color)
    return (node)

def draw_nodes(data, node_color, node_size, edge_color):
    nodes = {}
    for name in data['nodes']:
        if name == data['start'] or name == data['end']:
            node = draw_node(name, node_color, node_size * 7, edge_color)
        else:
            node = draw_node(name, node_color, node_size, edge_color)
        nodes[name] = node
    return (nodes)

def re_init(num, G, pos, speed_rate, data, ants, args, ant_img):

    fig.clear()
    node_size = 800

    if args.images == True:
        background = plt.imread('./images/Background.png')
        plt.imshow(background, zorder=0, extent=[-1.1, 0, 0, 1.10])
        plt.imshow(background, zorder=0, extent=[0, 1.10, 0, 1.10])
        plt.imshow(background, zorder=0, extent=[-1.1, 0, -1.10, 0])
        plt.imshow(background, zorder=0, extent=[0, 1.10, -1.10, 0])

    # nodes and tunnels
    tunnels = nx.draw_networkx_edges(G, pos, edge_color=edge_color, style = 'dotted',width=2.0)
    nodes = draw_nodes(data, default_node_color,
                       node_size, edge_color)
    # draw the ants
    for ant in ants:
        if num < len(ant.trip):
            draw_ant(ant.trip[num], ant.color, ant_img, args)
    room_names = nx.draw_networkx_labels(G,
                                         pos,
                                         font_size=10,
                                         labels=dict([(data['start'],
                                                       'START'),
                                                      (data['end'],
                                                       'END')]),
                                         font_color=text_color)
    fig.set_facecolor(bg_color)
    plt.axis('off')

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("map", help="Path to map file", type=str)
    parser.add_argument("-s", "--solution",
                        help="File path to solution", type=str)
    parser.add_argument("--images", help="Background activation = 1, ant activation = 2 both = 3", action="store_true")
    args = parser.parse_args()
    if not os.path.exists(args.map):
        raise IOError("Map file not found")

    if args.solution and not os.path.exists(args.solution):
        raise IOError("Solution file not found")
    data = parse(args.map, args.solution)
    # Graph
    G = nx.Graph()
    G.add_edges_from(data['tunnels'])
    # Fruchterman-Reingold force-directed algorithm's to set rooms.
    pos = nx.spring_layout(G)
    # Ants speed
    speed_rate = 7
    # create an array of * on the ants object
    ants = make_ants(pos, speed_rate, data)
    # size of the graph
    fig = plt.figure(figsize = (15, 10))
    ant_img = read_png('./images/Fourmisse.png')
    ani = FuncAnimation(
    fig,
    re_init,
    frames=data['num_turns'] *
    speed_rate,
    fargs=(
        G,
        pos,
        speed_rate,
        data,
        ants,
        args,
        ant_img),
    interval=30,
    repeat=True)
    plt.show()


def run_tornado(self, args):
        """ Tornado dev server implementation """
        server = self
        import tornado.ioloop
        import tornado.web
        import tornado.websocket

        ioloop = tornado.ioloop.IOLoop.current()

        class DevWebSocketHandler(tornado.websocket.WebSocketHandler):
            def open(self):
                super(DevWebSocketHandler, self).open()
                server.on_open(self)

            def on_message(self, message):
                server.on_message(self, message)

            def on_close(self):
                super(DevWebSocketHandler, self).on_close()
                server.on_close(self)

        class MainHandler(tornado.web.RequestHandler):
            def get(self):
                self.write(server.index_page)

        #: Set the call later method
        server.call_later = ioloop.call_later
        server.add_callback = ioloop.add_callback

        app = tornado.web.Application([
            (r"/", MainHandler),
            (r"/dev", DevWebSocketHandler),
        ])

        app.listen(self.port)
        print("Tornado Dev server started on {}".format(self.port))
        ioloop.start()


import RPi.GPIO as GPIO
import serial
import time
import thread
from unidecode import unidecode
import json
data = {}
data['AD1'] = []

#from time import sleep
ser = serial.Serial('/dev/ttyAMA0',9600);
def thread_1():
    while True:
        if ser.inWaiting:
            time.sleep(2)
            print("thread 1")
            read = ser.readline().decode().strip('\r\n');
            print("READ : " + read)
            readlist = read
            readlist = list(readlist)
            print(readlist[6])
        if(read == "AD1 + S1"):
            status = read
            print("S : " + status)
        elif(readlist[6] == "D"):
            processes = read
            print("p : " + processes)
        elif(read == "AD1 + S1OFF + S2ON"):
            endprocess = read
            print("ee : " + endprocess)
        elif(read == "AD1 + S1OFF + S2OFF"):
            endprocess_2 = read
            print("ee2 : " + endprocess_2)
        elif(read == "AD1 + END"):
            end = read
            print("e : " + end)
            data['AD1'].append({
                'status' : status,
                'process' : processes,
                'process_2' : endprocess_2,
                'endprocess' : endprocess,
                'end' : end
            })
            with open('data.json','w+') as outfile:
                json.dump(data,outfile)
                print("writefile")
        #thread.start_new_thread(thread_2())

def thread_2():
    while True:
            print("thread 2")
            ser.write("AD1 + ST" + "\r\n")
            time.sleep(3)
            #thread.start_new_thread(thread_1())

def thread_3():
    while True:
            print("thread 3")
            ser.write("AD2 + ST" + "\r\n")
            time.sleep(3)

def thread_4():
    while True:
            print("thread 4")
            ser.write("AD1 + R" + "\r\n")
            time.sleep(3)
def thread_5():
    while True:
            print("thread 5")
            ser.write("AD2 + R" + "\r\n")
            time.sleep(3)

thread.start_new_thread(thread_1,())
thread.start_new_thread(thread_2,())

while True:
    pass


class Graph:
    def __init__(self, numvertex):
        self.adjmatrix = [[-1]*numvertex for i in range(numvertex)]
        self.numvertex = numvertex
        self.vertices = {}
        self.verticeslist = [0]*numvertex
    def set_vertex(self, vertex, id):
        if 0<=vertex<=self.numvertex:
            self.vertices[id] = vertex
            self.verticeslist[vertex] = id
    def set_edge(self,frm,to,cost=0):
        frm = self.vertices[frm]
        to = self.vertices[to]
        self.adjmatrix[frm][to] = cost
        #directed graph
        self.adjmatrix[to][frm] = cost
    def get_vertex(self):
        return self.verticeslist
    def get_edges(self):
        edges = []
        for i in range(self.numvertex):
            for j in range(self.numvertex):
                if self.adjmatrix[i][j]!=-1:
                    edges.append(self.verticeslist[i],self.verticeslist[j],self.adjmatrix[i][j])
        return edges
    def get_matrix(self):
        return self.adjmatrix

g = Graph(6)
g.set_vertex(0,"s")
g.set_vertex(1,"e")
g.set_vertex(2,"l")
g.set_vertex(3,"c")
g.set_vertex(4,"i")
g.set_vertex(5,"a")
print(g.get_vertex())
g.set_edge("s","e",4)
print(g.get_edges())


from lppls import lppls
import numpy as np
import pandas as pd
from pandas_datareader import data as pdr
from datetime import timedelta, date
from matplotlib import pyplot as plt
import yfinance as yf
yf.pdr_override()

def main():
    ticker = 'ES=F'
    endDate = date.today()
    startDate = endDate - timedelta(days=4 * 365)
    data = pdr.get_data_yahoo(ticker, start=startDate, end=endDate)
    time = [pd.Timestamp.toordinal(t1) for t1 in data.index]
    price = np.log(data['Adj Close'].values)
    observations = np.array([time, price])
    lppls_model = lppls.LPPLS(observations=observations)

    res = lppls_model.mp_compute_nested_fits(
        workers=8,
        window_size=120,
        smallest_window_size=30,
        outer_increment=1,
        inner_increment=5,
        max_searches=25
    )

    lppls_model.plot_confidence_indicators(res)
    plt.show()

if __name__ == '__main__':
    main()


from __future__ import division

import logbook
import numpy as np
from collections import namedtuple
from math import isnan

from six import iteritems, itervalues

from catalyst.finance.performance.position import Position
from catalyst.finance.transaction import Transaction
from catalyst.utils.input_validation import expect_types
import catalyst.protocol as zp
from catalyst.assets import (
    Future,
    Asset
)
from . position import positiondict

from catalyst.constants import LOG_LEVEL

log = logbook.Logger('Performance', level=LOG_LEVEL)

PositionStats = namedtuple('PositionStats',
                           ['net_exposure',
                            'gross_value',
                            'gross_exposure',
                            'short_value',
                            'short_exposure',
                            'shorts_count',
                            'long_value',
                            'long_exposure',
                            'longs_count',
                            'net_value'])

def calc_position_values(positions):
    values = []

    for position in positions:
        if isinstance(position.asset, Future):
            # Futures don't have an inherent position value.
            values.append(0.0)
        else:
            values.append(position.last_sale_price * position.amount)

    return values

def calc_net(values):
    # Returns 0.0 if there are no values.
    return sum(values, np.float64())

def calc_position_exposures(positions):
    exposures = []

    for position in positions:
        exposure = position.amount * position.last_sale_price

        if isinstance(position.asset, Future):
            exposure *= position.asset.multiplier

        exposures.append(exposure)

    return exposures

def calc_long_value(position_values):
    return sum(i for i in position_values if i > 0)

def calc_short_value(position_values):
    return sum(i for i in position_values if i < 0)

def calc_long_exposure(position_exposures):
    return sum(i for i in position_exposures if i > 0)

def calc_short_exposure(position_exposures):
    return sum(i for i in position_exposures if i < 0)

def calc_longs_count(position_exposures):
    return sum(1 for i in position_exposures if i > 0)

def calc_shorts_count(position_exposures):
    return sum(1 for i in position_exposures if i < 0)

def calc_gross_exposure(long_exposure, short_exposure):
    return long_exposure + abs(short_exposure)

def calc_gross_value(long_value, short_value):
    return long_value + abs(short_value)

class PositionTracker(object):

    def __init__(self, data_frequency):
        # asset => position object
        self.positions = positiondict()
        self._unpaid_dividends = {}
        self._unpaid_stock_dividends = {}
        self._positions_store = zp.Positions()

        self.data_frequency = data_frequency

    @expect_types(asset=Asset)
    def update_position(self, asset, amount=None, last_sale_price=None,
                        last_sale_date=None, cost_basis=None):
        if asset not in self.positions:
            position = Position(asset)
            self.positions[asset] = position
        else:
            position = self.positions[asset]

        if amount is not None:
            position.amount = amount
        if last_sale_price is not None:
            position.last_sale_price = last_sale_price
        if last_sale_date is not None:
            position.last_sale_date = last_sale_date
        if cost_basis is not None:
            position.cost_basis = cost_basis

    def execute_transaction(self, txn):
        # Update Position
        # ----------------
        asset = txn.asset

        if asset not in self.positions:
            position = Position(asset)
            self.positions[asset] = position
        else:
            position = self.positions[asset]

        position.update(txn)

        if position.amount == 0:
            del self.positions[asset]

            try:
                # if this position exists in our user-facing dictionary,
                # remove it as well.
                del self._positions_store[asset]
            except KeyError:
                pass

    @expect_types(asset=Asset)
    def handle_commission(self, asset, cost):
        # Adjust the cost basis of the stock if we own it
        if asset in self.positions:
            self.positions[asset].adjust_commission_cost_basis(asset, cost)

    def handle_splits(self, splits):
        """
        Processes a list of splits by modifying any positions as needed.

        Parameters
        ----------
        splits: list
            A list of splits.  Each split is a tuple of (asset, ratio).

        Returns
        -------
        int: The leftover cash from fractional sahres after modifying each
            position.
        """
        total_leftover_cash = 0

        for asset, ratio in splits:
            if asset in self.positions:
                # Make the position object handle the split. It returns the
                # leftover cash from a fractional share, if there is any.
                position = self.positions[asset]
                leftover_cash = position.handle_split(asset, ratio)
                total_leftover_cash += leftover_cash

        return total_leftover_cash

    def earn_dividends(self, dividends, stock_dividends):
        """
        Given a list of dividends whose ex_dates are all the next trading day,
        calculate and store the cash and/or stock payments to be paid on each
        dividend's pay date.

        Parameters
        ----------
        dividends: iterable of (asset, amount, pay_date) namedtuples

        stock_dividends: iterable of (asset, payment_asset, ratio, pay_date)
            namedtuples.
        """
        for dividend in dividends:
            # Store the earned dividends so that they can be paid on the
            # dividends' pay_dates.
            div_owed = self.positions[dividend.asset].earn_dividend(dividend)
            try:
                self._unpaid_dividends[dividend.pay_date].append(div_owed)
            except KeyError:
                self._unpaid_dividends[dividend.pay_date] = [div_owed]

        for stock_dividend in stock_dividends:
            div_owed = \
                self.positions[stock_dividend.asset].earn_stock_dividend(
                    stock_dividend)
            try:
                self._unpaid_stock_dividends[stock_dividend.pay_date].\
                    append(div_owed)
            except KeyError:
                self._unpaid_stock_dividends[stock_dividend.pay_date] = \
                    [div_owed]

    def pay_dividends(self, next_trading_day):
        """
        Returns a cash payment based on the dividends that should be paid out
        according to the accumulated bookkeeping of earned, unpaid, and stock
        dividends.
        """
        net_cash_payment = 0.0

        try:
            payments = self._unpaid_dividends[next_trading_day]
            # Mark these dividends as paid by dropping them from our unpaid
            del self._unpaid_dividends[next_trading_day]
        except KeyError:
            payments = []

        # representing the fact that we're required to reimburse the owner of
        # the stock for any dividends paid while borrowing.
        for payment in payments:
            net_cash_payment += payment['amount']

        # Add stock for any stock dividends paid.  Again, the values here may
        # be negative in the case of short positions.
        try:
            stock_payments = self._unpaid_stock_dividends[next_trading_day]
        except:
            stock_payments = []

        for stock_payment in stock_payments:
            payment_asset = stock_payment['payment_asset']
            share_count = stock_payment['share_count']
            # note we create a Position for stock dividend if we don't
            # already own the asset
            if payment_asset in self.positions:
                position = self.positions[payment_asset]
            else:
                position = self.positions[payment_asset] = \
                    Position(payment_asset)

            position.amount += share_count

        return net_cash_payment

    def maybe_create_close_position_transaction(self, asset, dt, data_portal):
        if not self.positions.get(asset):
            return None

        amount = self.positions.get(asset).amount
        price = data_portal.get_spot_value(
            asset, 'price', dt, self.data_frequency)

        # Get the last traded price if price is no longer available
        if isnan(price):
            price = self.positions.get(asset).last_sale_price

        txn = Transaction(
            asset=asset,
            amount=(-1 * amount),
            dt=dt,
            price=price,
            commission=0,
            order_id=None,
        )
        return txn

    def get_positions(self):

        positions = self._positions_store

        for asset, pos in iteritems(self.positions):

            if pos.amount == 0:
                # Clear out the position if it has become empty since the last
                # time get_positions was called.  Catching the KeyError is
                # faster than checking `if asset in positions`, and this can be
                # potentially called in a tight inner loop.
                try:
                    del positions[asset]
                except KeyError:
                    pass
                continue

            position = zp.Position(asset)
            position.amount = pos.amount
            position.cost_basis = pos.cost_basis
            position.last_sale_price = pos.last_sale_price
            position.last_sale_date = pos.last_sale_date

            # Adds the new position if we didn't have one before, or overwrite
            # one we have currently
            positions[asset] = position

        return positions

    def get_positions_list(self):
        positions = []
        for asset, pos in iteritems(self.positions):
            if pos.amount != 0:
                positions.append(pos.to_dict())
        return positions

    def sync_last_sale_prices(self, dt, handle_non_market_minutes,
                              data_portal):
        if not handle_non_market_minutes:
            for asset, position in iteritems(self.positions):
                last_sale_price = data_portal.get_spot_value(
                    asset, 'price', dt, self.data_frequency
                )

                if not np.isnan(last_sale_price):
                    position.last_sale_price = last_sale_price
        else:
            for asset, position in iteritems(self.positions):
                last_sale_price = data_portal.get_adjusted_value(
                    asset,
                    'price',
                    data_portal.trading_calendar.previous_minute(dt),
                    dt,
                    self.data_frequency
                )

                if not np.isnan(last_sale_price):
                    position.last_sale_price = last_sale_price

    def stats(self):
        amounts = []
        last_sale_prices = []
        for pos in itervalues(self.positions):
            amounts.append(pos.amount)
            last_sale_prices.append(pos.last_sale_price)

        position_values = calc_position_values(itervalues(self.positions))
        position_exposures = calc_position_exposures(
            itervalues(self.positions)
        )

        long_value = calc_long_value(position_values)
        short_value = calc_short_value(position_values)
        gross_value = calc_gross_value(long_value, short_value)
        long_exposure = calc_long_exposure(position_exposures)
        short_exposure = calc_short_exposure(position_exposures)
        gross_exposure = calc_gross_exposure(long_exposure, short_exposure)
        net_exposure = calc_net(position_exposures)
        longs_count = calc_longs_count(position_exposures)
        shorts_count = calc_shorts_count(position_exposures)
        net_value = calc_net(position_values)

        return PositionStats(
            long_value=long_value,
            gross_value=gross_value,
            short_value=short_value,
            long_exposure=long_exposure,
            short_exposure=short_exposure,
            gross_exposure=gross_exposure,
            net_exposure=net_exposure,
            longs_count=longs_count,
            shorts_count=shorts_count,
            net_value=net_value
        )


import scrapy
from scrapy import signals
from fundscraper.items import OnlinedstfirstItem, onlinedstsecondItem
from fundscraper.spiders.send_email import send_email,load_previous_data,save_current_data

# Store previously scraped data in a file (you can use a database as well)
PREVIOUS_DATA_FILE1 = '~/.config/fundscraper/data/onlinedst_data1.csv'
PREVIOUS_DATA_FILE2 = '~/.config/fundscraper/data/onlinedst_data2.csv'
columns1=["serial_number","programme_or_scheme","division","start_date","end_date"]
columns2=["serial_number","programme_or_scheme","division"]
load_previous_data(PREVIOUS_DATA_FILE1,columns1)
load_previous_data(PREVIOUS_DATA_FILE2,columns2)
class OnlinedstSpider(scrapy.Spider):
    name = "onlinedst"
    allowed_domains = ["onlinedst.gov.in"]
    start_urls = ["https://onlinedst.gov.in/Login.aspx"]
    first_scraped_data=[]
    second_scraped_data=[]
    def parse(self, response):
        # Extracting data from the first table
        first_table_rows = response.xpath('//div[@id="divprojectformat"]/table//tr')[1:]  # Skipping the header row

        for row in first_table_rows:
            item = OnlinedstfirstItem()  # Create an instance of the OnlinedstfirstItem
            item['serial_number'] = row.xpath('.//td[1]/text()').get()
            item['programme_or_scheme'] = row.xpath('.//td[2]/a/text()').get()
            item['division'] = row.xpath('.//td[3]/span/text()').get()
            item['start_date'] = row.xpath('.//td[4]/span/text()').get()
            item['end_date'] = row.xpath('.//td[5]/text()').get()
            self.first_scraped_data.append({
                'serial_number': item['serial_number'],
                'programme_or_scheme': item['programme_or_scheme'],
                'division': item['division'],
                'start_date': item['start_date'],
                'end_date': item['end_date']
            })
            yield item

        # Extracting data from the second table
        second_table_rows = response.xpath('//div[@id="divprojectformat1"]//table//tr')[1:]  # Skipping the header row

        for row in second_table_rows:
            item = onlinedstsecondItem()
            item['serial_number']= row.xpath('.//td[1]/text()').get()
            item['programme_or_scheme']= row.xpath('.//td[2]/a/text()').get()
            item['division']= row.xpath('.//td[3]/text()').get()
            self.second_scraped_data.append({
                'serial_number': item['serial_number'],
                'programme_or_scheme': item['programme_or_scheme'],
                'division': item['division'],
            })
            yield item

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(OnlinedstSpider, cls).from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed)
        return spider

    def spider_closed(self, reason):
        if reason == 'finished':
            send_email(self.first_scraped_data,columns1,"programme_or_scheme",PREVIOUS_DATA_FILE1,"Onlinedst Updates")
            send_email(self.second_scraped_data,columns2,"programme_or_scheme",PREVIOUS_DATA_FILE2,"Onlinedst Updates")
            save_current_data(self.first_scraped_data,PREVIOUS_DATA_FILE1,columns1)
            save_current_data(self.second_scraped_data,PREVIOUS_DATA_FILE2,columns2)


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#%matplotlib inline
from sklearn.model_selection import train_test_split
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import unicodedata
import string
from nltk.stem.snowball import SnowballStemmer
from nltk.stem.wordnet import WordNetLemmatizer
from nltk.stem.porter import PorterStemmer
from nltk.util import ngrams
from nltk import pos_tag
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel
import operator
from wordcloud import WordCloud, STOPWORDS

#get data
def get_data():
    df_gd = pd.read_csv('data/gratefuldead.csv')
    df_pf = pd.read_csv('data/pinkfloyd.csv')
    df_phish = pd.read_csv('data/phish.csv')
    df_beatles = pd.read_csv('data/beatles.csv')
    #combine to single df
    df_sorted = pd.concat([df_gd, df_pf, df_phish, df_beatles], join  = 'outer', axis = 0, ignore_index = True)
    #shuffle rows so not sorted by band page
    df = df_sorted.sample(frac = 1, random_state=1)

    return df_gd, df_pf, df_phish, df_beatles, df

#get X and y
def get_X_y(df):
    df = df.set_index(df['id']).drop(columns=['id'])
    X = df['title'].to_numpy()
    y = df['subreddit'].to_numpy()
    return X, y

##clean text

#get unicode data
def remove_accents(input_str):
    nfkd_form = unicodedata.normalize('NFKD', input_str)
    only_ascii = nfkd_form.encode('ASCII', 'ignore')
    return only_ascii.decode()

#tokenize and get stem of each word. see which stemmer is preferred
# def tokenize(text):
#     stemmer = SnowballStemmer('english')
#     # stemmer = PorterStemmer()
#     # stemmer = WordNetLemmatizer()
#     return [stemmer.stem(word) for word in word_tokenize(text.lower())]

#get rid of accents, punctuation, make lowercase
# def filter_data(corpus):
#     X = corpus.copy()
#     punctuation = string.punctuation
#     stop_words = set(stopwords.words('english'))
#     stemmer = SnowballStemmer('english')
#     for i in range(len(X)):
#         #get unicode data
#         X[i] = remove_accents(X[i])
#         #get rid of punctuation and make lowercase
#         X[i] = X[i].translate(str.maketrans('', '', punctuation)).lower()
#         #make bag of words, without stop words
#         tokenized_words = [word for word in X[i].split() if word not in stop_words]
#         #get the stem of each word
#         X[i] = [stemmer.stem(word) for word in tokenized_words]
#     return X

def filter_data_text(text):
    X = text
    punctuation = string.punctuation
    stop_words = set(stopwords.words('english'))
    stemmer = SnowballStemmer('english')

    #get unicode data
    X = remove_accents(X)
    #get rid of punctuation and make lowercase
    X = X.translate(str.maketrans('', '', punctuation)).lower()
    #make bag of words, without stop words
    tokenized_words = [word for word in X.split() if word not in stop_words]
    #get the stem of each word
    X = [stemmer.stem(word) for word in tokenized_words]

    return X

def get_cosine_similarities(document_tfidf_matrix):
    cosine_similarities = linear_kernel(document_tfidf_matrix, document_tfidf_matrix)
    output = []
    for i in range(len(document_tfidf_matrix)):
        for j in range(len(document_tfidf_matrix)):
            output.append(i, j, cosine_similarities[i, j])
    return output

def get_top_n_words(corpus, n=100):
    """
    List the top n words in a vocabulary according to occurrence in a text corpus.

    get_top_n_words(["I love Python", "Python is a language programming", "Hello world", "I love the world"]) ->
    [('python', 2),
     ('world', 2),
     ('love', 2),
     ('hello', 1),
     ('is', 1),
     ('programming', 1),
     ('the', 1),
     ('language', 1)]
    """
    vec = CountVectorizer(tokenizer=filter_data_text).fit(corpus)
    bag_of_words = vec.transform(corpus)
    sum_words = bag_of_words.sum(axis=0)
    words_freq = [(word, sum_words[0, idx]) for word, idx in vec.vocabulary_.items()]
    words_freq =sorted(words_freq, key = lambda x: x[1], reverse=True)
    return words_freq[:n]

def plot_top_words(list_of_tuples, n_documents, xlabel, ylabel, title, string_file_name):
    '''
    takes a list of tuples: (word, count), sorted by top used words

    '''
    word = list(zip(*list_of_tuples))[0][:15]
    count = list(zip(*list_of_tuples))[1][:15]
    freq = tuple(ti/n_documents for ti in count)

    x_pos = np.arange(len(word))

    fig, ax = plt.subplots(figsize=(12,8))
    ax.barh(x_pos, freq, align='center')
    plt.yticks(x_pos, word)
    ax.set_ylabel(xlabel)
    ax.set_xlabel(ylabel)
    ax.set_title(title)
    plt.gca().invert_yaxis()
    plt.savefig(f'images/{string_file_name}.png')
    # plt.show()

def plot_cloud(wordcloud):
    # Set figure size
    plt.figure(figsize=(40, 30))
    # Display image
    plt.imshow(wordcloud)
    # No axis details
    plt.axis("off")

# Generate word cloud from dictionary of 100 top words + their counts
def create_wordcloud(word_freq_dict, file_name_string):

    wordcloud = WordCloud(width = 3000, height = 2000,
                      random_state=1, background_color='black', colormap='Set2',
                      collocations=False, stopwords = STOPWORDS).generate_from_frequencies(word_freq_dict)
    # Plot and save file
    wordcloud.to_file(f'images/{file_name_string}.png')
    # plot_cloud(wordcloud)

if __name__ == "__main__":

    #get dataframes
    df_gd, df_pf, df_phish, df_beatles, df = get_data()

    #get X and y
    X, y = get_X_y(df)

    #get training and testing data
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

    #filter X_train, tokenize words for each document
    # X_train_filtered = filter_data(X_train)
    X_train_tokens = [filter_data_text(doc) for doc in X_train]
    X_test_tokens = [filter_data_text(doc) for doc in X_test]

    #count vectorizer: tf
    #use filter_data_text function as tokenizer
    #fit to X_train
    tf = CountVectorizer(tokenizer=filter_data_text, max_features=5000)
    document_tf_matrix = tf.fit_transform(X_train).todense()
    #feature names
    tf_feature_names = tf.get_feature_names()
    #vocabulary dictionary
    tf_vocabulary_dict = tf.vocabulary_
    #df
    tf_df = pd.DataFrame(document_tf_matrix, columns=tf.get_feature_names())

    #tfidf vectorizer: tf-idf
    #use filter_data_text function as tokenizer
    #fit to X_train
    tfidf = TfidfVectorizer(tokenizer=filter_data_text, max_features=5000)
    document_tfidf_matrix = tfidf.fit_transform(X_train).todense()
    #feature names
    tfidf_feature_names = tfidf.get_feature_names()
    #vocabulary dictionary
    tfidf_vocabulary_dict = tfidf.vocabulary_
    #df
    tf_df = pd.DataFrame(document_tf_matrix, columns=tf.get_feature_names())

    #counts of posts with band mentions
    num_phish_docs = sum(['phish' in doc for doc in X_train_tokens])
    num_gd_docs = sum(['dead' in doc for doc in X_train_tokens])
    num_pf_docs = sum(['floyd' in doc for doc in X_train_tokens])
    num_beatles_docs = sum(['beatl' in doc for doc in X_train_tokens])
    #get top words across all documents/subreddits and plot
    top_words = get_top_n_words(X_train, n=100)
    plot_top_words(top_words, len(X_train), 'Word', 'Word Frequency Per Post', 'Top 15 Words Across Subreddits', 'all_word_freq_graph')

    #get top words for each individual subreddit and plot
    top_gd_words = get_top_n_words(X_train[y_train=='gratefuldead'], n=100)
    top_phish_words = get_top_n_words(X_train[y_train=='phish'], n=100)
    top_pf_words = get_top_n_words(X_train[y_train=='pinkfloyd'], n=100)
    top_beatles_words = get_top_n_words(X_train[y_train=='beatles'], n=100)
    #plot top words for each individual subreddit
    plot_top_words(top_gd_words, len(X_train[y_train=='gratefuldead']), 'Word', 'Word Frequencey Per Post', 'Top 15 Words In Grateful Dead Subreddit', 'gd_word_freq_graph')
    plot_top_words(top_phish_words, len(X_train[y_train=='phish']), 'Word', 'Word Frequency Per Post', 'Top 15 Words In Phish Subreddit', 'phish_word_freq_graph')
    plot_top_words(top_pf_words, len(X_train[y_train=='pinkfloyd']), 'Word', 'Word Frequency Per Post', 'Top 15 Words In Pink Floyd Subreddit', 'pf_word_freq_graph')
    plot_top_words(top_beatles_words, len(X_train[y_train=='beatles']), 'Word', 'Word Frequency Per Post', 'Top 15 Words In Beatles Subreddit', 'beatles_word_freq_graph')

    #create wordclouds
    create_wordcloud(dict(top_words), 'all_wordcloud' )
    create_wordcloud(dict(top_gd_words), 'gd_wordcloud')
    create_wordcloud(dict(top_phish_words), 'phish_wordcloud')
    create_wordcloud(dict(top_pf_words), 'pf_wordcloud')
    create_wordcloud(dict(top_beatles_words), 'beatles_wordcloud')


# -*- coding: utf-8 -*-
# from django.conf import settings

CKEDITOR_UPLOAD_PATH = "ck-uploads/"

CKEDITOR_CONFIGS = {
    'default': {
        'skin': 'bootstrapck',
        'toolbar': [["Format", "Bold", "Italic", "Underline", "Strike", "SpellChecker"],
                ['NumberedList', 'BulletedList', "Indent", "Outdent", 'JustifyLeft', 'JustifyCenter',
                 'JustifyRight', 'JustifyBlock'],
                ["Image", "Table", "Link", "Unlink", "Anchor", "SectionLink", "Subscript", "Superscript"], ['Undo', 'Redo'], ["Source"],
                ["Maximize"]],
        'height': 150,
        # 'width': 300,
        # "removePlugins": "Bold",
    },
    'small': {
        'skin': 'bootstrapck',
        'toolbar': [["Format", "Bold", "Italic", "Underline", "Strike", "SpellChecker", "Link", "Unlink"],
                ['NumberedList', 'BulletedList', "Indent", "Outdent", 'JustifyLeft', 'JustifyCenter',
                 'JustifyRight', 'JustifyBlock'],
                 ['Undo', 'Redo'], ["Source"],
                ["Maximize"]],
        'height': 100,
        # 'width': auto,
        "removePlugins": "Bold",
    },
    'awesome_ckeditor': {
        'toolbar': 'Basic',
    },
}


# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from django.conf import settings
from django.shortcuts import render

# Create your views here.
def home(request):

    title = 'Welcome!'
    if request.user.is_authenticated():
        title = 'Welcome %s' %(request.user)

    context = {
               "title":title,
               }

    return render(request, "/studentsdb/templates/groups.html",context)


from openerp.osv import osv, fields
import openerp.tools
from openerp.tools.translate import _
import base64
import xlwt
from cStringIO import StringIO
import datetime
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
import locale
import openerp.tools
from openerp.addons.sg_account_report.report.financial_report import account_balance_inherit

class bs_pl_xls_report(osv.osv_memory):
    _name = "bs.pl.xls.report"

    def _get_excel_export_data(self, cr, uid, context=None):
        if context is None:
            context = {}
        bank_obj = self.pool.get('hr.bank.details')
        workbook = xlwt.Workbook()
        worksheet = workbook.add_sheet('Sheet 1')
        font = xlwt.Font()
        font.bold = True
        header = xlwt.easyxf('font: bold 1, height 280')
        header2 = xlwt.easyxf('font: bold 1, height 180')
        header1 = xlwt.easyxf('pattern: pattern solid, fore_colour white; borders: top double, bottom double, bottom_color black; font: bold on, height 180, color black; align: wrap off')
        company_name = self.pool.get('res.users').browse(cr, uid, uid).company_id.name
        account_balance_inherit_obj = account_balance_inherit(cr, uid, '', context)
        acc_data = account_balance_inherit_obj.lines(context.get('form'), 0)
        style = xlwt.easyxf('align: wrap yes')
        worksheet.col(0).width = 15000
        worksheet.col(1).width = 5000
        worksheet.col(3).width = 4000
        worksheet.col(4).width = 5000
        worksheet.row(0).height = 500
        worksheet.row(1).height = 500
        worksheet.row(2).height = 500
        row = 6
        if context.get('inf_type') == 'BS':
            worksheet.write(0, 1, company_name , header)
            worksheet.write(1, 1, 'Balance Sheet' , header)
            worksheet.write(2, 1, 'As of ' + datetime.date.today().strftime('%m') + ' ' + context['form'].get('fiscalyear')[1] , header)
        if context.get('inf_type') == 'IS':
            worksheet.write(0, 1, company_name , header)
            worksheet.write(1, 1, 'Profit Loss' , header)
            worksheet.write(2, 1, context['form'].get('period_id')[1] , header)
            worksheet.write(3, 3, 'Current Month' , header2)
            worksheet.write(3, 4, 'Year to Date' , header2)
            worksheet.write(4, 3, 'Amount' , style)
            worksheet.write(4, 4, 'Amount' , style)
        for acc in acc_data:
            if context.get('inf_type') == 'BS':
                if acc['type']=='view' and acc['name'] or acc['name'].title():
                    if acc['total'] and not acc['label']:
                        worksheet.write(row, 0,'    '*(acc['level']-1) + acc['name'],header1)
                        worksheet.write(row, 1,'',header1)
                        worksheet.write(row, 2,'',header1)
                    else:
                        worksheet.write(row, 0,'    '*(acc['level']-1) + acc['name'],style)
                if acc['total']==True:
                    if acc['total'] and not acc['label']:
                        worksheet.write(row, 3, round(acc['balance'] or 0.00 , 2),header1)
                    else:
                        worksheet.write(row, 3, round(acc['balance'] or 0.00, 2),style)
                row += 1
            if context.get('inf_type') == 'IS':
                if acc['type']=='view' and acc['name'] or acc['name'].title():
                    if acc['total'] and not acc['label']:
                        worksheet.write(row, 0,'    '*(acc['level']-1) + acc['name'],header1)
                        worksheet.write(row, 1,'',header1)
                        worksheet.write(row, 2,'',header1)
                    else:
                        worksheet.write(row, 0,'    '*(acc['level']-1) + acc['name'],style)
                if acc['total']==True:
                    if acc['total'] and not acc['label']:
                        worksheet.write(row, 3, round(abs(acc['month']) or 0.00, 2),header1)
                        worksheet.write(row, 4, round(abs(acc['balance']) or 0.00, 2),header1)
                    else:
                        worksheet.write(row, 3, round(abs(acc['month']) or 0.00, 2),style)
                        worksheet.write(row, 4, round(abs(acc['balance']) or 0.00, 2),style)
                row += 1

        borders = xlwt.Borders()
        borders.top = xlwt.Borders.MEDIUM
        borders.bottom = xlwt.Borders.MEDIUM
        border_style = xlwt.XFStyle() # Create Style
        border_style.borders = borders
        row = 2
        payslip_obj = self.pool.get('hr.payslip')
        employee_obj = self.pool.get('hr.employee')
        hr_depart_obj = self.pool.get('hr.department')
        new_employee_ids = []
        style = xlwt.easyxf('align: wrap yes',style)
        fp = StringIO()
        workbook.save(fp)
        fp.seek(0)
        data = fp.read()
        fp.close()
        return base64.b64encode(data)

    _columns = {
        "file":fields.binary("Click On Download Link To Download Xls File", readonly=True),
        "name":fields.char("Name" , size=32, invisible="1")
    }

    _defaults = {
        'name':"BS PL.xls",
        'file': _get_excel_export_data
    }

bs_pl_xls_report()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: