import googlemaps
import json
import random
from django.conf import settings
from datetime import date as todaysDate
from django.utils.timezone import make_aware
from django.db import models
from usuarios.models import MyUser, Cliente, Transportista, Unidades
from django.urls import reverse
from django.utils import timezone
from django.dispatch import receiver
from django.utils.text import slugify
from django.db.models.signals import post_save, post_delete
from django.core.exceptions import ValidationError

ESTADOS = (
    ('Aguascalientes','Aguascalientes'),
    ('Baja California','Baja California'),
    ('Baja California Sur','Baja California Sur'),
    ('Campeche','Campeche'),
    ('Coahuila de Zaragoza','Coahuila de Zaragoza'),
    ('Colima','Colima'),
    ('Chiapas','Chiapas'),
    ('Chihuahua','Chihuahua'),
    ('CDMX','CDMX'),
    ('Durango','Durango'),
    ('Guanajuato','Guanajuato'),
    ('Guerrero','Guerrero'),
    ('Hidalgo','Hidalgo'),
    ('Jalisco','Jalisco'),
    ('México','México'),
    ('Michoacán de Ocampo','Michoacán de Ocampo'),
    ('Morelos','Morelos'),
    ('Nayarit','Nayarit'),
    ('Nuevo León','Nuevo León'),
    ('Oaxaca','Oaxaca'),
    ('Puebla','Puebla'),
    ('Querétaro','Querétaro'),
    ('Quintana Roo','Quintana Roo'),
    ('San Luis Potosí','San Luis Potosí'),
    ('Sinaloa','Sinaloa'),
    ('Sonora','Sonora'),
    ('Tabasco','Tabasco'),
    ('Tamaulipas','Tamaulipas'),
    ('Tlaxcala','Tlaxcala'),
    ('Veracruz de Ignacio de la Llave','Veracruz de Ignacio de la Llave'),
    ('Yucatán','Yucatán'),
    ('Zacatecas','Zacatecas'),
)

def validate_name_domicilio(name):
    if Domicilios.objects.filter(nombre=name).exists():
        raise ValidationError("No se puede agregar un domiclio con el mismo nombre {name}")

class Domicilios(models.Model):
    cliente_id = models.ForeignKey(Cliente, on_delete=models.CASCADE)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()
    nombre = models.CharField(verbose_name="Nombre para identificar domicilio", max_length=200)
    calle = models.CharField(verbose_name="Calle", max_length=200)
    num_ext = models.CharField(verbose_name="Numero exterior", max_length=200)
    num_int = models.CharField(verbose_name="Numero interior", max_length=200, blank=True)
    colonia = models.CharField(verbose_name="Colonia", max_length=200)
    municipio = models.CharField(verbose_name="Municipio o alcadía", max_length=200)
    cp = models.CharField(verbose_name="Código postal",max_length=200,)
    estado = models.CharField(verbose_name="Estado", choices=ESTADOS, max_length=100)
    referencias = models.TextField(verbose_name="Refrencias del domicilio")
    longitud = models.FloatField(verbose_name="Longitud", blank=True)
    latitud = models.FloatField(verbose_name="Latitud", blank=True)
    is_valid = models.BooleanField(verbose_name="Es válido", default=False)
    google_format = models.CharField(verbose_name="Dirección completa", max_length=200, blank=True)
    google_place_id = models.CharField(verbose_name="Google place ID", max_length=250, blank=True)
    slug = models.SlugField(null=True, blank=True, max_length=250)

    class Meta:
        verbose_name_plural = "Domicilios"

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.creado = timezone.now()
            gmaps = googlemaps.Client(key=settings.GOOGLE_API_KEY)
            direction = f'{self.calle} {self.num_ext} {self.colonia} {self.estado}'
            geocode_result = gmaps.geocode(direction)
            direccion_google = geocode_result[0]["formatted_address"]
            if len(geocode_result) == 0 or len(direccion_google) < 50:
                self.is_valid = False
                self.google_format = "Invalid"
                self.latitud = 0
                self.longitud = 0
                self.google_place_id = "not valid"
                self.google_format = "not valid"
            else:
                self.latitud = geocode_result[0]["geometry"]["location"]["lat"]
                self.longitud = geocode_result[0]["geometry"]["location"]["lng"]
                self.google_place_id = geocode_result[0]["place_id"]
                self.google_format = direccion_google
                self.is_valid = True
        self.modificado = timezone.now()
        if self.slug is None:
            self.slug = slugify(f"{self.nombre}-{self.cliente_id}")
        return super(Domicilios, self).save(*args, **kwargs)

    def __str__(self):
        return f'{self.nombre}'

    @property
    def direccion_completa(self):
        return f'{self.calle } {self.num_ext} {self.num_int}, C.P  {self.cp}  {self.colonia}  {self.municipio},  {self.estado}'

    @property
    def get_domiclios_user(self, user):
        pass

ESTADO_SOLICITUD = (
    ('Guardada','Guardada'),
    ('Publicada','Publicada'),
    ('Cotizada','Cotizada'),
    ('Asignada','Asignada'),
    ('Pagada','Pagada'),
    ('Cancelada','Cancelada'),
    ('Vencida','Vencida'),
)

def validate_date(date):
    if date.date() <= timezone.now().date():
        raise ValidationError("La fecha tiene que ser mayor a hoy")

class Solicitud(models.Model):
    cliente_id = models.ForeignKey(Cliente, on_delete=models.CASCADE)
    folio = models.CharField(verbose_name="Folio", max_length=100, editable=False, unique = True)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()
    descripcion_servicio = models.TextField(verbose_name="Descripción de servicio")
    caracteristicas_carga = models.TextField(verbose_name="Tipo de carga")
    peso_carga = models.FloatField(verbose_name="Peso de la carga(kg)")
    volumen_carga = models.FloatField(verbose_name="Volumen de la carga(mts3)")
    unidades_totales = models.IntegerField(verbose_name="Unidades totales de la carga")
    fecha_servicio = models.DateTimeField(verbose_name="Fecha de servicio", validators=[validate_date])
    hora = models.TimeField(verbose_name="Hora de servicio")
    tiempo_carga = models.IntegerField(verbose_name="Tiempo máximo para la carga(min)")
    domicilio_id = models.ForeignKey(Domicilios, on_delete=models.PROTECT, verbose_name="Origen")
    estado_solicitud = models.CharField(verbose_name="Estado de la solicitud", choices=ESTADO_SOLICITUD, max_length=40, default="Guardada")
    tiempo_total = models.FloatField(verbose_name="Tiempo total del viaje", null=True, blank=True)
    km_total = models.FloatField(verbose_name="Km totales del viaje", null=True, blank=True)
    slug = models.SlugField(null=True, blank=True)
    material_peligroso = models.BooleanField(
        verbose_name="Es material peligroso",
        default=False,)
    estado_origen = models.CharField(verbose_name="Estado", choices=ESTADOS, max_length=40,  null=True, blank=True)
    motivo_cancelacion = models.TextField(verbose_name="Motivo de cancelación",  null=True, blank=True)
    activo = models.BooleanField(
        verbose_name="Activo",
        default=True,)

    class Meta:
        verbose_name_plural = "Solicitudes"

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.creado = timezone.now()
        self.modificado = timezone.now()
        if not self.estado_origen:
            self.estado_origen = self.domicilio_id.estado
        return super(Solicitud, self).save(*args, **kwargs)

    def has_destinos(self):
        destinos =  Destino.objects.filter(solicitud_id=self.pk)
        if destinos:
            destinos = list(destinos)
            return "Ruta" if len(destinos) > 1 else "Sencillo"
        else:
            return "Sencillo"

    def __str__(self):
        return f'{self.folio}'

    def get_absolute_url(self):
        return reverse('detail-solicitud', kwargs={'pk':self.pk})

    def get_domiciliosid_destinos(self):
        destinos = Destino.objects.filter(solicitud_id=self.id)
        lista =[]

        for destino in destinos:
                lista.append(destino.domicilio_id.id)

        return lista

    def has_cotizaciones(self):
        cotizaciones =  Cotizacion.objects.filter(solicitud_id=self.pk)
        return True if cotizaciones else False

    def has_cotizacion_aceptada(self):
        cotizaciones =  Cotizacion.objects.filter(solicitud_id=self.pk)
        if cotizaciones:
            flag = False
            for cotizacion in cotizaciones:
                if cotizacion.estado_cotizacion == 'Aceptada':
                    return True
            return flag
        else:
            return False

    def cotizacionFinal(self):
        cotizacion = Cotizacion.objects.filter(solicitud_id=self.id).filter(estado_cotizacion='Confirmada') | Cotizacion.objects.filter(solicitud_id=self.id).filter(estado_cotizacion='Pagada') | Cotizacion.objects.filter(solicitud_id=self.id).filter(estado_cotizacion='Pendiente de pago') | Cotizacion.objects.filter(solicitud_id=self.id).filter(estado_cotizacion='Aceptada')
        return cotizacion[0] if cotizacion else False

    def cotizaciones(self):
        return Cotizacion.objects.filter(solicitud_id=self.id)

class Destino(models.Model):
    solicitud_id = models.ForeignKey(Solicitud, on_delete=models.CASCADE)
    domicilio_id = models.ForeignKey(Domicilios, on_delete=models.PROTECT)
    tiempo_descarga = models.IntegerField(verbose_name="Tiempo máximo para la descarga(min)")
    unidades_entregar = models.IntegerField(verbose_name="Unidades a entregar en este destino")
    foto1 = models.ImageField(verbose_name="Foto 1 evidencia de entrega", upload_to='unidades_pics', null=True, blank=True)
    foto2 = models.ImageField(verbose_name="Foto 2 evidencia de entrega", upload_to='unidades_pics', null=True, blank=True)
    foto3 = models.ImageField(verbose_name="Foto 3 evidencia de entrega", upload_to='unidades_pics', null=True, blank=True)
    foto4 = models.ImageField(verbose_name="Foto 4 evidencia de entrega", upload_to='unidades_pics', null=True, blank=True)
    foto5 = models.ImageField(verbose_name="Foto 5 evidencia de entrega", upload_to='unidades_pics', null=True, blank=True)
    #registro de llegada
    #registo de hora de llegada

    class Meta:
        verbose_name_plural = "Destinos"

    def __str__(self):
        return f'Destino {self.domicilio_id} de {self.solicitud_id}'

    def hasEvidencias(self):
        return True if self.foto1 else False

NIVEL_SEGURO = (
    ('Sin seguro', 'Sin seguro'),
    ('Nivel 1','Nivel 1'),
    ('Nivel 2','Nivel 2'),
    ('Nivel 3','Nivel 3'),
)

class Seguro(models.Model):
    nombre = models.CharField(verbose_name="Seguro", max_length=40, default="")
    costo = models.FloatField(verbose_name="Costo del seguro")
    cobertura = models.FloatField(verbose_name="Cobertura del seguro")

    class Meta:
        verbose_name_plural = "Seguros"

    def __str__(self):
        return f'{self.nombre}'

DEDUCCIONES_NOMBRES = (
    ('iva','iva'),
    ('comision_viaje','comision_viaje'),
)

class Deduccion(models.Model):
    #check optiosn of default
    nombre = models.CharField(verbose_name="Nombre de deducción", choices=DEDUCCIONES_NOMBRES, max_length=40, default="", unique=True)
    porcentaje = models.FloatField (verbose_name="%", help_text = "Ejemplo 0.16, agregar 0 al incio")
    descripcion = models.CharField(verbose_name="Descripcion de la deduccion", max_length=40, default="", blank=True)

    class Meta:
        verbose_name = "Deducciones"
        verbose_name_plural = "Deducciones"

    def __str__(self):
        return f'{self.nombre}'

#Cambiar Rechazada a No exitosa
ESTADO_COTIZACION = (
    ('Pendiente','Pendiente'),
    ('Aceptada','Aceptada'),
    ('Rechazada','Rechazada'),
    ('Confirmada','Confirmada'),
    ('Cancelada','Cancelada'),
    ('Solicitud cancelada','Solicitud cancelada'),
    ('Pagada','Pagada'),
    ('Pendiente de pago','Pendiente de pago')
)

