"""
Implements the baseclasses for all Component types in Lumen.

The base classes implement the core validation logic and the ability
to dynamically resolve Source and Variable references.
"""
from __future__ import annotations

import warnings

from functools import partial
from typing import (
    Any, ClassVar, Dict, List, Tuple, Type,
)

import pandas as pd
import panel as pn
import param  # type: ignore

from panel.io.cache import _container_hash, _hash_funcs
from panel.util import classproperty
from typing_extensions import Literal

from .state import state
from .util import (
    VARIABLE_RE, cleanup_expr, is_ref, resolve_module_reference,
)
from .validation import (
    ValidationError, match_suggestion_message, reverse_match_suggestion,
    validate_parameters,
)

class Component(param.Parameterized):
    """
    Baseclass for all Lumen component types including Source, Filter,
    Transform, Variable and View types. Components must implement
    serialization and deserialization into a specification dictionary
    via the `from_spec` and `to_spec` protocol. Additonally they
    should implement validation.
    """

    __abstract = True

    # Whether the component allows references
    _allows_refs: ClassVar[bool] = True

    # Parameters that are computed internally and are not part of the
    # component specification
    _internal_params: ClassVar[List[str]] = ['name']

    # Deprecated parameters that are still allowed as spec keys
    _legacy_params: ClassVar[List[str]] = []

    # Keys that must be declared declared as a list of strings or
    # tuples of strings if one of multiple must be defined.
    _required_keys: ClassVar[List[str | Tuple[str, ...]]] = []

    # Keys that are valid to define
    _valid_keys: ClassVar[List[str] | Literal['params'] | None] = None

    # Whether to enforce parameter validation in specification
    _validate_params: ClassVar[bool] = False

    def __init__(self, **params):
        self._refs = params.pop('refs', {})
        expected = list(self.param)
        validate_parameters(params, expected, type(self).name)
        if self._allows_refs:
            params = self._extract_refs(params, self._refs)
        super().__init__(**params)
        for p, ref in self._refs.items():
            if isinstance(state.variables, dict):
                continue
            elif isinstance(ref, str) and '$variables' in ref:
                ref_vars = VARIABLE_RE.findall(ref)
                state.variables.param.watch(partial(self._update_ref, p, ref), ref_vars)
                if '.' not in p and p not in params:
                    self._update_ref(p, ref)

    def _extract_refs(self, params: Dict[str, Any], refs: Dict[str, Any]):
        from .variables import Variable
        processed = {}
        for pname, pval in params.items():
            if is_ref(pval):
                refs[pname] = pval
            elif isinstance(pval, (pn.widgets.Widget, param.Parameter, Variable)):
                var = state.variables.add_variable(pval)
                processed[pname] = var.value
                refs[pname] = f'$variables.{var.name}'
                continue
            elif isinstance(pval, dict):
                subrefs = {}
                processed[pname] = self._extract_refs(pval, subrefs)
                for subkey, subref in subrefs.items():
                    refs[f'{pname}.{subkey}'] = subref
                continue
            else:
                processed[pname] = pval
        return processed

    def _update_ref(self, pname: str, ref: str, *events: param.parameterized.Event):
        """
        Component should implement appropriate downstream events
        following a change in a variable.
        """
        expr = cleanup_expr(ref)
        new_value = pd.eval(expr, local_dict=dict(state.variables), engine='python')
        if '.' in pname:
            pname, *keys = pname.split('.')
            old = getattr(self, pname)
            current = new = old.copy()
            for k in keys[:-1]:
                current = current[k]
            current[keys[-1]] = new_value
        else:
            new = new_value
        self.param.update({pname: new})

    def _sync_refs(self, trigger: bool = True):
        updates = []
        for p, ref in self._refs.items():
            if isinstance(state.variables, dict):
                continue
            elif isinstance(ref, str) and '$variables' in ref:
                with param.discard_events(self):
                    self._update_ref(p, ref)
                    pname, *_ = p.split('.')
                    updates.append(pname)
        if trigger:
            self.param.trigger(*updates)

    ##################################################################
    # Validation API
    ##################################################################

    @classproperty
    def _valid_keys_(cls) -> List[str] | None:
        if cls._valid_keys == 'params':
            valid = [p for p in cls.param if p not in cls._internal_params]
        else:
            valid = cls._valid_keys
        return valid if valid is None else valid + cls._legacy_params

    @classmethod
    def _validate_keys_(cls, spec: Dict[str, Any]):
        valid_keys = cls._valid_keys_
        for key in spec:
            if valid_keys is None or key in valid_keys:
                continue
            msg = f'{cls.__name__} component specification contained unknown key {key!r}.'
            msg = match_suggestion_message(key, cls._valid_keys_ or [], msg)
            raise ValidationError(msg, spec, key)

    @classmethod
    def _validate_required_(
        cls, spec: Dict[str, Any], required: List[str | Tuple[str, ...]] | None = None
    ):
        if required is None:
            required_keys = cls._required_keys
        else:
            required_keys = required
        for key in required_keys:
            if isinstance(key, str):
                if key in spec:
                    continue
                msg = f'The {cls.__name__} component requires {key!r} parameter to be defined.'
                msg, attr = reverse_match_suggestion(key, list(spec), msg)
                raise ValidationError(msg, spec, attr)
            elif isinstance(key, tuple):
                if any(f in spec for f in key):
                    continue
                skey = sorted(key)
                key_str = "', '".join(skey[:-1]) + f"' or '{skey[-1]}"
                msg = f"{cls.__name__} component requires one of '{key_str}' to be defined."
                for f in key:
                    msg, attr = reverse_match_suggestion(f, list(spec), msg)
                    if attr:
                        break
                raise ValidationError(msg, spec, attr)

    @classmethod
    def _validate_list_subtypes(
        cls, key: str, subtype: Type[Component], subtype_specs: List[Dict[str, Any] | str],
        spec: Dict[str, Any], context: Dict[str, Any], subcontext: List[Dict[str, Any] | str] | None = None
    ):
        if not isinstance(subtype_specs, list):
            raise ValidationError(
                f'{cls.__name__} component {key!r} key expected list type but got {type(subtype_specs).__name__}. '
                "This could be because of a missing dash in the yaml file.",
                spec, key
            )
        subtypes = []
        for subtype_spec in subtype_specs:
            subtype_spec = subtype.validate(subtype_spec, context)
            subtypes.append(subtype_spec)
            if subcontext is not None:
                subcontext.append(subtype_spec)
        return subtypes

    @classmethod
    def _validate_dict_subtypes(
        cls, key: str, subtype: Type[Component], subtype_specs: Dict[str, Dict[str, Any] | str],
        spec: Dict[str, Any], context: Dict[str, Any], subcontext: Dict[str, Any] | None = None
    ):
        if not isinstance(subtype_specs, dict):
            raise ValidationError(
                f'{cls.__name__} component {key!r} key expected dict type but got {type(subtype_specs).__name__}.',
                spec, key
            )
        subtypes = {}
        for subtype_name, subtype_spec in subtype_specs.items():
            subtypes[subtype_name] = subtype.validate(subtype_spec, context)
            if subcontext is not None:
                subcontext[subtype_name] = subtypes[subtype_name]
        return subtypes

    @classmethod
    def _validate_str_or_spec(
        cls, key: str, subtype: Type[Component], subtype_spec: Dict[str, Any] | str,
        spec: Dict[str, Any], context: Dict[str, Any]
    ):
        if isinstance(subtype_spec, str):
            if subtype_spec not in context[f'{key}s']:
                msg = f'{cls.__name__} component specified non-existent {key} {subtype_spec!r}.'
                msg = match_suggestion_message(subtype_spec, list(context[key]), msg)
                raise ValidationError(msg, spec, subtype_spec)
            return subtype_spec
        return subtype.validate(subtype_spec, context)

    @classmethod
    def _validate_dict_or_list_subtypes(
        cls, key: str, subtype: Type[Component], subtype_specs: Dict[str, Dict[str, Any] | str] | List[Dict[str, Any] | str],
        spec: Dict[str, Any], context: Dict[str, Any], subcontext: Dict[str, Any] | List[Dict[str, Any] | str] | None = None
    ):
        if isinstance(subtype_specs, list):
            assert subcontext is None or isinstance(subcontext, list)
            return cls._validate_list_subtypes(key, subtype, subtype_specs, spec, context, subcontext)
        else:
            assert subcontext is None or isinstance(subcontext, dict)
            return cls._validate_dict_subtypes(key, subtype, subtype_specs, spec, context, subcontext)

    @classmethod
    def _deprecation(
        cls, msg: str, key: str, spec: Dict[str, Any], update: Dict[str, Any]
    ):
        warnings.warn(msg, DeprecationWarning)
        if key not in spec:
            spec[key] = {}
        spec[key].update(update)

    @classmethod
    def _validate_ref(
        cls, key: str, value: Any, spec: Dict[str, Any], context: Dict[str, Any]
    ):
        refs = value[1:].split('.')
        if refs[0] == 'variables':
            if refs[1] not in context.get('variables', {}):
                msg = f'{cls.__name__} component {key!r} references undeclared variable {value!r}.'
                msg = match_suggestion_message(refs[1], list(context.get('variables', {})), msg)
                raise ValidationError(msg, spec, refs[1])
        elif refs[0] not in context.get('sources', {}):
            msg = f'{cls.__name__} component {key!r} references undeclared source {value!r}.'
            msg = match_suggestion_message(refs[1], list(context.get('sources', {})), msg)
            raise ValidationError(msg, spec, refs[1])

    @classmethod
    def _validate_param(cls, key: str, value: Any, spec: Dict[str, Any]):
        pobj = cls.param[key]
        try:
            if isinstance(pobj, param.Selector) and pobj.names and value in pobj.names:
                return
            pobj._validate(value)
        except Exception as e:
            msg = f"{cls.__name__} component {key!r} value failed validation: {str(e)}"
            raise ValidationError(msg, spec, key)

    @classmethod
    def _is_component_key(cls, key: str) -> bool:
        if key not in cls.param:
            return False
        pobj = cls.param[key]
        return (
            isinstance(pobj, param.ClassSelector) and
            isinstance(pobj.class_, type) and
            issubclass(pobj.class_, Component)
        )

    @classmethod
    def _is_list_component_key(cls, key: str) -> bool:
        if key not in cls.param:
            return False
        pobj = cls.param[key]
        return (
            isinstance(pobj, param.List) and
            isinstance(pobj.item_type, type) and
            issubclass(pobj.item_type, Component)
        )

    @classmethod
    def _validate_spec_(
        cls, spec: Dict[str, Any], context: Dict[str, Any] | None = None
    ) -> Dict[str, Any]:
        validated: Dict[str, Any] = {}
        if context is None:
            context = validated

        for key in (cls._valid_keys_ or list(spec)):
            if key not in spec:
                continue
            val = spec[key]
            if is_ref(val) and not cls._allows_refs:
                raise ValidationError(
                    f'{cls.__name__} component does not allow references but {key} '
                    f'value ({val!r}) is a reference.', spec, val
                )
            if hasattr(cls, f'_validate_{key}'):
                val = getattr(cls, f'_validate_{key}')(val, spec, context)
            elif cls._is_component_key(key):
                val = cls.param[key].class_.validate(val, context)
            elif cls._is_list_component_key(key):
                val = cls._validate_list_subtypes(
                    key, cls.param[key].item_type, val, spec, context
                )
            elif is_ref(val):
                cls._validate_ref(key, val, spec, context)
            elif key in cls.param:
                if isinstance(val, str) and val.startswith('@'):
                    continue
                cls._validate_param(key, val, spec)
            validated[key] = val
        return validated

    ##################################################################
    # Public API
    ##################################################################

    @property
    def refs(self) -> List[str]:
        return [v for k, v in self._refs.items() if v.startswith('$variables.')]

    @classmethod
    def from_spec(cls, spec: Dict[str, Any] | str) -> 'Component':
        """
        Creates a Component instance from a specification.

        Parameters
        ----------
        spec : dict or str
            Specification declared as a dictionary of parameter values
            or a string referencing a source in the sources dictionary.

        Returns
        -------
        Resolved and instantiated Component object
        """
        if isinstance(spec, str):
            raise ValueError(
                "Component cannot be materialized by reference. Please pass "
                "full specification for the component."
            )
        return cls(**spec)

    def to_spec(self, context: Dict[str, Any] | None = None) -> Dict[str, Any]:
        """
        Exports the full specification to reconstruct this component.

        Parameters
        ----------
        context: Dict[str, Any]
          Context contains the specification of all previously serialized components,
          e.g. to allow resolving of references.

        Returns
        -------
        Declarative specification of this component.
        """
        spec = {}
        for p, value in self.param.values().items():
            if p in self._internal_params or value == self.param[p].default:
                continue
            elif self._is_component_key(p):
                pspec = value.to_spec(context=context)
                if not pspec:
                    continue
                value = pspec
            elif self._is_list_component_key(p):
                value = [
                    None if v is None else v.to_spec(context=context)
                    for v in value
                ]
            spec[p] = value
        if context is not None:
            spec.update(self._refs)
        return spec

    @classmethod
    def validate(
        cls, spec: Dict[str, Any] | str, context: Dict[str, Any] | None = None
    ) -> Dict[str, Any] | str:
        """
        Validates the component specification given the validation context.

        Arguments
        -----------
        spec: dict | str
          The specification for the component being validated (or a referene to the component)
        context: dict
          Validation context contains the specification of all previously validated components,
          e.g. to allow resolving of references.

        Returns
        --------
        Validated specification.
        """
        if isinstance(spec, str):
            return spec
        context = {} if context is None else context
        cls._validate_keys_(spec)
        cls._validate_required_(spec)
        return cls._validate_spec_(spec, context)

