from django.shortcuts import render
from math import ceil
from django.views.generic import TemplateView
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, render
from django.http import HttpResponseRedirect, HttpResponse
from django.template.context import RequestContext
from aplicaciones.proyectos.models import Proyectos
from aplicaciones.fases.models import Fases
from aplicaciones.items.models import Items, ValorItem
from aplicaciones.relaciones.models import Relaciones
from aplicaciones.lineabase.models import LineaBase
from aplicaciones.usuarios.models import Usuarios
from .models import Solicitudes, Votos, Credenciales
from .forms import SolicitudNuevaForm, SolicitudPrimeraForm, votarSolicitudForm
from datetime import datetime, date, timedelta
from django.contrib.auth.decorators import login_required, permission_required
from django.db.models import Q
from aplicaciones.comite.models import Comite
import logging

# Create your views here.
logger = logging.getLogger(__name__)

def administrar_solicitud_recibidas (request):

    """ Recibe un request, se verifica cual es el usuario registrado y se obtiene la lista de solicitudes
    recibidas con los que esta relacionado desplegandolo en pantalla.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista administrar_solicitud_recibidas.

    @rtype: django.shortcuts.render_to_response.
    @return: solicitudesrecibidas.html, donde se listan las solicitudes de modificacion de item recibidas.

    @author: Marcelo Denis.

    """

    comites = Comite.objects.filter(miembros=request.user)
    list_proyect = []
    for comite in comites:
        list_proyect.append(comite.proyecto)
    solicitudes = Solicitudes.objects.filter(proyecto__in=list_proyect, estado='Pendiente')

    pendientes = 0
    lista_solicitud=[]
    for s in solicitudes:
        votantes = s.miembros_que_votaron.all()
        solic_votada = False
        for votante in votantes:
            if votante == request.user:
                solic_votada = True
        tupla = (s, solic_votada)
        if not solic_votada:
            pendientes = pendientes + 1
        lista_solicitud.append(tupla)
    logger.info('Listado de Solicitudes recibidas, hecho por %s' % request.user.username)
    template_name='solicitudes/solicitudesrecibidas.html'
    ctx = {'lista_solicitud':lista_solicitud, 'pendientes':pendientes}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def administrar_solicitud_realizadas (request):

    """ Recibe un request, se verifica cual es el usuario registrado y se obtiene la lista de solicitudes
    realizadas con los que esta relacionado desplegandolo en pantalla.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista administrar_solicitud_realizadas.

    @rtype: django.shortcuts.render_to_response.
    @return: solicitudesrealizadas.html, donde se listan las solicitudes de modificacion de item realizadas.

    @author: Marcelo Denis.

    """

    solicitudes = Solicitudes.objects.filter(usuario=request.user)
    logger.info('Listado de solicitudes realizadas, hecho por %s' % request.user.username)
    template_name='solicitudes/solicitudesrealizadas.html'
    ctx = {'solicitudes':solicitudes}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def crear_solicitud(request, id_proyecto, id_fase, id_item):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    proyecto = Proyectos.objects.get(id=id_proyecto)
    fase = Fases.objects.get(id=id_fase)
    item = Items.objects.get(id=id_item)
    if proyecto.estado=='Finalizado':
        mensaje = 'El proyecto se encuentra finalizado, no se puede solicitar modificaciones.'
        template_name='./solicitudes/solicitudalerta.html'
        ctx = {'mensaje': mensaje, 'id_proyecto':id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'proyecto':proyecto, 'fase':fase, 'item': item}
        return render_to_response(template_name, ctx, context_instance=RequestContext(request))
    try:
        credencial = Credenciales.objects.get(item_id=item.id, estado='Habilitado')
    except Credenciales.DoesNotExist:
        credencial = False
    if credencial:
        mensaje = 'Ya existe una solicitud aprobada en proceso para el item seleccionado.'
        template_name='./solicitudes/solicitudalerta.html'
        ctx = {'mensaje': mensaje, 'id_proyecto':id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'proyecto':proyecto, 'fase':fase, 'item': item}
        return render_to_response(template_name, ctx, context_instance=RequestContext(request))
    usuariosolic = Usuarios.objects.get(user_id=request.user.id)
    solicituditem = Solicitudes.objects.filter(item=item, estado='Pendiente', usuario=usuariosolic)
    if solicituditem:
        mensaje = 'Ya existe una solicitud pendiente para el item seleccionado.'
        template_name='./solicitudes/solicitudalerta.html'
        ctx = {'mensaje': mensaje, 'id_proyecto':id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'proyecto':proyecto, 'fase':fase, 'item': item}
        return render_to_response(template_name, ctx, context_instance=RequestContext(request))

    if request.method == 'POST':
        form = SolicitudNuevaForm(request.POST)
        if form.is_valid():
            usuarionuevo = request.user
            proyectonuevo = proyecto
            fasenueva = fase
            itemnuevo = item
            fechasolic = datetime.today()
            tiemposolic = form.cleaned_data['Tiempo_Solicitado_en_Dias']
            descripcion = form.cleaned_data['Descripcion']
            observaciones = form.cleaned_data['Observaciones']
            estado = 'Pendiente'
            duracionsolic = form.cleaned_data['Duracion_Solicitud_en_Dias']

            solicitud = Solicitudes()
            solicitud.usuario_id = usuarionuevo.id
            solicitud.proyecto_id = proyectonuevo.id
            solicitud.fase_id = fasenueva.id
            solicitud.item_id = itemnuevo.id
            solicitud.fecha_solicitud = fechasolic
            solicitud.tiempo_solicitado = tiemposolic
            solicitud.descripcion = descripcion
            solicitud.observaciones = observaciones
            solicitud.estado = estado
            solicitud.tiempo_esperado = duracionsolic
            solicitud.votos_rechazado = 0
            solicitud.votos_aprobado = 0
            solicitud.save()
            logger.info('Creacion de Solicitud de cambio id %s, hecho por %s' % (solicitud.id, request.user.username))
            mensaje = 'Solicitud creada con exito.'
            template_name='./solicitudes/solicitudcreada.html'
            ctx = {'mensaje': mensaje, 'id_proyecto':id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'proyecto':proyecto, 'fase':fase, 'item': item}
            return render_to_response(template_name, ctx, context_instance=RequestContext(request))

            #return render(request, template_name, {'id_proyecto': id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'id_tipoitem': id_tipoitem, 'lista_valores': lista_valores, 'lista_atributos': lista_atributos})
    else:
        fechasolic = datetime.today()
        estado = 'Pendiente'
        data = {'Proyecto': proyecto, 'Fase': fase, 'Item': item, 'Fecha_de_Solicitud': fechasolic, 'Estado': estado}
        form = SolicitudPrimeraForm(data)

    template_name='./solicitudes/solicitudnueva.html'
    return render(request, template_name, {'form': form, 'id_proyecto':id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'proyecto':proyecto, 'fase':fase, 'item': item})

def cancelar_solicitud(request, id_solicitud):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    solicitud = Solicitudes.objects.get(id=id_solicitud)
    solicitud.estado = 'Cancelado'
    solicitud.save()
    proyecto = solicitud.proyecto
    fase = solicitud.fase

    mensaje = 'Solicitud eliminada con exito.'
    logger.info('Cancelacion de solicitud id %s, hecho por %s' % (solicitud.id, request.user.username))
    template_name='./solicitudes/solicitudalerta.html'
    ctx = {'mensaje': mensaje, 'proyecto':proyecto, 'fase':fase}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def consultar_solicitud(request, id_solicitud):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    solicitud = Solicitudes.objects.get(id=id_solicitud)
    proyecto = solicitud.proyecto
    fase = solicitud.fase
    #item = Items.objects.get(proyecto_id=id_proyecto, fase_id=id_fase, id=id_item)
    # conseguir el contexto de las fases y sus estados
    #fases = Fases.objects.filter(id_proyecto = id_proyecto)
    logger.info('Consultad de solicitud con id %s, hecho por %s' % (solicitud.id, request.user.username))
    template_name = './solicitudes/consultarsolicitud.html'
    return render(request, template_name, {'fase': fase, 'proyecto':proyecto, 'fase':fase, 'solicitud': solicitud})

def votar_solicitud(request, id_solicitud):
    """ Recibe un request y el id de la solicitud  que se quiere  votar.
    Se retorna un html que indica al usuario que proceda a aceptar, rechazar la solicitud o
    cancelar la operacion de votar la solicitud

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: HttpRequest.HttpResponse
    @return: votar.html, donde se solicita el voto a  favor o en contra del miembro del comite

    @author: Eduardo Gimenez

    """

    if request.method == 'POST':
        form = votarSolicitudForm(request.POST)
        if form.is_valid():
            voto = form.cleaned_data['voto']
            solicitud = Solicitudes.objects.get(id = id_solicitud)
            #Registramos el voto del usuario miembro de comite
            if voto == "A":
                miVoto = Votos(miembro=request.user, solicitud=solicitud, fechaDeVotacion=datetime.today(), voto="A")
            else:
                miVoto = Votos(miembro=request.user, solicitud=solicitud, fechaDeVotacion=datetime.today(), voto="R")
            miVoto.save()
            comite = Comite.objects.get(proyecto=solicitud.proyecto)
            cantidad_miembros = comite.miembros.count()
            promedio = int(ceil(cantidad_miembros/2)) + 1
            #Calculamos la  cantidad de votos a favor  y en contra
            votos = Votos.objects.filter(solicitud=solicitud)
            votosAprobado = 0
            votosRechazado = 0
            for votoMiembro in votos:
                if votoMiembro.voto == 'A':
                    votosAprobado = votosAprobado + 1
                if votoMiembro.voto == 'R':
                    votosRechazado = votosRechazado + 1
            #Verificamos los votos para rechazar o aprobar la  solicitud
            cantidad_votos = votosAprobado + votosRechazado
            if cantidad_votos==cantidad_miembros:
                try:
                    credencialitem = Credenciales.objects.get(item_id=solicitud.item_id, estado='Habilitado')
                except Credenciales.DoesNotExist:
                    credencialitem = False
                if credencialitem:
                    solicitud.estado = 'Cancelado'
                    solicitud.save()
                    mensaje = 'Ya existe una solicitud aprobada en proceso para el item. Esta solicitud ha sido descartada.'
                    template_name='./solicitudes/solicitudalerta.html'
                    ctx = {'mensaje': mensaje}
                    return render_to_response(template_name, ctx, context_instance=RequestContext(request))
                if votosAprobado > votosRechazado:
                    solicitud.estado = 'Aprobada'
                    credencial = Credenciales()
                    credencial.usuario = solicitud.usuario
                    credencial.proyecto = solicitud.proyecto
                    credencial.fase = solicitud.fase
                    credencial.item = solicitud.item
                    credencial.version = solicitud.item.version
                    credencial.fecha_aprobacion = date.today()
                    credencial.fecha_expiracion = date.today()+timedelta(days=solicitud.tiempo_solicitado)
                    credencial.estado = 'Habilitado'
                    solicitud.save()
                    credencial.save()
                    logger.info('Generacion de credencial id %s, hecho por %s' % (credencial.id, request.user.username))
                    habilitar_items(credencial)
                    mensaje = 'Credencial Generada'
                    template_name='./solicitudes/credencialcreada.html'
                    ctx = {'mensaje': mensaje, 'credencial': credencial}
                    return render_to_response(template_name, ctx, context_instance=RequestContext(request))
                else:
                    solicitud.estado = 'Reprobada'
                    mensaje = 'La solicitud ha sido Reprobada'
            else:
                mensaje = 'Su voto ha sido procesado'

            logger.info('Votacion de solicitud con id %d, hecho por %s' % (solicitud.id, request.user.username))
            solicitud.save()
            template_name='./solicitudes/solicitudalerta.html'
            ctx = {'mensaje': mensaje}
            return render_to_response(template_name, ctx, context_instance=RequestContext(request))

    else:
        form = votarSolicitudForm()
    template_name='./solicitudes/votarsolicitud.html'
    return render(request, template_name, {'form': form, 'id_solicitud':id_solicitud})