class Cotizacion(models.Model):
    transportista_id = models.ForeignKey(
        Transportista,
        verbose_name="Transportista",
        on_delete=models.CASCADE)
    solicitud_id = models.ForeignKey(
        Solicitud,
        verbose_name="Solicitud",
        on_delete=models.CASCADE)
    unidad_id = models.ForeignKey(
        Unidades,
        verbose_name="Unidad",
        on_delete=models.CASCADE)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()
    monto = models.FloatField(
        verbose_name="Monto")
    folio = models.CharField(verbose_name="Folio", max_length=100, editable=True, unique = True)
    estado_cotizacion = models.CharField(verbose_name="Estado", choices=ESTADO_COTIZACION, max_length=40, default="Pendiente")
    motivo_cancelacion = models.TextField(verbose_name="Motivo de cancelación", null=True, blank=True)
    fecha_servicio = models.DateTimeField(verbose_name="Fecha de servicio de solictud",null=True, blank=True)
    correo_recordatorio = models.IntegerField(verbose_name="Corrreos enviados para recordatorio de confirmación", default=0)
    total = models.FloatField(
        verbose_name="Total", null=True, blank=True)
    iva = models.FloatField(verbose_name="IVA", default=0)
    comision = models.FloatField(verbose_name="Comision de viaje", default=0)
    slug = models.SlugField(null=True, blank=True)
    nivel_seguro = models.ForeignKey(
        Seguro,
        verbose_name="Nivel de Seguro",
        on_delete=models.CASCADE,
        null=True,
        blank=True)
    es_asegurada = models.BooleanField(
        verbose_name="Viaje asegurado",
        default=False,)
    aceptar_tyc = models.BooleanField(
        verbose_name="Aceptación de términos y condiciones de seguro",
        default=False,)
    activo = models.BooleanField(
        verbose_name="Activo",
        default=True,)

    class Meta:
        verbose_name = "Cotizaciones"
        verbose_name_plural = "Cotizaciones"

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        iva = Deduccion.objects.filter(nombre='iva').values()[0]['porcentaje']
        if self.iva == 0:
            self.iva = iva
        if self.comision == 0:
            self.comision = Deduccion.objects.filter(nombre='comision_viaje').values()[0]['porcentaje']
        if not self.id:
            self.creado = timezone.now()

        self.total = 0
        if self.es_asegurada:
            subtotal = self.monto + self.nivel_seguro.costo
        else:
            subtotal = self.monto
        #print(iva[0]['porcentaje'])
        self.total = int(subtotal + subtotal * iva)

        if self.fecha_servicio == None or self.fecha_servicio == "":
            self.fecha_servicio = self.solicitud_id.fecha_servicio

        self.modificado = timezone.now()

        return super(Cotizacion, self).save(*args, **kwargs)

    def __str__(self):
        return f'{self.folio}'

    @property
    def getClienteId(self):
        return self.solicitud_id.cliente_id

    @property
    def getSubtotal(self):
        return self.monto + self.nivel_seguro.costo if self.es_asegurada else self.monto

    @property
    def getIva(self):
        return self.getSubtotal * self.iva

    @property
    def getSubTotalComision(self):
        return self.monto * self.comision

    @property
    def getIvaComision(self):
        return self.getSubTotalComision * self.iva

    @property
    def getTotalComision(self):
        return self.getSubTotalComision + self.getIvaComision

ESTADO_ORDEN = (
    ('paid','paid'),
    ('Pendiente','Pendiente'),
)

class Orden(models.Model):
    cotizacion_id = models.OneToOneField(Cotizacion, on_delete=models.CASCADE)
    link_id = models.CharField(max_length = 500, null=True, blank=True)
    link_url = models.URLField(max_length = 500, null=True, blank=True)
    link_status = models.CharField(max_length = 200, null=True, blank=True)
    orden_id = models.CharField(max_length = 200, null=True, blank=True)
    orden_status = models.CharField(max_length = 200, null=True, blank=True)
    correo_recordatorio = models.IntegerField(verbose_name="Corrreos enviados para recordatorio de pago", default=0)

    class Meta:
        verbose_name = "Ordenes"
        verbose_name_plural = "Ordenes"

    def __str__(self):
        return f'Orden de cotización {self.cotizacion_id}'

    def has_orden(self):
        return True if self.orden_id else False

ESTADO_VIAJE = (
    ('Creado','Creado'),
    ('Iniciado','Iniciado'),
    ('Terminado','Terminado'),
    ('Pendiente de pago','Pendiente de pago'),
    ('Pendiente de validación','Pendiente de validación'),
    ('Cerrado','Cerrado'),
    ('Vencido','Vencido'),
    ('Disputa','Disputa'),
    ('Accidente','Accidente'),
    ('Cancelado por cliente','Cancelado por cliente'),
    ('Cancelado por transportista','Cancelado por transportista'),
)

class Viaje(models.Model):
    orden_id = models.OneToOneField(Orden, on_delete=models.CASCADE)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()
    folio = models.CharField(verbose_name="Folio", max_length=100, editable=True, unique = True)
    slug = models.SlugField(null=True, blank=True)
    estado_viaje = models.CharField(verbose_name="Estado", choices=ESTADO_VIAJE, max_length=40, default="Creado")
    hora_inicio = models.TimeField(verbose_name="Hora de inicio", null=True, blank=True)
    hora_llegada = models.TimeField(verbose_name="Hora de llegada", null=True, blank=True)
    nip_checkin = models.IntegerField(verbose_name="NIP de seguridad checkin", null=True, blank=True)
    nip_checkout = models.IntegerField(verbose_name="NIP de seguridad checkout", null=True, blank=True)
    comentarios = models.TextField(null=True, blank=True)
    fecha_servicio = models.DateTimeField(verbose_name="Fecha de servicio de solictud",null=True, blank=True)
    factura_pdf = models.FileField(upload_to='uploads/%Y/%m/%d/', verbose_name="Factura pdf", null=True, blank=True)
    factura_xml = models.FileField(upload_to='uploads/%Y/%m/%d/', verbose_name="Factura xml", null=True, blank=True)
    es_validado = models.BooleanField(verbose_name="Validado por administrador", default=False)
    motivo_cancelacion = models.TextField(verbose_name="Motivo de cancelación",  null=True, blank=True)
    activo = models.BooleanField(
        verbose_name="Activo",
        default=True,)
    is_calificado = models.BooleanField(
        verbose_name="Calificado",
        default=False,)
    #facturado_cliente = models.BooleanField(verbose_name="Es válido", default=False)
    #facturado_transportista = models.BooleanField(verbose_name="Es válido", default=False)

    class Meta:
        verbose_name_plural = "Viajes"

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.creado:
            self.creado = timezone.now()
        self.modificado = timezone.now()
        if self.nip_checkin is None:
            number = f'{random.randint(1,9)}{random.randint(0,9)}{random.randint(0,9)}{random.randint(0,9)}'
            self.nip_checkin = int(number)
        if self.nip_checkout is None:
            number = f'{random.randint(1,9)}{random.randint(0,9)}{random.randint(0,9)}{random.randint(0,9)}'
            self.nip_checkout = int(number)
        if self.folio is None or self.folio == "":
            self.folio = f'FS{self.orden_id.cotizacion_id.getClienteId}A{self.orden_id.cotizacion_id.id}'
        if self.slug is None:
            self.slug = f'FS{self.orden_id.cotizacion_id.getClienteId}A{self.orden_id.cotizacion_id.id}'
        if self.fecha_servicio == None or self.fecha_servicio == "":
            self.fecha_servicio = self.orden_id.cotizacion_id.solicitud_id.fecha_servicio
        return super(Viaje, self).save(*args, **kwargs)

    def __str__(self):
        return f'{self.folio}'

    @property
    def getClienteId(self):
        return self.orden_id.cotizacion_id.getClienteId

    @property
    def hasLlegada(self):
        return True if self.hora_llegada else False

    @property
    def hasInicio(self):
        return True if self.hora_inicio else False

    @property
    def getTransportista(self):
        return self.orden_id.cotizacion_id.transportista_id

    @property
    def solicitud(self):
        return self.orden_id.cotizacion_id.solicitud_id

    @property
    def cotizacion(self):
        return self.orden_id.cotizacion_id

    @property
    def hasCalificacion(self):
        return True if self.calificacionesviajes else False

    @property
    def hasFacturaCliente(self):
        try:
            return True if self.facturascliente else False
        except:
            return False

    @property
    def hasFacturaTransportista(self):
        try:
            return True if self.facturastransportista else False
        except:
            return False

STARS = (
    (1,'1'),
    (2,'2'),
    (3,'3'),
    (4,'4'),
    (5,'5'),
)

class CalificacionesViajes(models.Model):
    viaje_id = models.OneToOneField(Viaje, on_delete=models.CASCADE)
    #foreign key transportista
    transportista_id = models.ForeignKey(
        Transportista,
        verbose_name="Transportista",
        on_delete=models.CASCADE)
    calificacionTransportista =  models.IntegerField(choices=STARS, default=5)
    comentarios = models.TextField(verbose_name="Comentarios", null=False, default="")
    slug = models.SlugField(null=True, blank=True)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.creado = timezone.now()
        self.modificado = timezone.now()
        if self.slug is None:
            self.slug = f'FS{self.viaje_id}-{self.transportista_id}'
        return super(CalificacionesViajes, self).save(*args, **kwargs)

    def __str__(self):
        return f'{self.slug}'

class FacturasCliente(models.Model):
    viaje_id = models.OneToOneField(Viaje, on_delete=models.CASCADE)
    cliente_id = models.ForeignKey(Cliente, on_delete=models.CASCADE)
    folio = models.CharField(verbose_name="Folio", max_length=100, editable=True, unique = True)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()
    slug = models.SlugField(null=True, blank=True)

    def __str__(self):
        return f'{self.folio}'

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.creado = timezone.now()
        self.modificado = timezone.now()
        if self.slug is None:
            self.slug = f'FACL{self.viaje_id}'
        return super(FacturasCliente, self).save(*args, **kwargs)

class FacturasTransportista(models.Model):
    viaje_id = models.OneToOneField(Viaje, on_delete=models.CASCADE)
    transportista_id = models.ForeignKey(Transportista, on_delete=models.CASCADE)
    folio = models.CharField(verbose_name="Folio", max_length=100, editable=True, unique = True)
    creado = models.DateTimeField(editable=False)
    modificado = models.DateTimeField()
    slug = models.SlugField(null=True, blank=True)

    def __str__(self):
        return f'{self.folio}'

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.creado = timezone.now()
        self.modificado = timezone.now()
        if self.slug is None:
            self.slug = f'FATR{self.viaje_id}'
        return super(FacturasTransportista, self).save(*args, **kwargs)

#SIGNALS
#CREATE FOLIO AND SLUG OF SOLICITUD
@receiver(post_save, sender=Solicitud)
def createFolioSolicitud(sender,instance,**kwargs):
    folio = instance.id
    if instance.folio is None or instance.folio == "":
        Solicitud.objects.filter(
                id=folio
            ).update(
                folio=f'SCO{instance.cliente_id.user.username}A{folio}',
        )
    if instance.slug is None:
        Solicitud.objects.filter(
                id=folio
            ).update(
                slug=slugify(f"SCO{instance.cliente_id.user.username}A{folio}")
    )
#post_save.connect(createFolioSolicitud, sender=Solicitud)

#CREATE FOLIO AND SLUG OF COTIZACION
@receiver(post_save, sender=Cotizacion)
def createFolioCotizacion(sender,instance,**kwargs):
    folio = instance.id
    if instance.folio is None or instance.folio == "":
        Cotizacion.objects.filter(
                id=folio
            ).update(
                folio=f'CO{instance.transportista_id.user.username}A{folio}',
        )
    if instance.slug is None:
        Cotizacion.objects.filter(
                id=folio
            ).update(
                slug=slugify(f"{instance.transportista_id.user.username}A{folio}")
    )

#CREATE FOLIO AND SLUG OF FACTURACIONES CLIENTE
@receiver(post_save, sender=FacturasCliente)
def createFolioFacturacion(sender,instance,**kwargs):
    folio = instance.id
    if instance.folio is None or instance.folio == "":
        FacturasCliente.objects.filter(
                id=folio
            ).update(
                folio=f'FACL{instance.cliente_id.user.username}A{folio}',
        )
    if instance.slug is None:
        FacturasCliente.objects.filter(
                id=folio
            ).update(
                slug=slugify(f"FACL{instance.cliente_id.user.username}A{folio}")
    )

#CREATE FOLIO AND SLUG OF FACTURACIONES TRANSPORTISTA
@receiver(post_save, sender=FacturasTransportista)
def createFolioFacturacion(sender,instance,**kwargs):
    folio = instance.id
    if instance.folio is None or instance.folio == "":
        FacturasTransportista.objects.filter(
                id=folio
            ).update(
                folio=f'FATR{instance.transportista_id.user.username}A{folio}',
        )
    if instance.slug is None:
        FacturasTransportista.objects.filter(
                id=folio
            ).update(
                slug=slugify(f"FATR{instance.transportista_id.user.username}A{folio}")
    )