class MultiTypeComponent(Component):
    """
    MultiComponentType is the baseclass for extensible Lumen components.

    A `MultiTypeComponent` can be resolved using the `_get_type` method
    either by the name declared in the `<component>_type` attribute,
    where the name of the component represent the immediate subclasses
    of MultiTypeComponent. For example `class View(MultiTypeComponent)`
    should define `view_type` for all its descendants to override.

    Just as any other Component, `MultiTypeComponent` implements
    methods to construct an instance from a specification, export the
    specification of a component and the ability to validate a
    component.
    """

    __abstract = True

    _required_keys: ClassVar[List[str | Tuple[str, ...]]] = ['type']

    @classproperty
    def _valid_keys_(cls) -> List[str | Tuple[str, ...]] | None:
        if cls._valid_keys is None:
            valid = None
        elif cls._valid_keys == 'params':
            valid = list(cls.param)
        elif 'params' in cls._valid_keys:
            valid = cls._valid_keys.copy()
            valid.extend(list(cls.param))
        else:
            valid = cls._valid_keys.copy()

        if valid is not None and 'type' not in valid:
            valid.append('type')
        return valid if valid is None else valid + cls._legacy_params

    @classproperty
    def _base_type(cls):
        if cls is MultiTypeComponent:
            return
        return cls.__mro__[cls.__mro__.index(MultiTypeComponent)-1]

    @classproperty
    def _component_type(cls) -> str:
        component_type = getattr(cls, f'{cls._base_type.__name__.lower()}_type')
        if component_type is not None:
            return component_type
        return f'{cls.__module__}.{cls.__name__}'

    @classmethod
    def _import_module(cls, component_type: str):
        base_type = cls._base_type
        try:
            import_name = f'lumen.{base_type.__name__.lower()}s.{component_type}'
            __import__(import_name)
        except ImportError as e:
            if e.name != import_name:
                msg = (
                    f"In order to use the {base_type.__name__.lower()} "
                    f"component '{component_type}', the '{e.name}' package "
                    "must be installed."
                )
                raise ImportError(msg)

    @classmethod
    def _get_type(
        cls, component_type: str, spec: Dict[str, Any] | None = None
    ) -> Type['MultiTypeComponent']:
        base_type = cls._base_type
        if component_type is None:
            raise ValidationError(
                f"No 'type' was provided during instantiation of {base_type.__name__} component.",
                spec
            )
        if '.' in component_type:
            return resolve_module_reference(component_type, base_type)

        cls._import_module(component_type)

        subcls_types = set()
        for subcls in param.concrete_descendents(cls).values():
            subcls_type = subcls._component_type
            if subcls_type is None:
                continue
            subcls_types.add(subcls_type)
            if subcls_type == component_type:
                return subcls

        msg = f"{base_type.__name__} component specification declared unknown type '{component_type}'."
        msg = match_suggestion_message(component_type, list(subcls_types), msg)
        raise ValidationError(msg, spec, component_type)

    ##################################################################
    # Public API
    ##################################################################

    @classmethod
    def from_spec(cls, spec: Dict[str, Any] | str) -> 'MultiTypeComponent':
        if isinstance(spec, str):
            raise ValueError(
                "MultiTypeComponent cannot be materialized by reference. Please pass "
                "full specification for the MultiTypeComponent."
            )
        spec = dict(spec)
        component_cls = cls._get_type(spec.pop('type'), spec)
        return component_cls(**spec)

    def to_spec(self, context: Dict[str, Any] | None = None) -> Dict[str, Any]:
        """
        Exports the full specification to reconstruct this component.

        Returns
        -------
        Resolved and instantiated Component object
        """
        spec = super().to_spec(context=context)
        spec['type'] = self._component_type
        return spec

    @classmethod
    def validate(
        cls, spec: Dict[str, Any] | str, context: Dict[str, Any] | None = None
    ) -> Dict[str, Any] | str:
        """
        Validates the component specification given the validation context and the path.

        Arguments
        -----------
        spec: dict | str
          The specification for the component being validated or a reference to the component.
        context: dict
          Validation context contains the specification of all previously validated components,
          e.g. to allow resolving of references.

        Returns
        --------
        Validated specification.
        """
        if isinstance(spec, str):
            return spec
        context = {} if context is None else context
        if 'type' not in spec:
            msg = f'{cls.__name__} component specification did not declare a type.'
            msg, attr = reverse_match_suggestion('type', list(spec), msg)
            raise ValidationError(msg, spec, attr)
        component_cls = cls._get_type(spec['type'], spec)
        component_cls._validate_keys_(spec)
        component_cls._validate_required_(spec)
        return component_cls._validate_spec_(spec, context)