def impacto(request, id_proyecto, id_fase, id_item):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    item = Items.objects.get(id=id_item)

    imonetario = impacto_monetario(id_item)
    itemporal = impacto_temporal(id_item)
    items_afectado = calcular_items_afectados(id_item)
    items_afectados = []
    for items_af in items_afectado:
        if items_af.id!=item.id:
            items_afectados.append(items_af)

    logger.info('Calculo de impacto para item %s para la Solicitud de cambio, hecho por %s' % (item.nombre, request.user.username))
    ctx = {'id_proyecto':id_proyecto, 'id_fase': id_fase, 'id_item': id_item, 'impacto_monetario': imonetario, 'impacto_temporal': itemporal, 'items_afectados': items_afectados}
    template_name = './items/impacto.html'
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def impacto_monetario(id_item):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    item = Items.objects.get(id=id_item)
    costo = 0
    try:
        hijos = Items.objects.filter(padre=id_item)
    except Items.DoesNotExist:
        hijos = False
    if hijos:
        for hijo in hijos:
            costo = costo + impacto_monetario(hijo.id)
        costo = costo + item.costoMonetario
        return costo
    else:
        return item.costoMonetario

def impacto_temporal(id_item):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    item = Items.objects.get(id=id_item)
    costo = 0
    try:
        hijos = Items.objects.filter(padre=id_item)
    except Items.DoesNotExist:
        hijos = False
    if hijos:
        for hijo in hijos:
            costo = costo + impacto_temporal(hijo.id)
        costo = costo + item.costoTemporal
        return costo
    else:
        return item.costoTemporal

def calcular_items_afectados(id_item):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    item = Items.objects.get(id=id_item)
    lista_hijos = []
    try:
        hijos = Items.objects.filter(padre=id_item)
    except Items.DoesNotExist:
        hijos = False
    if hijos:
        for hijo in hijos:
            lista_hijos.extend(calcular_items_afectados(hijo.id))
        lista_hijos.append(item)
        return lista_hijos
    else:
        lista_hijos.append(item)
        return lista_hijos

def habilitar_items(credencial):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    item = Items.objects.get(id=credencial.item_id)
    fase = Items.objects.get(id=credencial.fase_id)
    lineasbase = LineaBase.objects.filter(fase_id=credencial.fase_id)
    items = []
    for lb in lineasbase:
        itemslb = lb.items.all()
        if item in itemslb:
            lineabase = lb
            items = lineabase.items.all()
            lineabase.is_active = False
            lineabase.save()

    for itemhijo in items:
        if itemhijo.estado=='Bloqueado' or itemhijo.estado=='Validado':
            itemhijo.estado='En Revision'
            itemhijo.save()

    lista_hijos = calcular_items_afectados(item.id)
    for hijo in lista_hijos:
        if hijo.estado=='Bloqueado' or hijo.estado=='Validado':
            hijo.estado = 'En Revision'
            hijo.save()
    item.estado = 'Habilitado'
    item.save()

def administrar_credenciales (request):

    """ Recibe un request, se verifica cual es el usuario registrado y se obtiene la lista de credenciales
    habilitadas con los que esta relacionado desplegandolo en pantalla.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista administrar_credenciales.

    @rtype: django.shortcuts.render_to_response.
    @return: credenciales.html, donde se listan las credenciales de modificacion de item habilitadas.

    @author: Marcelo Denis.

    """

    credenciales = Credenciales.objects.filter(usuario=request.user)
    logger.info('Listado de Credenciales, hecho por %s' % request.user.username)
    template_name='solicitudes/credenciales.html'
    ctx = {'lista_credenciales':credenciales}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def consultarCredencial(request, id_credencial):

    """ Recibe un request, se verifica cual es el usuario registrado y despliega los
     datos que pertenece a la credencial que se consulta

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista administrar_credenciales.

    @rtype: django.shortcuts.render_to_response.
    @return: consultar_credencial.html, donde se despliega los datos de la credencial.

    @author: Eduardo Gimenez.

    """

    credencial = Credenciales.objects.get(id=id_credencial)
    logger.info('Consulta de credncial con id %s, hecho por %s' % (credencial.id, request.user.username))
    template_name='solicitudes/consultar_credencial.html'
    ctx = {'credencial':credencial}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def cancelar_credencial(request, id_credencial):
    """ Recibe un request, se verifica cual es el usuario registrado y el proyecto del cual se solicita,
    se obtiene la lista de fases con las que estan relacionados el usuario y el proyecto
    desplegandola en pantalla, ademas permite realizar busquedas avanzadas sobre
    las fases que puede mostrar.

    @type request: django.http.HttpRequest.
    @param request: Contiene informacion sobre la solicitud web actual que llamo a esta vista.

    @rtype: django.shortcuts.render_to_response.
    @return: fases.html, donde se listan las fases, ademas de las funcionalidades para cada fase.

    @author: Ysapy Ortiz.

    """
    credencial = Credenciales.objects.get(id=id_credencial)

    lbs = LineaBase.objects.filter(fase_id=credencial.fase.id)
    eslb = False
    for lb in lbs:
        items = lb.items.all()
        for item in items:
            if credencial.item_id==item.id:
                eslb = lb
    if eslb:
        items = eslb.items.all()
        for item in items:
            item.estado = 'Bloqueado'
            item.save()
        eslb.is_active = True
        eslb.save()
    credencial.estado='Finalizado'
    credencial.save()

    revertir_credencial(credencial.proyecto_id, credencial.fase_id, credencial)

    mensaje = 'Credencial cancelada.'
    logger.info('Cancelacion de Credencial con id %s, hecho por %s' % (credencial.id, request.user.username))
    template_name='./solicitudes/solicitudalerta.html'
    ctx = {'mensaje': mensaje}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

def revertir_credencial(id_proyecto, id_fase, credencial):
    version_anterior = credencial.version
    item = Items.objects.get(id=credencial.item_id)
    version_actual = item.version
    if version_actual>version_anterior:
        for i in range(version_anterior+1,version_actual+1):
            atributositem = ValorItem.objects.filter(proyecto_id=id_proyecto, fase_id=id_fase, item_id=item.id, version=i)
            if atributositem:
                for atrib in atributositem:
                    atrib.version=0
                    atrib.save()
            try:
                relacionitem = Relaciones.objects.get(item=item.id, version=i)
            except Relaciones.DoesNotExist:
                relacionitem = False
            if relacionitem:
                relacionitem.version = 0
                relacionitem.save()
    item.version = version_anterior
    item.save()


# 3. b.
# Geometric Transformations of Images
# Perspective Transformation

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