#CREATE FacturaCliente if viaje don´t have it
@receiver(post_save, sender=Viaje)
def createFacturacionCliente(sender,instance,**kwargs):
    if not instance.hasFacturaCliente and not instance.hasFacturaTransportista and instance.estado_viaje == 'Pendiente de pago':
        facturaC = FacturasCliente.objects.create(viaje_id=instance,cliente_id=instance.getClienteId)
        facturaT = FacturasTransportista.objects.create(viaje_id=instance,transportista_id=instance.getTransportista)

@receiver(post_save, sender=Cotizacion)
def create_ruta(sender, instance, **kwargs):
    solicitud = instance.solicitud_id
    if solicitud.estado_solicitud != 'Asignada':
        solicitud.estado_solicitud = "Cotizada"
        solicitud.save()

@receiver(post_delete, sender=Cotizacion)
def validarEsatdoCotizacion(sender,instance,**kwargs):
    solicitud = instance.solicitud_id
    if not solicitud.has_cotizaciones():
        solicitud.estado_solicitud = "Publicada"
        solicitud.save()

@receiver(post_save, sender=Domicilios)
def addLonLat(sender, instance, **kwargs):
    gmaps = googlemaps.Client(key=settings.GOOGLE_API_KEY)
    direction = f'{instance.calle} {instance.num_ext} {instance.colonia} {instance.estado}'
    geocode_result = gmaps.geocode(direction)
    direccion_google = geocode_result[0]["formatted_address"]
    if len(geocode_result) == 0 or len(direccion_google) < 50:
        Domicilios.objects.filter(id=instance.id).update(
            is_valid = False,
            google_format = "Invalid"
        )
    else:
        Domicilios.objects.filter(id=instance.id).update(
            latitud = geocode_result[0]["geometry"]["location"]["lat"],
            longitud = geocode_result[0]["geometry"]["location"]["lng"],
            google_place_id = geocode_result[0]["place_id"],
            google_format = direccion_google,
            is_valid = True
        )

#CREATE VIAJE WHEN ORDEN IS 'Pagada'
@receiver(post_save, sender=Orden)
def crearViaje(sender, instance, **kwargs):
    orden = instance

    if orden.orden_status == 'Pagada':
        viaje = Viaje.objects.create(orden_id=orden)

#CREATE FACTURA CLIENTE WHEN VIAJE IS 'CERRADO'
# @receiver(post_save, sender=Viaje)
# def crearViaje(sender, instance, **kwargs):
#     viaje = instance

#     if orden.orden_status == 'Pagada':
#         viaje = Viaje.objects.create(orden_id=orden)


import argparse

rows = 128     ### sliced spectrogram height
cols = 1024    ### sliced spectrogram width
channels = 2

max_width = 10337 ### maximum raw spectrogram width
split_count = 10  ### number of slices per song

epochs = 100
batch_size = 32
spectrogram_features = ['h', 'p']   ### Percussive & harmonic component spectrogram

CLASSES = ['Cai Luong', 'Cach Mang', 'Dan Ca - Que Huong', 'Dance', 'Khong Loi',
               'Thieu Nhi', 'Trinh', 'Tru Tinh', 'Rap Viet', 'Rock Viet']
num_classes = len(CLASSES)

parser = argparse.ArgumentParser()
parser.add_argument("--train_csv", type=str, default="data/train_set.csv", help='path to train set csv')
parser.add_argument("--val_csv", type=str, default="data/val_set.csv", help='path to validation set csv')
parser.add_argument("--spectr_dir", type=str, default="data/spectr/train", help='path to train spectrogram images')

parser.add_argument("--model", type=str, default="resnet18",
                    choices=["resnet18", "resnet34", "CRNN", "simpleCNN"], help='model type')
parser.add_argument("--checkpoint", type=str, default='music_genre_cnnit .h5', help='path to checkpoint')

parser.add_argument('--evaluate', action='store_true', help='evaluate trained model with validation data')
parser.add_argument('--use_cache', action='store_true', help='use cached .npy data from disk')
parser.add_argument('--resume', action='store_true', help='resume training from latest checkpoint')
args = parser.parse_args()

model_name = args.checkpoint   ### Saved model name


import pytest
from loguru import logger
from pytest_mock import MockerFixture

from fastapi_cloud_logging.fastapi_cloud_logging_handler import FastAPILoggingHandler

@pytest.fixture
def logging_handler(mocker: MockerFixture) -> FastAPILoggingHandler:
    return FastAPILoggingHandler(
        mocker.Mock(), transport=mocker.Mock(), structured=True
    )

def test_with_logger_message(logging_handler: FastAPILoggingHandler):
    logger.add(logging_handler, format="{message}")
    logger.info("Hello")

    (_, message_payloads), args = logging_handler.transport.send.call_args
    assert args["labels"]["python_logger"] == "tests.test_loguru"
    assert args["source_location"] is not None
    assert message_payloads == {"message": "Hello"}

def divide(a, b):
    return a / b

def test_with_logger_exception(logging_handler: FastAPILoggingHandler):
    logger.add(logging_handler, format="{message}")
    try:
        divide(5, 0)
    except ZeroDivisionError:
        logger.exception("An error has occurred")

    (record, message_payloads), args = logging_handler.transport.send.call_args
    assert record.exc_info is None
    assert args["labels"]["python_logger"] == "tests.test_loguru"
    assert args["source_location"] is not None
    assert message_payloads["message"].startswith("An error has occurred\n")
    assert len(message_payloads["traceback"]) == 2


import os
import torch
import numpy as np
from torch.utils.data import Dataset, DataLoader, sampler
from PIL import Image
import random
from scipy import signal
import wave
import struct
import random

class wave_spec(Dataset):

	def __init__(self,root_dir,trans = None):
		self.root_dir = root_dir
		self.trans = trans
		classes = [fn for fn in os.listdir(self.root_dir) if os.path.isdir(self.root_dir + '/' + fn) ]
		class_index = {}
		j = 0
		for i in classes:
			class_index[i] = j
			j+=1
		self.sounds = []
		for i in classes:
			self.sounds = self.sounds + [(root_dir + '/' + i + '/' + fn,class_index[i]) for fn in os.listdir(root_dir + '/' + i + '/') if fn.endswith('.wav') ]

	def __getitem__(self,idx):

		wave_file = wave.open(self.sounds[idx][0],'rb')
		fs = wave_file.getframerate()
		N = wave_file.getnframes()
		stft_img = self.stft_img(wave_file,fs,N)
		img = Image.fromarray(stft_img.astype('uint8'),'L')

		if self.trans:
			img = self.trans(img)

		label = self.sounds[idx][1]
		sample = {'image': img , 'label': label, 'path': self.sounds[idx][0]}

		return sample

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

	def stft_img(self, wave_file,fs,N):
		wf = wave_file.readframes(N)
		wf = np.array(struct.unpack('h'*N, wf))
		_, _, Sxx = signal.spectrogram(wf, fs,return_onesided=True)
		return Sxx


import numpy as np
import findiff

def curl_2d (x,y,u,v):
  d_dy = findiff.FinDiff(0, y, acc=10)
  d_dx = findiff.FinDiff(1, x, acc=10)
  dv_dx = d_dx(v)
  du_dy = d_dy(u)
  curl_2d = dv_dx - du_dy
  # (nul, nul, D) = Derivative_Calc.cheb_derivative(velocity)
  # curl_2d = np.matmul(-v , D.transpose()) - np.matmul(D, u)
  return (curl_2d)


import torch
from torch import Tensor, nn

from dataclasses import dataclass, field
from typing import List, Tuple

from prediction.model import PredictionModel, PredictionModelConfig
from prediction.types import Trajectories
from prediction.utils.transform import transform_using_actor_frame_gauss
from prediction.utils.reshape import flatten, unflatten_batch

class ProbabilisticMLP(nn.Module):
    ## write the code for the new model here
    def __init__(self, config: PredictionModelConfig) -> None:
        super().__init__()
        self._encoder = nn.Sequential(
            nn.Flatten(),
            nn.Linear(30, 64),
            nn.ReLU(),
            nn.Linear(64, 128),
            nn.ReLU(),
        )

        self._decoder = nn.Sequential(
                nn.Flatten(),
                nn.Linear(128, 64),
                nn.ReLU(),
                nn.Linear(64, 50),
                nn.ReLU(),
            )

class ProbabilisticModel(PredictionModel):
    def __init__(self, config: PredictionModelConfig) -> None:
        super().__init__(config)
        self._encoder = ProbabilisticMLP(PredictionModelConfig)._encoder
        self._decoder = ProbabilisticMLP(PredictionModelConfig)._decoder

    @staticmethod
    def _postprocess(
        out: Tensor, batch_ids: Tensor, original_x_pose: Tensor
    ) -> List[Tensor]:
        """Postprocess predictions

        1. Unflatten time and position dimensions
        2. Transform predictions back into SDV frame
        3. Unflatten batch and actor dimension

        Args:
            out (Tensor): predicted input trajectories [batch_size * N x T * 2]
            batch_ids (Tensor): id of each actor's batch in the flattened list [batch_size * N]
            original_x_pose (Tensor): original position and yaw of each actor at the latest timestep in SDV frame
                [batch_size * N, 3]

        Returns:
            List[Tensor]: List of length batch_size of output predicted trajectories in SDV frame [N x T x 2]
        """
        num_actors = len(batch_ids)
        out = out.reshape(num_actors, -1, 5)  # [batch_size * N x T x 6]
        # Transform from actor frame, to make the prediction problem easier
        transformed_out = transform_using_actor_frame_gauss(
            out, original_x_pose, translate_to=False
        )

        # Translate so that latest timestep for each actor is the origin
        out_batches = unflatten_batch(transformed_out, batch_ids)
        return out_batches


"""Database debug and diagnostics functions."""

import json

from typing import Any, Generator, Dict
from . import db
from . import user as usermod
from . import request as requestmod

def sprint_users(*criterions) -> Generator[str, None, None]:
    """Yields a generator whose elements are strings representing a user in json format."""

    users = usermod.get_users(*criterions)
    if users is None:
        return

    for u in users:
        yield sprintv(u)

def print_users(*criterions) -> None:
    """Like sprint_users, but prints out each user instead."""
    for s in sprint_users(*criterions):
        print(s)

def sprintv(x: Any) -> str:
    """Prints the attributes of 'x' in json format."""
    return json.dumps({k: str(v) for k, v in vars(x).items() if "_" not in k},
                      sort_keys=True,
                      indent=4)

def printv(x: Any) -> None:
    """Like sprint_users, but prints out each user instead."""
    print(sprintv(x))

def sprint_requests(requests: Dict[int, db.RequestStatus]) -> str:
    """Returns a formatted string of a 'requests', dictionary of request_id's and the corresponding
    RequestStatus."""
    return json.dumps(
        {
            requestid: {
                "id": requestid,
                "srcnetid": requestmod.get_srcnetid(requestid),
                "destnetid": requestmod.get_destnetid(requestid),
                "status": status.to_readable(),
            } for requestid, status in requests.items()
        },
        sort_keys=True,
        indent=4)


# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
from collections import deque

class Solution:
    def isSymmetrical(self, pRoot):
        if pRoot == None:
            return True

        queue = deque()
        stack = []
        queue.append(pRoot)
        stack.append(-1) # 注意这里，由于测试用例中有与根节点相同的val，所以这里设置为-1，避免根的val被栈弹出。

        while len(queue) > 0:
            elem = queue.popleft()
            if elem == None:
                continue
            else:
                queue.append(elem.left)
                if elem.left == None:
                    if elem.left == stack[-1]:
                        stack.pop()
                    else:
                        stack.append(None)
                elif elem.left.val == stack[-1]:
                    stack.pop()
                else:
                    stack.append(elem.left.val)

                queue.append(elem.right)
                if elem.right == None:
                    if elem.right == stack[-1]:
                        stack.pop()
                    else:
                        stack.append(None)
                elif elem.right.val == stack[-1]:
                    stack.pop()
                else:
                    stack.append(elem.right.val)

        if len(stack) == 1:
            return True
        return False

# 借鉴了层次遍历的思想，使用Python额外的数据结构双端队列deque，栈中保存遍历的元素的值，如果有两个值相等就弹栈，最后留下根节点的值，个人认为比较好理解。


# Python XML DOM Minidom
# xml.dom.minidom — Minimal DOM implementation.
# xml.dom.minidom is a minimal implementation of the Document Object Model interface, with an API similar to that in other languages.
# It is intended to be simpler than the full DOM and also significantly smaller.
# Users who are not already proficient with the DOM should consider using the xml.etree.ElementTree module for their XML processing instead.
#

#
# Warning:
# The xml.dom.minidom module is not secure against maliciously constructed data.
# If you need to parse untrusted or unauthenticated data see XML vulnerabilities.
#