_hash_funcs[Component] = lambda component: _container_hash(component.to_spec())


import configparser
from wireguard_keys import *

PUB_KEY = '...' # здесь должен быть указан public key

if __name__ == "__main__":

	try:
		with open('curr_ip.txt', 'r') as f:
			IP_N = int(f.readline())
	except FileNotFoundError:
		IP_N = int(input('не найден последний IP, введите его вручную: '))

	#numbers of clients
	N = int(input('введите количество генерируемых конфигов: '))

	for i in range(1, N+1):

		cur_ip = IP_N + i # increment IP-address
		(privkey, pubkey, sharkey) = generate_wireguard_keys()
		config = configparser.ConfigParser()
		config['Interface'] = {
							'PrivateKey': privkey,
							'ListenPort': '51820',
							'Address':  f'172.26.1.{cur_ip}/24',
							'DNS': '192.9.200.124, 192.9.200.132',
							'#pubkey': f'{pubkey}'}
		config['Peer'] = {
		'PublicKey': f'{PUB_KEY}',
		'PresharedKey': f'{sharkey}',
		'AllowedIPs': '172.26.1.0/24, 192.9.200.0/24',
		'Endpoint': '...:...', # здесь должен быть указан внешний адрес и порт
		'PersistentKeepalive': 5
		}

		name_config = input('введите дескрипшн конфига: ')

		with open(f'wg_lan_{cur_ip}_{name_config}.conf', 'w') as f:
			config.write(f)

		print('-------------------------------------')
		print(f'ip: 172.26.1.{cur_ip}')
		print(f'имя конфига: {name_config}')
		print(f'pubkey: {pubkey}')
		print(f'sharkey: {sharkey}')
		print('-------------------------------------')
		print()

	#update last ip
	with open('curr_ip.txt', 'w') as f:
		f.write(str(cur_ip))


#!/bin/python3
import sys
import csv
from pysam import VariantFile
import subprocess

vcf_in = VariantFile(sys.argv[1])
multiVcf = VariantFile(sys.argv[2])
new_header = vcf_in.header
# new_header.generic.add("Multi allelic variants added from Pisces.")

vcf_out = VariantFile(sys.argv[3], 'w', header=new_header)