# Perspective Transformation
img = cv.imread('D:/DIP/images/sudoku.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

Perform Image Processing Models/3_b_Perspective Transformation.py


from enum import Enum

from tools.utils import *

class TokenType(Enum):
    const = 0
    name = 1
    left_bracket = 2
    right_bracket = 3
    comma = 4
    error = 10

class Token:
    def __init__(self, patternstream: io.StringIO):
        self.size = 0
        self.value = None
        skip_spaces(patternstream)
        res = patternstream.read(1)
        if len(res) == 0:
            error_buffer_empty()
        elif res[0] == '(':
            self.size = 1
            self.type = TokenType.left_bracket
        elif res[0] == ')':
            self.size = 1
            self.type = TokenType.right_bracket
        elif res[0] == ',':
            self.size = 1
            self.type = TokenType.comma
        elif res[0].isdigit():
            self.type = TokenType.const
            patternstream.seek(patternstream.tell()-1)
            self.value = get_const_token(patternstream)
        elif res[0].isalpha:
            self.type = TokenType.name
            self.value = res + get_name_token(patternstream)
        else:
            self.type = TokenType.error

def get_const_token(patternstream: io.StringIO):
    value = 0
    while True:
        res = patternstream.read(1)
        if len(res) == 0:
            return value
        if not res[0].isdigit():
            patternstream.seek(patternstream.tell()-1)
            return value

        value *= 10
        value += ord(res[0]) - ord('0')

def get_name_token(patternstream: io.StringIO):
    res = ''
    while True:

        extra = patternstream.read(1)
        if len(extra) == 0:
            return res
        res += extra
        if not res[-1].isalnum() and  res[-1] != '_':
            patternstream.seek(patternstream.tell()-1)
            return res[:-1]

def get_token_with_type(patternstream: io.StringIO, type: TokenType):
    token = Token(patternstream)
    if token.type != type:
        error_unexpected_token()
    return token


from collections import deque
from sys import stdin

f, s, g, u, d = map(int, stdin.readline().rstrip().split())
d = d * (-1)
b = [-1] * (10 ** 6 + 1)

q = deque()
q.append(s)
b[s] = 0
done = False

while q:
    cur = q.popleft()

    if cur == g:
        done = True
        break

    for i in [u, d]:
        t = cur + i
        if (1 <= t <= f) and b[t] == -1:
            b[t] = b[cur] + 1
            q.append(t)

if done:
    print(b[g], end="")
else:
    print("use the stairs", end="")


import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
from PyQt5.QtCore import *

class MainProgram(QMainWindow):
    def __init__(self):

        super(MainProgram,self).__init__()
        loadUi('default.ui',self)
        self.btnSetting.clicked.connect(self.btnSetting_clicked)

    @pyqtSlot()
    def btnSetting_clicked(self):
        os.system('python setting.py')

if __name__=='__main__':
    app=QApplication(sys.argv)
    window=MainProgram()
    #window.setWindowTitle('Virtual Assisten')
    window.show()
    sys.exit(app.exec_())


"""
33. N皇后问题
n皇后问题是将n个皇后放置在n*n的棋盘上，皇后彼此之间
不能相互攻击。

给定一个整数n，返回所有不同的n皇后问题的解决方案。

每个解决方案包含一个明确的n皇后放置布局，其中“Q”和“.”
分别表示一个女王和一个空位置。

样例
对于4皇后问题存在两种解决的方案：

[

    [".Q..", // Solution 1

     "...Q",

     "Q...",

     "..Q."],

    ["..Q.", // Solution 2

     "Q...",

     "...Q",

     ".Q.."]

]

挑战
你能否不使用递归完成？
"""
class Solution:
    """
    @param: n: The number of queens
    @return: All distinct solutions
    """
    def solveNQueens(self, n):
        # write your code here
        boards = []
        visited = {
            'col': set(),
            'sum': set(),
            'diff': set()
        }
        self.dfs(n, [], visited, boards)
        return boards

    def dfs(self, n, permutation, visited, boards):
        if n == len(permutation):
            boards.append(self.draw(permutation))
            return

        row = len(permutation)
        for col in range(n):
            if not self.is_valid(permutation, visited, col):
                continue
            permutation.append(col)
            visited['col'].add(col)
            visited['sum'].add(row + col)
            visited['diff'].add(row - col)
            self.dfs(n, permutation, visited, boards)
            visited['col'].remove(col)
            visited['sum'].remove(row + col)
            visited['diff'].remove(row - col)
            permutation.pop()

    def is_valid(self, permutation, visited, col):
        row = len(permutation)
        if col in visited['col']:
            return False
        if row + col in visited['sum']:
            return False
        if row - col in visited['diff']:
            return False
        return True

    def draw(self, permutation):
        board = []
        n = len(permutation)
        for col in permutation:
            row_string = ''.join(['Q' if c == col else '.' for c in range(n)])
            board.append(row_string)
        return board


#!/usr/bin/env python3

import requests
import argparse

argparser = argparse.ArgumentParser()
argparser.add_argument('-i','--ip',help="IP Address", required=True)

args = argparser.parse_args()

ip = args.ip

def main():
  print(ip)

if '__main__' in __name__:
    main()


# This test script is utilized to do the following simple things.
# Pull an image
# Create a coontaineer on that image
# Run a task on that container
# Close that container.
# It is tested in python3.7 and latest docker SDK.
# https://docker-py.readthedocs.io/en/stable/
import docker
import grpc

import object_detection_pb2_grpc
import object_detection_pb2
import base64
class Orchestrator:
    def __init__(self):
        self.image_repos = {"yolov3-object-detection":"https://raw.githubusercontent.com/singnet/dnn-model-services/master/services/yolov3-object-detection/Dockerfile",
                            "cntk-image-reco":"https://raw.githubusercontent.com/singnet/dnn-model-services/master/services/cntk-image-recon/Dockerfile"}

        self.client = docker.from_env()

    def build(self, image_name):
        """
        This builds images specified using images.build option.

        :param image_name: the image from the self.image_repos that is going to be built.
        """
        img_ret, json_respone = self.client.images.build(path=self.image_repos[image_name],tag=image_name)
        for i in json_respone:
            print(i)

        # we need to capture the various issues. And inform the user about that. The output above is quite not
        # insightful.

    def create(self, image_name, argument, port):
        """
        This creates the container using the image name.

        The listing of the arguments is going to be tough. We need to make it specific that it would be good.

        :param argument: The startup arguments for the image.
        :param image_name: The image that is going to create a container
        """

        container = self.client.containers.run(image_name,ports={str(port):port}, command= argument, detach=True)

        #TODO find means to store this value.
        print(container.status)
        print(container.name)
        return container

    def delete(self, container):
        """
        Stop and Delete a container
        :param container:
        """
        container.stop()
        container.remove()

    def call(self, container, port):
        """
        Now, this is a bit tricky. Now we have created the containers. We have to call them using an image the user
        has submmited. Which creates this issue:
        - We have to include the grpc server in this code base. Or some kinda of adaptor that is similar to snetdapp.

        And how would this function scale is the main problem.

        For now; I have implemented the system using natively installed GRPC clients. But this won't scale and would
        make this kinda of organizatino bloated.
        :param container:
        """

        if container == 'yolo':
            channel = grpc.insecure_channel('localhost:'+str(port))
            stub = object_detection_pb2_grpc.DetectStub(channel)

            grpc_method = "detect"
            model = "yolov3"
            confidence = "0.7"

            request = object_detection_pb2.Input(model=model, confidence=confidence, img_path="https://raw.githubusercontent.com/singnet/dnn-model-services/master/docs/assets/users_guide/backpack_man_dog.jpg")
            response = stub.detect(request)

            print(response)

        # Another point that we need to discuss; we have to take this and change this to some format that would be fed.

if __name__ == '__main__':
    orch = Orchestrator()
    orch.build("yolov3-object-detection")
    orch.build("cntk-image-reco")

    yolo_arg = ["python3", "-m", "service.object_detection_service", "--grpc-port","8889"]
    yolo_cont = orch.create("yolov3-object-detection", yolo_arg, 8889)

    cntk_arg = ["/root/anaconda3/envs/cntk-py35/bin/python", "-m", "service.image_recon_service", "--grpc-port","8890"]
    cntk_cont = orch.create("cntk-image-reco", cntk_arg, 8890)

    orch.call("yolo", 8889)

    orch.delete(yolo_cont)
    orch.delete(cntk_cont)


"""
Engineer: Robert Gaines III
File Name : VehicleAerodynamicsModel.py
Purpose : Contains functions to compute aerodynamic forces and moments acting on the MAV given certain control surface inputs
"""

import math
from ..Containers import States
from ..Containers import Inputs
from ..Modeling import VehicleDynamicsModel
from ..Modeling import WindModel
from ..Utilities import MatrixMath
from ..Utilities import Rotations
from ..Constants import VehiclePhysicalConstants as VPC
from matplotlib import pyplot as plt
import numpy as np

def cl_attached(alpha):
    #print("calculating cl attached")
    x = VPC.CL0 + VPC.CLalpha * alpha
    #print("cl_attached= " + str(x))
    return x

def cd_attached(alpha):
    #print("calculating cd attached")
    x = VPC.CDp + (math.pow((VPC.CL0 + VPC.CLalpha * alpha),2.0))/(math.pi * VPC.e* VPC.AR)
    #print("cd_attached= " + str(x))
    return x

def cl_seperated(alpha):
    #print("calculating cl seperated ")
    x = 2.0 *math.sin(alpha) * math.cos(alpha)
    #print("cl_seperated= " + str(x))
    return x

def cd_seperated(alpha):
    #print("calculating cd seperated ")
    x = 2.0 * math.pow(math.sin(alpha), 2.0)
    #print("cd_seperated =" + str(x))
    return x

def Cl_fromA(alpha):
                                #not sure what we should pass for M, do i need to calculate this?

    sigmasss = sigma(alpha, VPC.alpha0, VPC.M)
    x = (1.0 - sigmasss) * cl_attached(alpha) + sigmasss*cl_seperated(alpha)
    #print (x)
    return  x

def Cd_fromA(alpha):
                                #not sure what we should pass for M, do i need to calculate this?
    sigmasss = sigma(alpha, VPC.alpha0, VPC.M)
    #print(sigmasss)
    a = cd_attached(alpha)
    s = cd_seperated(alpha)
    x = ( 1.0 - sigmasss )*  a + sigmasss * s
    #print(x)
    return x

#blending function

def sigma(a, a0, M):
    num = (1.0 + np.exp(-M*(a-a0)) + np.exp(M*(a+a0)))
    den = (1.0 + np.exp(-M*(a-a0)))*(1.0 + np.exp(M*(a+a0)))
    return num/den

#EQUATION 4.6
def calcLiftForce(state):

    c_2Va = (0.5 * VPC.c * state.q )/ state.Va

    fLiftTerm1 = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S
    fLiftTerm2 = Cl_fromA(state.alpha)
    fLiftTerm3 = (VPC.CLq * c_2Va)
    return fLiftTerm1 * (fLiftTerm2 + fLiftTerm3)
#EQUATION 4.7
def calcDragForce(state):

    c_2Va = (0.5 * VPC.c * state.q )/ state.Va

    fLiftTerm1 = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S
    fLiftTerm2 = Cd_fromA(state.alpha)
    fLiftTerm3 = (VPC.CDq * c_2Va)
    return fLiftTerm1 * (fLiftTerm2 + fLiftTerm3)
#EQUATION 4.5
def calcMoment(state):

    c_2Va = (0.5 * VPC.c * state.q) / state.Va

    fLiftTerm1 = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * VPC.c
    fLiftTerm2 = VPC.CM0
    fLiftTerm3 = VPC.CMalpha * state.alpha
    fLiftTerm4 = (VPC.CMq* c_2Va)
    return fLiftTerm1 * (fLiftTerm2 + fLiftTerm3 + fLiftTerm4)

#EQUATION 4.14
def calcFy(state):

    b_2Va = (0.5 * VPC.b) / state.Va
    fLiftTerm1 = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S
    fLiftTerm2 = VPC.CY0
    fLiftTerm3 = VPC.CYbeta * state.beta
    fLiftTerm4 = (VPC.CYp* b_2Va* state.p)
    fLiftTerm5 = (VPC.CYr* b_2Va * state.r)
    return fLiftTerm1 * (fLiftTerm2 + fLiftTerm3 + fLiftTerm4 + fLiftTerm5)

#EQUATION 4.15
def calcMomentL(state):

    b_2Va = (0.5 * VPC.b)/ state.Va
    fLiftTerm1 = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * VPC.b
    fLiftTerm2 = VPC.Cl0
    fLiftTerm3 = VPC.Clbeta * state.beta
    fLiftTerm4 = (VPC.Clp* b_2Va * state.p)
    fLiftTerm5 = (VPC.Clr* b_2Va * state.r)
    return fLiftTerm1 * (fLiftTerm2 + fLiftTerm3 + fLiftTerm4 + fLiftTerm5)

#EQUATION 4.16
def calcMomentN(state):

    b_2Va = (0.5 * VPC.b) / state.Va

    fLiftTerm1 = (1.0/2.0) * VPC.rho * math.pow(state.Va, 2.0) * VPC.S * VPC.b
    fLiftTerm2 = VPC.Cn0
    fLiftTerm3 = VPC.Cnbeta * state.beta
    fLiftTerm4 = (VPC.Cnp* b_2Va * state.p)
    fLiftTerm5 = (VPC.Cnr* b_2Va * state.r)
    return fLiftTerm1 * (fLiftTerm2 + fLiftTerm3 + fLiftTerm4 + fLiftTerm5)

class VehicleAerodynamicsModel:

    def __init__(self, initialSpeed = VPC.InitialSpeed, initialHeight = VPC.InitialDownPosition):
        #create class instance of vehicle dynamics
        self.dynamicsModel = VehicleDynamicsModel.VehicleDynamicsModel()
        self.myWindModel = WindModel.WindModel()
        self.dynamicsModel.state.pe = VPC.InitialEastPosition
        self.dynamicsModel.state.pn = VPC.InitialNorthPosition
        self.dynamicsModel.state.pd = VPC.InitialDownPosition
        self.dynamicsModel.state.u = VPC.InitialSpeed

        self.initialHeight = initialHeight
        self.initialSpeed = initialSpeed

    def reset(self):
        #self.dynamicsModel.reset()
        self.myWindModel.reset()
        #print(self.dynamicsModel)
        state = States.vehicleState()
        self.dynamicsModel.state = state
        self.dynamicsModel.pd = self.initialHeight
        self.dynamicsModel.u  = self.initialSpeed
        self.dynamicsModel.dot = state

    def getVehicleState(self):
        return self.dynamicsModel.state

    def setVehicleState(self, state):
        self.dynamicsModel.state = state
        return

    def getVehicleDynamicsModel(self):

        return self.dynamicsModel

    def Update(self, controls):

        DIYAISCRAZY = self.dynamicsModel.getVehicleState()
        f = self.updateForces(DIYAISCRAZY, controls, self.myWindModel.getWind())
        self.dynamicsModel.Update(f)
        '''
        self.myWindModel.Update()
        airspeed = self.CalculateAirspeed(DIYAISCRAZY, self.myWindModel)
        self.dynamicsModel.state.Va = airspeed[0]
        self.dynamicsModel.state.alpha = airspeed[1]
        self.dynamicsModel.state.beta = airspeed[2]
        '''

    #:param alpha, Angle of Attack [rad]
    # return:
    #Coefficient of Lift, CL_alpha (unitless), Coefficient of Drag,
    #CD_alpha (unitless), Coefficoent of Moment, CM_alpha (unitless)
    def CalculateCoeff_alpha(self, alpha):
        Cd_alpha = Cd_fromA(alpha)
        Cl_alpha = Cl_fromA(alpha)
        Cm_alpha = VPC.CM0 + VPC.CMalpha * alpha
        #print("returning CdAlpha = " + str(Cd_alpha))
        #print("returning ClAlpha = " + str(Cl_alpha))
        #print("returning CmAlpha = " + str(Cm_alpha))
        return Cl_alpha, Cd_alpha, Cm_alpha

    #you’ll be calculating the first two terms of Beard 4.6 and 4.7, the first three terms
    #of Beard 4.5, and the first four terms of Beard 4.14, 4.15, and 4.16.

    def aeroForces(self, state):
        #print("start aeroForces()")
        forcesnMoments = Inputs.forcesMoments()
        if(math.isclose(state.Va, 0.0)):
            Fl = 0.0
            Fd = 0.0
            l = 0.0
            m = 0.0
            n = 0.0
            Fy = 0.0
        else:

           # #print("calculated beta now for actaul function")
            Fl = calcLiftForce(state)
            Fd = calcDragForce(state)
            l = calcMomentL(state)
            m = calcMoment(state)
            n = calcMomentN(state)
            Fy = calcFy(state)

            ##print("end aeroForces")
            forcesnMoments.Fx = Fl
            forcesnMoments.Fy = Fy
            forcesnMoments.Fz = Fd
            forcesnMoments.Mx = l
            forcesnMoments.My = m
            forcesnMoments.Mz = n

            m_1 = [[-1.0*Fd],[-1.0*Fl]]
            m_2 = [[math.cos(state.alpha), -1*math.sin(state.alpha)],[math.sin(state.alpha), math.cos(state.alpha)]]
            m_3 = MatrixMath.multiply(m_2, m_1)

            forcesnMoments.Fx = m_3[0][0]
            forcesnMoments.Fz = m_3[1][0]
        return forcesnMoments

    def controlForces(self, state, controls):
        forcesnMoments = Inputs.forcesMoments()
        Fprop = self.CalculatePropForces(state.Va, controls.Throttle)

        Fl =  (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * (VPC.CLdeltaE * controls.Elevator)
        Fd =  (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * (VPC.CDdeltaE * controls.Elevator)
        l = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * VPC.b * (VPC.CldeltaA * controls.Aileron + VPC.CldeltaR * controls.Rudder)
        m = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S  * VPC.c * (VPC.CMdeltaE * controls.Elevator)
        n = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * VPC.b * (VPC.CndeltaA * controls.Aileron + VPC.CndeltaR * controls.Rudder)
        Fy = (1.0/2.0)* VPC.rho * math.pow(state.Va, 2.0) * VPC.S * (VPC.CYdeltaA * controls.Aileron + VPC.CYdeltaR * controls.Rudder)

        #print("end aeroForces")
        forcesnMoments.Fx = Fd
        forcesnMoments.Fy = Fy
        forcesnMoments.Fz = Fl
        forcesnMoments.Mx = l
        forcesnMoments.My = m
        forcesnMoments.Mz = n

        m_1 = [[-1.0*Fd],[-1.0*Fl]]
        m_2 = [[math.cos(state.alpha), -1*math.sin(state.alpha)],[math.sin(state.alpha), math.cos(state.alpha)]]
        m_3 = MatrixMath.multiply(m_2, m_1)

        forcesnMoments.Fx = m_3[0][0]
        forcesnMoments.Fz = m_3[1][0]

        forcesnMoments.Fx += Fprop[0]
        forcesnMoments.Mx += Fprop[1]
        return forcesnMoments

    def gravityForces(self, state):

        forcesnMoments = Inputs.forcesMoments()
        forceVector = [[forcesnMoments.Fx],[forcesnMoments.Fy],[VPC.g0*VPC.mass]]
        gravityInBody = MatrixMath.multiply(state.R, forceVector)

        forcesnMoments.Fx = gravityInBody[0][0]
        forcesnMoments.Fy = gravityInBody[1][0]
        forcesnMoments.Fz = gravityInBody[2][0]

        return forcesnMoments

    def CalculatePropForces(self, Va, Throttle):
        Kt = 60.0/(2.0*math.pi*VPC.KV)
        a = (VPC.rho * math.pow(VPC.D_prop,5.0) * VPC.C_Q0)/(4.0*math.pow(math.pi,2.0))
        b = (VPC.rho * math.pow(VPC.D_prop,4.0) * Va * VPC.C_Q1)/(2.0*math.pi) + (Kt*Kt)/VPC.R_motor
        c = (VPC.rho * math.pow(VPC.D_prop,3.0) * math.pow(Va, 2.0) * VPC.C_Q2) - (Kt*((VPC.V_max*Throttle)/VPC.R_motor)) + Kt*VPC.i0
        try:
            omega = (-b + math.sqrt((b ** 2.0) - (4.0 * a * c))) / (2.0 * a)
        except:
   # print("Crashed Propeller Model doing square root (imaginary), Va = {}, dT = {}, b = {}, c = {}".format(Va, DeltaT, b, c))
            omega = 100.0
        #omega = (-1*b + math.sqrt(math.pow(b,2) - (4*a*c)))/(2*a)
        J =  (2.0* math.pi * Va)/(omega*VPC.D_prop)
        Ct = VPC.C_T0 + VPC.C_T1 * J + VPC.C_T2 * math.pow(J,2.0)
        Cq = VPC.C_Q0 + VPC.C_Q1 * J + VPC.C_Q2 * math.pow(J,2.0)

        Fprop = (VPC.rho * math.pow(omega, 2.0) * math.pow(VPC.D_prop, 4.0) * Ct)/(4.0*math.pow(math.pi,2.0))
        Mprop = (-1.0 * VPC.rho * math.pow(omega, 2.0) * math.pow(VPC.D_prop, 5.0) * Cq)/(4.0*math.pow(math.pi,2.0))

        return (Fprop, Mprop)

    def updateForces(self, state, controls, wind=None):
        if wind is not None:
            #wind.Update(wind.Wu,wind.Wv, wind.Ww)
            airspeed = self.CalculateAirspeed(state, wind)
            state.Va = airspeed[0]
            state.alpha = airspeed[1]
            state.beta = airspeed[2]
        else:
            state.Va = math.hypot(state.u, state.v, state.w)
            state.alpha = math.atan2(state.w,state.u)
            if(math.isclose(state.Va, 0.0)):
                state.beta = 0.0
            else:
                state.beta = math.asin(state.v/math.hypot(state.u, state.v, state.w))
        forcesnMoments = Inputs.forcesMoments()
        aF = self.aeroForces(state)
        cF = self.controlForces(state, controls)
        gF = self.gravityForces(state)

        forcesnMoments.Fx = aF.Fx + cF.Fx + gF.Fx
        forcesnMoments.Fy = aF.Fy + cF.Fy + gF.Fy
        forcesnMoments.Fz = aF.Fz + cF.Fz + gF.Fz

        forcesnMoments.Mx = aF.Mx + cF.Mx
        forcesnMoments.My = aF.My + cF.My
        forcesnMoments.Mz = aF.Mz + cF.Mz

        return forcesnMoments

    def getWindModel(self):

        return self.myWindModel

    def setWindModel(self,windModel):

        self.myWindModel = windModel

    def CalculateAirspeed(self, state, wind):

        Wind_Steady_Mat = [[wind.Wn], [wind.We], [wind.Wd]]
        Wind_Gust_Mat = [[wind.Wu],[wind.Wv],[wind.Ww]]

        #term1 = MatrixMath.multiply(Rotations.euler2DCM(state.yaw, state.pitch, state.roll), Wind_Steady_Mat)
        #WindCombination_InBodyFrame = MatrixMath.add(term1, Wind_Gust_Mat)

        Ws = math.hypot(wind.Wn, wind.We, wind.Wd)
        Xw = math.atan2(wind.We, wind.Wn)
        if math.isclose(Ws, 0.0):
            Yw = 0.0
        else:
            Yw = -1.0 * math.asin(wind.Wd/(math.hypot(wind.Wn, wind.We, wind.Wd)))

        Azimuth_Elevation_RMat = [
        [(math.cos(Xw)*math.cos(Yw)), (math.sin(Xw)*math.cos(Yw)), (-math.sin(Yw))],
        [(-math.sin(Xw)), (math.cos(Xw)), 0.0],
        [(math.cos(Xw)*math.sin(Yw)), (math.sin(Xw)*math.sin(Yw)), (math.cos(Yw))]
        ]

        WindInBody = MatrixMath.multiply(Rotations.euler2DCM(state.yaw, state.pitch, state.roll),MatrixMath.add(Wind_Steady_Mat, MatrixMath.multiply(MatrixMath.transpose(Azimuth_Elevation_RMat),Wind_Gust_Mat)))

        #va = MatrixMath.subtract([[state.u], [state.v], [state.w]], WindInBody)
        AirspeedVec = [
            [state.u-WindInBody[0][0]],
            [state.v-WindInBody[1][0]],
            [state.w-WindInBody[2][0]]
        ]
        va = math.hypot(AirspeedVec[0][0], AirspeedVec[1][0], AirspeedVec[2][0])
        alpha = math.atan2(AirspeedVec[2][0], AirspeedVec[0][0])
        if math.isclose(va, 0.0):
            beta = 0.0
        else:
            beta = math.asin(AirspeedVec[1][0]/va)
        return va, alpha, beta


from django.urls import path

from .views import ItemListView, ItemCreateView, ItemUpdateView

app_name = 'menus'

urlpatterns = [
    path('', ItemListView.as_view(), name='list'),
    path('create/', ItemCreateView.as_view(), name="create"),
    path('<int:pk>/', ItemUpdateView.as_view(), name="detail"),

]


from fastapi import FastAPI, Header
from fastapi.responses import Response
from os import getcwd, path

app = FastAPI()

PORTION_SIZE = 1024 * 1024

current_directory = getcwd() + "/"

@app.get("/video/{name_video}")
def get_video(name_video: str, range: str = Header(None)):
    # bytes=0-
    start, end = range.replace("bytes=", "").split("-")
    start = int(start)
    end = int(start + PORTION_SIZE)

    # LEEMOS LA POSICION EXACTA DEL ARCHIVO

    with open(current_directory + name_video, "rb") as myfile:
        myfile.seek(start)
        data = myfile.read(end - start)
        size_video = str(path.getsize(current_directory + name_video))

        headers = {
            'Content-Range': f'bytes {str(start)}-{str(end)}/{size_video}',
            'Accept-Ranges': 'bytes'
        }
        return Response(content=data, status_code=206, headers=headers, media_type="video/mp4")


import os
import cv2
from random import shuffle
import  pandas as pd
import numpy as np
from random import shuffle
import  pandas as pd
import numpy as np
import shutil
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Input, Dropout
from keras.models import Model, load_model
from keras.utils import np_utils
from keras.models import Sequential
from keras.utils import to_categorical
from sklearn.preprocessing import MinMaxScaler
from matplotlib import pyplot as plt
from  keras.applications import *

def resize_image(source,dest,h=150,w=150,ignore=None):

    dest=dest+"/Resized_"
    if not os.path.exists(dest):
        os.mkdir(dest)
    for file in os.listdir(source):
        if (ignore is not None and file not in ignore) or ignore is None:
            image = cv2.imread(source + "/" + file)
            new_image = cv2.resize(image, (h, w))
            cv2.imwrite(dest + "/" + file, new_image)

source_1 = "../input/all-hog/all_aug/All_aug"
source_2 = "./"
resize_image(source_1,source_2,ignore=["GTruth.csv"])
shutil.copy("../input/all-hog/all_aug/All_aug/GTruth.csv", "Resized_/GTruth.csv")

def data_process(input_path, training_, testing_, validation, truth_values):
    if round(training_ + testing_ + validation, 5) != 1:
        print("Error, sum is not 1 !!! " + str(training_ + testing_ + validation))
        return
    scaler = MinMaxScaler()
    img_val = []
    training_X = []
    testing_X = []
    validationX = []
    training_Y = []
    testing_Y = []
    validationY = []
    img_list = []
    for file in os.listdir(input_path):
        if file != truth_values:
            img_val.append(file.split(".")[0])
            img_list.append(cv2.imread(input_path + "/" + file))
    # shuffle(img_val)
    img_list = np.array(img_list) / 255
    gt = pd.read_csv(input_path + "/" + truth_values)
    temporary = gt["Id"].values.tolist()
    truth_value = gt["Ground_Truth"].values.tolist()

    from_length = 0
    to_length = round(len(img_val) * training_)
    id_list = img_val[from_length:to_length]
    training_X = img_list[from_length:to_length]
    training_Y = [truth_value[temporary.index(int(name))] for name in id_list if int(name) in temporary]
    training_Y = to_categorical(training_Y, 2)

    from_length = to_length
    to_length = to_length + round(len(img_val) * validation)
    id_list = img_val[from_length:to_length]
    validationX = img_list[from_length:to_length]
    validationY = [truth_value[temporary.index(int(name))] for name in id_list if int(name) in temporary]
    validationY = to_categorical(validationY, 2)

    from_length = to_length
    to_length = to_length + round(len(img_val) * validation)
    id_list = img_val[from_length:to_length]
    testing_X = img_list[from_length:to_length]
    testing_Y = [truth_value[temporary.index(int(name))] for name in id_list if int(name) in temporary]
    testing_Y = to_categorical(testing_Y, 2)

    return training_X, validationX, testing_X, training_Y, validationY, testing_Y

def model_build(inp_dim, result):
    model_architecture = Sequential()
    model_architecture.add(Conv2D(32, (3, 3), padding='same', activation='relu', inp_dim=inp_dim))
    model_architecture.add(Conv2D(32, (3, 3), activation='relu'))
    model_architecture.add(MaxPooling2D(pool_size=(2, 2)))
    model_architecture.add(Dropout(0.125))

    model_architecture.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
    model_architecture.add(Conv2D(64, (3, 3), activation='relu'))
    model_architecture.add(MaxPooling2D(pool_size=(2, 2)))
    model_architecture.add(Dropout(0.1))

    model_architecture.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
    model_architecture.add(Conv2D(64, (3, 3), activation='relu'))
    model_architecture.add(MaxPooling2D(pool_size=(2, 2)))
    model_architecture.add(Dropout(0.2))

    model_architecture.add(Flatten())
    model_architecture.add(Dense(512, activation='relu'))
    model_architecture.add(Dropout(0.19))
    model_architecture.add(Dense(result, activation='softmax'))
    return model_architecture

def pre_trained_model_architecture(name_id,inp_dim1,result):
  model_architecture = Sequential()
  model_architecture.add(name_id(weights='imagenet',include_top=False,input_shape=inp_dim1))
  model_architecture.add(Flatten())
  model_architecture.add(Dense(512, activation='relu'))
  model_architecture.add(Dropout(0.5))
  model_architecture.add(Dense(result, activation='softmax'))
  return model_architecture

trainX,valX,testX,trainY,valY,testY=data_process("Resized_",0.7,0.2,0.1,"GTruth.csv")

model=model_build(trainX.shape[1:],2)
#model=pre_trained_model(InceptionV3,trainX.shape[1:],2)
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
model.summary()

batch_size = 256
epochs = 20
res_set = model.fit(trainX, trainY, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(valX, valY))
model.evaluate(testX,testY)

plt.style.use('seaborn-ticks')
plt.plot(res_set.history['acc'])
plt.plot(res_set.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

#loss graph
plt.plot(res_set.history['loss'])
plt.plot(res_set.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()


import matplotlib.pyplot as plt
import pandas as pd
import os
import numpy as np
plt.ion()
#from matplotlib import cm

df = pd.read_csv('ising_correlacion_Jcrit.txt',header=None,sep=' ',skiprows=2)
datos = np.loadtxt('ising_correlacion_J=0_B=0.txt', skiprows=1)

plt.plot(datos[0,:])

J = np.arange(0.4,0.65,0.05)

datos = np.loadtxt('ising_correlacion_Js_06.txt', skiprows=2)

plt.figure()
for i in range(0,6):
	plt.plot(datos[i,:], label='j = 0.{}'.format(1-i))
plt.legend()
plt.ylim([-1,2])

#m = cm.ScalarMappable(norm=None, cmap='gist_rainbow')
#colores = m.to_rgba(np.arange(0.1,1.4,0.1)/1.4)
#colores = m.to_rgba(J/max(J))

for i in range(df.shape[0]-1):
	plt.plot(df.iloc[i,:],label='J={0:.2f}'.format(J[i]))#,c=colores[i])
plt.xlabel('Pasos por sitio ($k/L^2$)')
plt.ylabel('C')
plt.title('Correlacion para magnetizacion')
#plt.ylim([-1,1])
plt.legend()
plt.grid()

plt.show()

datos = np.loadtxt('magnetizacion_vs_B.txt', skiprows=2)
B = datos[:,0]
m = datos[:,1]
u = datos[:,2]

plt.plot(B,m/(-20), label='mag')
plt.plot(B,u/100, label='energia')
plt.legend()


import sqlite3
from tkinter import *
from tkinter.messagebox import showerror, showinfo
from tkinter.ttk import Combobox

class test:

    conn=sqlite3.connect("timetabledata.sqlite3")

    def save(self):
        ans=self.cr.fetchall()
        flag= False
        for r in self.ans:
            if str(r[0]).upper()==self.txt2.get().upper:
                flag=True
                break
        if flag==True:
            showinfo("","Duplicate Course Name")
        elif self.txt2.get()=="" or self.txt3.get()=="":
            showerror("","Please Fill The Record")
        else:

            cr = self.conn.cursor()
            s = "insert into programmes values ('" +self.txt2.get()+ "','" + self.txt3.get() + "')"

            self.cr.execute(s)
            self.conn.commit()
            showinfo("", "Record Added Successfully")

    def __init__(self):
        self.root=Tk()
        self.root.geometry("550x550")
        self.cr=self.conn.cursor()
        s="select * from Programmes"
        self.cr.execute(s)
        self.ans=self.cr.fetchall()
        p=["Select Programme"]
        for r in self.ans:
            p.append(r[0])

        self.lb3 = Label(self.root, text="Add Programme Name")
        self.lb4 = Label(self.root, text="Add Description")
        self.bt3 = Button(self.root, text='Save',command=self.save)
        self.txt2=Entry(self.root)
        self.txt3=Entry(self.root)

        self.lb3.grid(row=3,column=0)
        self.lb4.grid(row=4,column=0)
        self.txt2.grid(row=3,column=1)
        self.txt3.grid(row=4,column=1)
        self.bt3.grid(row=5,column=1)

        self.root.mainloop()


import sys
import sympy

def get_safe_prime(prime_number):
    N = 2 * prime_number + 1
    if sympy.isprime(N):
        return N, sympy.primitive_root(N)

def main():
    if len(sys.argv) < 2:
        print(f'Usage: {sys.argv[0]} <number of primes>')
        return

    print('{')
    first = True
    for i in range(1, int(sys.argv[1])):
        prime_number = sympy.prime(i)
        N = 2 * prime_number + 1
        if sympy.isprime(N):
            if not first:
                print(',')
            print(f'    {{{N}, {sympy.primitive_root(N)}}}', end='')
            first = False
    print('\n}')

if __name__ == '__main__':
    main()


def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:

        if len(inorder) < 1:
            return None

        root = TreeNode(preorder[0])

        rootindex = inorder.index(root.val)

        lefttree = inorder[:rootindex]

        righttree = inorder[rootindex+1:]

        preorder.remove(root.val)

        root.left = self.buildTree(preorder,lefttree)
        root.right = self.buildTree(preorder, righttree)

        return root

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:

        def buildTree(r1,r2):
            nxtNode = TreeNode()

            if not r1 and not r2:
                return

            if r1 and r2:
                nxtNode = TreeNode(r1.val + r2.val)
            else:
                if not r1 and r2:
                    nxtNode = TreeNode(r2.val)
                elif r1 and not r2:
                    nxtNode = TreeNode(r1.val)
                else:
                    nxtNode = TreeNode(r1.val or r2.val)

            if r1.left and r2.left:
                nxtNode.left = buildTree(r1.left,r2.left)
            else:
                nxtNode.left = r1.left or r2.left

            if r1.right and r2.right:
                nxtNode.right = buildTree(r1.right, r2.right)
            else:
                nxtNode.right = r1.right or r2.right

            return nxtNode

        if not root1:
            return root2
        if not root2:
            return root1

        rtnode = TreeNode(root1.val + root2.val)
        print(rtnode)
        rtnode.left = buildTree(root1.left, root2.left)
        rtnode.right = buildTree(root1.right, root2.right)

        return rtnode


######LOGGING SETTINGS##########

LOG_LOCATION = "/var/log/frankie-steen.log"
LOG_VERBOSITY = 10 #DEBUG 10, INFO 20, WARNING 30, ERROR 40, CRITICAL 50 -OUTPUT to file
LOG_SHELL_VERBOSITY = 10 #Level of verbosity for what shows up in the shell
LOG_NAME = "frankie-steen"
FRAME_COUNT = 0
ROTATION = 0

#####STEPPER SETTTINGS#######

STEPPER_RES = "1" #The resolution of the stepper motor could be 1, 1/2, 1/4. 1/8. 1/16. 1/32
STEPPER_MAX = 0.001 #The fastest speed the stepper motor can go before chopping
STEPPER_MIN = 1 #The lowest reasonable speed for the stepper
STEPPER_DEFAULT = .01 #Speed for default operations
STEPPER_FRAME_DEGREE = 22.5
STEPPER_TOTAL_STEPS = 200.0

STEPPER_FLOATS = [1.0, 0.5, 0.25, 0.125, 0.0625, 0.03125]

#####GPIO PINOUT######

GPIO_MODE = "BCM"

GPIO_STEPPER_0_DIR = 4
GPIO_STEPPER_0_ON =  5
GPIO_STEPPER_0_STEP = 13
GPIO_STEPPER_0_MODE0 = 7
GPIO_STEPPER_0_MODE1 = 8
GPIO_STEPPER_0_MODE2 = 9

GPIO_STEPPER_2_DIR = 11
GPIO_STEPPER_2_ON =  10
GPIO_STEPPER_2_STEP = 12
GPIO_STEPPER_2_MODE0 = 15
GPIO_STEPPER_2_MODE1 = 14
GPIO_STEPPER_2_MODE2 = 6

STEPPER_FULL = [0,0,0]
STEPPER_HALF = [1,0,0]
STEPPER_QUART = [0,1,0]
STEPPER_EIGHT = [1,1,0]
STEPPER_SIXT = [0,0,1]
STEPPER_THIRT = [1,0,1]

GPIO_MOTOR_1_DIR = 16
GPIO_STEPPER_1_ON =  17

GPIO_STATUS_RED = 19
GPIO_STATUS_GREEN = 20
GPIO_STATUS_BLUE = 21

GPIO_TOGGLE_RUN = 22
GPIO_TOGGLE_UPTAKE = 23
GPIO_BTN_POWER = 24
GPIO_BTN_CALIBRATE = 25

GPIO_CAMERA_SHUTTER = 26

GPIO_FREQUENCIES = [250.0, 200.0, 160.0, 100.0, 80.0, 50.0, 40.0, 20.0, 10.0]

#####ADC CHANNEL####

ADC_KNOB_0 = 0
ADC_KNOB_1 = 1
ADC_KNOB_2 = 2
ADC_PHOTOSENSOR_1 = 4
ADC_GAIN = 1
ADC_KNOB_SELECT = 0
ADC_KNOB_SWEEP = 1
ADC_KNOB_HI = 26500
ADC_KNOB_LO = 220

ADC_KNOB_THRESHOLD = .05

SELECT_MANUAL_ADJUST = 0
SELECT_RUN = 1


from django.shortcuts import render, HttpResponseRedirect
from . forms import AeroportsForm
from . import models

def formulaire(request):
    if request.method == "POST":
        form = AeroportsForm(request)
        return render(request, "basedonnees/aeroport/formulaire.html", {"form": form})
    else:
        form = AeroportsForm()
        id = ""
        return render(request, "basedonnees/aeroport/formulaire.html", {"form": form, "id": id})

def traitement(request):
    lform = AeroportsForm(request.POST)
    if lform.is_valid():
        lform.save()
        return HttpResponseRedirect('/indexaeroport/')
    else:
        return render(request, "basedonnees/aeroport/formulaire.html", {"form": lform})

def index(request):
    liste = list(models.Aeroports.objects.all())
    return render(request, 'basedonnees/aeroport/index.html', {'liste': liste})

def affiche(request, id):
    aeroport = models.Aeroports.objects.get(pk=id)
    return render(request, 'basedonnees/aeroport/affiche.html', {"aeroport": aeroport})

def update(request, id):
    aeroport = models.Aeroports.objects.get(pk=id)
    form = AeroportsForm(aeroport.dico())
    return render(request, 'basedonnees/aeroport/update.html', {'form': form, 'id': id})

def updatetraitement(request, id):
    lform = AeroportsForm(request.POST)
    if lform.is_valid():
        aeroport = lform.save(commit=False)
        aeroport.id = id
        aeroport.save()
        return HttpResponseRedirect('/aeroports/indexaeroport/')
    else:
        return render(request, "aeroport/update.html", {"form": lform, "id": id})

def delete(request, id):
    aeroports = models.Aeroports.objects.get(pk=id)
    aeroports.delete()
    return HttpResponseRedirect('/aeroports/indexaeroport/')


#06-01-2020_

#Follow up: Recursive solution is trivial, could you do it iteratively?
#The Infamous
#The Ambiguous
#The Stack Approach

#Runtime: 24 ms, faster than 91.59% of Python3 online submissions for Binary Tree Inorder Traversal.
#Memory Usage: 13.9 MB, less than 6.56% of Python3 online submissions for Binary Tree Inorder Traversal.
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        contents = []
        stack = []
        curr = root
        while curr or len(stack) > 0:
            while curr:
                stack.append(curr)
                curr = curr.left
            curr = stack.pop()
            contents.append(curr.val)
            curr = curr.right
        return contents

#Runtime: 28 ms, faster than 74.06% of Python3 online submissions for Binary Tree Inorder Traversal.
#Memory Usage: 13.9 MB, less than 6.56% of Python3 online submissions for Binary Tree Inorder Traversal.
class Solution:
    contents = []
    first = 0
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if self.first == 0:
            self.contents = []
            self.first+=1
        if root:
            self.inorderTraversal(root.left)
            self.contents.append(root.val)
            self.inorderTraversal(root.right)
        return self.contents


import pytest

import capybara
import capybara.dsl

def pytest_runtest_setup(item):
    if item.get_marker("js"):
        capybara.current_driver = capybara.javascript_driver

    driver = item.get_marker("driver")
    if driver:
        assert len(driver.args) == 1, "exactly one driver must be specified"
        capybara.current_driver = driver.args[0]

def pytest_runtest_teardown():
    capybara.reset_sessions()
    capybara.use_default_driver()

@pytest.fixture
def page():
    return capybara.dsl.page


import mariadb as db
import DbInteractions.dbhandler as dbh
import traceback

# Function that will get users that follow a specific userId

def get_followers(userId):
    follows_list = []
    conn, cursor = dbh.db_connect()
    try:
        cursor.execute(
            "SELECT `user`.id, email, username, bio, birthdate, imageUrl, bannerUrl FROM follow inner join `user` on follow.user_id = `user`.id WHERE follow_id = ?", [userId])
        users = cursor.fetchall()
        for user in users:
            follows_list.append(
                {
                    'userId': user[0],
                    'email': user[1],
                    'username': user[2],
                    'bio': user[3],
                    'birthdate': user[4],
                    'imageUrl': user[5],
                    'bannerUrl': user[6]
                })
    except db.OperationalError:
        traceback.print_exc()
        print('Something went  wrong with the db!')
    except db.ProgrammingError:
        traceback.print_exc()
        print('Error running DB query')
    except:
        traceback.print_exc()
        print("Something unexpected went wrong")
    dbh.db_disconnect(conn, cursor)
    return True, follows_list


import random

def selectSortFn(ListaAleatoria):
  for i in range(len(lista)):
    for j in range(len(lista)):
      if lista[i] < lista[j]:
        lista[j],lista[i] = lista[i],lista[j]
  return lista

lista = []
totalLista = random.randrange(1,20)
for x in range(totalLista):
  lista.append(random.randrange(1,100))

print(lista)
print(selectSortFn(lista))


import basf2 as b2
from stdPi0s import stdPi0s
import modularAnalysis as ma

def add_analysis_dqm(path):
    """Add the analysis DQM modules to the ``path``.
    Builds a list of muons, pi0's, Kshorts and the Fox Wolfram event shape variables.
    Also M(mumu) for nominal beam energy monitoring.

    Parameters:
        path (basf2.Path): modules are loaded onto this path
    """

    # muons, Kshorts and pi0s
    ma.fillParticleList('mu+:KLMDQM', 'p>0.2 and abs(d0) < 2 and abs(z0) < 4', path=path)
    ma.fillParticleList('gamma:physDQM', 'E > 0.15', path=path)
    ma.fillParticleList('pi+:physDQM', 'pt>0.2 and abs(d0) < 2 and abs(z0) < 4', path=path)
    ma.fillParticleList('mu+:physDQM', 'pt>2. and abs(d0) < 2 and abs(z0) < 4', path=path)
    ma.reconstructDecay('pi0:physDQM -> gamma:physDQM gamma:physDQM', '0.10 < M < 0.15', 1, True, path)
    ma.reconstructDecay('K_S0:physDQM -> pi-:physDQM pi+:physDQM', '0.48 < M < 0.52', 1, True, path)
    ma.reconstructDecay('Upsilon:physDQM -> mu-:physDQM mu+:physDQM', '9 < M < 12', 1, True, path)

    # have to manually create "all" lists of pi+ and photons to use inside buildEventShape
    # to avoid loading the photons' beamBackgroundMVA variable on the DQM
    ma.fillParticleList('pi+:evtshape', '', path=path)
    ma.fillParticleList('gamma:evtshape', '', path=path)
    ma.buildEventShape(
        path=path,
        inputListNames=['pi+:evtshape', 'gamma:evtshape'],
        default_cleanup=False,  # do not want any clean up
        foxWolfram=True,
        cleoCones=False,
        collisionAxis=False,
        harmonicMoments=False,
        jets=False,
        sphericity=False,
        thrust=False)

    dqm = b2.register_module('PhysicsObjectsDQM')
    dqm.param('PI0PListName', 'pi0:physDQM')
    dqm.param('KS0PListName', 'K_S0:physDQM')
    dqm.param('UpsPListName', 'Upsilon:physDQM')
    path.add_module(dqm)

def add_mirabelle_dqm(path):
    """Add the mirabelle DQM modules to the ``path``.
    Runs on conditional paths depending on the software trigger results.
    Building D*'s or dimuons on the conditional paths.

    Parameters:
        path (basf2.Path): modules are loaded onto this path
    """
    # Software Trigger to divert the path
    MiraBelleMumu_path = b2.create_path()
    MiraBelleDst1_path = b2.create_path()
    MiraBelleNotDst1_path = b2.create_path()
    MiraBelleDst2_path = b2.create_path()

    trigger_skim_mumutight = path.add_module(
        "TriggerSkim",
        triggerLines=["software_trigger_cut&skim&accept_mumutight"],
        resultOnMissing=0,
    )
    trigger_skim_mumutight.if_value("==1", MiraBelleMumu_path, b2.AfterConditionPath.CONTINUE)

    trigger_skim_dstar_1 = path.add_module(
        "TriggerSkim",
        triggerLines=["software_trigger_cut&skim&accept_dstar_1"],
        resultOnMissing=0,
    )
    trigger_skim_dstar_1.if_value("==1", MiraBelleDst1_path, b2.AfterConditionPath.CONTINUE)

    trigger_skim_not_dstar_1 = path.add_module(
        "TriggerSkim",
        triggerLines=["software_trigger_cut&skim&accept_dstar_1"],
        expectedResult=0,
        resultOnMissing=0,
    )
    trigger_skim_not_dstar_1.if_value("==1", MiraBelleNotDst1_path, b2.AfterConditionPath.CONTINUE)
    trigger_skim_dstar_2 = MiraBelleNotDst1_path.add_module(
        "TriggerSkim",
        triggerLines=["software_trigger_cut&skim&accept_dstar_2"],
        resultOnMissing=0,
    )
    trigger_skim_dstar_2.if_value("==1", MiraBelleDst2_path, b2.AfterConditionPath.CONTINUE)

    # MiraBelle di-muon path
    ma.fillParticleList('mu+:physMiraBelle', '', path=MiraBelleMumu_path)
    ma.reconstructDecay('Upsilon:physMiraBelle -> mu+:physMiraBelle mu-:physMiraBelle', '9 < M < 12', path=MiraBelleMumu_path)
    MiraBelleMumu = b2.register_module('PhysicsObjectsMiraBelle')
    MiraBelleMumu.param('MuPListName', 'mu+:physMiraBelle')
    MiraBelleMumu.param('MuMuPListName', 'Upsilon:physMiraBelle')
    MiraBelleMumu_path.add_module(MiraBelleMumu)

    # MiraBelle D* (followed by D0 -> K pi) path
    ma.fillParticleList('pi+:MiraBelleDst1', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst1_path)
    ma.fillParticleList('K+:MiraBelleDst1', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst1_path)
    ma.reconstructDecay('D0:MiraBelleDst1_kpi -> K-:MiraBelleDst1 pi+:MiraBelleDst1', '1.7 < M < 2.1', path=MiraBelleDst1_path)
    ma.reconstructDecay('D*+:MiraBelleDst1_kpi -> D0:MiraBelleDst1_kpi pi+:MiraBelleDst1',
                        'useCMSFrame(p) > 2.5 and massDifference(0) < 0.16', path=MiraBelleDst1_path)
    MiraBelleDst1 = b2.register_module('PhysicsObjectsMiraBelleDst')
    MiraBelleDst1.param('DstListName', 'D*+:MiraBelleDst1_kpi')
    MiraBelleDst1_path.add_module(MiraBelleDst1)

    # MiraBelle D* (followed by D0 -> K pi pi0) path
    ma.fillParticleList('pi+:MiraBelleDst2', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst2_path)
    ma.fillParticleList('K+:MiraBelleDst2', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst2_path)
    stdPi0s(listtype='eff60_May2020', path=MiraBelleDst2_path)
    ma.reconstructDecay(
        'D0:MiraBelleDst2_kpipi0 -> K-:MiraBelleDst2 pi+:MiraBelleDst2 pi0:eff60_May2020',
        '1.7 < M < 2.1',
        path=MiraBelleDst2_path)
    ma.reconstructDecay('D*+:MiraBelleDst2_kpipi0 -> D0:MiraBelleDst2_kpipi0 pi+:MiraBelleDst2',
                        'useCMSFrame(p) > 2.5 and massDifference(0) < 0.16', path=MiraBelleDst2_path)
    MiraBelleDst2 = b2.register_module('PhysicsObjectsMiraBelleDst2')
    MiraBelleDst2.param('DstListName', 'D*+:MiraBelleDst2_kpipi0')
    MiraBelleDst2_path.add_module(MiraBelleDst2)


# -*- coding: utf-8 -*-
"""
Created on Thu Dec 26 14:58:57 2019

@author: Administrator

MCD12 LandCover Types：
DBF == 4：DBF,5：MF
EBF == 2：EBF
NF == 1：ENF,3：DNF
CRO == 12: CRO, 14: CRO&NV
GRA == 10: GRA
SHR == 6：CSH, 7：OSH
SAV == 8：WSA, 9：SAV
"""

import numpy as np
import matplotlib.pyplot as plt
import os
from osgeo import gdal_array
import matplotlib.gridspec as gridspec
import warnings
warnings.filterwarnings('ignore')

in_file_path = r"F:\Chlorophyll_Fluorescence\Process\Europe\Step14.Boreal_Map"
landcover_file = r"F:\Chlorophyll_Fluorescence\Process\Europe\Step14.Boreal_Map\MOD12_LandUse_N.tif"
plot_path = r"F:\Chlorophyll_Fluorescence\Process\Europe\Step4.Table\Polygon\4.11.Box_Plot_His"

Products = ["TROPOMI_SC","TROPOMI_SR","NIRv","EVI"]
LandCover = ["DBF", "NF", "SAV", "GRA", "SHR", "CRO"]
LC_CODE = [[4,5],[1,3],[8,9],[10],[6,7],[12,14]]
Metrics = [1,3,5] #1,3,5分别代表SOS,EOS,LOS
Name = ["DBF", "NF", "SAV", "GRA", "SHR", "CRO"]
nrows = 2
ncols = 3
figure_scale_row = nrows * 2.0
figure_scale_col = ncols * 2.0
fig = plt.figure(figsize=(figure_scale_col, figure_scale_row))#, sharey=True)
gs = gridspec.GridSpec(nrows, ncols, wspace=0.1, hspace=0.6)

fs = 5 # fontsize
x_labels = ['SOS', 'EOS', 'GSL'] #'Tropomi_SR', 'MODIS', 'OCO-2']
y_lables = [0, 100, 200, 300]
min_y = 0
max_y = 365
ny = 4 #y轴刻度个数
bar_width = 0.15 #柱状体宽度
capsize = 1.2 #柱状体标准差参数1
capthick = 0.8  #柱状体标准差参数2
elinewidth = 0.8 #柱状体标准差参数3
linewidth = 1.0 #边框线宽度
ftsize = 10 #字体大小
ftfamily = "Times New Roman"
axlength = 2.0 #轴刻度长度
axwidth = 1.2 #轴刻度宽度
legendcols = 5 #图例一行的个数

for i in range(len(LandCover)):
    mean = []
    err = []
    for j in range(len(Metrics)):
        lc_array = gdal_array.LoadFile(landcover_file)
        SIF_SC_array = gdal_array.LoadFile(os.path.join(in_file_path, "14.1.SC_GSL_Mask/SC_{0}.tif".format(Metrics[j])))
        SIF_SR_array = gdal_array.LoadFile(os.path.join(in_file_path, "14.1.SR_GSL_Mask/SR_{0}.tif".format(Metrics[j])))
        dcSIF_array = gdal_array.LoadFile(os.path.join(in_file_path, "14.1.dcSIF_GSL_Mask/dcSIF_{0}.tif".format(Metrics[j])))
        EVI_array = gdal_array.LoadFile(os.path.join(in_file_path, "14.1.EVI_GSL_Mask/EVI_{0}.tif".format(Metrics[j])))
        NIRv_array = gdal_array.LoadFile(os.path.join(in_file_path, "14.1.NIRv_GSL_Mask/NIRv_{0}.tif".format(Metrics[j])))

        SIF_SC = []
        SIF_SR = []
        dcSIF = []
        NIRv = []
        EVI = []

        for m in range(len(lc_array)):
            for n in range(len(lc_array[0])):
               if lc_array[m,n] in LC_CODE[i]:
                  if abs(SIF_SC_array[m,n]) < 999:
                      SIF_SC.append(SIF_SC_array[m,n])
                  if abs(SIF_SR_array[m,n]) < 999:
                      SIF_SR.append(SIF_SR_array[m,n])
                  if abs(dcSIF_array[m,n]) < 999:
                      dcSIF.append(dcSIF_array[m,n])
                  if abs(NIRv_array[m,n]) < 999:
                      NIRv.append(NIRv_array[m,n])
                  if abs(EVI_array[m,n]) < 999:
                      EVI.append(EVI_array[m,n])

        mean.append([np.nanmean(SIF_SC), np.nanmean(SIF_SR), np.nanmean(dcSIF), np.nanmean(NIRv), np.nanmean(EVI)])
        err.append([np.nanstd(SIF_SC), np.nanstd(SIF_SR), np.nanstd(dcSIF), np.nanstd(NIRv), np.nanstd(EVI)])
    mean = np.array(mean)
    err = np.array(err)

    #画直方图
    x = np.arange(int(len(x_labels)))
    col = int(i % ncols)
    row = int(i / ncols)
    axes = fig.add_subplot(gs[row, col])

    SIF_SC = axes.bar(x + 0 * bar_width, mean[:,0], bar_width, yerr = err[:,0],  error_kw = {'ecolor' : '0.2', 'elinewidth':elinewidth, 'capsize' :capsize, 'capthick' :capthick}, color="olivedrab", label = "SIF$_T$$_R$$_O$$_P$$_O$$_M$$_I$$_\_$$_t$$_o$$_t$$_a$$_l$$_-$$_S$$_C$", align="center", alpha=1)
    SIF_SR = axes.bar(x + 1 * bar_width, mean[:,1], bar_width, yerr = err[:,1],  error_kw = {'ecolor' : '0.2', 'elinewidth':elinewidth, 'capsize' :capsize, 'capthick' :capthick}, color="yellowgreen",  label = "SIF$_T$$_R$$_O$$_P$$_O$$_M$$_I$$_\_$$_t$$_o$$_t$$_a$$_l$$_-$$_S$$_R$", align="center", alpha=1)
    dcSIF = axes.bar(x + 2 * bar_width, mean[:,2], bar_width, yerr = err[:,2],  error_kw = {'ecolor' : '0.2', 'elinewidth':elinewidth, 'capsize' :capsize, 'capthick' :capthick}, color="forestgreen",   label = "SIF$_T$$_R$$_O$$_P$$_O$$_M$$_I$$_\_$$_O$$_b$$_s$", align="center", alpha=1)
    NIRv = axes.bar(x + 3 * bar_width, mean[:,3], bar_width, yerr = err[:,3],  error_kw = {'ecolor' : '0.2', 'elinewidth':elinewidth, 'capsize' :capsize, 'capthick' :capthick}, color="darkgoldenrod",   label = "NIRv", align="center", alpha=1)
    EVI = axes.bar(x + 4 * bar_width, mean[:,4], bar_width, yerr = err[:,4],  error_kw = {'ecolor' : '0.2', 'elinewidth':elinewidth, 'capsize' :capsize, 'capthick' :capthick}, color="gold",   label = "EVI", align="center", alpha=1)

    axes.set_title("({0}) {1}".format(chr(97+i),Name[i]), fontsize = ftsize/1.2, family = ftfamily)
    axes.set_xticks(x + 2 * bar_width)
    axes.set_xticklabels(x_labels, fontsize = fs, family = ftfamily)
    axes.set_ylim(min_y, max_y)
    axes.spines['left'].set_linewidth(linewidth)
    axes.spines['right'].set_linewidth(linewidth)
    axes.spines['top'].set_linewidth(linewidth)
    axes.spines['bottom'].set_linewidth(linewidth)
    axes.tick_params(axis='both', length = axlength, width = axwidth, labelsize = ftsize/1.5)
    if col == 0:
        axes.set_ylabel('Day of Year (days)', fontsize = ftsize/1.6, family=ftfamily)
        axes.set_yticks(np.linspace(min_y, max_y - 65, ny))
        axes.set_yticklabels(y_lables, fontsize = fs + 2, family=ftfamily)
    else:
        axes.yaxis.set_visible(False)
    axes.set_xlabel('Phenological Metrics', fontsize = ftsize/1.5, family=ftfamily)

    handles = [SIF_SC, SIF_SR, dcSIF, NIRv, EVI]

    labels = ['SIF$_\mathdefault{total-SC}$',\
              'SIF$_\mathdefault{total-SR}$',\
              'SIF$_\mathdefault{Obs}$',\
              'NIR$_\mathdefault{V}$','EVI']
    """
    if i == 0:
        axes.legend(handles, labels, loc ='upper left', fancybox = False, shadow = False,frameon = False,
                   ncol = legendcols, prop={'family':ftfamily, 'size':ftsize/3})
    """

fig.legend(handles, labels, loc ='lower center', fancybox = False, shadow = False,frameon = False,
          ncol = legendcols, handletextpad = 0.2, columnspacing = 1.5, prop={'family':"Times New Roman", 'size':ftsize/1.3})
fig.tight_layout()
fig.subplots_adjust(left = None, right = None, bottom = 0.15)
Plot_path = os.path.join(plot_path, "Rs2-Global.jpg")
plt.show()
fig.savefig(Plot_path, dpi=600, quality=100,bbox_inches='tight')


from controllers.controller_classe import ControllerClasse
from controllers.controller_combate import ControllerCombate
from controllers.controller_jogador import ControllerJogador
from controllers.controller_npc import ControllerNpc
from controllers.controller_poder import ControllerPoder
from exceptions import exceptions
from utils.opcoes_menus import MenuInicial
from utils.setup import setup

from views.view_menu import ViewMenu

class ControllerMain:

    def __init__(self):
        self.__view_menu = ViewMenu()
        self.__controller_classe = ControllerClasse()
        self.__controller_poder = ControllerPoder()
        self.__controller_jogador = ControllerJogador(
            self.__controller_classe,
            self.__controller_poder
        )
        self.__controller_npc = ControllerNpc()
        self.__controller_combate = ControllerCombate(
            self.__controller_jogador,
            self.__controller_npc,
            self.__controller_poder,
            self.__controller_classe
        )

    def recriar_objetos(self, resetar=False):
        inicializado = len(self.__controller_classe.get_all()) == 0
        inicializado |= len(self.__controller_poder.get_all()) == 0
        inicializado |= len(self.__controller_combate.get_all()) == 0
        inicializado |= len(self.__controller_jogador.get_all()) == 0

        if not inicializado and not resetar:
            return

        setup(
            controller_classe=self.__controller_classe,
            controller_poder=self.__controller_poder,
            controller_npc=self.__controller_npc,
            controller_jogador=self.__controller_jogador,
            controller_combate=self.__controller_combate,
        )

    def main(self):
        self.recriar_objetos()
        while True:
            nivel = self.__controller_jogador.get_all()[0].classe.nivel
            try:
                # Display menu
                escolha = self.__view_menu.menu_inicial(nivel)

                # O grupo será composto por 3 personagens
                if escolha == MenuInicial.CRIAR_GRUPO:
                    # Criar grupo de personagens
                    # Grupo possui 3 personagens
                    for index in range(1, 4):
                        self.__controller_jogador.criar_personagem(index, nivel)

                elif escolha == MenuInicial.MOSTRAR_GRUPO:
                    # Mostrar grupo atual
                    estatisticas_classes = []
                    nomes_poderes_personagens = []
                    for jogador in self.__controller_jogador.get_all():
                        estatisticas_classes.append(self.__controller_classe.estatisticas_dict(jogador.classe.nome))
                        nomes_poderes_personagens.append(self.__controller_poder.nomes(jogador.poderes))

                    self.__view_menu.grupo(
                        self.__controller_jogador.nomes(self.__controller_jogador.get_all()),
                        estatisticas_classes,
                        nomes_poderes_personagens,
                        nivel
                    )

                elif escolha == MenuInicial.MOSTRAR_ESTATISTICAS:
                    # Mostrar grupo atual
                    self.__view_menu.estatisticas(
                        self.__controller_jogador.estatisticas(),
                    )

                elif escolha == MenuInicial.RESETAR_DATABASE:
                    # Mostrar grupo atual
                    self.__view_menu.resetar_database()
                    self.recriar_objetos(True)

                elif escolha.value in MenuInicial.COMBATES.value:
                    combate_numero = escolha.value

                    # Iniciar um combate
                    vitoria = self.__controller_combate.iniciar_combate(combate_numero)

                    # Vencer o ultimo combate liberado faz o personagem aumentar de nivel
                    if vitoria and nivel != 3:
                        nivel += 1
                        self.__controller_jogador.aumentar_nivel()
            except exceptions.FecharPrograma as e:
                break
            except exceptions.SairCombate as e:
                pass
            except exceptions.VoltarMenu as e:
                pass
            except Exception as e:
                pass
        self.__view_menu.sair()


from PIL import Image, ImageFont, ImageDraw
from io import BytesIO
import os

font_size = {
    'big': 12,
    'small': 10
}

text_margin = {
    'big': 7,
    'small': 6
}

img_margin = {
    'big': 20,
    'small': 10
}

config = {}

def init_font(size='small'):
    if 'font' not in config:
        config['font'] = {}

    if size not in config['font']:
        config['font'][size] = ImageFont.truetype(os.path.dirname(os.path.realpath(__file__)) + "/Helvetica Bold.ttf", font_size[size])

    return config['font'][size]

def read_image(_type, direction, size):
    if _type not in config:
        config[_type] = {}
    if direction not in config[_type]:
        config[_type][direction] = {}
    if size not in config[_type][direction]:
        config[_type][direction][size] = Image.open(os.path.dirname(os.path.realpath(__file__)) + "/imgs/%s_%s_%s.png" % (_type, direction, size))

    return config[_type][direction][size]

def draw_single_img(number, image_left, image_right, font, _size='small'):
    number = to_text(number)

    text_size = font.getsize(number)
    size = (image_left.size[0] + text_size[0] + image_right.size[0], image_left.size[1])

    text_pos = (image_left.size[0], text_margin[_size])
    text_rec = (image_left.size[0], 0, image_left.size[0] + text_size[0], size[1])
    line_top_rec = (image_left.size[0], 0, text_rec[2], 0)
    line_bot_rec = (image_left.size[0], size[1] - 1, text_rec[2], size[1])
    left_rec = (0,0,image_left.size[0], size[1])
    right_rec = (text_rec[2], 0, size[0], size[1])

    img = Image.new("RGBA", size, None)

    img.paste(image_left, left_rec)
    img.paste(image_right, right_rec)

    draw = ImageDraw.Draw(img)

    draw.rectangle(text_rec, fill=(250,250,250))

    draw.rectangle(line_top_rec, fill=(213,213,213))
    draw.rectangle(line_bot_rec, fill=(213,213,213))
    draw.text(text_pos, number, (54,54,54), font=font)

    return img

def draw_stars(stars, size='small', save=False):
    image_left = read_image('star', 'left', size)
    image_right = read_image('star', 'right', size)
    font = init_font(size)

    img = draw_single_img(stars, image_left, image_right, font, size)

    if save:
        img.save("stars.png")

    return img

def draw_folks(folks, size='small', save=False):
    image_left = read_image('folk', 'left', size)
    image_right = read_image('folk', 'right', size)
    font = init_font(size)

    img = draw_single_img(folks, image_left, image_right, font, size)

    if save:
        img.save("folks.png")

    return img

def draw_watches(watches, size='small', save=False):
    image_left = read_image('watch', 'left', size)
    image_right = read_image('watch', 'right', size)
    font = init_font(size)

    img = draw_single_img(watches, image_left, image_right, font, size)

    if save:
        img.save("watches.png")

    return img

def draw_image(watches=None, stars=None, folks=None, _size='small', save=False):
    imgs = []
    if watches != None:
        imgs.append(draw_watches(watches, _size, save))

    if stars != None:
        imgs.append(draw_stars(stars, _size, save))

    if folks != None:
        imgs.append(draw_folks(folks, _size, save))

    if not imgs:
        return None

    size = [0,0]

    for img in imgs:
        size[0] += img.size[0]
        size[1] = img.size[1]

    size[0] += (len(imgs) - 1) * img_margin[_size]
    size = (size[0], size[1])

    result_img = Image.new('RGBA', size, None)
    result_img.paste(imgs[0], (0,0) + imgs[0].size)

    left = imgs[0].size[0] + img_margin[_size]
    for img in imgs[1:]:
        result_img.paste(img, (left, 0, left + img.size[0], img.size[1]))
        left += img_margin[_size] + img.size[0]

    if save:
        result_img.save('out.png')

    out = BytesIO()
    result_img.save(out, 'PNG')

    out.seek(0)
    return out

def to_text(stars):
    stars = str(stars)
    result = []
    while stars:
        result.append(stars[-3:])
        stars = stars[:-3]

    result.reverse()
    return ','.join(result) + ' '

if __name__ == '__main__':
    draw_image(434545,2325,34325,save=True)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import datetime as dt
import numpy as np
import matplotlib.pyplot as mp
import matplotlib.dates as md

def dmy2ymd(dmy):
    dmy = str(dmy, encoding='utf-8')
    date = dt.datetime.strptime(dmy, '%d-%m-%Y').date()
    ymd = date.strftime('%Y-%m-%d')
    return ymd
dates, opening_prices, highest_prices, \
    lowest_prices, closing_prices = np.loadtxt(
        '../../data/aapl.csv', delimiter=',',
        usecols=(1, 3, 4, 5, 6), unpack=True,
        dtype='M8[D], f8, f8, f8, f8',
        converters={1: dmy2ymd})
trend_points = (highest_prices + lowest_prices +
                closing_prices) / 3
spreads = highest_prices - lowest_prices
resistance_points = trend_points + spreads
support_points = trend_points - spreads
days = dates.astype(int)
a = np.column_stack((days, np.ones_like(days)))
x = np.linalg.lstsq(a, trend_points)[0]
trend_line = days * x[0] + x[1]
x = np.linalg.lstsq(a, resistance_points)[0]
resistance_line = days * x[0] + x[1]
x = np.linalg.lstsq(a, support_points)[0]
support_line = days * x[0] + x[1]
mp.figure('Trend', facecolor='lightgray')
mp.title('Trend', fontsize=20)
mp.xlabel('Date', fontsize=14)
mp.ylabel('Price', fontsize=14)
ax = mp.gca()
ax.xaxis.set_major_locator(
    md.WeekdayLocator(byweekday=md.MO))
ax.xaxis.set_minor_locator(
    md.DayLocator())
ax.xaxis.set_major_formatter(
    md.DateFormatter('%d %b %Y'))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
dates = dates.astype(md.datetime.datetime)
rise = closing_prices - opening_prices >= 0.01
fall = opening_prices - closing_prices >= 0.01
fc = np.zeros(dates.size, dtype='3f4')
ec = np.zeros(dates.size, dtype='3f4')
fc[rise], fc[fall] = (1, 1, 1), (0.85, 0.85, 0.85)
ec[rise], ec[fall] = (0.85, 0.85, 0.85), (0.85, 0.85, 0.85)
mp.bar(dates, highest_prices - lowest_prices, 0,
       lowest_prices, color=fc, edgecolor=ec)
mp.bar(dates, closing_prices - opening_prices, 0.8,
       opening_prices, color=fc, edgecolor=ec)
mp.scatter(dates, trend_points, c='dodgerblue',
           alpha=0.5, s=60, zorder=2)
mp.scatter(dates, resistance_points, c='orangered',
           alpha=0.5, s=60, zorder=2)
mp.scatter(dates, support_points, c='limegreen',
           alpha=0.5, s=60, zorder=2)
mp.plot(dates, trend_line, c='dodgerblue',
        linewidth=3, label='Trend')
mp.plot(dates, resistance_line, c='orangered',
        linewidth=3, label='Resistance')
mp.plot(dates, support_line, c='limegreen',
        linewidth=3, label='Support')
mp.legend()
mp.gcf().autofmt_xdate()
mp.show()


# https://www.lintcode.com/problem/143/description
# Given an array of n objects with k different colors (numbered from 1 to k),
# sort them so that objects of the same color are adjacent, with the colors in the order 1, 2, ... k.

# Example1
# Input:
# [3,2,2,1,4]
# 4
# Output:
# [1,2,2,3,4]

# Example2
# Input:
# [2,1,1,2,2]
# 2
# Output:
# [1,1,2,2,2]

# Challenge
# You can directly use The counting sorting algorithm scan twice, but it will cost O(k) extra memory.
# Now can you do it in use O(logk) extra memory?
from typing import List

class SortColorsII:

    # brute force: counting sort

    def sort_colors2(self, colors: List[int], k: int):
        if not colors:
            return
        if len(colors) < 2:
            return

        self.sort(colors, 0, len(colors) - 1, 1, k)

    def sort(self, colors, start, end, colorFrom, colorTo) -> None:
        if start >= end or colorFrom == colorTo:
            return

        left = start
        right = end
        colorMid = (colorFrom + colorTo) / 2

        while left <= right:
            while left <= right and colors[left] <= colorMid:
                left += 1

            while left <= right and colors[right] > colorMid:
                right -= 1

            if left <= right:
                leftCopy = colors[left]
                colors[left] = colors[right]
                colors[right] = leftCopy

        self.sort(colors, start, right, colorFrom, colorMid)
        self.sort(colors, left, end, colorMid + 1, colorTo)


import json
import requests
from datetime import date
from spotify_tokens import spotify_token, spotify_user_id
from refresh import Refresh

class MonthlyFavorites:
    def __init__(self):
        self.user_id = spotify_user_id
        self.spotify_token = spotify_token
        self.tracks = ""

    def find_songs(self):
        print ("Finding songs in saved tracks...")

        spotify_type = "tracks"
        time_range = "short_term"

        tracks_endpoint = f"https://api.spotify.com/v1/me/top/{spotify_type}?time_range={time_range}"

        response = requests.get(tracks_endpoint,
                                headers = {"Content-Type" : "application/json",
                                "Authorization": "Bearer {}".format(self.spotify_token)})

        response_json = response.json()

        # Loops through playlists tracks and add them to a list
        for i in response_json["items"]:
            # get the tracks and join them with commas
            self.tracks += (i["uri"] + ",")
        self.tracks = self.tracks[:-1]
        self.add_songs()

    def create_playlist(self):
        print ("Creating a playlist...")

        playlist_endpoint = f"https://api.spotify.com/v1/users/{spotify_user_id}/playlists"

        actual_month = date.today().strftime("%m")
        months_names = {"01" : "January", "02" : "February", "03" : "March", "04" : "April", "05" : "May",
                        "06" : "June", "07" : "July", "08" : "August", "09": "September", "10" : "October", "11" : "November", "12": "December"}

        request_body = json.dumps({"name": months_names[actual_month] + " Favorite Songs",
                                    "description": "Monthly generated playlist of my favorite songs",
                                    "public": True})

        response = requests.post(playlist_endpoint,
                                data = request_body,
                                headers = {"Content-Type" : "application/json",
                                "Authorization": "Bearer {}".format(self.spotify_token)})

        response_json = response.json()

        return response_json["id"]

    def add_songs(self):
        print ("Adding Songs...")

        self.playlist_id = self.create_playlist()

        tracks_endpoint = f"https://api.spotify.com/v1/playlists/{self.playlist_id}/tracks?uris={self.tracks}"

        response = requests.post(tracks_endpoint,
                                headers = {"Content-Type" : "application/json",
                                "Authorization": "Bearer {}".format(self.spotify_token)})

    def start(self):
        # We have to refresh the token in order to send a new query
        refreshCaller = Refresh()

        self.spotify_token = refreshCaller.refresh()

        self.find_songs()

a = MonthlyFavorites()
a.start()


import streamlit as st
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import f1_score
from sklearn.metrics import recall_score
from sklearn.metrics import precision_score
import numpy as np
from sklearn.model_selection import cross_val_score

def load_data():
    data = pd.read_csv('train.csv')
    return data

data = load_data()

duplicated = data[data.duplicated(keep=False)]
duplicated = duplicated.sort_values(by=['gender', 'height', 'weight'], ascending= False)
duplicated.head()
data.drop_duplicates(keep = 'first', inplace = True)
st.write('Total {} datapoints remaining with {} features'.format(data.shape[0], data.shape[1]))

X = data.drop(['cardio', 'id'], axis=1,)
data.drop('id', axis=1, inplace = True)
y = data['cardio']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=65)

# Обучение модели случайного леса
best_model = None
best_accuracy = 0

for est in range(1,15):
    model = RandomForestClassifier(
        random_state=42,
        n_estimators=est,
        max_depth=5,
        #min_samples_split=8,
        #min_samples_leaf=3,
        #max_features='auto'
    )
    cv_scores = cross_val_score(model, X_test, y_test, cv=5, scoring='accuracy')
    model.fit(X_train, y_train)
    result = model.score(X_test, y_test)

    if result > best_accuracy:
        best_model = model
        best_accuracy = result
st.write('Точность модели на тестовых данных:', best_accuracy)
st.write("Средняя точность:", cv_scores.mean())

test_score = best_model.score(X_test, y_test)
st.write('accuracy on test:', test_score)

y_pred = model.predict(X_test)

def calc_metrics(prefix, model, X_test, y_test, y_pred):

    accuracy = accuracy_score(y_test, y_pred)
    precision = precision_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    f1 = f1_score(y_test, y_pred)

    st.write('Accuracy:', accuracy)
    st.write('Precision:', precision)
    st.write('Recall:', recall)
    st.write('F1-Score:', f1)

calc_metrics('RF', model, X_test, y_test, y_pred)

st.title('Предсказание сердечно-сосудистых заболеваний')

st.sidebar.header('Введите данные пациента:')
# Ввод данных
age = st.sidebar.number_input('Возраст', min_value=1, max_value=100)
gender = st.sidebar.radio('Пол', ('Мужчина', 'Женщина'))
height = st.sidebar.number_input('Рост (в см)', min_value=50, max_value=250)
weight = st.sidebar.number_input('Вес (в кг)', min_value=10, max_value=500)
cholesterol = st.sidebar.selectbox('Холестерин', ('Низкий','Нормальный', 'Высокий'))
smoke = bool(st.sidebar.checkbox('Курит ли пациент?'))
alco = bool(st.sidebar.checkbox('Пьет ли пациент?'))
gluc = st.sidebar.selectbox('Уровень глюкозы', ('Низкий','Нормальный', 'Высокий'))
ap_hi = st.sidebar.number_input('Верхнее давление (ap_hi)', min_value=1)
ap_lo = st.sidebar.number_input('Нижнее давление (ap_lo)', min_value=1)
active = st.sidebar.radio('Активность', ('Активный', 'Не активный'))

# Преобразование входных данных в числовые значения
gender_mapping = {'Мужчина': 1, 'Женщина': 2}
cholesterol_mapping = {'Низкий': 1,'Нормальный': 2, 'Высокий': 3}
gluc_mapping = {'Низкий': 1,'Нормальный': 2, 'Высокий': 3}
active_mapping = {'Активный': 1, 'Не активный': 0}
smoke_mapping = {'Не курит': 0, 'Курит': 1}
alco_mapping = {'Не пьет': 0, 'Пьет': 1}

gender = gender_mapping[gender]
cholesterol = cholesterol_mapping[cholesterol]
gluc = gluc_mapping[gluc]
active = active_mapping[active]
smoke = int(smoke)
alco = int(alco)

# Создание массива с введенными данными
user_data = [age, gender, height, weight, cholesterol, smoke, alco, gluc, ap_hi, ap_lo, active]

# Предсказание
if st.sidebar.button('Предсказать'):
    st.write('user_data:', user_data)
    prediction = model.predict([user_data])
    st.write(prediction)
    if prediction[0] == 1:
        st.error('Пациент имеет риск сердечно-сосудистого заболевания.')
    else:
        st.success('Пациент не имеет риска сердечно-сосудистого заболевания.')
st.subheader('Данные из CSV:')
st.write('Список признаков в данных из CSV:', data.columns.tolist())

st.write(data)