#
# This example program is a fairly realistic example of a simple program.
# In this particular case, we do not take much advantage of the flexibility of the DOM.
#

import xml.dom.minidom

document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>

<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""

dom = xml.dom.minidom.parseString(document)

def getText(nodelist):
    rc = []

    for node in nodelist:

        if node.nodeType == node.TEXT_NODE:
            rc.append(node.data)

    return ''.join(rc)

def handleSlideshow(slideshow):
    print("")

    handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
    slides = slideshow.getElementsByTagName("slide")

    handleToc(slides)
    handleSlides(slides)

    print("")

def handleSlides(slides):
    for slide in slides:

        handleSlide(slide)

def handleSlide(slide):
    handleSlideTitle(slide.getElementsByTagName("title")[0])

    handlePoints(slide.getElementsByTagName("point"))

def handleSlideshowTitle(title):
    print("<title>%s</title>" % getText(title.childNodes))

def handleSlideTitle(title):
    print("
%s
" % getText(title.childNodes))

def handlePoints(points):
    print("
")

    for point in points:
        handlePoint(point)

    print("
")

def handlePoint(point):
    print("
%s
" % getText(point.childNodes))

def handleToc(slides):

    for slide in slides:
        title = slide.getElementsByTagName("title")[0]

        print("
%s
" % getText(title.childNodes))

handleSlideshow(dom)


from  工商银行完整版 import bank_addUser
from 工商银行完整版 import bank_saveMoney
from 工商银行完整版 import getRandom
from unittest import TestCase
from ddt import  ddt
from ddt import data
from ddt import unpack
import xlrd
import xlwt
from xlutils.copy import copy

# username,password,country,province,street,door,money
table=xlrd.open_workbook(filename="HKR.xlsx",encoding_override=True )
st = table.sheet_by_index(0)

a=1
list=[]
while a<len(st.col_values(0)):
    nol=st.row_values(a)

    list.append(nol)
    a=a+1
j=1
while j < len(st.col_values(0)):

    i=0
    while i <4:
        del list[j-1][8]
        i=i+1
    j=j+1
print(list)

@ddt
class TestBank(TestCase):
    @data(*list)
    @unpack
    def testAddUser(self,a,b,c,d,e,f,g,h):

        result = bank_addUser(a,b,c,d,e,f,g)
        z = 1
        wb = copy(table)
        ws = wb.get_sheet(0)
        while z < len(st.col_values(0)):

            if result != h:  # 将测试结果回写到excel表格中。
                ws.write(z, 8, "不通过！")
                wb.save("123.xlsx")

            else:
                ws.write(z, 8, "通过！")
                wb.save("123.xlsx")

            z=z+1

        self.assertEqual(result,h)


import argparse
import sys
import traceback
from logging import error, warning
from typing import Dict, List, Text
from urllib.parse import urlparse

import act.api
import requests
import urllib3
from act.api.libs import cli

import act
from act.workers.libs import worker

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

MAX_RECURSIVE = 10  # max number of redirects to attempt to follow (failsafe)

def check_redirect(
    url: Text,
    url_shorteners: List[Text],
    user_agent: Text,
    proxies: Dict[Text, Text],
    timeout: int = 30,
) -> Text:
    """Take a url. Attempt to make it a http:// url and check if it is to one
    of the known url shortening services. If it is.. find the first redirect"""

    headers = {"User-agent": user_agent}

    org_url = url

    p = urlparse(url)
    if p.scheme == "":
        url = "http://{}".format(url)
    p = urlparse(url)

    if p.hostname not in url_shorteners:
        return org_url

    r = requests.get(
        url, allow_redirects=False, timeout=timeout, headers=headers, proxies=proxies
    )
    if r.is_redirect:
        return str(r.next.url)  # type: ignore

    return org_url

def process(
    api: act.api.Act,
    shorteners: List[Text],
    user_agent: Text,
    proxies: Dict[Text, Text],
    output_format: Text = "json",
) -> None:
    """Read queries from stdin, resolve each one through passivedns printing
    generic_uploader data to stdout"""

    for query in sys.stdin:
        query = query.strip()
        if not query:
            continue

        n = 0
        while True:
            redirect = check_redirect(query, shorteners, user_agent, proxies)
            if redirect == query or n > MAX_RECURSIVE:
                break
            n += 1

            try:
                act.api.helpers.handle_uri(api, query, output_format=output_format)
            except act.api.base.ValidationError as err:
                warning("Unable to add {0} [{1}]".format(query, err))
                break

            try:
                act.api.helpers.handle_uri(api, redirect, output_format=output_format)
            except act.api.base.ValidationError as err:
                warning("Unable to add {0} [{1}]".format(redirect, err))
                break

            act.api.helpers.handle_fact(
                api.fact("redirectsTo")
                .source("uri", query)
                .destination("uri", redirect),
                output_format=output_format,
            )

            query = redirect

def parseargs() -> argparse.Namespace:
    parser = worker.parseargs("URL unshortener worker")

    parser.add_argument(
        "--url-shorteners",
        dest="url_shorteners",
        default="adf.ly, bit.ly, bitly.com, cc.uz, evassmat.com, goo.gl, is.gd, lnkd.in, smarturl.it, www.t2m.io, tiny.cc, tinyurl.com, x.co",
        help="Comma separated list of shortener-domains",
    )
    parser.add_argument(
        "--user-agent",
        dest="user_agent",
        default="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
        help="User-agent to present to the redirect services",
    )

    return cli.handle_args(parser)

def main() -> None:
    """Main function"""
    # Look for default ini file in "/etc/actworkers.ini" and
    # ~/config/actworkers/actworkers.ini (or replace .config with
    # $XDG_CONFIG_DIR if set)
    args = parseargs()

    try:
        shorteners = [x.strip() for x in args.url_shorteners.split(",")]
    except AttributeError:
        cli.fatal("Empty list of shorteners?")

    actapi = worker.init_act(args)

    proxies = (
        {"http": args.proxy_string, "https": args.proxy_string}
        if args.proxy_string
        else None
    )

    process(actapi, shorteners, args.user_agent, proxies, args.output_format)

def main_log_error() -> None:
    "Main function wrapper. Log all exceptions to error"
    try:
        main()
    except Exception:
        error("Unhandled exception: {}".format(traceback.format_exc()))
        raise

if __name__ == "__main__":
    main_log_error()


import copy
import sys
import numpy as np
from scipy.signal import convolve2d

# scors for sets
set_4=10
set_3_op=5
set_3=1

# kernels
horizontal_kernel = np.array([[ 1, 1, 1, 1]])
vertical_kernel = np.transpose(horizontal_kernel)
diag1_kernel = np.eye(4, dtype=np.uint8)
diag2_kernel = np.fliplr(diag1_kernel)
detection_kernels = [horizontal_kernel, vertical_kernel, diag1_kernel, diag2_kernel]

class State:
    def __init__(self, parent,isroot,board,cp,arow=None,acul=None,Q=0,N=sys.float_info.epsilon):
        self.__parent = parent
        if not isroot:
            self.__board=copy.deepcopy(parent.get_board())
        else:
            self.__board=copy.deepcopy(board)
        self.__Q=Q
        self.__N=N
        self.__children=[]
        self.__player=cp
        self.__arow=arow
        self.__acul=acul

    def get_Q(self):
        return self.__Q
    def get_N(self):
        return self.__N
    def set_Q(self,value):
        self.__Q=value
    def set_N(self,count):
        self.__N=count
    def get_children(self):
        return self.__children
    def add_child(self,child):
        self.__children.append(child)
    def get_player(self):
        return self.__player
    def set_player(self,cp):
        self.__player=cp
    def get_board(self):
        return self.__board
    def change_board(self,row,cul):
        self.__board[row][cul]=self.__player
    def set_children(self,children):
        self.__children=children
    def get_arow(self):
        return self.__arow
    def undo_move(self,row,cul):
        self.__board[row][cul] = 0
    def get_acul(self):
        return self.__acul
    def get_parent(self):
        return self.__parent

    def heuristic(self,moves):
        cp=self.__player
        points=[]
        min_score=0
        for move in moves:
            self.change_board(move[0],move[1])
            score=0
            for kernel in detection_kernels:
                result_board = convolve2d(self.__board, kernel, mode="valid")
                matrix=result_board*cp
                if 4 in matrix:
                    score=set_4
                else:
                    score=score-np.count_nonzero(matrix == -3)*set_3_op
                    score=score+np.count_nonzero(matrix == 3)*set_3

            points.append(score)
            if score<min_score:
                min_score=score
            self.undo_move(move[0],move[1])
        points=[point-min_score+1 for point in points]
        total=sum(points)
        probs=[(point/total) for point in points]
        return probs

    def legal_moves(self):
        moves = []
        for i in range(self.__board.shape[1]):
            blanks = np.where(self.__board[:, i] == 0)
            if len(blanks[0]) != 0:
                moves.append([blanks[0][-1], i])
        return moves

    def evaluation(self,cp=None):
        if cp is None:
            cp=self.__player
        for kernel in detection_kernels:
            result_board = convolve2d(self.__board, kernel, mode="valid")
            if 4 in result_board*cp:
                return "win"
            if -4 in result_board*cp:
                return "loss"

        if len(np.where(self.__board == 0)[0]) == 0:
            return "draw"

        return "is not terminal"

    def plot(self):
        print(str(self.__board).replace(' [', '').replace('[', '').replace(']', ''))
        print("player: "+str(self.__player))
        print("visit count: "+str(self.__N))
        print("value: "+str(self.__Q))
        print("action row: "+str(self.__arow))
        print("action row: "+str(self.__acul))
        print("*"*20)


# from django.http import HttpResponse
from django.shortcuts import render
# from random import randint
# Create your views here.
from . models import Article # 같은 폴더 안의 models에서 Article을 사용할거야

def index(request):
    # random_number = randint(1,18)
    # return HttpResponse("Hello, word {}".format(random_number))

    # name = "Jay"
    # return render(request, "index.html", {"name" : name})

    article_list = Article.objects.all()

    # Article.objects.create(
    #     title = "hello^^",
    #     contents = "test",
    #     view_count = 0
    # )
    ctx = {
        "article_list" : article_list
    }
    return render(request, "index.html", ctx)


# -*- coding: utf-8 -*-
"""
Created on Thu Oct 25 15:04:22 2018

@author: Nagano Masatoshi
"""

import cv2
import os
#import ffmpeg as fp

def main():
    #動画を読み込む
    filename = './movie/output.mp4'
    video = cv2.VideoCapture(filename)

    path = 'movie2'
    if not os.path.exists(path):
        os.mkdir(path)

    savepath = 'image2'
    if not os.path.exists(savepath):
        os.mkdir(savepath)

    #フレーム数確認
    frames = int(video.get(7))
    print ('frame rate:',frames)

    for i in range(0,frames):
        _, frame = video.read()
        cv2.imwrite(savepath+"/%d.png"%i,frame)

if __name__ == '__main__':
    main()


#! //Users/tyt15771/miniconda3/envs/pymol/bin/python

from pymol import cmd
import json
import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    "-l",
    "--lig_path", required=True,
    )
parser.add_argument(
    "-p",
    "--prot_path", required=True,
    )

parser.add_argument(
    "-t",
    "--target", required=True,
    )

args = vars(parser.parse_args())

lig = args["lig_path"]
prot = args["prot_path"]
target = args["target"]

bits = json.load(open('bits.json', 'r'))

dirname = f'{os.getcwd()}/{target}_complexes'

def extend_save(filepath, moltype, atom, depth, num, bit):
    struc = filepath.split('/')[-1].split('.')[0]
    cmd.reinitialize()
    cmd.load(filepath)
    cmd.select('root', f'index {atom}')
    cmd.select('ext', f'root extend {depth}')
    cmd.save(f'{dirname}/{bit}/{struc}_{moltype}{num}.pdb', 'ext')

for bit in bits:
    num = 0
    for pair in bits[bit]:

        if not os.path.isdir(f'{dirname}/{bit}'):
            os.mkdir(f'{dirname}/{bit}')
        lig_atom = pair[0]
        lig_depth = pair[1]
        prot_atom = pair[2]
        prot_depth = pair[3]

        extend_save(lig, 'lig', lig_atom, lig_depth, num, bit)
        extend_save(prot, 'prot', prot_atom, prot_depth, num, bit)

        num += 1


import cv2
import os
import re
import mediapipe as mp
import pandas as pd

# Initialize mediapipe lib
mpPose = mp.solutions.pose
pose = mpPose.Pose()
mpDraw = mp.solutions.drawing_utils

lm_list = []
label = "FALLBACK"
no_of_frames = 200

def make_landmark_timestep(results):
    c_lm = []
    for id, lm in enumerate(results.pose_landmarks.landmark):
        c_lm.append(lm.x)
        c_lm.append(lm.y)
        c_lm.append(lm.z)
        c_lm.append(lm.visibility)
    return c_lm

def draw_landmark_on_image(mpDraw, results, frame):
    # Draw the line to connect the landmarks
    mpDraw.draw_landmarks(frame, results.pose_landmarks, mpPose.POSE_CONNECTIONS)

    # Draw the landmarks on the frame
    for id, lm in enumerate(results.pose_landmarks.landmark):
        h, w, c = frame.shape
        cx, cy = int(lm.x * w), int(lm.y * h)
        cv2.circle(frame, (cx, cy), 5, (255, 0, 0), cv2.FILLED)
    return frame

# Set the path of all the videos
video_folder_fallback = '/home/yuu/Documents/PBL5-demo/Data/Fall_backwards'
video_folder_fallforward = '/home/yuu/Documents/PBL5-demo/Data/Fall_forward'
video_folder_fallleft = '/home/yuu/Documents/PBL5-demo/Data/Fall_left'
video_folder_fallright = '/home/yuu/Documents/PBL5-demo/Data/Fall_right'
video_folder_fallsitting = '/home/yuu/Documents/PBL5-demo/Data/Fall_sitting'
video_folder_walk = '/home/yuu/Documents/PBL5-demo/Data/Walk'

# Read video from the folder and save the landmarks to a csv file
def read_video(video_folder):
    for video in os.listdir(video_folder):
        video_path = os.path.join(video_folder, video)
        cap = cv2.VideoCapture(video_path)

        if (cap.isOpened() == False):
            print("Error opening video stream or file")

        while cap.isOpened():
            ret, frame = cap.read()

            if ret:
                # Recognize the pose
                frameRGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                results = pose.process(frameRGB)

                if results.pose_landmarks:
                    # Read the value of the landmarks
                    lm = make_landmark_timestep(results)
                    lm_list.append(lm)

                    # Draw the landmarks on the frame
                    frame = draw_landmark_on_image(mpDraw, results, frame)

                cv2.imshow('frame', frame)
                if cv2.waitKey(1) == ord('q'):
                    break

            else:
                break

        cap.release()
        cv2.destroyAllWindows()

# Save the landmarks to a csv file
def save_landmark_to_csv(label):
    df = pd.DataFrame(lm_list)
    df.to_csv(label + '.csv')


import moviepy.editor as mp
from assembly_api import *
def convert(name):
    video = mp.VideoFileClip(name)
    video.audio.write_audiofile("converted.wav")

print("Please enter the name of video file you want to summarize along with its type...... eg: test.mp4")
name = input()
convert(name)
def start():
    filename = "converted.wav"
    audio_url = upload(filename)

    save_transcript(audio_url, "output1")
print("The video has been converted to wav format successfully.")
start()


#!/usr/bin/python
# -*- coding: utf-8 -*-
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import Selector
from score.items import ScoreItem
from sunburnt import SolrInterface

class ScoreSpider(CrawlSpider):
    name = 'score'
    allowed_domains = ['matchendirect.fr']
    start_urls = ['http://www.matchendirect.fr/hier/']
    rules = [Rule(SgmlLinkExtractor(allow=(r'/live-score/[a-z0-9\-]+\.html$', r'/foot-score/[a-z0-9\-]+\.html$')), 'parse_score')]

    # init solr instance
    def __init__(self, *args, **kwargs):
        super(ScoreSpider, self).__init__(*args, **kwargs)
        self.si = SolrInterface('http://localhost:8080/solr')

    # called on start urls
    # get host, visitor, scores
    def parse_start_url(self, response):
        sel = Selector(response)
        leagues = sel.xpath('//h3')
        docs = []
        for league in leagues:
            table = league.xpath('following-sibling::table[@class="tableau"][1]')
            rows = table.xpath('tr')
            for row in rows:
                # if match has has started & is finished
                scoring = row.xpath('td[@class="lm4"]/a[not(span)]/text()').extract()
                isPlaying = row.xpath('td[@class="lm2_1"]').extract()
                if scoring and not isPlaying:
                    score = ScoreItem()
                    score['id'] = 'http://www.matchendirect.fr' + row.xpath('td[@class="lm4"]/a/@href').extract().pop()
                    score['host'] = row.xpath('td[@class="lm3"]/a/text()').extract().pop()
                    score['visitor'] = row.xpath('td[@class="lm5"]/a/text()').extract().pop()

                    scoringArr = scoring.pop().split(' - ')
                    score['scorehost'] = int(scoringArr[0])
                    score['scorevisitor'] = int(scoringArr[1])
                    if score['scorehost'] > score['scorevisitor']:
                        score['winner'] = score['host']
                    elif score['scorehost'] < score['scorevisitor']:
                        score['winner'] = score['visitor']

                    leagueArr = league.xpath('a[1]/text()').extract().pop().split(' : ')
                    score['country'] = leagueArr[0]
                    score['league'] = leagueArr[1]

                    docs.append(dict(score))

        # index crawled games
        self.si.add(docs)
        self.si.commit()

    # called on followed urls
    # get game details (goal scorer & time)
    def parse_score(self, response):
        sel = Selector(response)
        # if match has started & is finished
        scorehost = sel.xpath('//div[@id="match_score"]/div[@class="col2"]/text()').extract().pop().strip()
        scorevisitor = sel.xpath('//div[@id="match_score"]/div[@class="col3"]/text()').extract().pop().strip()
        isPlaying = sel.xpath('//div[@id="match_entete_2"]/img').extract()

        if scorehost and scorevisitor and not isPlaying:
            score = ScoreItem()

            # get already indexed data
            solr_doc = self.si.query(id=response.url).execute()
            if list(solr_doc):
                doc = solr_doc[0]
            else:
                doc = {}
                score['id'] = response.url

            # get goals
            table = sel.xpath('//table[@class="tableau match_evenement"]')
            rows = table.xpath('tr')
            score['goalscorershost'], score['goalscorersvisitor'], score['goaltimeshost'], score['goaltimesvisitor'] = ([], [], [], [])
            score['penaltytimeshost'], score['penaltytimesvisitor'], score['ogtimeshost'], score['ogtimesvisitor'] = ([], [], [], [])
            for row in rows:
                tdgoalhost = row.xpath('td[@class="c1" and span[@class="ico_evenement1"]]')
                tdpenaltyhost = row.xpath('td[@class="c1" and span[@class="ico_evenement2"]]')
                tdowngoalhost = row.xpath('td[@class="c1" and span[@class="ico_evenement7"]]')
                tdgoalvisitor = row.xpath('td[@class="c3" and span[@class="ico_evenement1"]]')
                tdpenaltyvisitor = row.xpath('td[@class="c3" and span[@class="ico_evenement2"]]')
                tdowngoalvisitor = row.xpath('td[@class="c3" and span[@class="ico_evenement7"]]')
                tdgoalhost = tdgoalhost or tdpenaltyhost or tdowngoalhost
                tdgoalvisitor = tdgoalvisitor or tdpenaltyvisitor or tdowngoalvisitor
                if tdgoalhost:
                    time = tdgoalhost.xpath('following-sibling::td[@class="c2"][1]/text()').extract().pop().rstrip("'")
                    if tdpenaltyhost:
                        score['penaltytimeshost'].append(time)
                    elif tdowngoalhost:
                        score['ogtimeshost'].append(time)
                    score['goaltimeshost'].append(time)
                    score['goalscorershost'].append(tdgoalhost.xpath('a/text()').extract().pop())
                elif tdgoalvisitor:
                    time = tdgoalvisitor.xpath('preceding-sibling::td[@class="c2"][1]/text()').extract().pop().rstrip("'")
                    if tdpenaltyvisitor:
                        score['penaltytimesvisitor'].append(time)
                    elif tdowngoalvisitor:
                        score['ogtimesvisitor'].append(time)
                    score['goaltimesvisitor'].append(time)
                    score['goalscorersvisitor'].append(tdgoalvisitor.xpath('a/text()').extract().pop())

            # get time, refree & stadium
            matchinfos = sel.xpath('//table[@id="match_entete_1"]/tr/td[@class="info"]/text()').extract()
            matchinfos.pop()
            matchinfos = [x.lstrip('\n\t\r') for x in matchinfos]
            if u'Arbitre : - ' in matchinfos:
                matchinfos.remove(u'Arbitre : - ')
            date = format_date(matchinfos[0])
            time = matchinfos[1].split(' ')[-1].replace('h', ':') + ':00'
            score['date'] = "%sT%sZ" % (date, time)
            if len(matchinfos) >= 3:
                score['stadium'] = matchinfos[2]
                if len(matchinfos) == 4:
                    score['referee'] = matchinfos[3].split(' : ')[1]

            # index all datas
            doc = dict(doc.items() + dict(score).items())
            self.si.add(doc)
            self.si.commit()

def format_date(date):
    months = {
        u'janvier': '01',
        u'février': '02',
        u'mars': '03',
        u'avril': '04',
        u'mai': '05',
        u'juin': '06',
        u'juillet': '07',
        u'août': '08',
        u'septembre': '09',
        u'octobre': '10',
        u'novembre': '11',
        u'décembre': '12'
    }
    date_list = date.split(' ')[1:]
    date_list.reverse()
    date_list[1] = months[date_list[1]]
    formatted_date = '-'.join(date_list)

    return formatted_date


import json
import ptvsd
import sys
import requests
import boto3

ptvsd.enable_attach(address=('0.0.0.0', 5678), redirect_output=True)

print("waiting for debugger to attach...")

sys.stdout.flush()

ptvsd.wait_for_attach()

print("attached")

# import requests

def create_dynamo_table(event, context, table_name_value, enable_streams=False, read_capacity=1, write_capacity=1,region='us-west-2'):

    table_name = table_name_value
    print('creating table: ' + table_name)
    responseObject = {}
    responseObject['headers'] = {}
    responseObject['headers']['content-type'] = 'application/json'

    try:

        client = boto3.client(service_name='dynamodb', region_name=region)
        table = (client.create_table(TableName=table_name,
                                    AttributeDefinitions=[
                                        {'AttributeName': 'EventId', 'AttributeType': 'S'},
                                        {'AttributeName': 'EventDay', 'AttributeType': 'N' }
                                        ],
                                    KeySchema=[{'AttributeName': 'EventId', 'KeyType': 'HASH'},
                                        {'AttributeName': 'EventDay','KeyType': 'RANGE'},
                                        ],
                                    ProvisionedThroughput={'ReadCapacityUnits': read_capacity, 'WriteCapacityUnits': write_capacity}))

        print(table)
        responseObject['statusCode'] = 200
        responseObject['body'] = json.dumps(table)
    except Exception as e:
        print(str(type(e)))
        print(e.__doc__)
        responseObject['statusCode'] = 500
        responseObject['body'] = json.dumps(e.__doc__)

    return responseObject

def create_handler(event, context):
    table_name = 'user-visits'
    return create_dynamo_table(event, context, table_name, False, 1, 1)


import setuptools

import version

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="uncertainty-wizard",
    version=version.RELEASE,
    author="Michael Weiss",
    author_email="code@mweiss.ch",
    description="Quick access to uncertainty and confidence of Keras networks.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/testingautomated-usi/uncertainty_wizard",
    packages=setuptools.find_packages(),
    classifiers=[
        "Development Status :: 4 - Beta",
        "Programming Language :: Python :: 3",
        "Topic :: Scientific/Engineering :: Artificial Intelligence",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)


import os
import sys
from typing import Callable

from utils.inputs import int_input
from utils.prints import Color, print_line, print_result

def get_exercices_count() -> int:
	"""
	Retourne le nombre d'exercices.
	:return: Le nombre d'exercices.
	:rtype: int
	"""

	# count the number of files with pattern "ex[number].py" in directory ../src
	return len([name for name in os.listdir('src') if name.startswith('ex') and name.endswith('.py')])

def get_exercice(number: int) -> tuple[str, str, Callable[[], None]]:
	"""
	Retourne le tuple contenant le nom, la consigne et la fonction à exécuter.
	:param number: Le numéro de l'exercice.
	:type number: int
	:return: Le tuple contenant le nom, la consigne et la fonction à exécuter.
	:rtype: tuple[str, str, Callable[[], None]]
	"""
	file: object = __import__(f"src.ex{number}")
	module: object = getattr(file, f"ex{number}")
	function: Callable[[], None] = getattr(module, f"ex{number}")
	return getattr(module, "__title__"), str(function.__doc__), function

def get_instructions_from_docstring(function: tuple[str, str, Callable[[], None]]) -> str:
	"""
	Retourne la consigne de l'exercice.
	:param function: L'exercice.
	:type function: tuple[str, str, Callable[[], None]]
	:return: La consigne de l'exercice depuis le docstring.
	:rtype: str
	"""
	return function[1].split(':return:')[0].strip().replace('\t', '')

def print_menu() -> None:
	"""
	Affiche le menu de sélection des exercices.
	:return: None
	:rtype: None
	"""
	print_line("Menu", color = Color.YELLOW)
	exercices: list[tuple[str, str, Callable[[], None]]] = [get_exercice(i) for i in range(1, get_exercices_count() + 1)]
	list_exercices: str = '\n'.join([f"Exercice {Color.cyan(i + 1)} - {Color.green(exercices[i][0])}" for i in range(len(exercices))])
	list_exercices += Color.red('\n\nSTOP pour arrêter.')
	print(list_exercices)

def menu() -> None:
	"""
	Lance le programme.
	:return: None
	:rtype: None
	"""
	print(Color.red('Bienvenue dans le menu du TP 3'))
	while True:
		print_menu()
		try:
			input1: int = int_input(Color.blue('Veuillez choisir un exercice : '), 1, lambda _: get_exercices_count(), True)
			exercice: tuple[str, str, Callable[[], None]] = get_exercice(input1)
			print(exercice)
			print_line(f"Exercice n°{input1}", color = Color.YELLOW)
			print_result(f"{get_instructions_from_docstring(exercice)}\n", Color.BLUE)
			exercice[2]()
			input(Color.cyan('Appuyez sur ENTRÉE pour continuer...'))
		except:
			print(Color.cyan('\nAu revoir :)'))
			sys.exit(1)

if __name__ == '__main__':
	menu()


import cv2
import os
import torch
import torch.nn as nn
import torchvision
import argparse
import numpy as np
import copy
from torch.autograd import Variable

pa = argparse.ArgumentParser()
pa.add_argument("--input_row", type=int, default=0)
pa.add_argument("--input_col", type=int, default=0)
pa.add_argument("--input_channel", type=int, default=0)

opt = pa.parse_args()
opt.input_row = 24
opt.input_col = 32
opt.input_channel = 1
print(opt)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# device = torch.device("cpu")
print("++++++++++Your CUDA is available!++++++++++" if torch.cuda.is_available() else "----------No CUDA available!----------")

def readDataL(num):
    paths = os.getcwd() + "/RobomasterNumData/" + str(num) + "L/"
    filelist = os.listdir(paths)
    AllDataSub = torch.rand(len(filelist), 1, 24, 32)
    for i in range(len(filelist)):
        I = cv2.imread(paths + filelist[i])
        I = cv2.resize(I, (opt.input_col, opt.input_row))
        I = cv2.cvtColor(I, cv2.COLOR_BGRA2GRAY)  # 原始图竟然是四通道的！！
        temp = torch.from_numpy(I)
        AllDataSub[i, 0, :, :] = temp
        # cv2.imshow("1", I)
        # cv2.waitKey(1)
    return AllDataSub

def readDataS(num):
    paths = os.getcwd() + "/RobomasterNumData/" + str(num) + "S/"
    filelist = os.listdir(paths)
    AllDataSub = torch.rand(len(filelist), 1, 24, 32)
    for i in range(len(filelist)):
        I = cv2.imread(paths + filelist[i])
        I = cv2.resize(I, (opt.input_col, opt.input_row))
        I = cv2.cvtColor(I, cv2.COLOR_BGRA2GRAY)  # 原始图竟然是四通道的！！
        temp = torch.from_numpy(I)
        AllDataSub[i, 0, :, :] = temp
        # cv2.imshow("1", I)
        # cv2.waitKey(1)
    return AllDataSub

class Num_Reg(nn.Module):
    def __init__(self):
        super(Num_Reg, self).__init__()
        self.convA = nn.Sequential(
            nn.Conv2d(
                in_channels=opt.input_channel,
                out_channels=10,
                kernel_size=5,
                stride=1,
                padding=2
            ),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2)
        )
        self.convB = nn.Sequential(
            nn.Conv2d(
                in_channels=10,
                out_channels=30,
                kernel_size=5,
                stride=1,
                padding=2
            ),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2)
        )
        self.f1 = nn.Linear(8 * 6 * 1 * 30, 200)
        self.f2 = nn.Linear(200, 16)

    def forward(self, x):
        x = self.convA(x)
        x = self.convB(x)
        x = x.view(x.size(0), -1)  # why it's -1
        x = self.f1(x)
        x = self.f2(x)
        return x

Recognizer = Num_Reg()
print("Your Model's structure: ", Recognizer)

# prepare the data
AllData1 = readDataL(1)
AllData2 = readDataL(2)
AllData3 = readDataL(3)
AllData4 = readDataL(4)
AllData5 = readDataL(5)
AllData6 = readDataL(6)
AllData7 = readDataL(7)
AllData8 = readDataL(8)

AllData1s = readDataS(1)
AllData2s = readDataS(2)
AllData3s = readDataS(3)
AllData4s = readDataS(4)
AllData5s = readDataS(5)
AllData6s = readDataS(6)
AllData7s = readDataS(7)
AllData8s = readDataS(8)
AllData = torch.cat((AllData1, AllData2, AllData3, AllData4, AllData5, AllData6, AllData7, AllData8,
                     AllData1s, AllData2s, AllData3s, AllData4s, AllData5s, AllData6s, AllData7s, AllData8s), 0)

# prepare the label
label = np.zeros((50 * 16), int)
k = 0
for i in range(16):
    for j in range(50):
        label[k] = i
        k = k + 1
        # print(k, "  ", label[k])
label = torch.from_numpy(label)

# test your label and your data
for j in range(800):
    cv2.imwrite("./TestImage/" + str(j) + "-" + str(label.numpy()[j]) + ".jpg", AllData[j, 0, :, :].numpy())
print("Here is your data's shape", AllData.shape)
print("Here is your label's shape", label.shape)

# exit(128)
# shuffle it
shuffle_kernel = np.arange(0, 800, 1)
np.random.shuffle(shuffle_kernel)

labeltemp = label.numpy()
labeltemp1 = copy.deepcopy(labeltemp)

AllDataTemp = copy.deepcopy(AllData)
for n in range(800):
    AllDataTemp[n, :, :, :] = AllData[shuffle_kernel[n], :, :, :]
    labeltemp1[n] = labeltemp[shuffle_kernel[n]]

label = torch.from_numpy(labeltemp1)
for n in range(800):
    cv2.imwrite("./TestImage2/" + str(n) + "-" + str(label.numpy()[n]) + ".jpg", AllDataTemp[n, 0, :, :].numpy())
AllData = copy.deepcopy(AllDataTemp)
# print("labeltemp1", labeltemp1)
# print("label", label)
# exit(255)

# optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)   # optimize all cnn parameters
optimizer = torch.optim.Adam(Recognizer.parameters(), lr=0.001)  # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()  # the target label is not one-hotted
loss_func.cuda(device)
Recognizer.cuda(device)
for num in range(750):
    xx = AllData[num, :, :, :]
    x = torch.rand(1, 1, 24, 32)
    x[0, 0, :, :] = xx
    x = x / 255.0
    x = x.cuda(device)
    # print(type(x), x.is_floating_point(), x.dtype)

    label = label.cuda(device)
    y = Recognizer(x)[0]
    y = y.reshape(1, 16)
    y = y.cuda(device)
    # print(type(y), y.is_floating_point(), y.dtype)

    labelv = Variable(label[num])
    labelv = labelv.reshape(1)
    # labelv = labelv.to(torch.int64)
    labelv = labelv.cuda(device)
    # print(type(labelv), labelv.is_floating_point(), labelv.dtype)

    # print(y.shape, labelv)
    loss = loss_func(y, labelv)  # cross entropy loss
    optimizer.zero_grad()  # clear gradients for this training step
    loss.backward()  # backpropagation, compute gradients
    optimizer.step()  # apply gradients
    print("num: ", num)
print("OVER! ")

for rr in range(50):
    rrr = rr+750
    xx = AllData[rrr, :, :, :]
    x = torch.rand(1, 1, 24, 32)
    x[0, 0, :, :] = xx
    x = x/255.0
    # print(x.shape)
    x = x.cuda()
    test_output = Recognizer(x)[0]

    test_output = test_output.cpu()
    test_output = test_output.reshape(1, 16)
    # print(test_output)
    pred_y = torch.max(test_output, 1)[1].data.numpy()
    label = label.cpu()
    # print(rr, 'prediction number', pred_y, 'real number', label[rrr], test_output, pred_y == label[rrr].numpy())
    print(rr, 'prediction number', pred_y, 'real number', label[rrr], pred_y == label[rrr].numpy())

torch.save(Recognizer, "./RoboMaterData.t7")
print("OVER! ")


from hypothesis import given, assume, strategies as st
from quadratic import quadratic
import cmath

@given(a = st.floats(min_value=-10000, max_value=10000),
       b = st.floats(min_value=-10000, max_value=10000),
       c = st.floats(min_value=-10000, max_value=10000))
def test_quad(a, b, c):
    assume(abs(a) >= 0.0001)
    x1, x2 = quadratic(a, b, c)
    assert cmath.isclose(a*x1**2 + b*x1 + c, 0.0, abs_tol=0.0001)
    assert cmath.isclose(a*x1**2 + b*x1 + c, 0.0, abs_tol=0.0001)

if __name__ == '__main__':

    test_quad()


import pandas as pd
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

from transformers import AutoTokenizer, AutoModel
import torch

from typing import List

from patent_phrase_similarity.data.analysis.visualize_datasets import plot_score_vs_test_score
from patent_phrase_similarity.data.transformation.cpc_datasets import Datasets, CPCDatasets

def get_similar_score_v1(model, context: str, similar_sentences: List[str]) -> List[float]:
    sentence_embeddings = model.encode([context] + similar_sentences)
    print("Sentences Shape", sentence_embeddings.shape)

    similarity_distance = cosine_similarity(
        [sentence_embeddings[0]],
        sentence_embeddings[1:]
    )[0]
    return similarity_distance

def get_similar_score_v2(tokenizer, model, context: str, similar_sentences: List[str]) -> List[float]:
    tokens = {'input_ids': [], 'attention_mask': []}

    _sentences = [context] + similar_sentences
    for sentence in sentences:
        # encode each sentence and append to dictionary
        new_tokens = tokenizer.encode_plus(sentence, max_length=128,
                                           truncation=True, padding='max_length',
                                           return_tensors='pt')
        tokens['input_ids'].append(new_tokens['input_ids'][0])
        tokens['attention_mask'].append(new_tokens['attention_mask'][0])

    # reformat list of tensors into single tensor
    tokens['input_ids'] = torch.stack(tokens['input_ids'])
    tokens['attention_mask'] = torch.stack(tokens['attention_mask'])

    outputs = model(**tokens)
    outputs.keys()

    embeddings = outputs.last_hidden_state

    attention_mask = tokens['attention_mask']
    print("Attention Mask Tensor", attention_mask.shape)

    mask = attention_mask.unsqueeze(-1).expand(embeddings.size()).float()
    # print(mask.shape)

    masked_embeddings = embeddings * mask

    # Then we sum the remained of the embeddings along axis 1:
    summed = torch.sum(masked_embeddings, 1)

    # Then sum the number of values that must be given attention in each position of the tensor:
    summed_mask = torch.clamp(mask.sum(1), min=1e-9)

    # Finally, we calculate the mean as the sum of the embedding activations summed
    # divided by the number of values that should be given attention in each position summed_mask:
    mean_pooled = summed / summed_mask

    # convert from PyTorch tensor to numpy array
    mean_pooled = mean_pooled.detach().numpy()

    # calculate
    similarity_distance = cosine_similarity(
        [mean_pooled[0]],
        mean_pooled[1:]
    )[0]

    return similarity_distance

if __name__ == '__main__':
    model_V1 = SentenceTransformer('bert-base-nli-mean-tokens')

    tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/bert-base-nli-mean-tokens')
    model_v2 = AutoModel.from_pretrained('sentence-transformers/bert-base-nli-mean-tokens')
    sentences = [
        "Three years later, the coffin was still full of Jello.",
        "The fish dreamed of escaping the fishbowl and into the toilet where he saw his friend go.",
        "The person box was packed with jelly many dozens of months later.",
        "He found a leprechaun in his walnut shell."
    ]
    # similar_v1 = get_similar_score_v1(sentences[0], sentences[1:])
    # similar_v2 = get_similar_score_v2(sentences[0], sentences[1:])
    #
    # print(similar_v1)
    # print(similar_v2)

    # context = [
    #     'HUMAN NECESSITIES',
    #     'AGRICULTURE',
    #     'FORESTRY',
    #     'ANIMAL HUSBANDRY',
    #     'HUNTING',
    #     'TRAPPING',
    #     'FISHING',
    #     'SOIL WORKING IN AGRICULTURE OR FORESTRY',
    #     'PARTS, DETAILS, OR ACCESSORIES OF AGRICULTURAL MACHINES OR IMPLEMENTS, IN GENERAL ',
    #     'PLANTING',
    #     'SOWING',
    #     'FERTILISING ',
    #     'HARVESTING',
    #     'MOWING',
    #     'PROCESSING OF HARVESTED PRODUCE',
    #     'HAY OR STRAW PRESSES',
    #     'DEVICES FOR STORING AGRICULTURAL OR HORTICULTURAL PRODUCE ',
    #     'HORTICULTURE',
    #     'CULTIVATION OF VEGETABLES, FLOWERS, RICE, FRUIT, VINES, HOPS OR SEAWEED',
    #     'FORESTRY',
    #     'WATERING ',
    #     'NEW PLANTS OR ',
    #     ' PROCESSES FOR OBTAINING THEM',
    #     'PLANT REPRODUCTION BY TISSUE CULTURE TECHNIQUES',
    #     'MANUFACTURE OF DAIRY PRODUCTS ',
    #     'ANIMAL HUSBANDRY',
    #     'CARE OF BIRDS, FISHES, INSECTS',
    #     'FISHING',
    #     'REARING OR BREEDING ANIMALS, NOT OTHERWISE PROVIDED FOR',
    #     'NEW BREEDS OF ANIMALS',
    #     'SHOEING OF ANIMALS',
    #     'CATCHING, TRAPPING OR SCARING OF ANIMALS ',
    #     'APPARATUS FOR THE DESTRUCTION OF NOXIOUS ANIMALS OR NOXIOUS PLANTS',
    #     'PRESERVATION OF BODIES OF HUMANS OR ANIMALS OR PLANTS OR PARTS THEREOF ',
    #     'BIOCIDES, e.g. AS DISINFECTANTS, AS PESTICIDES OR AS HERBICIDES ',
    #     'PEST REPELLANTS OR ATTRACTANTS',
    #     'PLANT GROWTH REGULATORS'
    # ]
    #
    # similar_vector = get_similar_score_v1('\n'.join(context), ['panel', 'panel frame'])
    # print(similar_vector)
    # print("Difference:", 100 * abs(similar_vector[0] - similar_vector[1]), "%")
    #
    # similar_vector = get_similar_score_v1('\n'.join(context), ['distributor pipe', 'pipe'])
    # print(similar_vector)
    # print("Difference:", 100 * abs(similar_vector[0] - similar_vector[1]), "%")
    #
    # similar_vector = get_similar_score_v1('\n'.join(context), ['distributor pipe', 'liquid channels'])
    # print(similar_vector)
    # print("Difference:", 100 * abs(similar_vector[0] - similar_vector[1]), "%")
    #
    # similar_vector = get_similar_score_v1('\n'.join(context), ['distributor pipe', 'optical pipe'])
    # print(similar_vector)
    # print("Difference:", 100 * abs(similar_vector[0] - similar_vector[1]), "%")

    datasets = Datasets()
    cpc_datasets = CPCDatasets()

    train_df = datasets.get_train_df()
    cpc_train_df = cpc_datasets.merge_with_df(train_df)

    cpc_train_df['test_score'] = cpc_train_df.apply(lambda row: get_similar_score_v1(model_V1, row['anchor'], [row['target']])[0], axis=1)
    # similar_vector = get_similar_score_v1('distributor pipe', ['optical pipe'])
    # print(similar_vector)
    # print("Difference:", 100 * abs(similar_vector[0] - similar_vector[1]), "%")

    plot_score_vs_test_score(cpc_train_df, column_a='score', column_b='test_score')


"""
This unit test tests the uri resolver.
It is often the case, that a taxonomy schema imports another taxonomy using a relative path.
i.e:
<link:linkbaseRef [..] xlink:href="./../example_lab.xml" [..]/>
The job of the uri resolver is to resolve those relative paths and urls and return an absolute path or url
"""
import logging
import sys
import unittest

from xbrl.transformations import normalize, TransformationException

logging.basicConfig(stream=sys.stdout, level=logging.INFO)

testTransforms = {
    "http://www.xbrl.org/inlineXBRL/transformation/2010-04-20": [
        # [format,value,expected]
        ['datedoteu', '17.07.22', '2022-07-17'],
        ['datedoteu', '17.07.2022', '2022-07-17'],

        ['datedotus', '07.17.22', '2022-07-17'],
        ['datedotus', '07.17.2022', '2022-07-17'],

        ['datelonguk', '17 July 2022', '2022-07-17'],
        ['datelonguk', '17 July 22', '2022-07-17'],
        ['datelonguk', '7 February 2022', '2022-02-07'],

        ['datelongus', 'July 17, 2022', '2022-07-17'],
        ['datelongus', 'July 17, 22', '2022-07-17'],
        ['datelongus', 'February 7, 2022', '2022-02-07'],

        ['dateshortuk', '17 Jul. 2022', '2022-07-17'],
        ['dateshortuk', '17 Jul. 22', '2022-07-17'],
        ['dateshortuk', '7 Feb. 2022', '2022-02-07'],

        ['dateshortus', 'Jul. 17, 2022', '2022-07-17'],
        ['dateshortus', 'Jul. 17, 22', '2022-07-17'],
        ['dateshortus', 'Feb. 7, 2022', '2022-02-07'],

        ['dateslasheu', '17/07/2022', '2022-07-17'],
        ['dateslasheu', '17/07/22', '2022-07-17'],

        ['dateslashus', '07/17/2022', '2022-07-17'],
        ['dateslashus', '07/17/22', '2022-07-17'],

        ['datelongdaymonthuk', '17 July', '--07-17'],
        ['datelongdaymonthuk', '7 February', '--02-07'],

        ['datelongmonthdayus', 'July 17', '--07-17'],
        ['datelongmonthdayus', 'February 7', '--02-07'],

        ['dateshortdaymonthuk', '17 Jul.', '--07-17'],
        ['dateshortdaymonthuk', '7 Feb', '--02-07'],

        ['dateshortmonthdayus', 'Jul. 17', '--07-17'],
        ['dateshortmonthdayus', 'Feb 7', '--02-07'],

        ['dateslashdaymontheu', '7/2', '--02-07'],
        ['dateslashdaymontheu', '07/02', '--02-07'],

        ['dateslashmonthdayus', '2/7', '--02-07'],
        ['dateslashmonthdayus', '02/07', '--02-07'],

        ['datelongyearmonth', '22 February', '2022-02'],
        ['datelongyearmonth', '2022 February', '2022-02'],

        ['dateshortyearmonth', '22 Feb.', '2022-02'],
        ['dateshortyearmonth', '2022 Feb', '2022-02'],

        ['datelongmonthyear', 'February 22', '2022-02'],
        ['datelongmonthyear', 'February 2022', '2022-02'],

        ['dateshortmonthyear', 'Feb. 22', '2022-02'],
        ['dateshortmonthyear', 'Feb 2022', '2022-02'],

        ['numcomma', '1400,40', '1400.40'],
        ['numcomma', '1,40', '1.40'],

        ['numcommadot', '1,400.40', '1400.40'],
        ['numcommadot', '1,000,400.40', '1000400.40'],

        ['numdash', 'any value', '0'],

        ['numdotcomma', '123.123.123,12', '123123123.12'],

        ['numspacecomma', '123 123 123,12', '123123123.12'],

        ['numspacedot', '123 123 123.12', '123123123.12']
    ],
    "http://www.xbrl.org/inlineXBRL/transformation/2011-07-31": [
        # [format,value,expected]
        ['booleanfalse', 'any string', 'false'],

        ['booleantrue', 'any string', 'true'],

        ['datedaymonth', '2.1', '--01-02'],
        ['datedaymonth', '02*01', '--01-02'],

        ['datedaymonthen', '2. January', '--01-02'],
        ['datedaymonthen', '02*Jan', '--01-02'],

        ['datedaymonthyear', '2*1*22', '2022-01-02'],
        ['datedaymonthyear', '02 01 2022', '2022-01-02'],

        ['datedaymonthyearen', '2*Jan*22', '2022-01-02'],
        ['datedaymonthyearen', '02 January 2022', '2022-01-02'],

        ['datemonthday', '2 1', '--02-01'],
        ['datemonthday', '02-01', '--02-01'],

        ['datemonthdayen', 'Feb. 1', '--02-01'],
        ['datemonthdayen', 'February 1', '--02-01'],

        ['datemonthdayyear', '12.01.99', '1999-12-01'],
        ['datemonthdayyear', '12.01.1999', '1999-12-01'],

        ['datemonthdayyearen', 'Dec. 1 99', '1999-12-01'],
        ['datemonthdayyearen', 'December 01 99', '1999-12-01'],

        ['datemonthyearen', 'Dec. 99', '1999-12'],
        ['datemonthyearen', 'December 1999', '1999-12'],

        ['dateyearmonthen', '99 Dec.', '1999-12'],
        ['dateyearmonthen', '1999 December', '1999-12'],

        ['nocontent', 'any string', ''],

        ['numcommadecimal', '123 123 123,123', '123123123.123'],
        ['numcommadecimal', '123.123.123,123', '123123123.123'],

        ['numdotdecimal', '123 123 123.123', '123123123.123'],
        ['numdotdecimal', '123,123,123.123', '123123123.123'],

        ['zerodash', '-', '0'],
    ],
    "http://www.xbrl.org/inlineXBRL/transformation/2015-02-26": [
        # [format,value,expected]
        ['booleanfalse', 'nope', 'false'],

        ['booleantrue', 'yeah', 'true'],

        ['datedaymonth', '11.12', '--12-11'],
        ['datedaymonth', '1.2', '--02-01'],

        ['datedaymonthen', '2. December', '--12-02'],
        ['datedaymonthen', '2 Sept.', '--09-02'],
        ['datedaymonthen', '14.    april', '--04-14'],

        ['datedaymonthyear', '2.12.2021', '2021-12-02'],
        ['datedaymonthyear', '1.1.99', '1999-01-01'],
        ['datedaymonthyear', '18. 02 2022', '2022-02-18'],

        ['datedaymonthyearen', '02. December 2021', '2021-12-02'],
        ['datedaymonthyearen', '13. Dec. 21', '2021-12-13'],
        ['datedaymonthyearen', '1 Feb 99', '1999-02-01'],

        ['datemonthday', '1.2', '--01-02'],
        ['datemonthday', '12-1', '--12-01'],
        ['datemonthday', '1.30', '--01-30'],

        ['datemonthdayen', 'Jan 02', '--01-02'],
        ['datemonthdayen', 'February 13', '--02-13'],
        ['datemonthdayen', 'sept. 1', '--09-01'],

        ['datemonthdayyear', '12-30-2021', '2021-12-30'],
        ['datemonthdayyear', '2-16-22', '2022-02-16'],
        ['datemonthdayyear', '2-1-2019', '2019-02-01'],

        ['datemonthdayyearen', 'March 31, 2021', '2021-03-31'],
        ['datemonthdayyearen', 'Dec. 31, 22', '2022-12-31'],
        ['datemonthdayyearen', 'april 12 2021', '2021-04-12'],

        ['datemonthyear', '12 2021', '2021-12'],
        ['datemonthyear', '1 22', '2022-01'],
        ['datemonthyear', '02-1999', '1999-02'],

        ['datemonthyearen', 'December 2021', '2021-12'],
        ['datemonthyearen', 'apr. 22', '2022-04'],
        ['datemonthyearen', 'Sept. 2000', '2000-09'],

        ['dateyearmonthday', '2021.12.31', '2021-12-31'],
        ['dateyearmonthday', '2021 1  31', '2021-01-31'],
        ['dateyearmonthday', '22-1-1', '2022-01-01'],

        ['dateyearmonthen', '2021 December', '2021-12'],
        ['dateyearmonthen', '22 sept.', '2022-09'],
        ['dateyearmonthen', '21.apr.', '2021-04'],

        ['nocontent', 'Bla bla', ''],

        ['numcommadecimal', '1.499,99', '1499.99'],
        ['numcommadecimal', '100*499,999', '100499.999'],
        ['numcommadecimal', '0,5', '0.5'],

        ['numdotdecimal', '1,499.99', '1499.99'],
        ['numdotdecimal', '1*499', '1499'],
        ['numdotdecimal', '1,000,000.5', '1000000.5'],

        ['zerodash', '--', '0'],
    ],
    "http://www.xbrl.org/inlineXBRL/transformation/2020-02-12": [
        # [format,value,expected]
        ['date-day-month', '1.1', '--01-01'],
        ['date-day-month', '31-12', '--12-31'],
        ['date-day-month', '27*2', '--02-27'],

        ['date-day-month-year', '1-2-20', '2020-02-01'],
        ['date-day-month-year', '1-02-20', '2020-02-01'],
        ['date-day-month-year', '01 02 2020', '2020-02-01'],

        ['date-day-monthname-en', '1. sept.', '--09-01'],
        ['date-day-monthname-en', '01. sep.', '--09-01'],
        ['date-day-monthname-en', '30 August', '--08-30'],

        ['date-day-monthname-year-en', '30 August 22', '2022-08-30'],
        ['date-day-monthname-year-en', '01 Aug 22', '2022-08-01'],
        ['date-day-monthname-year-en', '1 Aug 2022', '2022-08-01'],

        ['date-month-day', '1 31', '--01-31'],
        ['date-month-day', '01-31', '--01-31'],
        ['date-month-day', '12.1', '--12-01'],

        ['date-month-day-year', '12. 1 22', '2022-12-01'],
        ['date-month-day-year', '01/12/2022', '2022-01-12'],
        ['date-month-day-year', '01.12.2022', '2022-01-12'],

        ['date-month-year', '1*22', '2022-01'],
        ['date-month-year', '01  22', '2022-01'],
        ['date-month-year', '12.2022', '2022-12'],

        ['date-monthname-day-en', 'April/1', '--04-01'],
        ['date-monthname-day-en', 'Sept./20', '--09-20'],
        ['date-monthname-day-en', 'december 31', '--12-31'],

        ['date-monthname-day-year-en', 'december 31, 22', '2022-12-31'],
        ['date-monthname-day-year-en', 'dec. 31, 2022', '2022-12-31'],
        ['date-monthname-day-year-en', 'dec. 1, 2022', '2022-12-01'],

        ['date-year-month', '99/1', '1999-01'],
        ['date-year-month', '2022 - 12', '2022-12'],
        ['date-year-month', '2022 -/ 1', '2022-01'],

        ['date-year-month-day', '   22-1-2 ', '2022-01-02'],
        ['date-year-month-day', ' 2022/1/2 ', '2022-01-02'],
        ['date-year-month-day', '  22/01/02 ', '2022-01-02'],

        ['date-year-monthname-en', '22/december', '2022-12'],
        ['date-year-monthname-en', '22/dec.', '2022-12'],
        ['date-year-monthname-en', '2022-dec', '2022-12'],

        ['fixed-empty', 'some text', ''],
        ['fixed-false', 'some text', 'false'],
        ['fixed-true', 'some text', 'true'],
        ['fixed-zero', 'some text', '0'],

        ['num-comma-decimal', '1.499,99', '1499.99'],
        ['num-comma-decimal', '100*499,999', '100499.999'],
        ['num-comma-decimal', '0,5', '0.5'],

        ['num-dot-decimal', '1,499.99', '1499.99'],
        ['num-dot-decimal', '1*499', '1499'],
        ['num-dot-decimal', '1,000,000.5', '1000000.5'],

    ],
    "http://www.sec.gov/inlineXBRL/transformation/2015-08-31": [
        # [format,value,expected]
        ['duryear', '-22.3456', '-P22Y4M4D'],
        ['duryear', '21.84480', 'P21Y10M5D'],
        ['duryear', '+0.3456', 'P0Y4M4D'],

        ['durmonth', '22.3456', 'P22M10D'],
        ['durmonth', '-0.3456', '-P0M10D'],

        ['durwordsen', 'Five years, two months', 'P5Y2M0D'],
        ['durwordsen', '9 years, 2 months', 'P9Y2M0D'],
        ['durwordsen', '12 days', 'P0Y0M12D'],
        ['durwordsen', 'ONE MONTH AND THREE DAYS', 'P0Y1M3D'],

        ['numwordsen', 'no', '0'],
        ['numwordsen', 'None', '0'],
        ['numwordsen', 'nineteen hundred forty-four', '1944'],
        ['numwordsen', 'Seventy Thousand and one', '70001'],

        ['boolballotbox', '☐', 'false'],
        ['boolballotbox', '☐', 'false'],
        ['boolballotbox', '☑', 'true'],
        ['boolballotbox', '☑', 'true'],
        ['boolballotbox', '☒', 'true'],
        ['boolballotbox', '☒', 'true'],

        ['exchnameen', 'The New York Stock Exchange', 'NYSE'],
        ['exchnameen', 'New York Stock Exchange LLC', 'NYSE'],
        ['exchnameen', 'NASDAQ Global Select Market', 'NASDAQ'],
        ['exchnameen', 'The Nasdaq Stock Market LLC', 'NASDAQ'],
        ['exchnameen', 'BOX Exchange LLC', 'BOX'],
        ['exchnameen', 'Nasdaq BX, Inc.', 'BX'],
        ['exchnameen', 'Cboe C2 Exchange, Inc.', 'C2'],
        ['exchnameen', 'Cboe Exchange, Inc.', 'CBOE'],
        ['exchnameen', 'Chicago Stock Exchange, Inc.', 'CHX'],
        ['exchnameen', 'Cboe BYX Exchange, Inc.', 'CboeBYX'],
        ['exchnameen', 'Cboe BZX Exchange, Inc.', 'CboeBZX'],
        ['exchnameen', 'Cboe EDGA Exchange, Inc.', 'CboeEDGA'],
        ['exchnameen', 'Cboe EDGX Exchange, Inc.', 'CboeEDGX'],
        ['exchnameen', 'Nasdaq GEMX, LLC', 'GEMX'],
        ['exchnameen', 'Investors Exchange LLC', 'IEX'],
        ['exchnameen', 'Nasdaq ISE, LLC', 'ISE'],
        ['exchnameen', 'Miami International Securities Exchange', 'MIAX'],
        ['exchnameen', 'Nasdaq MRX, LLC', 'MRX'],
        ['exchnameen', 'NYSE American LLC', 'NYSEAMER'],
        ['exchnameen', 'NYSE Arca, Inc.', 'NYSEArca'],
        ['exchnameen', 'NYSE National, Inc.', 'NYSENAT'],
        ['exchnameen', 'MIAX PEARL, LLC', 'PEARL'],
        ['exchnameen', 'Nasdaq PHLX LLC', 'Phlx'],

        ['stateprovnameen', 'Alabama', 'AL'],
        ['stateprovnameen', 'Alaska', 'AK'],
        ['stateprovnameen', 'Arizona', 'AZ'],
        ['stateprovnameen', 'Arkansas', 'AR'],
        ['stateprovnameen', 'California', 'CA'],
        ['stateprovnameen', 'Colorado', 'CO'],
        ['stateprovnameen', 'Connecticut', 'CT'],
        ['stateprovnameen', 'Delaware', 'DE'],
        ['stateprovnameen', 'Florida', 'FL'],
        ['stateprovnameen', 'Georgia', 'GA'],
        ['stateprovnameen', 'Hawaii', 'HI'],
        ['stateprovnameen', 'Idaho', 'ID'],
        ['stateprovnameen', 'Illinois', 'IL'],
        ['stateprovnameen', 'Indiana', 'IN'],
        ['stateprovnameen', 'Iowa', 'IA'],
        ['stateprovnameen', 'Kansas', 'KS'],
        ['stateprovnameen', 'Kentucky', 'KY'],
        ['stateprovnameen', 'Louisiana', 'LA'],
        ['stateprovnameen', 'Maine', 'ME'],
        ['stateprovnameen', 'Maryland', 'MD'],
        ['stateprovnameen', 'Massachusetts', 'MA'],
        ['stateprovnameen', 'Michigan', 'MI'],
        ['stateprovnameen', 'Minnesota', 'MN'],
        ['stateprovnameen', 'Mississippi', 'MS'],
        ['stateprovnameen', 'Missouri', 'MO'],
        ['stateprovnameen', 'Montana', 'MT'],
        ['stateprovnameen', 'Nebraska', 'NE'],
        ['stateprovnameen', 'Nevada', 'NV'],
        ['stateprovnameen', 'New Hampshire', 'NH'],
        ['stateprovnameen', 'New Jersey', 'NJ'],
        ['stateprovnameen', 'New Mexico', 'NM'],
        ['stateprovnameen', 'New York', 'NY'],
        ['stateprovnameen', 'North Carolina', 'NC'],
        ['stateprovnameen', 'North Dakota', 'ND'],
        ['stateprovnameen', 'Ohio', 'OH'],
        ['stateprovnameen', 'Oklahoma', 'OK'],
        ['stateprovnameen', 'Oregon', 'OR'],
        ['stateprovnameen', 'Pennsylvania', 'PA'],
        ['stateprovnameen', 'Rhode Island', 'RI'],
        ['stateprovnameen', 'South Carolina', 'SC'],
        ['stateprovnameen', 'South dakota', 'SD'],
        ['stateprovnameen', 'Tennessee', 'TN'],
        ['stateprovnameen', 'Texas', 'TX'],
        ['stateprovnameen', 'Utah', 'UT'],
        ['stateprovnameen', 'Vermont', 'VT'],
        ['stateprovnameen', 'Virginia', 'VA'],
        ['stateprovnameen', 'Washington', 'WA'],
        ['stateprovnameen', 'Washington D.C.', 'DC'],
        ['stateprovnameen', 'West Virginia', 'WV'],
        ['stateprovnameen', 'Wisconsin', 'WI'],
        ['stateprovnameen', 'Wyoming', 'WY'],

        ['entityfilercategoryen', 'accelerated filer', 'Accelerated Filer']
    ]
}

class TransformationTest(unittest.TestCase):

    def test_normalize(self):
        """
        :return:
        """
        for namespace in testTransforms:
            for i, testCase in enumerate(testTransforms[namespace]):
                formatCode, testInput, expected = testCase
                if expected == 'exception':
                    try:
                        testOutput = normalize(namespace, formatCode, testInput)
                        self.fail('Expected Transformation Exception, received ' + testOutput)
                    except TransformationException:
                        pass
                else:
                    testOutput = normalize(namespace, formatCode, testInput)
                    self.assertEqual(expected, testOutput, msg=f'Failed at test case {testCase} of registry {namespace}')

if __name__ == '__main__':
    unittest.main()


# -*-coding:utf-8-*-
"""
File Name: mouse_response_and_type_conversion.py
Program IDE: PyCharm
Date: 10:04
Create File By Author: Hong
"""
import cv2 as cv
import numpy as np

# 在图像上画矩形框
x1 = -1
y1 = -1
x2 = -1
y2 = -1

# canvas = np.zeros((300, 300, 3), dtype=np.uint8)
canvas = cv.imread('images/2.png', cv.IMREAD_COLOR)
img = np.copy(canvas)

# 回调，系统调用回调函数解决你的问题
# 鼠标响应回调函数，参数固定；对应鼠标事件、横坐标、纵坐标、flags和其他参数
def mouse_drawing(event, x, y, flags, param):
    # print(x, y)
    global x1, y1, x2, y2
    if event == cv.EVENT_LBUTTONDOWN:
        x1 = x
        y1 = y
    if event == cv.EVENT_MOUSEMOVE:
        if x1 < 0 or y1 < 0:
            return
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            # 擦除重叠
            # canvas[:, :] = 0
            canvas[:, :, :] = img[:, :, :]
            cv.rectangle(canvas, (x1, y1), (x2, y2), (255, 0, 0), 2, 8, 0)
    if event == cv.EVENT_LBUTTONUP:
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            # canvas[:, :] = 0
            canvas[:, :, :] = img[:, :, :]
            cv.rectangle(canvas, (x1, y1), (x2, y2), (255, 0, 0), 2, 8, 0)

        x1 = -1
        y1 = -1
        x2 = -1
        y2 = -1

def mouse_response():
    cv.namedWindow('Mouse Response', cv.WINDOW_AUTOSIZE)
    # 再某个窗口上设置鼠标响应函数
    cv.setMouseCallback('Mouse Response', mouse_drawing)

    while True:
        cv.imshow('Mouse Response', canvas)
        c = cv.waitKey(1)
        if c == 27:
            break

    cv.destroyAllWindows()

# 图像像素类型转换和归一化
def pixel_normalization(image_path: str):
    img = cv.imread(image_path, cv.IMREAD_COLOR)
    # 可以显示整数和浮点数像素图片
    # 图像归一化
    # 方法1
    # print(img/255.0)
    cv.imshow('input', img / 255.0)

    # 方法2
    result = np.zeros_like(np.float32(img))
    cv.normalize(img, result, 0, 1, cv.NORM_MINMAX, dtype=cv.CV_32F)
    print(result)
    cv.imshow('result', result)

    cv.waitKey(0)
    cv.destroyAllWindows()

if __name__ == '__main__':
    path = 'images/2.png'
    mouse_response()
    # pixel_normalization(path)