for record in vcf_in.fetch():
    vcf_out.write(record)
    for mRecord in multiVcf.fetch():
        if record.contig == mRecord.contig and record.pos == mRecord.pos:
            # import pdb; pdb.set_trace()
            if record.alts[0] != mRecord.alts[0]:
                vcf_out.write(mRecord)


# pylint: disable=E1111

from faker import Faker

from src.infra.entities import Pet as PetModel
from src.infra.config.db_config import DBConnectionHandler
from src.infra.entities.pet import AnimalTypes
from .pet_repository import PetRepository

faker = Faker()
pet_repository = PetRepository()
db_connection_handle = DBConnectionHandler()

def test_insert_pet():
    """Should Insert pet"""

    name = faker.name()
    species = "dog"
    age = faker.random_number(digits=2)
    user_id = faker.random_number()

    engine = db_connection_handle.get_engine()

    # SQL Commands
    new_pet = pet_repository.insert_pet(name, species, age, user_id)
    query_pet = engine.execute(f"SELECT * FROM pets WHERE id='{new_pet.id}'").fetchone()

    engine.execute(f"DELETE FROM pets WHERE id='{new_pet.id}'")

    assert new_pet.id == query_pet.id
    assert new_pet.name == query_pet.name
    assert new_pet.species == query_pet.species
    assert new_pet.age == query_pet.age
    assert new_pet.user_id == query_pet.user_id

def test_select_pet():
    """Should Select a pet in pets table and comapare it"""

    pet_id = faker.random_number(digits=5)
    name = faker.name()
    species = "fish"
    age = faker.random_number(digits=1)
    user_id = faker.random_number()

    species_mock = AnimalTypes("fish")
    data = PetModel(
        id=pet_id, name=name, species=species_mock, age=age, user_id=user_id
    )

    engine = db_connection_handle.get_engine()
    engine.execute(
        "INSERT INTO pets (id, name, species, age, user_id) "
        + f"VALUES ('{pet_id}', '{name}', '{species}', '{age}', '{user_id}')"
    )

    query_pet1 = pet_repository.select_pet(pet_id=pet_id)
    query_pet2 = pet_repository.select_pet(user_id=user_id)
    query_pet3 = pet_repository.select_pet(pet_id=pet_id, user_id=user_id)

    assert data in query_pet1
    assert data in query_pet2
    assert data in query_pet3

    engine.execute(f"DELETE FROM pets WHERE id='{pet_id}'")


from datetime import date

ano_atual = date.today().year
nascimento = int(input('Digite seu ano de nascimento: '))
idade = ano_atual - nascimento

if idade == 18:
    print('Se alistar')
elif idade < 18:
    saldo = 18 - idade
    print('ainda faltam {} anos(s) para se alistar'.format(saldo))
    ano = ano_atual + saldo
    print('Seu alistamento será em {}'.format(ano))
elif idade > 18:
    saldo = idade - 18
    print('Já devia ter se alistado a {} ano'.format(saldo))
    ano = ano_atual - saldo
    print('Seu alistamento deveria ter sido em {}'.format(ano))


from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    username = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    fecha_nacimiento = models.CharField(max_length=10, blank=True, null=True)
    nacional = models.BooleanField(default=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def profile(self):
        profile = Profile.objects.get(user=self)

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    full_name = models.CharField(max_length=1000)
    bio = models.CharField(max_length=100)
    image = models.ImageField(upload_to="user_images", default="default.jpg")
    verified = models.BooleanField(default=False)

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

class TipoEvento(models.Model):
    nombre = models.CharField(max_length=100)
    descripcion = models.TextField()

class ActividadTipo(models.Model):
    tipoevento = models.ForeignKey(TipoEvento, on_delete=models.CASCADE)
    idactividades = models.ManyToManyField('Actividad')

class Actividad(models.Model):
    nombre = models.CharField(max_length=100)
    longitud = models.DecimalField(max_digits=10, decimal_places=6)
    latitud = models.DecimalField(max_digits=10, decimal_places=6)
    fecha = models.DateField()
    descripcion = models.TextField()
    img1 = models.TextField(blank=True, null=True)
    img2 = models.TextField(blank=True, null=True)

class UsuarioActividad(models.Model):
    idusuario = models.ForeignKey(User, on_delete=models.CASCADE)
    idactividad = models.ForeignKey(Actividad, on_delete=models.CASCADE)
    fecha_de_interes = models.DateField()


# -*- coding: utf-8 -*-
import os
import boto3
import settings
from jsonschema import validate, ValidationError
from cognito_trigger_base import CognitoTriggerBase
from user_util import UserUtil
from private_chain_util import PrivateChainUtil

class CustomMessage(CognitoTriggerBase):
    def get_schema(self):
        return {
            'type': 'object',
            'properties': {
                'phone_number': settings.parameters['phone_number']
            }
        }

    def validate_params(self):
        params = self.event['request']['userAttributes']
        if UserUtil.check_try_to_register_as_line_user(self.event['userName']) or \
           UserUtil.check_try_to_register_as_twitter_user(self.event['userName']) or \
           UserUtil.check_try_to_register_as_yahoo_user(self.event['userName']) or \
           UserUtil.check_try_to_register_as_facebook_user(self.event['userName']):
            raise ValidationError("external provider's user can not execute")
        if params.get('phone_number', '') != '' and \
           params.get('phone_number_verified', '') != 'true' and \
           self.event['triggerSource'] != 'CustomMessage_ForgotPassword':
            validate(params, self.get_schema())
            client = boto3.client('cognito-idp')
            response = client.list_users(
                    UserPoolId=self.event['userPoolId'],
                    Filter='phone_number = "%s"' % params['phone_number'],
                )
            for user in response['Users']:
                for attribute in user['Attributes']:
                    if attribute['Name'] == 'phone_number_verified' and attribute['Value'] == 'true':
                        raise ValidationError('This phone_number is already exists')
        # セキュリティ観点より、電話番号変更を実行させない。
        # これにより XSS が発生したとしても、電話番号認証が必要な処理は回避が可能
        if self.event['triggerSource'] == 'CustomMessage_VerifyUserAttribute':
            # phone_number_verified が true の場合は電話番号変更を行っていないため当チェックは不要
            if params.get('phone_number_verified', '') != 'true':
                self.__validate_has_not_token(params)

        # サードパーティを利用したユーザの場合、パスワード変更を実行させない
        if self.event['triggerSource'] == 'CustomMessage_ForgotPassword':
            # サードパーティを利用したユーザかを確認
            if UserUtil.is_external_provider_user(self.dynamodb, self.event['userName']):
                raise ValidationError("external provider's user can not execute")

    def exec_main_proc(self):
        if self.event['triggerSource'] == 'CustomMessage_ForgotPassword':
            self.event['response']['smsMessage'] = '{user}さんのパスワード再設定コードは {code} です。'.format(
                user=self.event['userName'], code=self.event['request']['codeParameter'])
            self.event['response']['emailSubject'] = '【ALIS】パスワードの変更：再設定コードの送付'
            self.event['response']['emailMessage'] = "{user}さんのパスワード再設定コードは {code} です".format(
                code=self.event['request']['codeParameter'],
                user=self.event['userName'])
        else:
            self.event['response']['smsMessage'] = 'ALISです。\n{user}さんの認証コードは {code} です。'.format(
                user=self.event['userName'], code=self.event['request']['codeParameter'])
            self.event['response']['emailSubject'] = '【ALIS】登録のご案内：メールアドレスの確認'
            self.event['response']['emailMessage'] = """\
{user}様

ALISをご利用いただきありがとうございます。

仮登録が完了しました。
下記URLにアクセスし、ログインをして登録手続きを完了してください。

https://{domain}/confirm?code={code}&user={user}

※注意事項
・24時間以内に手続きを完了しない場合、上記URLは無効になります。最初から手続きをやり直してください。
・上記URLをクリックしてもページが開かない場合は、URLをコピーし、ブラウザのアドレス欄に貼り付けてください。
・このメールにお心当たりの無い場合は、恐れ入りますが、下記までお問合せください。
    お問合せ（https://{domain}/help）
・このメールアドレスは配信専用となっております。本メールに返信していただきましても、お問合せにはお答えできませんのでご了承ください。

ALIS：https://alismedia.jp
            """.format(
                domain=os.environ['DOMAIN'],
                code=self.event['request']['codeParameter'],
                user=self.event['userName']
            ).replace("\n", "<br />")
        return self.event

    # トークンを保持していた場合は例外を出力
    def __validate_has_not_token(self, params):
        address = params.get('custom:private_eth_address')
        if address is not None:
            url = 'https://' + os.environ['PRIVATE_CHAIN_EXECUTE_API_HOST'] + '/production/wallet/balance'
            payload = {'private_eth_address': address[2:]}
            token = PrivateChainUtil.send_transaction(request_url=url, payload_dict=payload)
            if token is not None and token != '0x0000000000000000000000000000000000000000000000000000000000000000':
                raise ValidationError("Do not allow phone number updates")


from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import HttpResponse
from .models import Product
from math import ceil

# Create your views here.
def index(request):
    #products = Product.objects.all()
    #n = len(products)
    allProds = []
    catprods = Product.objects.values('cat' , 'Product_id')
    cates = {item['cat'] for item in catprods}
    for cats in cates:
        prod = Product.objects.filter(cat=cats)
        n = len(prod)
        nSlides = n//4 + ceil((n/4) - (n//4))
        #parms = {'no_of_slide':nSlide,'range':range(1,nSlide),'product':products}
        #allProds=[[products, range(1, len(products)), nSlides],[products, range(1, len(products)), nSlides]]
        allProds.append([prod,range(1,nSlides),nSlides])
    parms={'allProds':allProds }
    #print(catprods)
    #print(cates)
    #print(cats)
    #print(prod)
    return render(request, 'shop/template/index.html',parms)

    #{% for products, range(1, len(products)), nSlides in allProds %}

def productview(request,myid):
    product = Product.objects.filter(Product_id=myid)
    print(product)
    return render(request,'shop/template/prodview.html',{'product':product[0]})


import os
import tarfile
import time
import shutil
from scipy.io import loadmat
import csv

DEVKIT_FILE_NAME = "ILSVRC2012_devkit_t12.tar.gz"
TRAIN_FILE_NAME = "ILSVRC2012_img_train.tar"
VAL_FILE_NAME = "ILSVRC2012_img_val.tar"
TEST_FILE_NAME = "ILSVRC2012_img_test_v10102019.tar"

def untar(file, target_dir="", is_show_detail=False):
    file_name = file.split('.')[0]
    file_ext = file.split('.')[-1]
    mode = 'r'
    if file_ext == 'gz':
        mode = 'r:gz'
    if is_show_detail:
        print("read the file" + file)
    tar_file = tarfile.open(file, mode)
    if is_show_detail:
        print("check or create directory")
    if target_dir == "":
        target_dir = file_name
    if not os.path.exists(target_dir):
        os.mkdir(target_dir)
    files = tar_file.getnames()
    if is_show_detail:
        total_files = len(files)
        current_file_index = 1
        print("start to extract files")
    for f in files:
        if is_show_detail:
            print("[" + str(current_file_index) + "/" + str(total_files) + "] extracting: " + f)
        tar_file.extract(f, target_dir)
        if is_show_detail:
            print("[" + str(current_file_index) + "/" + str(total_files) + "] successfully extracted: " + f)
            current_file_index += 1
    tar_file.close()

def clear_folder(folder):
    if os.path.exists(folder):
        for root, dirs, files in os.walk(folder):
            for file in files:
                os.remove(os.path.join(root, file))
                print("remove " + os.path.join(root, file))
            for directory in dirs:
                clear_folder(os.path.join(root, directory))
        os.rmdir(folder)

if __name__ == '__main__':

    #unzip dev kit
    print("{1/4} extract development kit ")
    DEVKIT_NAME = DEVKIT_FILE_NAME.split('.')[0]
    untar(DEVKIT_FILE_NAME, "devkit")
    print("{1/4} parse the validation ground truth")
    val_index_label_pairs = {}
    path_devkit_data = os.path.join("devkit",DEVKIT_NAME)
    path_devkit_data = os.path.join(path_devkit_data,"data")
    path_val_ground_truth = os.path.join(path_devkit_data,"ILSVRC2012_validation_ground_truth.txt")
    file_val_ground_truth = open(path_val_ground_truth, "r")
    lines = file_val_ground_truth.readlines()
    line_index = 1
    for line in lines:
        val_index_label_pairs[line_index]=line.strip('\n')
        line_index += 1
    print("{1/4} validation ground truth cached")
    print("{1/4} create the wnid-label-category-explanation form")
    headers = ['wnid', 'label', 'category', 'explanation']
    rows = []
    path_train_labels = os.path.join(path_devkit_data,"meta.mat")
    train_labels = loadmat(path_train_labels)
    train_labels = train_labels['synsets']
    for i in range(len(train_labels)):
        row = {'wnid': train_labels[i][0][1][0], 'label': train_labels[i][0][0][0][0], 'category':train_labels[i][0][2][0], 'explanation': train_labels[i][0][3][0]}
        rows.append(row)
    with open('train_labels.csv', 'w') as f:
        f_csv = csv.DictWriter(f, headers)
        f_csv.writeheader()
        f_csv.writerows(rows)
    print("{1/4} wnid-label-category-explanation form created")
    print("{1/4} development kit successfully extracted")

    #unzip the training data
    print("{2/4} extract training data")
    print("{2/4} clean the train folder")
    clear_folder("train")
    print("{2/4} unzip the training dataset, may take a longer time")
    untar(TRAIN_FILE_NAME, "train", is_show_detail=True)
    print("{2/4} unzip the subfolders of training dataset, may take a longer time")
    train_tar_files = os.listdir("train")
    total_train_tar_files = len(train_tar_files)
    train_tar_file_counter = 0
    for train_tar_file in train_tar_files:
        untar("train/"+train_tar_file, is_show_detail=False)
        os.remove("train/"+train_tar_file)
        train_tar_file_counter += 1
        print("[" + str(train_tar_file_counter) + "/" + str(total_train_tar_files) + "] extracted: " + train_tar_file)
    print("{2/4} trainning data successfully extracted")

    #unzip the validation data
    print("{3/4} extract validation data")
    print("{3/4} clean the validation folder")
    clear_folder("val")
    print("{3/4} unzip the validation dataset, may take a longer time")
    untar(VAL_FILE_NAME, "val", is_show_detail=True)
    val_images = os.listdir('val')
    num_val_images = len(val_images)
    val_image_counter = 0
    for image in val_images:
        image_path = os.path.join("val", image)
        image_index = int(image.split('.')[0].split('_')[-1])
        image_target_dir = os.path.join("val", val_index_label_pairs[image_index])
        if not os.path.exists(image_target_dir):
            os.mkdir(image_target_dir)
        shutil.move(image_path, image_target_dir)
        val_image_counter += 1
        print("[" + str(val_image_counter) + "/" + str(num_val_images) + "] moved: " + image)
    print("{3/4} validation data successfully extracted")

    #unzip the test data
    print("{4/4} extract testing data")
    print("{4/4} clean the test folder")
    clear_folder("test")
    print("{4/4} unzip the test dataset, may take a longer time")
    untar(TEST_FILE_NAME, "test", is_show_detail=True)
    print("{4/4} testing data successfully extracted")

    print("Finished!")


from django.urls import path
from . import views

app_name = 'main'

urlpatterns = [
    path('category_list/', views.category_list, name='category_list'),
    path('delete_category/<int:category_id>/', views.delete_category, name='delete_category'),
    path('update_category/<int:category_id>/', views.update_category, name='update_category'),
    path('product_list/', views.product_list, name='product_list'),
    path('delete_product/<int:code>/', views.delete_product, name='delete_product'),
    path('update_products/<int:pk>/', views.update_products, name='update_products'),
    path('export_pdf/', views.export_pdf, name='export_pdf'),
    path('export_excel/', views.export_excel, name='export_excel'),
    path('import_excel/', views.import_excel, name='import_excel'),
    path('export_import/', views.export_import, name='export_import'),
    #path('add_product/', views.add_product, name='add_product'),
    #path('update_product/<int:product_id>/', views.update_product, name='update_product'),
    #path('delete_product/<int:product_id>/', views.delete_product, name='delete_product'),
    #path('index/', views.index, name='index'),
]


from __future__ import absolute_import
import sys
from optparse import OptionParser

import sumolib  # noqa
from functools import reduce

def parse_args():
    USAGE = "Usage: " + sys.argv[0] + " <netfile> [options]"
    optParser = OptionParser()
    optParser.add_option("-o", "--outfile", help="name of output file")
    optParser.add_option("-r", "--radius", type=float, default=10., help="maximum air distance around the edge")
    optParser.add_option("-t", "--travel-distance", type=float, help="maximum travel distance in the graph")
    optParser.add_option("--symmetrical", action="store_true",
                         default=False, help="extend the bidi-relationship to be symmetrical")
    options, args = optParser.parse_args()
    try:
        options.net, = args
    except Exception:
        sys.exit(USAGE)
    if options.outfile is None:
        options.outfile = options.net + ".taz.xml"
    return options

def getCandidates(edge, net, radius):
    candidates = []
    r = min(radius, sumolib.geomhelper.polyLength(edge.getShape()) / 2)
    for x, y in edge.getShape():
        nearby = set()
        for edge2, dist in net.getNeighboringEdges(x, y, r):
            nearby.add(edge2)
        candidates.append(nearby)
    return candidates

ASYM_BIDI_CACHE = {}  # edge : opposites

def computeBidiTazAsymByRadius(edge, net, radius):
    if edge not in ASYM_BIDI_CACHE:
        candidates = getCandidates(edge, net, radius)
        opposites = reduce(lambda a, b: a.intersection(b), candidates)
        opposites.update(set(edge.getToNode().getOutgoing()).intersection(
            set(edge.getFromNode().getIncoming())))
        ASYM_BIDI_CACHE[edge] = opposites
    return ASYM_BIDI_CACHE[edge]

def computeAllBidiTaz(net, radius, travelDist, symmetrical):
    for edge in net.getEdges():
        travelOpposites = set()
        if travelDist is not None:
            queue = [(edge, -1.)]
            while not len(queue) == 0:
                edge2, dist = queue.pop()
                if edge2 not in travelOpposites and dist < travelDist:
                    travelOpposites.add(edge2)
                    if dist == -1.:
                        dist = 0.
                    else:
                        dist += edge2.getLength()
                    toN = edge2.getToNode()
                    fromN = edge2.getFromNode()
                    for e in toN.getOutgoing() + toN.getIncoming() + fromN.getOutgoing() + fromN.getIncoming():
                        queue.append((e, dist))
        if radius is not None and radius > 0.:
            opposites = computeBidiTazAsymByRadius(edge, net, radius)
            if symmetrical:
                candidates = reduce(
                    lambda a, b: a.union(b), getCandidates(edge, net, radius))
                for cand in candidates:
                    if edge in computeBidiTazAsymByRadius(cand, net, radius):
                        opposites.add(cand)
            travelOpposites.update(opposites)

        yield edge, travelOpposites

def main(netFile, outFile, radius, travelDist, symmetrical):
    net = sumolib.net.readNet(netFile, withConnections=False, withFoes=False)
    with open(outFile, 'w') as outf:
        sumolib.writeXMLHeader(
            outf, "$Id$")  # noqa
        outf.write('<tazs>\n')
        for taz, edges in computeAllBidiTaz(net, radius, travelDist, symmetrical):
            outf.write('    <taz id="%s" edges="%s"/>\n' % (
                taz.getID(), ' '.join(sorted([e.getID() for e in edges]))))
        outf.write('</tazs>\n')
    return net

if __name__ == "__main__":
    options = parse_args()
    main(options.net, options.outfile, options.radius,
         options.travel_distance, options.symmetrical)


import cv2
from cvzone.HandTrackingModule import HandDetector
import numpy as np
import pyfirmata

cap = cv2.VideoCapture(0)

cap.set(3, 1280)
cap.set(4, 720)

if not cap.isOpened():
    print("Camera couldn't access")
    exit()

detector = HandDetector(detectionCon=0.7)

port = "COM7"
board = pyfirmata.Arduino(port)
servo_pinX = board.get_pin('d:5:s') #pin 5 Arduino
servo_pinY = board.get_pin('d:6:s') #pin 6 Arduino

x, y = 150, 230
w, h = 200, 200
col  = (255, 0, 255)

while cap.isOpened():
    success, img = cap.read()
    img = detector.findHands(img)
    lmList, bboxInfo = detector.findPosition(img)

    servoX = np.interp(x, [0, 1280], [0, 180])
    servoY = np.interp(y, [0, 720], [0, 180])

    if lmList:
        dist,_,_ = detector.findDistance(8, 12, img, draw = False)
        #print(dist)
        fingers = detector.fingersUp()
        if fingers[1] == 1 and fingers[2] == 1:
            cursor = lmList[8]
            if dist < 50:
                if x-w // 2 < cursor[0] < x+w-120 // 2 and y-h // 2 < cursor[1] < y+h-120 // 2:
                    col = (255, 255, 0)
                    x, y = cursor
                cv2.circle(img, cursor, 50, (255, 255, 0), cv2.FILLED)
                cv2.putText(img, "HOLD", (cursor[0]-40, cursor[1]), cv2.FONT_HERSHEY_COMPLEX,1,(0,0,255), 2)

            else:
                col = (255, 0, 255)

    cv2.rectangle(img, (x-w // 2, y-h // 2), (x+w // 2, y+h // 2), col, cv2.FILLED)
    cv2.putText(img, f'({str(x)}, {str(y)})', (x-90, y), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2)
    cv2.rectangle(img, (40,20), (350,110), (0,255,255), cv2.FILLED)
    cv2.putText(img, f'Servo X: {int(servoX)} deg', (50, 50), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 0), 2)
    cv2.putText(img, f'Servo Y: {int(servoY)} deg', (50, 100), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 0), 2)

    servo_pinX.write(servoX)
    servo_pinY.write(servoY)

    cv2.imshow("Image", img)
    cv2.waitKey(1)


#PCA => Principal componet analysis using HSI
import math
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.decomposition import KernelPCA

class princiapalComponentAnalysis:

    def __init__(self):
        pass

    def __str__(self):
        pass

    def pca_calculate(self,imagen_in,varianza = None,componentes = None):
        dataImagen = imagen_in.copy()
        if varianza != None :
            imageTemp = dataImagen.reshape((dataImagen.shape[0],dataImagen.shape[1]*dataImagen.shape[2])).T
            pca = PCA()
            pca.fit(imageTemp)
            imageTemp = pca.transform(imageTemp)
            #Evaluar el numero de coeficientes en base a los datos de varianza
            var = 0
            num_componentes = 0
            for i in range(pca.explained_variance_ratio_.shape[0]):
                var += pca.explained_variance_ratio_[i]
                if var > varianza:
                    break
                else:
                    num_componentes += 1
            imageTemp = imageTemp.reshape( (dataImagen.shape[1], dataImagen.shape[2],dataImagen.shape[0]) )
            imagePCA = np.zeros( (num_componentes, dataImagen.shape[1], dataImagen.shape[2]) )
            for i in range(imagePCA.shape[0]):
                imagePCA[i] = imageTemp[:,:,i]
        if componentes != None:
            imageTemp = dataImagen.reshape((dataImagen.shape[0],dataImagen.shape[1]*dataImagen.shape[2])).T
            c_pca = PCA(n_components=componentes)
            c_pca.fit(imageTemp)
            imageTemp = c_pca.transform(imageTemp)
            imageTemp = imageTemp.reshape( (dataImagen.shape[1], dataImagen.shape[2],imageTemp.shape[1]) )
            imagePCA = np.zeros( (componentes, dataImagen.shape[1], dataImagen.shape[2]) )
            for i in range(imagePCA.shape[0]):
                imagePCA[i] = imageTemp[:,:,i]
        return imagePCA

    def kpca_calculate(self, imagenInput, componentes = None):
        imagen_in = imagenInput.copy()
        #TOMA LA PORCION DE LA IMAGEN DE TAMAÑO W
        i = 0 #Indice x para la imagen
        j = 0 #Indice y para la imagen
        W = 50 #Tamaño de subconjunto 50  por indices
        fx_pc = 10 #Numero fijo de componentes
        n_componentes = 0 #Numero inicial de componentes principales

        for i in range(imagen_in.shape[1]): #Recorrer x
            i_l = i*W
            i_h = (i+1)*W
            if i_l >= imagen_in.shape[1]:
                break
            if i_h > imagen_in.shape[1]:
                i_h = imagen_in.shape[1]
            for j in range(imagen_in.shape[2]):  #Recorrer y
                j_l = j*W
                j_h = (j+1)*W
                if j_l >= imagen_in.shape[2]:
                    break
                if j_h > imagen_in.shape[2]:
                    j_h = imagen_in.shape[2]

                dataImagen = imagen_in[:, i_l:i_h, j_l:j_h]
                imageTemp = dataImagen.reshape((dataImagen.shape[0],dataImagen.shape[1]*dataImagen.shape[2])).T  #Reorganiza para aplicar KPCA
                #APLICA KPCA SOBRE TODOS LOS ELEMENTOS DIMENSIONALES
                kpca = KernelPCA( kernel='rbf' ) # n_components=None, gamma=0.01
                X_transformed = kpca.fit_transform(imageTemp)
                #Calcula el porcentaje de varianza de cada componente y el número de componentes a utilizar
                if componentes != None :
                    if n_componentes == 0:
                        n_componentes = componentes
                        ImagenOut = np.zeros( (n_componentes, imagen_in.shape[1], imagen_in.shape[2]) )
                else:
                    if n_componentes == 0:
                        sum_varianza = 0
                        varianza  = kpca.lambdas_/np.sum(kpca.lambdas_)
                        for v in range(varianza.shape[0]):
                            sum_varianza = sum_varianza+varianza[v]
                            if sum_varianza > 0.95:
                                break
                            else:
                                n_componentes += 1
                        if n_componentes < fx_pc:
                            print('pc find:'+str(n_componentes))
                            n_componentes = fx_pc
                            print('msn 1: fix number of PC used')
                        if n_componentes >  imagen_in.shape[0]/2:
                            print('pc find:'+str(n_componentes))
                            n_componentes = fx_pc
                            print('msn 2: fix number of PC used')
                        ImagenOut = np.zeros( (n_componentes, imagen_in.shape[1], imagen_in.shape[2]) )
                #RECUPERA EL NUMERO DE COMPONENTES NECESARIO
                imageTemp = X_transformed[:,0:n_componentes].reshape( (dataImagen.shape[1], dataImagen.shape[2],n_componentes) )
                imageKPCA = np.zeros( (n_componentes, dataImagen.shape[1], dataImagen.shape[2]) )
                # RECONTRUIR LA SALIDA EN LA FORMA DE LA IMAGEN DE ENTRADA
                for i in range(imageKPCA.shape[0]):
                    imageKPCA[i] = imageTemp[:,:,i]
                ImagenOut[:, i_l:i_h, j_l:j_h] = imageKPCA
        return ImagenOut

    def kpca2_calculate(self, imagen_in, componentes):
        dataImagen = imagen_in.copy()
        imageTemp = dataImagen.reshape((dataImagen.shape[0],dataImagen.shape[1]*dataImagen.shape[2])).T
        print(imageTemp.shape)
        kpca = KernelPCA(n_components=componentes, kernel='rbf', gamma=0.3)
        X_transformed = kpca.fit_transform(imageTemp)
        print(X_transformed.shape)
        imageTemp = X_transformed.reshape( (dataImagen.shape[1], dataImagen.shape[2],X_transformed.shape[1]) )
        imageKPCA = np.zeros( (componentes, dataImagen.shape[1], dataImagen.shape[2]) )
        for i in range(imageKPCA.shape[0]):
            imageKPCA[i] = imageTemp[:,:,i]
        return imageKPCA

    def graficarPCA(self,imagePCA, channel):
        plt.figure(1)
        plt.imshow(imagePCA[channel])
        plt.colorbar()
        plt.show()


import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import numpy as np
import pickle

with open("/home/ekin/Desktop/workspace/RotatetObjectDetectionReview/test_data/gt_area.pickle", 'rb') as handle:
    gt_area = pickle.load(handle)

np.sort(gt_area)
'''
plt.hist(gt_area, bins='auto', edgecolor='black')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Histogram of Data')
plt.grid(True)
plt.show()
'''

# Reshape the data to have a single feature dimension
data_reshaped = np.array(gt_area).reshape(-1, 1)

# Number of clusters
num_clusters = 6

# Perform K-means clustering
kmeans = KMeans(n_clusters=num_clusters)
kmeans.fit(data_reshaped)

# Get the cluster labels
labels = kmeans.labels_
cluster_centers = kmeans.cluster_centers_
print(np.sort(cluster_centers,axis = 0))

# Plot the scatter plot
plt.scatter(range(len(gt_area)), gt_area, c=labels, cmap='viridis')
plt.xlabel('Data Point')
plt.ylabel('Value')
plt.title('K-means Clustering')
plt.savefig("/home/ekin/Desktop/workspace/RotatetObjectDetectionReview/figures/area.png")


import functools
from typing import Callable, Union

from aiohttp import web

from .exceptions import AuthRequiredException, ForbiddenException, AuthException

def login_required(func):
    """
    If not authenticated user tries to reach to a `login_required` end-point
    returns UNAUTHORIZED response.
    """

    def wrapper(request):
        if not isinstance(request, web.Request):
            raise TypeError(f"Invalid Type '{type(request)}'")

        if not getattr(request, "user", None):
            return AuthRequiredException.make_response(request)
        return func(request)

    return wrapper

def permissions(
    *required_scopes: Union[set, tuple], algorithm="any"
) -> web.json_response:

    """
    Open the end-point for any user who has the permission to access.
    """
    assert required_scopes, "Cannot be used without any permission!"

    def request_handler(view: Callable) -> Callable:
        @functools.wraps(view)
        async def wrapper(request: web.Request):
            if not isinstance(request, web.Request):
                raise TypeError(f"Invalid Type '{type(request)}'")

            authenticator = request.app["authenticator"]
            try:
                provided_scopes = await authenticator.get_permissions(request)
                has_permission = await authenticator.check_permissions(
                    provided_scopes, required_scopes, algorithm=algorithm
                )

                if not has_permission:
                    raise ForbiddenException()

                return await view(request)

            except AuthException as e:
                return e.make_response(request)

        return wrapper

    return request_handler


import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import numpy as np

df = pd.read_csv('mail_data.csv')

# Data Preprocessing
df['Category'] = df['Category'].map({'spam': 0, 'ham': 1})

X = df['Message']
Y = df['Category']
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=3)

# Feature Extraction
feature_extraction = TfidfVectorizer(min_df=1, stop_words='english', lowercase=True)
X_train_features = feature_extraction.fit_transform(X_train)
X_test_features = feature_extraction.transform(X_test)

Y_train = Y_train.astype('int')
Y_test = Y_test.astype('int')

# Model Training
model = LogisticRegression()
model.fit(X_train_features, Y_train)

# Model Evaluation
prediction_on_training_data = model.predict(X_train_features)
accuracy_on_training_data = accuracy_score(Y_train, prediction_on_training_data)
print(f'Accuracy on Training Data: {accuracy_on_training_data}')

prediction_on_test_data = model.predict(X_test_features)
accuracy_on_test = accuracy_score(Y_test, prediction_on_test_data)
print(f'Accuracy on Test Data: {accuracy_on_test}')

# Input Mail Prediction
input_your_mail = ["Congratulations! You won 3000$ Walmart gift card. Go to http://bit.ly/123456 tp claim now."]

input_data_features = feature_extraction.transform(input_your_mail)
prediction = model.predict(input_data_features)

if prediction[0] == 1:
    print('Ham')
else:
    print('Spam')

print(prediction)


import itertools
import pandas as pd
import math
from pathlib import Path

def composite_SD(means, SDs, ncounts):
    '''Calculate combined standard deviation via ANOVA (ANalysis Of VAriance)
       See: http://www.burtonsys.com/climate/composite_standard_deviations.html
       Inputs are:
         means, the array of group means
         SDs, the array of group standard deviations
         ncounts, the array of number of samples in each group
       Result is the overall standard deviation.
    '''
    num_groups = len(means)
    if num_groups != len(SDs) or num_groups != len(ncounts):
        raise Exception('inconsistent list lengths')

    # calculate total number of samples, N, and grand mean, GM
    N = sum(ncounts)
    if N == 1:
        return SDs[0]
    GM = 0.0
    for i in range(num_groups):
        GM += means[i] * ncounts[i]
    GM /= N

    # calculate Error Sum of Squares
    ESS = 0.0
    for i in range(num_groups):
        ESS += ((SDs[i]) ** 2) * (ncounts[i] - 1)

    # calculate Total Group Sum of Squares
    TGSS = 0.0
    for i in range(num_groups):
        TGSS += ((means[i] - GM) ** 2) * ncounts[i]

    # calculate standard deviation as square root of grand variance
    result = math.sqrt((ESS + TGSS)/(N - 1))
    return result

def create_transunion_csv():
    """
    This python script is used to merge all the parquet data files into one
    single csv file. TransUnion data needs to be partitioned into 10 different
    csv files due to the memory limitation.
    """
    num_partition = 10
    data_dir = Path("data/transunion/")
    num_files = math.ceil(len(list(data_dir.glob("*.parquet"))) / num_partition)

    for i in range(num_partition):

        df = pd.concat(
            pd.read_parquet(parquet_file, engine="pyarrow")
            for parquet_file in itertools.islice(data_dir.glob("*.parquet"), i *
                                                num_files, (i + 1) * num_files))
        df.to_csv("data/transunion_{}.csv".format(i))

def expand_df(df, columns):
    """
    Parameters:
    ----------
    df: pd.series
    Each cell holds a 2d array.
    colums: list
    Column names for the expanded DataFrame.

    Return:
    -------
    A expanded DataFrame.
    """
    df = df.explode()
    df = df.apply(pd.Series)
    df.rename(columns=lambda x: columns[x], inplace=True)
    return df