# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals  # isort:skip

import logging

from collections import OrderedDict
# Biblioteca Padrao
from datetime import datetime

# Bibliotecas de terceiros
import re
import status
from braces.views import MultiplePermissionsRequiredMixin
from dal import autocomplete
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.core.exceptions import ObjectDoesNotExist
from django.urls import reverse_lazy, reverse
from django.db import transaction, models
from django.db.models import Q
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import redirect, get_object_or_404, render
from django.utils import timezone
import six
from django.utils.decorators import method_decorator
from django.views import generic
from django.views.decorators.cache import cache_page, never_cache
from django.views.generic import ListView, TemplateView, View
from django.views.generic.edit import UpdateView
from djdocuments.views.mixins import FormActionViewMixin
from constance import config

# Solar
from atividade_extraordinaria.models import AtividadeExtraordinariaTipo
from contrib.utils import validar_cpf, validar_cnpj
from defensor.models import Atuacao, Defensor, Documento as DocAtuacao
from defensor.forms import LotacaoForm, ExcluirAtuacaoForm
from meritocracia.models import IndicadorMeritocracia

# Modulos locais
from . import forms
from .models import (
    CEP,
    Area,
    Bairro,
    Comarca,
    Endereco,
    Estado,
    Municipio,
    Servidor,
    Util,
    Vara,
    Defensoria
)
from .services import buscar_servidor_api_athenas_e_ldap

logger = logging.getLogger(__name__)

@login_required
def busca_rapida(request):

    filtro_texto = request.GET.get('filtro', '').strip()
    filtro_numero = re.sub('[^0-9]', '', filtro_texto)
    filtro_cpf = False

    # Verifica se número é um CPF/CNPJ válido
    if len(filtro_numero) == 11 and validar_cpf(filtro_numero):
        filtro_cpf = True
    elif len(filtro_numero) == 14 and validar_cnpj(filtro_numero):
        filtro_cpf = True

    if filtro_numero and not filtro_cpf and len(filtro_numero) != 12:
        resposta = redirect('{}?filtro={}'.format(reverse('processo_listar'), filtro_numero))
    else:
        resposta = redirect('{}?filtro={}'.format(reverse('atendimento_buscar'), filtro_texto))

    return resposta

@login_required
def listar_defensorias(request):

    agora = datetime.now()

    defensorias = Defensoria.objects.filter(ativo=True).order_by('nucleo', 'comarca', 'numero')

    resposta = []
    for defensoria in defensorias:

        obj = Util.object_to_dict(defensoria, {})
        obj['atuacoes'] = []

        atuacoes = defensoria.all_atuacoes.filter(
            Q(ativo=True) &
            Q(data_inicial__lte=agora) &
            (
                Q(data_final__gte=agora) |
                Q(data_final=None)
            )
        ).values(
            'defensor__servidor__nome',
            'data_inicial',
            'data_final',
            'tipo',
            'documento__tipo',
            'documento__numero',
            'documento__data',
        )

        for atuacao in atuacoes:
            tipo = None
            if not atuacao['documento__tipo'] is None:
                tipo = DocAtuacao.LISTA_TIPO[atuacao['documento__tipo']][1]
            documento = {
                'tipo': tipo,
                'numero': atuacao['documento__numero'],
                'data': atuacao['documento__data'],
            }

            if documento['tipo'] and documento['numero'] and documento['data']:
                documento['nome'] = '{tipo} {numero} de {data:%d/%m/%Y}'.format(**documento)

            obj['atuacoes'].append({
                'defensor': atuacao['defensor__servidor__nome'],
                'data_inicial': Util.date_to_json(atuacao['data_inicial']),
                'data_final': Util.date_to_json(atuacao['data_final']),
                'tipo': atuacao['tipo'],
                'documento': documento,
            })

        resposta.append(obj)

    return JsonResponse(resposta, safe=False)

@login_required
def get_defensoria(request, defensoria_id):
    defensoria = get_object_or_404(Defensoria, id=defensoria_id)
    agora = datetime.now()

    defensores = defensoria.all_atuacoes.filter(
        Q(data_inicial__lte=agora) &
        (
            Q(data_final__gte=agora) |
            Q(data_final=None)
        ) &
        Q(ativo=True)
    ).order_by(
        'defensor__servidor__nome'
    ).values_list(
        'defensor_id',
        'defensor__servidor_id',
        'defensor__servidor__nome',
        'defensor__eh_defensor'
    ).distinct()

    resposta = Util.object_to_dict(defensoria, {})
    resposta['defensores'] = [
        {
            'id': d[0],
            'servidor': d[1],
            'nome': d[2],
            'eh_defensor': d[3]
        } for d in defensores]

    # se a defensoria está vinculada a um núcleo, recupera qualificacoes relacionadas (apenas para tarefas)
    if defensoria.nucleo:
        qualificacoes = defensoria.nucleo.qualificacao_set.ativos().tarefas()
        resposta['qualificacoes'] = [
            Util.object_to_dict(qualificacao, {}) for qualificacao in qualificacoes
        ]
    else:
        resposta['qualificacoes'] = []

    return JsonResponse(resposta)

class DefensoriaListView(ListView):
    queryset = Defensoria.objects.ativos().select_related(
        'comarca__coordenadoria',
        'predio'
    ).order_by(
        'comarca__nome',
        'numero',
        'nome'
    )
    model = Defensoria
    paginate_by = 50
    template_name = "contrib/defensoria_buscar.html"

    def get_context_data(self, **kwargs):
        context = super(DefensoriaListView, self).get_context_data(**kwargs)
        context.update({
            'form': forms.BuscarDefensoriaForm(self.request.GET)
        })
        return context

    def get_queryset(self):

        queryset = super(DefensoriaListView, self).get_queryset()
        q = Q()

        if not self.request.user.has_perm('contrib.view_all_defensorias'):

            if hasattr(self.request.user.servidor, 'defensor') and self.request.user.servidor.defensor.ativo:
                defensorias_ids = list(self.request.user.servidor.defensor.defensorias.values_list('id', flat=True))
                defensorias_ids += list(Defensoria.objects.filter(mae__in=defensorias_ids).values_list('id', flat=True))
                q &= Q(id__in=defensorias_ids)
            else:
                q &= Q(comarca=self.request.user.servidor.comarca)

        form = forms.BuscarDefensoriaForm(self.request.GET)

        if form.is_valid():

            data = form.cleaned_data

            # Filtro por comarca
            if data.get('comarca'):
                q &= Q(comarca=data.get('comarca'))

            # Filtro por nome
            if data.get('filtro'):
                q &= Q(nome__icontains=data.get('filtro'))

        return queryset.filter(q)

class DefensoriaUpdateView(UpdateView):
    model = Defensoria
    pk_url_kwarg = 'defensoria_id'
    template_name = 'contrib/defensoria_cadastrar.html'
    form_class = forms.EditarDefensoriaForm

    def form_valid(self, form):
        self.object = form.save(commit=False)

        # Se usuário tem permissão, salva tipos de eventos associados à defensoria
        if self.request.user.has_perm('contrib.change_defensoriatipoevento'):

            form_tipos_eventos = forms.EditarDefensoriaTiposEventosForm(data=self.request.POST, instance=self.object)

            if form_tipos_eventos.is_valid():
                self.object = form_tipos_eventos.save(commit=False)

        self.object.save()
        return super().form_valid(form)

    def get_success_url(self):
        messages.success(self.request, u'Registro salvo com sucesso!')
        return '{}?prev={}'.format(reverse('defensoria_editar', kwargs={'defensoria_id': self.object.id}), self.request.GET.get('prev'))

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        context.update({
            'form_tipos_eventos': forms.EditarDefensoriaTiposEventosForm(instance=self.object),
            'prev': self.request.GET.get('prev', reverse('defensoria_buscar')),
            'angular': 'CadastroTelefoneCtrl',
            'telefone': self.object.telefone
        })

        return context

class DefensoriaTipoEventoUpdateView(TemplateView):
    template_name = 'contrib/defensoria_associar_tipos_eventos.html'
    form_class = forms.EditarDefensoriaTiposEventosForm

    def get_context_data(self, **kwargs):

        # Recupera lista de defensorias
        defensorias = Defensoria.objects.filter(id__in=self.request.GET.getlist('defensoria'))
        # Recupera lista de tipos de eventos já associados às defensorias selecionadas
        tipos_eventos = AtividadeExtraordinariaTipo.objects.ativos().filter(
            defensorias__in=defensorias
        )

        context = super().get_context_data(**kwargs)

        context.update({
            'form': self.form_class(initial={'tipos_eventos': tipos_eventos}),
            'defensorias': defensorias
        })

        return context

    def post(self, request, *args, **kwargs):

        defensorias = Defensoria.objects.filter(id__in=self.request.POST.getlist('defensoria'))

        for defensoria in defensorias:
            form = self.form_class(data=request.POST, instance=defensoria)
            if form.is_valid():
                form.save()

        messages.success(request, u'Registros salvos com sucesso!')

        return self.get(request, *args, **kwargs)

def cep_to_json_response(cep):
    # gera dicionario com dados do cep
    data = Util.object_to_dict(cep, {})
    data['estado_id'] = cep.municipio.estado.id
    data['municipio_id'] = cep.municipio.id

    if cep.bairro:
        data['bairro'] = cep.bairro.nome
        data['bairro_id'] = cep.bairro.id

    return JsonResponse(data)

@login_required
def get_endereco_by_cep(request, numero):
    from pycep_correios import get_address_from_cep, exceptions, WebService

    """
    Recupera informacoes de endereco a partir do CEP informado
    :param request:
    :param val:
    :return:
    """

    if len(numero) != 8:
        return JsonResponse({'erro': True, 'msg': 'O cep {} está mal formatado'.format(numero)})

    # Verifica se o CEP já existe no banco de dados
    cep = CEP.objects.filter(cep=numero).first()

    # Se não encontrado ou expirado, faz busca nos Correios
    if (cep is None or cep.expirado):

        try:
            data = get_address_from_cep(numero)
        # Caso o CEP aponte como invalido, testa com um segundo webservice
        except exceptions.InvalidCEP:
            try:
                data = get_address_from_cep(numero, webservice=WebService.VIACEP)
            except exceptions.InvalidCEP:
                return JsonResponse({
                    'erro': True,
                    'servico_disponível': True,
                    'msg': 'Erro ao consultar o CEP {} no serviço externo: número inválido'.format(numero)
                })
        except exceptions.CEPNotFound:
            return JsonResponse({
                'erro': True,
                'servico_disponível': True,
                'msg': 'Erro ao consultar o CEP {} no serviço externo: não encontado'.format(numero)
            })
        except Exception as e:
            # Se serviço indisponível retorna dados salvos
            if cep:
                return cep_to_json_response(cep)
            # Se não tiver dados salvos, retorna erro
            else:
                return JsonResponse({
                    'erro': True,
                    'servico_disponível': False,
                    'msg': 'Erro ao consultar o CEP {} no serviço externo: {}'.format(numero, str(e))
                })

        municipio = None
        bairro = None

        # Procura por Município
        try:
            municipio = Municipio.objects.get(
                estado__uf=data['uf'],
                nome__unaccent__iexact=Util.normalize(data['cidade'])
            )
        except ObjectDoesNotExist:
            # O erro pode ocorrer caso o município tenha mudado de nome
            msg = 'Erro ao cadastrar o cep {}: município {} - {} não encontado'.format(numero, data['cidade'], data['uf'])  # noqa: E501
            logger.error(msg)
            return JsonResponse({'erro': True, 'msg': msg})

        # Se informado, procura ou cadastra Bairro
        if data['bairro']:
            try:
                bairro, _ = Bairro.objects.get_or_create(
                    municipio=municipio,
                    nome__unaccent__iexact=Util.normalize(data['bairro']),
                    desativado_em=None,
                    defaults={
                        # necessário por ter usado uma func no get_or_create para esse field
                        'nome': data['bairro']
                    }
                )
            except Bairro.MultipleObjectsReturned:
                bairro = Bairro.objects.filter(
                    municipio=municipio,
                    nome__unaccent__iexact=Util.normalize(data['bairro']),
                    desativado_em=None
                ).first()

        # Cria/atualiza cadastro do CEP
        cep, _ = CEP.objects.update_or_create(
            cep=numero,
            defaults={
                'municipio': municipio,
                'bairro': bairro,
                'logradouro': data['logradouro'],
                'complemento': data['complemento'],
                'eh_geral': False
            }
        )

    return cep_to_json_response(cep)

@login_required
def listar_bairro(request, municipio_id):
    lst = Bairro.objects.filter(
        municipio=municipio_id
    ).order_by(
        'nome'
    ).distinct(
        'nome'
    ).values_list(
        'nome',
        flat=True
    )
    return JsonResponse(list(lst), safe=False)

@login_required
def listar_diretoria(request):
    diretorias = OrderedDict()

    for i in Comarca.objects.coordenadorias().ativos().order_by('nome'):

        comarcas = []
        for j in i.comarcas():
            comarcas.append({'id': j.id, 'nome': j.nome})
        diretorias.update({i.nome: {'id': i.id, 'nome': i.nome, 'comarcas': comarcas}})

    return JsonResponse(diretorias)

@login_required
def listar_indicadores_meritocracia(request):
    indicadores = []

    for area in IndicadorMeritocracia.objects.filter(ativo=True):
        indicadores.append({
            'id': area.id,
            'nome': area.nome,
            'ativo': area.ativo
            })

    return JsonResponse(list(indicadores), safe=False)

@login_required
def listar_logradouro(request, municipio_id):
    lst = Endereco.objects.filter(
        municipio=municipio_id
    ).distinct(
        'logradouro'
    ).order_by(
        'logradouro'
    ).values_list(
        'logradouro',
        flat=True
    )
    return JsonResponse(list(lst), safe=False)

@login_required
def listar_municipio(request):
    lst = Municipio.objects.all().order_by('nome').values_list('nome', flat=True)
    return JsonResponse(list(lst), safe=False)

@login_required
@cache_page(60 * 60 * 24 * 7)  # 7 dias
def listar_municipio_uf(request, estado_id):
    arr = []

    lst = Municipio.objects.select_related('comarca__coordenadoria').filter(estado=estado_id).order_by('nome')
    for i in lst:
        arr.append({
            'id': i.id,
            'nome': i.nome,
            'comarca': {
                'nome': i.comarca.nome,
                'diretoria': i.comarca.coordenadoria.nome if i.comarca.coordenadoria else i.comarca.nome
            } if i.comarca else None,
        })

    return JsonResponse(arr, safe=False)

@login_required
@cache_page(60 * 60 * 24 * 7)  # 7 dias
def listar_estado(request):
    arr = []
    lst = Estado.objects.all().order_by('nome')
    for i in lst:
        arr.append({'id': i.id, 'nome': i.nome, 'uf': i.uf})

    return JsonResponse(arr, safe=False)

@login_required
def listar_area(request):
    arr = []
    for area in Area.objects.filter(ativo=True):
        arr.append({
            'id': area.id,
            'nome': area.nome,
            'ativo': area.ativo})

    return JsonResponse(arr, safe=False)

@login_required
def listar_vara(request):

    varas = Vara.objects.filter(
        ativo=True
    ).extra(
        select={'numero': 'CAST(SUBSTRING(nome FROM \'[0-9]+\') AS INTEGER)'}
    ).order_by(
        'numero', 'nome'
    )

    arr = []
    for vara in varas:
        arr.append({
            'id': vara.id,
            'nome': vara.nome,
            'comarca': vara.comarca_id,
            'grau': vara.grau,
        })

    return JsonResponse(arr, safe=False)

def remove_acentos(data):
    """
    Remove acentos de strings unicode ex: u'ção' = u'cao'
    :param data:
    :return:
    """

    import string
    import unicodedata

    return ''.join(x for x in unicodedata.normalize('NFKD', data) if x in string.ascii_letters).lower()

class BuscarServidorListView(ListView):
    template_name = "contrib/listar_servidor.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        context.update({
            'total_ativos': self.get_queryset().filter(ativo=True).count(),
            'total_inativos': self.get_queryset().filter(ativo=False).count(),
            'form': forms.BuscarServidorForm(self.request.GET),
        })

        return context

    def get_queryset(self):

        qs = Servidor.objects.none()
        form = forms.BuscarServidorForm(self.request.GET)

        # Só filtra se valores de busca forem válidos
        if form.is_valid():

            qs = Servidor.objects.filter(uso_interno=False).order_by('-ativo', '-usuario__is_superuser', 'nome')

            if not self.request.user.is_superuser:
                qs = qs.filter(usuario__is_superuser=False)

            data = form.cleaned_data

            if data.get('comarca'):
                qs = qs.filter(comarca=data.get('comarca'))

            if data.get('papel'):
                qs = qs.filter(papel=data.get('papel'))

            for nome in data.get('nome', '').split():
                qs = qs.filter(
                    Q(nome__unaccent__icontains=nome)
                    | Q(matricula__icontains=nome)
                    | Q(usuario__username__icontains=nome)
                )

        return qs

@never_cache
@login_required
def listar_servidor_json(request):
    """Utilizado para buscar servidores em Itinerante e em Relatórios"""

    servidores_queryset = Servidor.objects.filter(
        ativo=True,
    ).values_list(
        'id',
        'nome',
        'defensor__ativo',
        'defensor__supervisor__servidor',
        'uso_interno'
    ).order_by('nome')

    servidores = []

    for servidor in servidores_queryset:
        servidores.append({
            'id': servidor[0],
            'nome': servidor[1],
            'defensor': True if servidor[2] else False,
            'supervisor': servidor[3] if servidor[2] else None,
            'uso_interno': servidor[4]
        })

    return JsonResponse(servidores, safe=False)

@login_required
def listar_servidor_por_atuacao_json(request, defensoria_id):
    queryset = Q(defensoria_id=defensoria_id)

    cargo_id = request.GET.get('cargo_id')

    if cargo_id:
        queryset &= Q(cargo_id=cargo_id)

    vigente = True

    if request.GET.get('vigente'):
        vigente = request.GET.get('vigente')

    queryset &= Q(ativo=vigente)

    atuacoes = Atuacao.objects.filter(queryset).values('defensor__servidor__id',
                                                       'defensor__servidor__nome',
                                                       'cargo_id'
                                                       )

    servidores = []

    for atuacao in atuacoes:
        servidores.append({
            'servidor_id': atuacao['defensor__servidor__id'],
            'nome': atuacao['defensor__servidor__nome'],
            'cargo_id': atuacao['cargo_id']
        })

    return JsonResponse(servidores, safe=False)

@never_cache
@login_required
@permission_required('contrib.change_servidor')
def perfil_servidor(request, servidor_id):

    servidor = Servidor.objects.get(usuario_id=servidor_id, uso_interno=False)

    if hasattr(servidor, 'defensor') and servidor.defensor.eh_defensor:
        assessores = servidor.defensor.lista_assessores
    else:
        assessores = None

    return render(request=request, template_name="contrib/perfil_servidor.html", context=locals())

@never_cache
@login_required
@permission_required('contrib.change_servidor')
def editar_servidor(request, servidor_id, lotacao_id=None):

    servidor = get_object_or_404(Servidor, usuario_id=servidor_id, uso_interno=False)

    if hasattr(servidor, 'defensor'):
        lotacoes = servidor.defensor.atuacoes().select_related(
            'defensoria',
            'cadastrado_por__usuario'
        )
    else:
        lotacoes = Atuacao.objects.none()

    if lotacao_id:
        lotacao = get_object_or_404(Atuacao, id=lotacao_id, ativo=True)
        form_excluir_lotacao = ExcluirAtuacaoForm(instance=lotacao, initial={'data_final': datetime.now().date})

    if request.POST:

        formulario = forms.ServidorForm(request.POST, instance=servidor)

        if formulario.is_valid():
            with transaction.atomic():
                servidor = formulario.save(commit=False)
                servidor.nome = servidor.usuario.get_full_name()
                servidor.save()

                servidor.usuario.is_active = servidor.ativo
                servidor.usuario.save(update_fields=['is_active'])

                # desativa as atuações de servidor caso seja inativado
                if not servidor.usuario.is_active:
                    if servidor.defensor and not servidor.defensor.eh_defensor:
                        for lotacao in lotacoes:
                            lotacao.ativo = False
                            lotacao.data_final = timezone.now()
                            lotacao.save(update_fields=['ativo', 'data_final'])

        return HttpResponseRedirect(reverse_lazy('perfil_servidor', kwargs={'servidor_id': servidor_id}))

    else:

        form = forms.ServidorForm(instance=servidor)
        url_voltar = request.META.get('HTTP_REFERER', '/')

        if hasattr(servidor, 'defensor') and not servidor.defensor.eh_defensor:
            form_lotacao = LotacaoForm(prefix='lotacao', instance=Atuacao(defensor=servidor.defensor))

        return render(request=request, template_name="contrib/editar_servidor.html", context=locals())

@login_required
def foto_servidor_pelo_username(request, username):
    try:
        servidor = Servidor.objects.get(usuario__username=username, uso_interno=False)
    except Exception:
        servidor = Servidor()

    return redirect(servidor.get_foto())

class DefensorSupervisorAutocomplete(autocomplete.Select2QuerySetView):
    """
    Autocomplete view to Django User Based
    """

    @method_decorator(never_cache)
    def dispatch(self, request, *args, **kwargs):
        return super(DefensorSupervisorAutocomplete, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        # Don't forget to filter out results depending on the visitor !
        # if not self.request.user.is_authenticated:
        #     return USER_MODEL.objects.none()
        # assinado_por = self.forwarded.get('assinado_por', None)

        qs = Defensor.objects.filter(supervisor=None, eh_defensor=True, ativo=True).order_by('servidor__nome')

        if self.q:
            qs = qs.filter(Q(servidor__nome__icontains=self.q))

        return qs

    def get_result_label(self, result):
        return result.servidor.nome

class CadastrarServidorView(MultiplePermissionsRequiredMixin, FormActionViewMixin, generic.CreateView):
    model = Servidor
    document_json_fields = ('nome', 'usuario.username')
    form_class = forms.SolarUserCreationForm
    template_name = 'contrib/criar_usuario_solar.html'
    ajax_success_message = None
    form_action = reverse_lazy('criar_usuario_solar')
    raise_exception = True
    permissions = {
        "all": ("contrib.add_servidor",),
        "any": None
    }

    @method_decorator(never_cache)
    def dispatch(self, request, *args, **kwargs):
        return super(CadastrarServidorView, self).dispatch(request, *args, **kwargs)

    def get_ajax_success_message(self, object_instance=None):
        return self.ajax_success_message

    def post(self, request, *args, **kwargs):
        with transaction.atomic():
            return super(CadastrarServidorView, self).post(request, *args, **kwargs)

    def get_success_url(self):
        url = None
        if self.object:
            usuario_pk = self.object.usuario_id
            url = reverse('editar_servidor', kwargs={'servidor_id': usuario_pk})
        return url

    def get_context_data(self, **kwargs):
        context = super(CadastrarServidorView, self).get_context_data(**kwargs)
        context['form_cpf_nome'] = forms.NomeCompletoCPFForm()
        context['angular'] = "CadastroServidorCtrl"
        return context

    def form_valid(self, form):
        response = super(CadastrarServidorView, self).form_valid(form)
        if self.request.is_ajax():
            # object_dict = model_to_dict(self.object, fields=[field.name for field in self.object._meta.fields])
            # object_instance = object_dict
            dados_instancia = {
                'nome': self.object.nome,
                'username': self.object.usuario.username,
                'email': self.object.usuario.email,
                'id': self.object.usuario_id,
                'enviar_email_ao_cadastrar_servidor': config.ENVIAR_EMAIL_AO_CADASTRAR_SERVIDOR,
            }
            data = {'object_instance': dados_instancia, 'errors': None,
                    'success_url': self.get_success_url(), 'pode_cadastrar': True}
            message = self.get_ajax_success_message(self.object)
            if message:
                messages.add_message(self.request, messages.SUCCESS, message)
            return JsonResponse(data=data)
        return response

    def get_form_fields(self):
        fields = self.document_json_fields
        if not fields:
            form = self.get_form()
            fields = six.iterkeys(form.fields)
        return fields

    def get_object_members(self):
        data = {}
        if hasattr(self, 'object'):
            if self.object:
                for field in self.get_form_fields():
                    if hasattr(self.object, field):
                        field_instance = getattr(self.object, field)
                        if isinstance(field_instance, models.Model):
                            field_data = field_instance.pk
                        else:
                            field_data = field_instance
                        data[field] = field_data
        return data

    def form_invalid(self, form):
        response = super(CadastrarServidorView, self).form_invalid(form)
        if self.request.is_ajax():
            data = {'errors': form.errors, 'success_url': self.get_success_url(), 'pode_cadastrar': True}
            # members = self.get_object_members()
            return JsonResponse(data=data, status=status.HTTP_400_BAD_REQUEST)
        return response

class ConsultarAthenasView(View):
    http_method_names = ['post']

    @method_decorator(never_cache)
    def dispatch(self, request, *args, **kwargs):
        return super(ConsultarAthenasView, self).dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        # if request.is_ajax():
        #     POST = simplejson.loads(request.body)
        # else:
        POST = self.request.POST

        cpf_matricula = POST.get('cpf_matricula')
        nome_completo = POST.get('nome_completo')
        dados = buscar_servidor_api_athenas_e_ldap(cpf_matricula, nome_completo)
        dados['pode_cadastrar'] = True
        if dados['errors']['__all__'] or dados['botoes']:
            dados['pode_cadastrar'] = False

        return JsonResponse(data=dados)

    def put(self, *args, **kwargs):
        return super(ConsultarAthenasView, self).post(*args, **kwargs)


"""
View for recipe api
"""

from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
# for the use of the permission we check from user before they use
from rest_framework.permissions import IsAuthenticated

from core.models import Recipe
from recipe import serializers

#Tag
#mixin is just things that we can add into view
from rest_framework import mixins
from core.models import Tag

#Ingredients
from core.models import Ingredient

#image
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response

#filter
from drf_spectacular.utils import (
    extend_schema_view,
    extend_schema,
    OpenApiParameter,
    OpenApiTypes,
)

#changing the open api parameter
@extend_schema_view(
    list=extend_schema(
        parameters=[
            OpenApiParameter(
                'tags',
                OpenApiTypes.STR,
                description='Comma separated list of tag IDs to filter',
            ),
            OpenApiParameter(
                'ingredients',
                OpenApiTypes.STR,
                description='Comma separated list of ingredient IDs to filter',
            ),
        ]
    )
)

# ModelViewSet is use the direct interact with a model
class RecipeViewSet(viewsets.ModelViewSet):
    """View for manage recipe api"""
    #the variable names below are not to be modified
    serializer_class = serializers.RecipeDetailSerializer
    # the objects that are avaible for this view set
    queryset = Recipe.objects.all()
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    #recieving filter arguments as a list of ids, comma seperated
    def _params_to_ints(self, qs):
        'convert a list of string to intergers'
        return [int(str_id) for str_id in qs.split(',')]

    # override the orignal function to filter the queryset thats related to the user
    def get_queryset(self):
        """Retrieve recipes for authenticated user"""
        #user that is assigned with the request
        tags = self.request.query_params.get('tags')
        ingredients = self.request.query_params.get('ingredients')
        queryset = self.queryset
        if tags:
            tag_ids = self._params_to_ints(tags)
            queryset = queryset.filter(tags__id__in=tag_ids)
        if ingredients:
            ingredient_ids = self._params_to_ints(ingredients)
            queryset = queryset.filter(ingredients__id__in=ingredient_ids)

        return queryset.filter(
            user=self.request.user
        ).order_by('-id').distinct()

    def get_serializer_class(self):
        "Return the serializer class for the request"
        #the minor defference of RecipeSerializer vs RecipeDetailSerializer
        #is when the action are requesting the list of recipes that are without detail
        #so we use RecipeSerializer .
        #where as if with detail than we use RecipeDetailSerializer
        if self.action == 'list':
            return serializers.RecipeSerializer
        elif self.action == 'upload_image':
            return serializers.RecipeImageSerializer

        return self.serializer_class

    def perform_create(self, serializer): #we override the create method of django
        "create a new recipe"
        #when we create a new recipe through the create feature of the view,
        #it's going to call this function
        serializer.save(user=self.request.user)

    @action(methods=['POST'], detail=True, url_path='upload-image')
    def upload_image(self, request, pk=None):
        """Upload an image to recipe."""
        recipe = self.get_object()
        serializer = self.get_serializer(recipe, data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@extend_schema_view(
    list=extend_schema(
        parameters=[
            OpenApiParameter(
                'assigned_only',
                OpenApiTypes.INT, enum=[0, 1],
                description='Filter by items assigned to recipes.',
            ),
        ]
    )
)

#tag => using viewset; viewset can provide simple CRUD
#GenericViewSet must be the last inheritance
#mixins.UpdateModelMixin => we can update the tags
#mixins.DestroyModelMixin => we can delete the tags
class BaseRecipeAttrViewSet(mixins.DestroyModelMixin,
                            mixins.UpdateModelMixin,
                            mixins.ListModelMixin,
                            viewsets.GenericViewSet):
    """Base viewset for recipe attributes."""
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        "Filter queryset to authenticated user"
        assigned_only = bool(
            int(self.request.query_params.get('assigned_only', 0))
        )
        queryset = self.queryset
        #assign_only = true than
        if assigned_only:
            queryset = queryset.filter(recipe__isnull=False)

        return queryset.filter(
            user=self.request.user
        ).order_by('-name').distinct()

class TagViewSet(BaseRecipeAttrViewSet):
    'Manage tags in the database'
    serializer_class=serializers.TagSerializer
    queryset = Tag.objects.all()

class IngredientViewSet(BaseRecipeAttrViewSet):
    'manage ingredients in the database'
    serializer_class=serializers.IngredientSerializer
    queryset = Ingredient.objects.all()


from django.conf.urls.defaults import patterns, url
from fashion.feeds import FashionFeed, FashionByTagFeed

urlpatterns = patterns('fashion.views',
    url('^$', 'fashion_list', name='fashion_list'),
    url('^(?P<slug>[-\w]+)/$', 'fashion_detail', name='fashion_detail'),
    url('^tag/(?P<tag_slug>[-\w]+)/$', 'fashion_list', name='fashion_tag_list'),
)

#Feeds
urlpatterns+= patterns('',
    url('^rss/$', FashionFeed(), name='fashion_feed'),
    url('^rss/(?P<tag_slug>[-\w]+)/$', FashionByTagFeed(), name='fashion_tag_feed'),
)


import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# Reading CSV file with data and looking at it's header to understand which values do we have to work with

sheet_url = "https://docs.google.com/spreadsheets/d/16i38oonuX1y1g7C_UAmiK9GkY7cS-64DfiDMNiR41LM/edit#gid=0"
csv_url = sheet_url.replace("/edit#gid=", "/export?format=csv&gid=")
data = pd.read_csv(csv_url)
print(data.head())

# Looking at summary statistics for given dataset:

print(data.describe())

# To take closer look at outliers in order_amount column, let's plot the data.
# As we can see below, there are quite a few outliers in our dataset.

sns.set_style('darkgrid')
sns.boxplot(data=data, x='order_amount')
plt.title('Order amount distribution, uncleaned data')
plt.show()

# Adding a column with item price, to find any overpriced items.
# As we can see, maximum item value is 25725.00, which is way above median value of 153.00 and does not seam right,
# knowing, that all the shops are selling sneakers.

data['item_price'] = data.order_amount / data.total_items
print(data['item_price'].describe())

# Let's take a look at item prices without 25725.00 outlier.
# We can see, that there is still one item with a price outside of of our range (around 350.00).
# But as this outlier has not an absurdly high price, we can leave it as a part of our analysis,
# because it can be some very specific shoe type, like runner shoe for the long distances, that is
# using innovative technologies or very unique designer shoes.
plt.clf()
sns.set_style('darkgrid')
sns.boxplot(data=data.item_price[data.item_price < 25000])
plt.title('Item price distribution, below 25K')
plt.show()

# Let's find out, who made the highest value purchases.
# Below we can see, that all maximum orders where placed by user #607 in shop #42 with total items
# in one order 2000 pieces at 4:00 AM. That should be counted as an outlier, because such customer behaviour
# is not common and can not be counted in our statistical analysis, as is skewing our data.

print(data[data.order_amount == data.order_amount.max()])

# Let's find out, what else was user #607 ordering.
# Only purchases made by user #607 where those, with maximum total amount,
# so we can remove this user from our data, to make more accurate statistical findings.

print(data[data.user_id == 607])

# What particular shops are selling the most expensive shoes:

print('Shops selling most expensive shoes: ', data.shop_id[data.item_price > 250].unique())

# Prices in most expensive shops:

print('Prices in most expensive shops: ', data[(data.shop_id == 42) | (data.shop_id == 78)].item_price.unique())

# As shop with id #78 sells unrealistically overpriced shoes (over 25000.00), has to be removed from our data for
# analysis. Let's take a look at another expensive shop #42. Here we can see, that all other users,
# except user #607 were ordering small amount of items. So we are deciding to leave data containing orders from this
# shop overall, but to remove orders, made by user with id #607.

print(data[data.shop_id == 42])

# Removing outliers, that we found earlier:
# shop with id #78 sells unrealistically overpriced shoes (over 25000.00);
# orders made by user #607, who was ordering same extremely large amounts of high priced items from the same shop.

data_cleaned = data[(data.shop_id != 78) & (data.user_id != 607)]
print(data_cleaned.describe())

# Plotting order amount distribution
plt.clf()
sns.set_style('darkgrid')
sns.boxplot(data=data_cleaned, x='order_amount')
plt.title('Order amount distribution')
plt.show()

# Printing some summary statistics for the cleaned from outliers data:

print('Average order amount: ', np.round(np.mean(data_cleaned.order_amount), 2), 'that lays between minimum of ',
      np.min(data_cleaned.order_amount), ' and maximum of ', np.max(data_cleaned.order_amount), '.')
print('Average order contained: ', np.round(np.mean(data_cleaned.total_items)),
      ' items, with maximum ordered items per single order being ', np.max(data_cleaned.total_items), '.')
print('Average item price is: ', np.round(np.mean(data_cleaned.item_price), 2), ' in range from ',
      np.min(data_cleaned.item_price), ' to ', np.max(data_cleaned.item_price), '.')

# Plotting total orders by store distribution:

total_order_amount_by_store = data_cleaned.groupby('shop_id').order_amount.sum()

plt.clf()
sns.set_style('darkgrid')
sns.violinplot(x=total_order_amount_by_store)
plt.title('Total order amount by store')
plt.show()

print('Average total order amount for one shop is: ', np.round(total_order_amount_by_store.mean(), 2))
print('Minimum total order amount for one shop is: ', data_cleaned.groupby('shop_id').order_amount.sum().min())
print('Maximum total order amount for one shop is: ', data_cleaned.groupby('shop_id').order_amount.sum().max())

# Plotting sales count by shop(how many orders each shop made):
plt.clf()
plt.plot(data_cleaned.groupby('shop_id').count()['order_id'])
plt.title('Order count by shop')
plt.xlabel('Shop id')
plt.ylabel('Total orders count')
plt.show()

# We can see below, that shop #53 made 68 sales, which is maximum within shops in our data,
# while shop #42 made a minimum of 34 sales. Average sales count for one shop is: 50.0

order_count = data_cleaned.groupby('shop_id').count()['order_id'].reset_index().sort_values(['order_id'],
                                                                                ascending=False).rename(
    columns={'order_id': 'sales_count'})
print(order_count)
print('Average sales count for one shop is: ', np.round(np.mean(order_count.sales_count)))

# We can see below, that shop #13 sold 136 pairs, which is maximum within shops in our data,
# while shop #42 sold a minimal 63 pairs of sneakers. Average sold items total for one shop is: 99.0 pairs of shoes.

shop_items_total = data_cleaned.groupby('shop_id').sum()['total_items'].reset_index().sort_values(['total_items'],
                                                                                ascending=False)
print(shop_items_total)
print('Average sold items total for one shop is: ', np.round(np.mean(shop_items_total.total_items)), 'pairs of shoes.')

# From scatter plot below, we can see, that middle priced sneakers were sold the most.
# But there is no strong relationship between price increase and sales increase.

sales_by_price = data_cleaned.groupby('item_price').total_items.sum().reset_index().sort_values(['item_price'])

plt.clf()
sns.scatterplot(x=sales_by_price.item_price, y=sales_by_price.total_items)
plt.title('Sold pairs by price')
plt.show()

# Finding customer, who ordered the most pairs of sneakers.
# Average customer ordered total of: 33.0 pairs of shoes in 30 days period,
# while customer #718 ordered total of 58 pairs, which is maximum within data.

customer_orders = data_cleaned.groupby('user_id').total_items.sum().reset_index().sort_values(['total_items'],
                                                                                ascending=False)
print(customer_orders)
print('Average customer ordered total of: ', np.round(np.mean(customer_orders.total_items)),
      'pairs of shoes in 30 days period.')

# Finding customer, who spent the most.
# Average customer spent total of: 4979.0 on sneakers in 30 days period,
# while customer #718 spent total of 8952.0, which is maximum within data.

customer_orders_amount = data_cleaned.groupby('user_id').order_amount.sum().reset_index().sort_values(['order_amount'],
                                                                                ascending=False)
print(customer_orders_amount)
print('Average customer spent total of: ', np.round(np.mean(customer_orders_amount.order_amount)),
      'on sneakers in 30 days period.')

# From plot below we can see, that more customers choose to pay with credit card, compared to debit and cash payments,
# but the difference is not significant.
plt.clf()
sns.countplot(data=data_cleaned, x='payment_method')
plt.title('Payment method distribution')
plt.xlabel('Payment method')
plt.ylabel('Orders')
plt.show()

# Changing type of data in column 'created_at' to datetime, adding new column with extracted hour of purchase and
# plotting orders by hour. We can see, that in 24 hour range more orders were placed at 3 and 7 AM, as well as 5 PM (
# 17:00), but there is no significant difference in order times.

data_cleaned.loc[:, 'created_at'] = data_cleaned.created_at.astype('datetime64[ns]')
data_cleaned.loc[:, 'order_time'] = data_cleaned['created_at'].dt.hour

plt.clf()
sns.countplot(x=data_cleaned['order_time'])
plt.title('Orders by hour')
plt.xlabel('Hour')
plt.ylabel('Order count')
plt.show()


import itertools
import collections
input_line=int(input())
s=[]
for i in range(input_line):
    line = input().rstrip().split(" ")
    line = list(map(int, line))
    start,end = line
    s.append(list(range(start,end+1)))
s=(list(itertools.chain.from_iterable(s)))
so_s=sorted(s)
# print(so_s)
c = collections.Counter(so_s)
# print(max(c.values()))
if max(c.values())==input_line:
    print("OK")
else:print("NG")

# print(s[0])
# for i in range(input_line):

    # if s[i] in s[i+1]:
    #     print("OK")
    # else:print("NG")


import os
import tempfile
import unittest
from unittest.mock import mock_open, patch

from .. import GetDataFailed, InvalidUser, SetDataFailed, UnsetDataFailed
from ..file import FileStorage

class TestFileStorage(unittest.TestCase):

    data = b'data'

    def get_filestorage(self):
        fs = FileStorage('data_dir')
        return fs

    @patch('pycred.storages.file.create_secure_file')
    @patch('pycred.storages.file.check_file_security')
    def test_get_data(self, create_mock, check_mock):
        with patch('builtins.open', new_callable=mock_open, read_data=self.data) as m:
            fs = self.get_filestorage()
            result = fs.get_data('user')
            m.assert_called_with('data_dir/user.dat', 'rb')
            self.assertEqual(self.data, result)

    @patch('pycred.storages.file.create_secure_directory')
    @patch('pycred.storages.file.create_secure_file')
    @patch('pycred.storages.file.check_file_security')
    def test_set_data(self, create_dir_mock, create_file_mock, check_mock):
        with patch('builtins.open', new_callable=mock_open) as m:
            fs = self.get_filestorage()
            fs.set_data('user', self.data)
            m.assert_called_with('data_dir/user.dat', 'wb')
            m().write.assert_called_with(self.data)

    def test_unset_data(self):
        with patch('os.unlink') as m:
            fs = self.get_filestorage()
            fs.unset_data('user')
            m.assert_called_with('data_dir/user.dat')

    @patch('pycred.storages.file.delete_unused_directory')
    def test_delete(self, delete_mock):
        fs = self.get_filestorage()
        fs.delete()
        delete_mock.assert_called_with('data_dir')

    @patch('pycred.storages.file.create_secure_file')
    @patch('pycred.storages.file.check_file_security')
    def test_get_data_raises_invaliduser_if_the_user_is_not_found(self, create_mock, check_mock):
        fs = self.get_filestorage()
        with self.assertRaises(InvalidUser):
            fs.get_data('user')

    @patch('pycred.storages.file.create_secure_file')
    @patch('pycred.storages.file.check_file_security')
    def test_get_data_raises_get_data_failed_for_permission_errors(self, create_mock, check_mock):
        with patch('builtins.open', side_effect=PermissionError()):
            fs = self.get_filestorage()
            with self.assertRaises(GetDataFailed):
                fs.get_data('user')

    @patch('pycred.storages.file.create_secure_file')
    @patch('pycred.storages.file.check_file_security')
    def test_set_data_raises_set_data_failed(self, create_mock, check_mock):
        fs = FileStorage('/invalid/random/path')
        with self.assertRaises(SetDataFailed):
            fs.set_data('user', self.data)

    def test_unset_data_raises_unset_data_failed(self):
        fs = FileStorage('data_dir')
        with patch('os.unlink', side_effect=PermissionError()):
            with self.assertRaises(UnsetDataFailed):
                fs.unset_data('user')

    def test_get_users(self):
        fs = self.get_filestorage()
        with patch('glob.glob', return_value=['data_dir/user2.dat', 'data_dir/user1.dat']):
            users = fs.get_users()
        self.assertEqual(['user1', 'user2'], users)

    def test_storage_file_created_with_correct_permissions(self):
        with tempfile.TemporaryDirectory(prefix='pycred-') as d:
            user = 'user'
            fs = FileStorage(d)
            path = fs.get_path(user)
            self.assertFalse(
                os.path.isfile(path), "Failed precondition, file '{path}' exists".format(path=path))
            fs.set_data(user, self.data)
            # Contains self-checks for permissions on creation.
            assert os.path.isfile(path)

    def test_storage_file_with_incorrect_permissions_raise_exception(self):
        with tempfile.TemporaryDirectory(prefix='pycred-') as d:
            user = 'user'
            fs = FileStorage(d)
            path = fs.get_path(user)
            self.assertFalse(
                os.path.isfile(path), "Failed precondition, file '{path}' exists".format(path=path))
            with open(path, 'w+'):
                pass
            with self.assertRaises(GetDataFailed):
                fs.get_data(user)


import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.model_selection import RandomizedSearchCV
import pickle

df = pd.read_csv('./Data/winequality_red.csv')
print(df.head())

x = df.drop(columns=['quality'])
y = df['quality']

scaler = StandardScaler()
X_scaled = scaler.fit_transform(x)
# print(X_scaled)

x_train, x_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.25, random_state=355)

rfc = RandomForestClassifier()
rfc.fit(x_train, y_train)
y_pred = rfc.predict(x_test)

print("The Testing accuracy score is : ", accuracy_score(y_test, y_pred))
print("Confusion Matrix : ", confusion_matrix(y_test, y_pred))
print("Classification Report : ", classification_report(y_test, y_pred))

param_dist = {
    "n_estimators": range(100, 3000, 50),
    'criterion': ['gini', 'entropy'],
    'max_depth': range(2, 51, 1),
    'min_samples_leaf': range(1, 51, 1),
    'min_samples_split': range(2, 51, 1),
    'max_features': ['auto', 'log2']
}
randomized_search = RandomizedSearchCV(estimator=rfc, param_distributions=param_dist, n_iter=300, cv=7, random_state=160, n_jobs=-1, verbose=3)
randomized_search.fit(x_train, y_train)

print("After RandomizedSearch CV)")
print('Best Parameters : ', randomized_search.best_params_)
rfc_best = randomized_search.best_estimator_
print(f'rf_best:{rfc_best}')
y_pre = rfc_best.predict(x_test)
print("Accuracy Score :- ", accuracy_score(y_test, y_pre))
print("Confusion Matrix :- ", confusion_matrix(y_test, y_pre))
print("Classification Report :- ", classification_report(y_test, y_pre))

# with open('Final_ModelForPrediction.pkl', 'wb') as f:
#     pickle.dump(rfc_best,f)
# pickle.dump(scaler, open('scaler_model.pkl', 'wb'))

loaded_model = pickle.load(open('Final_ModelForPrediction.pkl', 'rb'))
scaler_model = pickle.load(open('scaler_model.pkl', 'rb'))
d=scaler_model.transform([[7, 0.8, 0.5, 12, 0.4, 50, 200, 0.9970, 3, 1.2, 13]])
pred=loaded_model.predict(d)
print('This data belongs to class :', pred[0])


import os
from dataclasses import dataclass
from diffusers import DiffusionPipeline, StableDiffusionUpscalePipeline
import torch

import opts
from constants import EMPTY_MODEL
from convert_checkpoint import convert_checkpoint

cache_path = os.path.join(os.path.dirname(__file__), 'cache')
ckpt_path = os.path.join(os.path.dirname(__file__), 'models')
editing_path = os.path.join(os.path.dirname(__file__), 'editing_cache')
for path in [cache_path, ckpt_path, editing_path]:
    os.makedirs(path, exist_ok=True)

def get_model_path(model_name):
    if model_name == EMPTY_MODEL:
        raise Exception(f'Cannot get model for {EMPTY_MODEL}')
    print('using model at path', os.path.join(cache_path, model_name)
          )
    return os.path.join(cache_path, model_name)

# def get_upscaler_choice():
#     dirs = [f for f in os.listdir(cache_path) if os.path.isdir(
#         os.path.join(cache_path, f))]
#     upscalers = [f for f in dirs if f.endswith('upscaler')]
#     return EMPTY_MODEL if len(upscalers) == 0 else upscalers[0]

def get_cache_models():
    dirs = [f for f in os.listdir(cache_path) if os.path.isdir(
        os.path.join(cache_path, f))]
    # print('opts', opts.global_opts)
    # upscalers = [f for f in dirs if f.endswith('upscaler')]
    return {
        'regular': [EMPTY_MODEL] + [f for f in dirs if not (f.endswith('inpainting') or f.endswith('upscaler'))],
        'inpainting': [EMPTY_MODEL] + [f for f in dirs if f.endswith('inpainting')],
        # 'upscalerChoice': get_upscaler_choice(),
        'regularChoice': opts.global_opts.regularChoice,
        'inpaintingChoice': opts.global_opts.inpaintingChoice,
        'outpaintingChoice': opts.global_opts.outpaintingChoice,
    }

def get_ckpts():
    return [EMPTY_MODEL] + [f for f in os.listdir(ckpt_path) if f.endswith('.ckpt')]

# create a dataclass called ModelDownload with the following fields:
# name: str
# url: str
# description: str

@dataclass
class ModelDownload:
    name: str
    save_name: str
    repo_id: str
    description: str

    def download(self):
        from dotenv import load_dotenv
        load_dotenv()
        if os.environ.get('HF_TOKEN', None) is None:
            print('hugging face token is required. set HF_TOKEN env var.')
            return
        print('Downloading model', self.name)
        # pipe_class = DiffusionPipeline if not self.repo_id.endswith(
        #     'upscaler') else StableDiffusionUpscalePipeline
        pipe_class = DiffusionPipeline
        try:
            pipe = pipe_class.from_pretrained(
                self.repo_id,
                torch_dtype=torch.float16,
                revision='fp16',
                use_auth_token=os.environ['HF_TOKEN'])
        except OSError:
            print('Error! Trying again without fp16 revision')
            pipe = pipe_class.from_pretrained(
                self.repo_id,
                torch_dtype=torch.float16,
                use_auth_token=os.environ['HF_TOKEN'])
        path = get_model_path(self.save_name)
        os.makedirs(path, exist_ok=True)
        print('Saving model to', path)
        pipe.save_pretrained(path)
        print('Done.')

downloads = [
    ModelDownload(
        name='SD2.1 - 512',
        save_name='sd2-1-512',
        repo_id="stabilityai/stable-diffusion-2-1-base",
        description='stabilityai/stable-diffusion-2-1-base: Stable Diffusion v2.1 model trained on 512x512 images. Good starting model.',
    ),
    ModelDownload(
        name='SD2 - 768',
        save_name='sd2-768',
        repo_id="stabilityai/stable-diffusion-2",
        description='stabilityai/stable-diffusion-2: Stable Diffusion v2 model trained on 768x768 images. For more powerful GPUs, this allows you to generate larger images with higher fidelity.',
    ),
    ModelDownload(
        name='SD2 - Inpainting',
        save_name='sd2-inpainting',
        repo_id="stabilityai/stable-diffusion-2-inpainting",
        description='stabilityai/stable-diffusion-2-inpainting: Stable Diffusion v2 model trained for inpainting and outpainting.',
    ),
    # ModelDownload(
    #     name='SD2 - Upscaler',
    #     save_name='sd2-upscaler',
    #     repo_id="stabilityai/stable-diffusion-x4-upscaler",
    #     description='Model specifically for upscaling. Download in order to use the upscaler.',
    # ),
]

def get_downloads():
    return [d.__dict__ for d in downloads]

def download_model(name):
    for d in downloads:
        if d.name == name:
            d.download()
            return True
    return False

def download_by_repo_id(save_name, repo_id):
    d = ModelDownload(
        name=save_name,
        save_name=save_name,
        repo_id=repo_id,
        description='Custom model',
    )
    d.download()

def convert_ckpt(save_name, ckpt_name, inpainting=False):
    pipe = convert_checkpoint(
        os.path.join(ckpt_path, ckpt_name),
        inpainting=inpainting,
    )
    path = get_model_path(save_name)
    print('Saving model to', path)
    pipe.save_pretrained(path)
    print('Done.')

def get_model_data(clear_download=False):
    res = {
        'models': get_cache_models(),
        'ckpts': get_ckpts(),
        'downloads': get_downloads(),
    }
    if clear_download:
        res['downloading'] = None
    return res


from ast import AST, FunctionDef
from typing import List, Optional

from ..i18n import t
from ..instrument import Instrumentor, ProgramData
from ..models import QLC, QLCPrepared
from .options import pick_options, options, take_options, fill_options

WORD_LIST = ['total', 'other', 'foo', 'bar', 'n', 'tmp', 'magic', 'temp', 'important']

class VariableNames(QLCPrepared):
  def __init__(self, pos: int, type: str, data: ProgramData):
    super().__init__(pos, type)
    self.data = data

  def make(self):
    vars = list(self.data.elements_for_types(['variable']))
    if len(vars) == 0:
      return None
    kws = list(self.data.elements_for_types(['keyword']))
    bis = list(self.data.elements_for_types(['builtin']))
    uws = [w for w in WORD_LIST if self.data.element_for_id(w) is None]
    return QLC(
      self.pos,
      self.type,
      t('q_variable_names'),
      pick_options(
        take_options(2, [e.id for e in vars], 'variable', t('o_variable_name'), True),
        fill_options(3, [e.id for e in kws], 'reserved_word', t('o_reserved_word')),
        take_options(1, [e.id for e in bis], 'builtin_function', t('o_built_in_function')),
        fill_options(5, uws, 'unused_word', t('o_unused_word')),
      )
    )

def variable_names(
  pos: int,
  type: str,
  tree: AST,
  call: Optional[str],
  ins: Instrumentor
) -> List[VariableNames]:
  return [VariableNames(pos, type, ins.data)]

class ParameterNames(QLCPrepared):
  def __init__(self, pos: int, type: str, data: ProgramData, function: ProgramData.Element):
    super().__init__(pos, type)
    self.data = data
    self.function = function

  def make(self):
    args = list(self.data.elements_in_scope(self.function.container_scope, ['argument']))
    if len(args) == 0:
      return None
    vars = list(self.data.elements_in_scope(self.function.container_scope, ['variable']))
    kws = list(self.data.elements_for_types(['keyword']))
    return QLC(
      self.pos,
      self.type,
      t('q_parameter_names', self.function.declaration.node.lineno),
      pick_options(
        take_options(2, [e.id for e in args], 'parameter', t('o_parameter_name'), True),
        options([self.function.id], 'function', t('o_function_name')),
        take_options(2, [e.id for e in vars], 'variable', t('o_variable_name')),
        fill_options(5, [e.id for e in kws], 'reserved_word', t('o_reserved_word')),
      )
    )

def parameter_names(
  pos: int,
  type: str,
  tree: AST,
  call: Optional[str],
  ins: Instrumentor
) -> List[ParameterNames]:
  return [ParameterNames(pos, type, ins.data, e) for e in ins.data.elements_for_types(['function'])]


import argparse
import os
from collections import namedtuple
from typing import List, Union
from pathlib import Path

import numpy as np
from skimage import measure, io

from ctc_dataset import Dataset

CellSubimage = namedtuple('CellSubimage', ['label', 'image', 'mask'])

def extract_cell_subimages(image: np.ndarray, labels: np.ndarray) -> List[CellSubimage]:
    props: List[measure._regionprops.RegionProperties] = measure.regionprops(labels, image)

    subimages: List[CellSubimage] = []
    # KDIR = '/home/radoslav/PhD_prep/debug/'
    for region in props:
        lab_sub = np.where(region.image.copy(), 255, 0).astype(np.uint8)
        # io.imsave(os.path.join(KDIR, f'big_{region.label}.png'), (255 * (labels > 0)).astype(np.uint8))
        # io.imsave(os.path.join(KDIR, f'sub_{region.label}.png'), lab_sub)
        img_sub = region.intensity_image.copy()
        subimages.append(CellSubimage(region.label, img_sub, lab_sub))
    return subimages

def save_cell_subimages(subimages: List[CellSubimage], ident: Union[int, str], folder: str, save: str='both'):
    save_image = save == 'both' or save == 'image'
    save_mask = save == 'both' or save == 'mask'

    base_name = 'N' + str(ident) + '_'
    for subimage in subimages:
        specific_name = base_name + str(subimage.label) + '_'
        image_name = specific_name + 'i.tiff'
        mask_name = specific_name + 'm.png'
        if save_image:
            io.imsave(os.path.join(folder, 'images', image_name), subimage.image)
        if save_mask:
            io.imsave(os.path.join(folder, 'masks', mask_name), subimage.mask)

def make_dir(fol):
    nonexistent = []
    current_path = os.path.normpath(fol)
    while not os.path.exists(current_path):
        nonexistent.append(current_path)
        current_path, _ = os.path.split(current_path)
    for path in reversed(nonexistent):
        os.mkdir(path)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Extract individual cell mask from segmentation masks for a given CTC folder.")
    parser.add_argument('ctc_folder', help='Cell tracking challenge dataset folder.')
    parser.add_argument('--save_pairs', action='store_true', help='if provided, extracts also the corresponding intensity subimage')
    parser.add_argument('--truth', default='GT', help='Kind of annotation to extract, either ST(silver) or GT(gold) truth', choices=['GT', 'ST'])
    parser.add_argument('--out', default='./', help='Folder where the extracted mask will be saved. Defaults to {current_dir}/{ctc_folder}_cell_masks/')

    args = parser.parse_args()

    in_path = os.path.abspath(args.ctc_folder)
    out_path = os.path.join(os.path.abspath(args.out), f'{os.path.split(in_path)[1]}_cell_masks_{args.truth}/')
    out_path = os.path.normpath(out_path)

    save_flag = 'both' if args.save_pairs else 'mask'
    truth = args.truth

    if not os.path.exists(out_path):
        make_dir(out_path)

    if not (Path(out_path) / 'images').exists():
      make_dir(Path(out_path) / 'images')

    if not (Path(out_path) / 'masks').exists():
      make_dir(Path(out_path) / 'masks')

    print(in_path)
    print(out_path)

    ds = Dataset(in_path)

    for seq in ds.sequences:
        seq_str = f'{seq.seq_id:0>2}'
        imgs_anns = seq.get_abs_truth_file_names(truth)
        for i, (img, ann) in enumerate(imgs_anns):
            img = io.imread(img, as_gray=True)
            ann = io.imread(ann, as_gray=True)

            subimages = extract_cell_subimages(img, ann)
            save_cell_subimages(subimages, seq_str + '_' + str(i), folder=out_path, save=save_flag)


from tkinter import *
from tkinter import ttk
from ttkthemes import themed_tk as tk
from PIL import Image, ImageTk

from sklearn import preprocessing
import xgboost as xgb

import pickle
import numpy as np
import pandas as pd
import tkinter.messagebox

with open("Analiza_Modeli/model_reg.pickle", 'rb') as file:
    trained_regmodel = pickle.load(file)

with open("Analiza_Modeli/model_class.pickle", 'rb') as file:
    trained_classmodel = pickle.load(file)

trained_regmodel
trained_classmodel

with open("encoders.pickle", 'rb') as file2:
    encoders = pickle.load(file2)

encoders

version = 'v0.102'

####### pomocnicze zmienne listy itp #####################

kursy_walut = {'SGD': 0.7218272535233189, 'EUR': 1.1238612937944434, 'DKK': 0.14862087297218637, 'CAD': 0.8145423808817589, 'AUD': 0.8029694136890776, 'GBP': 1.5207327949927543, 'USD': 1.0, 'MXN': 0.05303800288397823, 'HKD': 0.12838130718608456, 'CHF': 1.0320771710383756, 'JPY': 0.008826237200036304, 'SEK': 0.12031274002718356, 'NZD': 0.7616139550831179, 'NOK': 0.12166770926093867, 'PLN': 0.3125, 'Specify goal in USD':1}

kraj_waluta = {'not considered': 'Specify goal in USD','Poland':'PLN','Other':'Specify goal in USD','Singapore': 'SGD', 'Ireland': 'EUR', 'Norway': 'NOK', 'New Zealand': 'NZD', 'Netherlands': 'EUR', 'Australia': 'AUD', 'Spain': 'EUR', 'Mexico': 'MXN', 'Hong Kong': 'HKD', 'United States': 'USD', 'Denmark': 'DKK', 'Japan': 'JPY', 'Luxembourg': 'EUR', 'Italy': 'EUR', 'Germany': 'EUR', 'Canada': 'CAD', 'Sweden': 'SEK', 'Great Britain (UK)': 'GBP', 'Belgium': 'EUR', 'Austria': 'EUR', 'Switzerland': 'CHF', 'France': 'EUR'}

chosen_main_cat = ''
chosen_country = ''
chosen_subcat = ''
chosen_currency = ''

chosen_goal = ''
chosen_main_cat_cat = ''
chosen_duration = 30

############# definicje fukcji ##########

# pomocnicza z kursu tkinter
def doNothing():
    print("ok ok I won't...")

# sprawdzenie i użycie testowe wybranych w widźetach parametrów
def checkParamas():
    tmpCAT = catMenu.get()
    tmpCNTR = countryMenu.get()
    tmpSUBCAT = subcatMenu.get()
    tmpGOAL = goalSpinbox.get()
    tmpDUR = durationSpinbox.get()

    global chosen_main_cat
    chosen_main_cat = tmpCAT

    global chosen_duration
    chosen_duration = tmpDUR

    global chosen_country
    chosen_country = tmpCNTR

    global chosen_subcat
    chosen_subcat = tmpSUBCAT

    global chosen_goal
    chosen_goal = tmpGOAL

    global  chosen_main_cat_cat
    chosen_main_cat_cat = f"{chosen_main_cat}>{chosen_subcat}"

    if tmpCAT != '' and tmpCNTR != '' and tmpSUBCAT != '' and tmpGOAL != '' and tmpDUR != '':
        localCURR = kraj_waluta[tmpCNTR]
        global chosen_currency
        chosen_currency = localCURR
        localGOAL = round(float(tmpGOAL) / kursy_walut[localCURR], 1)
        paramInfolabel.configure(text = f"Your Campaign's main category: {tmpCAT}\n"
                                        f"Your Campaing's sub category : {tmpSUBCAT}\n"
                                        f"Your Campaign's launch country: {tmpCNTR}\n"
                                        f"Your Campaign's duration: {tmpDUR}\n"
                                        f"Your Campaign's goal is {tmpGOAL} USD ({localGOAL} in {localCURR} ).\n"
                                        f"All parameters selected. Check your chances... EVALUATE CAMPAIGN")
    else:
        paramInfolabel.configure(text=f"Not all parameters selected!")

#pomocnicza funkcja sprawdzająca (w konsoli) czy została zapisana wartość globalnej zmiennej main_chosen
def run_magic():
    print(chosen_main_cat)

#kodowanie podanych danych
def input_encode():
    global enc_main_cat_cat
    enc_main_cat_cat = encoders['main_cat_cat'].transform([chosen_main_cat_cat])
    global enc_country
    enc_country = encoders['country'].transform([chosen_country])
    global enc_currency
    enc_currency = encoders['currency'].transform([chosen_currency])

def predict_pledged():
    input_encode()
    data = pd.DataFrame(data = {'main_cat_cat': enc_main_cat_cat, 'country':enc_country, 'duration' : float(chosen_duration), 'currency': enc_currency, 'goal_in_usd': float(chosen_goal)})

    preds = trained_regmodel.predict(data)
    pred_succes = trained_classmodel.predict(data)
    if pred_succes.mean() == 1 and preds.mean() > int(chosen_goal):
        resultlabel.configure(text=f"Propably you WILL SUCCED !! \n"
                                   f"You may have a chance to reach even higher GOAL : {preds.mean().round()}$!")
    elif pred_succes.mean() == 1 and preds.mean() < int(chosen_goal):
        resultlabel.configure(text=f"Propably you WILL SUCCED !! \n"
                                   f"The GOAL you've chosen looks JUST OK!")

    elif pred_succes.mean() == 0 and preds.mean() < int(chosen_goal) and preds.mean() > 0:
        resultlabel.configure(text=f"Propably you WILL LOOSE $$$. \n"
                                   f"You may have a chance to collect around : {preds.mean().round()}$.")

    else:
        resultlabel.configure(text=f"Propably you WILL LOOSE money. \n"
                                   f"For your campaign, we CANNOT suggest a reasonable GOAL.")

######### lista podkategorii do wyboru dla poszczególnych wybrbanych main_category
sub_categories = {'Art':
                          ['Sculpture',
                           'Conceptual Art',
                           'Illustration',
                           'Public Art',
                           'Mixed Media',
                           'Video Art',
                           'Art',
                           'Installations',
                           'Ceramics',
                           'Textiles',
                           'Painting',
                           'Digital Art',
                           'Performance Art'],
                      'Comics':
                          ['Comic Books',
                           'Events',
                           'Anthologies',
                           'Graphic Novels',
                           'Comics',
                           'Webcomics'],
                      'Crafts':
                          ['Weaving',
                           'Letterpress',
                           'Crochet',
                           'Candles',
                           'Taxidermy',
                           'Crafts',
                           'Knitting',
                           'Embroidery',
                           'Pottery',
                           'Glass',
                           'Quilts',
                           'Printing',
                           'DIY',
                           'Stationery',
                           'Woodworking'],
                      'Dance':
                          ['Dance',
                           'Spaces',
                           'Residencies',
                           'Workshops',
                           'Performances'],
                      'Design':
                          ['Graphic Design',
                           'Product Design',
                           'Civic Design',
                           'Interactive Design',
                           'Architecture',
                           'Typography',
                           'Design'],
                      'Fashion':
                          ['Couture',
                           'Childrenswear',
                           'Footwear',
                           'Fashion',
                           'Accessories',
                           'Jewelry',
                           'Apparel',
                           'Ready-to-wear',
                           'Pet Fashion'],
                      'Film & Video':
                          ['Television',
                           'Horror',
                           'Film & Video',
                           'Science Fiction',
                           'Music Videos',
                           'Documentary',
                           'Family',
                           'Animation',
                           'Fantasy',
                           'Experimental',
                           'Movie Theaters',
                           'Comedy',
                           'Webseries',
                           'Festivals',
                           'Romance',
                           'Drama',
                           'Shorts',
                           'Narrative Film',
                           'Thrillers',
                           'Action'],
                      'Food':
                          ['Spaces',
                           'Vegan',
                           'Drinks',
                           'Restaurants',
                           'Food',
                           'Events',
                           'Farms',
                           'Cookbooks',
                           "Farmer's Markets",
                           'Food Trucks',
                           'Community Gardens',
                           'Small Batch',
                           'Bacon'],
                      'Games':
                          ['Playing Cards',
                           'Puzzles',
                           'Games',
                           'Mobile Games',
                           'Gaming Hardware',
                           'Video Games',
                           'Tabletop Games',
                           'Live Games'],
                      'Journalism':
                          ['Print',
                           'Video',
                           'Journalism',
                           'Web',
                           'Photo',
                           'Audio'],
                      'Music':
                          ['Classical Music',
                           'Faith',
                           'Chiptune',
                           'Blues',
                           'Indie Rock',
                           'Pop',
                           'Kids',
                           'Hip-Hop',
                           'World Music',
                           'Jazz',
                           'Latin',
                           'Metal',
                           'Comedy',
                           'Country & Folk',
                           'R&B',
                           'Rock',
                           'Music',
                           'Punk',
                           'Electronic Music'],
                      'Photography':
                          ['Photobooks',
                           'Animals',
                           'Places',
                           'Nature',
                           'People',
                           'Fine Art',
                           'Photography'],
                      'Publishing':
                          ['Radio & Podcasts',
                           'Art Books',
                           'Literary Journals',
                           'Poetry',
                           'Calendars',
                           'Comedy',
                           'Letterpress',
                           'Literary Spaces',
                           "Children's Books",
                           'Zines',
                           'Academic',
                           'Publishing',
                           'Anthologies',
                           'Periodicals',
                           'Nonfiction',
                           'Fiction',
                           'Translations',
                           'Young Adult'],
                      'Technology':
                          ['Technology',
                           'Wearables',
                           'Apps',
                           'Space Exploration',
                           'Sound',
                           'Gadgets',
                           'Software',
                           '3D Printing',
                           'Robots',
                           'DIY Electronics',
                           'Hardware',
                           'Web',
                           'Makerspaces',
                           'Camera Equipment',
                           'Flight',
                           'Fabrication Tools'
                           ],
                      'Theater':
                          ['Spaces',
                           'Comedy',
                           'Festivals',
                           'Experimental',
                           'Musical',
                           'Theater',
                           'Plays',
                           'Immersive'],
                      '':
                          ['choose main category first']
                           }

#funkcja, która daje listę podkategorii do wyboru na podstawie wybranej kategorii
def narrow_subcat(event):
    tmpCAT = catMenu.get()
    subcatMenu.configure(values = sub_categories[tmpCAT])

################### definicja interfesju ############
'''
Tkinter opiera się o "ramki" - frames, w których upakowuje się poszczególne fragmentu interfejsu:
- przyciski
- pola tekstowe
- menu wybieralne
- slidery
- okienka inputu
i pewnie jeszce wiele innych

ramek może być wiele poziomów, sam stosuje poniżej "ramki w większych ramkach"

'''

# ***** GUI start *****

#root - główna, najbardziej zewnętrzna ramka, definiowana jako klasa ThemedTk (themed, zeby skorzystać z predefiniowanego styu)
# "okno programu, nazwa root wzięta z kursu"

root = tk.ThemedTk()
root.geometry('1000x600')
root.set_theme("clearlooks")

# ***** The Toolbar - górny pasek z przyciakami  *****

#pierwsza zewnętrzna ramka, umieszczamy ją w oknie 'root', "pakujemy" na górze
toolbar = ttk.Frame(root)
toolbar.pack(side = TOP)

#### poniżej definicja przycików używanych, które "pakujemy" w w ramce "toolbar"
#### w dalszej części na podobnej zasadzie są zdefiniowane i "upakowane" pozostałe elementy interfejsu

# *** toolbar buttons *****
insertButt = ttk.Button(toolbar, text="UPDATE PARAMETERS", command=checkParamas)
insertButt.pack(side=LEFT, padx=10, pady=10)

testButt = ttk.Button(toolbar, text="EVALUATE CAMAPIGN", command=predict_pledged)
testButt.pack(side=LEFT, padx=10, pady=10)

quitButt = ttk.Button(toolbar, text="Quit", command=root.quit)
quitButt.pack(side=RIGHT, padx=10, pady=10)

# ***** Menus Frame *****

menuFrame = Frame(root)
menuFrame.configure(padx = 30,pady = 10)

menuFrame.pack(side = TOP)

MenusLabel1 = ttk.Label(menuFrame, text = 'Please specify campaign parameters',font = ('Helvetica', 20, 'bold'), anchor = CENTER )
MenusLabel1.pack(side = TOP, pady = 20)

#** Main Category selector *****

catMenuFrame = Frame(menuFrame, padx = 2, pady = 2)

mcats = ['Art',
             'Fashion',
             'Music',
             'Crafts',
             'Photography',
             'Design',
             'Film & Video',
             'Food',
             'Journalism',
             'Publishing',
             'Dance',
             'Comics',
             'Technology',
             'Theater',
             'Games']

catMenuLabel = ttk.Label(catMenuFrame, text = 'Choose Main Category    ', anchor = N )
catMenuLabel.pack(side = LEFT)

catMenu = ttk.Combobox(catMenuFrame, values = mcats)
#poniżej odpalenie funkcji, która zawęża podkategorie na podstawie wybranej głównej kategorii
catMenu.bind('<<ComboboxSelected>>', narrow_subcat )
catMenu.pack(side = LEFT)

catMenuFrame.pack(side = TOP)

# ** Sub Category selector *****

subcatMenuFrame = Frame(menuFrame, padx = 2, pady = 2)

subcatMenuLabel = ttk.Label(subcatMenuFrame, text = 'Choose Sub-Category     ' )
subcatMenuLabel.pack(side = LEFT)

subcatMenu = ttk.Combobox(subcatMenuFrame, values = sub_categories[chosen_main_cat])
subcatMenu.pack(side = LEFT)

subcatMenuFrame.pack(side = TOP)

# ** Country selector *****
countryMenuFrame = Frame(menuFrame, padx = 2, pady = 2)

country_list = [ 'Australia',
                'Austria',
                'France',
                'Switzerland',
                'Belgium',
                'Denmark',
                'Canada',
                'Singapore',
                'New Zealand',
                'Hong Kong',
                'Sweden',
                'Germany',
                'Ireland',
                'Luxembourg',
                'Japan',
                'Netherlands',
                'Italy',
                'Great Britain (UK)',
                'Spain',
                'United States',
                'Mexico',
                'Norway']

countryMenuLabel = ttk.Label(countryMenuFrame, text = 'Choose Country          ' )
countryMenuLabel.pack(side = LEFT)

countryMenu = ttk.Combobox(countryMenuFrame, values = country_list)
countryMenu.pack(side = LEFT)

countryMenuFrame.pack(side = TOP)

# ** Goal selector *****
goalMenuFrame = Frame(menuFrame, padx = 2, pady = 2)

goalMenuLabel = ttk.Label(goalMenuFrame, text = 'Set Goal in USD         ' )
goalMenuLabel.pack(side = LEFT)

min_goal = 1
max_goal = 1000000

goalSpinbox = ttk.Spinbox(goalMenuFrame, from_ = min_goal, to = max_goal, increment=50, command = checkParamas)
goalButton = Button(goalMenuFrame, text="OK", command=checkParamas)

goalSpinbox.pack(side = LEFT)

goalButton.pack(side = LEFT, padx = 5)

goalMenuFrame.pack(side = TOP)

# slider poniżej

#przyznam, że w sumie średnio mi się ten slider podoba, do przegadania czy go nie wywalić

sliderFrame = Frame(menuFrame, padx = 2, pady = 2)

goalSlider = Scale(sliderFrame, orient = HORIZONTAL, showvalue = 0, from_ = min_goal, to = max_goal, length = 300, variable = IntVar )
goalSlider.configure(command = goalSpinbox.set)
goalSlider.pack(side = TOP, padx = 0, fill = X )

########### SLIDER GOAL WYŁĄCZONY PONIŻEJ

#sliderFrame.pack(side = TOP)

# ** Duration selector *****
durationMenuFrame = Frame(menuFrame, padx = 2, pady = 2)

durationMenuLabel = ttk.Label(durationMenuFrame, text = 'Choose campaign duration ' )
durationMenuLabel.pack(side = LEFT)

min_dur = 1
max_dur = 90

durationSpinbox = ttk.Spinbox(durationMenuFrame, from_ = min_dur, to = max_dur, increment = 1, command=checkParamas)
durationButton = Button(durationMenuFrame, text="OK", command=checkParamas)

#durationSpinbox.pack(side = LEFT)

#durationButton.pack(side = LEFT, padx = 5)

def dur_slider_contr(event):
    durationSpinbox.set(event)
    checkParamas()

durSlider = Scale(durationMenuFrame, orient = HORIZONTAL, showvalue = 1, from_ = min_dur, to = max_dur, length = 300, variable = IntVar )
durSlider.set(30)

durSlider.configure(command = dur_slider_contr)
durSlider.pack(side = LEFT, padx = 5, fill = X )

durationMenuFrame.pack(side = TOP)

# ### SLIDER DLA DURATION
#
# slider2Frame = Frame(menuFrame, padx = 2, pady = 2)
#
#
#
#
#
#
#
# slider2Frame.pack(side = TOP)

# ***** Main Window showing result *****

mainFrame1 = Frame(root)
mainFrame1.pack(side = TOP, pady = 40)

paramInfolabel = ttk.Label(mainFrame1, text = 'choose campaign parameters',font = ('Times', 11, 'bold'))

paramInfolabel.pack(side = TOP, anchor = CENTER, fill = BOTH)

resultlabel = ttk.Label(mainFrame1, text = '', font = ('Times', 15, 'bold'))

resultlabel.pack(side = TOP, anchor = CENTER, fill = BOTH, pady = 20)

# ***** Status Bar *****

status = ttk.Label(root, text=f"PandP, ML_project, {version}", relief=GROOVE, anchor=W)

status.pack(side=BOTTOM, fill=X)

durationSpinbox.set(30)

checkParamas()

# "włączenie" programu, interfejs musi się zawierać pomiędzy "otwarciem" roota i jego "mainloop'em", trochę jak w html'u
root.mainloop()


"""
Bidirectional LSTMS on VOXELS

Usage:

- extract_path is the where the extracted data samples are available.
- checkpoint_model_path is the path where to checkpoint the trained models during the training process

EXAMPLE: SPECIFICATION

extract_path = '/Users/sandeep/Research/Ti-mmWave/data/extract/Train_Data_voxels_'
checkpoint_model_path="/Users/sandeep/Research/Ti-mmWave/data/extract/LSTM"
"""

extract_path = '/home/wt/RadHAR/Data/extract/Train_Data_voxels_'
checkpoint_model_path="/home/wt/RadHAR/Data/model"

import glob
import os
import numpy as np
# random seed.
rand_seed = 1
from numpy.random import seed
seed(rand_seed)
#from tensorflow import set_random_seed
#set_random_seed(rand_seed)
import tensorflow
tensorflow.random.set_seed(rand_seed)

import keras
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, LSTM, Dense, Dropout, Flatten, Activation
from keras.layers.core import Permute, Reshape
from keras import backend as K

from keras import optimizers
from keras.optimizers import SGD
from keras.optimizers import Adam
from keras.metrics import categorical_crossentropy
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import *
from keras.callbacks import Callback
from keras.callbacks import ModelCheckpoint
from keras.layers import Conv2D, MaxPooling2D, LSTM, Dense, Dropout, Flatten, Bidirectional,TimeDistributed
from sklearn.model_selection import train_test_split
from keras.models import load_model

sub_dirs=['stand','swing']

def one_hot_encoding(y_data, sub_dirs, categories=5):
    Mapping=dict()

    count=0
    for i in sub_dirs:
        Mapping[i]=count
        count=count+1

    y_features2=[]
    for i in range(len(y_data)):
        Type=y_data[i]
        Type = Type.decode('utf-8')
        lab=Mapping[Type]
        #lab = Mappin.get(Type)

        y_features2.append(lab)

    y_features=np.array(y_features2)
    #print(y_features.shape)
    y_features=y_features.reshape(y_features.shape[0],1)

    from keras.utils import to_categorical
    y_features = to_categorical(y_features)
    #print(y_features.shape)
    return y_features

def full_3D_model(summary=False):
    print('building the model ... ')
    model = Sequential()

    model.add(Bidirectional(LSTM(64, return_sequences=False, stateful=False,input_shape=(60, 10*1024) )))
    model.add(Dropout(.5,name='dropout_1'))
    model.add(Dense(128, activation='relu', name='DENSE_1'))
    model.add(Dropout(.5,name='dropout_2'))
    model.add(Dense(2, activation='softmax', name = 'output'))

    return model

frame_tog = [60]

#loading the train data
Data_path = extract_path+'stand'

data = np.load(Data_path+'.npz')
train_data = data['arr_0']
train_data = np.array(train_data,dtype=np.dtype(np.int32))
train_label = data['arr_1']
#print(train_label.shape)
del data
print(train_data.shape,train_label.shape)

Data_path = extract_path+'swing'
data = np.load(Data_path+'.npz')
train_data = np.concatenate((train_data, data['arr_0']), axis=0)
train_label = np.concatenate((train_label, data['arr_1']), axis=0)

del data

print(train_data.shape,train_label.shape)

train_label = one_hot_encoding(train_label, sub_dirs, categories=2)

train_data = train_data.reshape(train_data.shape[0],train_data.shape[1], train_data.shape[2]*train_data.shape[3]*train_data.shape[4])

print('Training Data Shape is:')
print(train_data.shape,train_label.shape)

X_train, X_val, y_train, y_val  = train_test_split(train_data, train_label, test_size=0.20, random_state=1)
del train_data,train_label

##shuffle before use validation split
from sklearn.utils import shuffle
#np.random.shuffle(X_train)
#y_train[X_train[:,0]]
X_train, y_train = shuffle(X_train, y_train)

model = full_3D_model()

print("Model building is completed")

adam = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None,
                       decay=0.0, amsgrad=False)

model.compile(loss=keras.losses.categorical_crossentropy,
                   optimizer=adam,
                  metrics=['accuracy'])

checkpoint = ModelCheckpoint(checkpoint_model_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')

callbacks_list = [checkpoint]

import time

timestamp = time.time()

# Training the model
learning_hist = model.fit(X_train, y_train,
                             batch_size=20,
                             epochs=30,
                             verbose=1,
                             shuffle=True,
                             validation_split = 0.2,
                           #validation_data=(X_val,y_val),

                           callbacks=callbacks_list
                          )

finish_timestamp = time.time()

#calculate time

timestruct = time.localtime(finish_timestamp - timestamp)
print(time.strftime('%Y-%m-%d %H:%M:%S', timestruct))

##show the history
import matplotlib.pyplot as plt

# 绘制训练 & 验证的准确率值
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# 绘制训练 & 验证的损失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# Evaluate the model on the test data using `evaluate`
print("Evaluate on test data")
results = model.evaluate(X_val, y_val, batch_size=20)
print("test loss, test acc:", results)

## Saving the model

model.save( checkpoint_model_path + '/LSTM.h5')   # HDF5 file, you have to pip3 install h5py if don't have it

del model


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        ('admin', '0001_initial'),
        ('user_expenses', '0002_auto_20160907_0806'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='usermodel',
            name='user_ptr',
        ),
        migrations.AlterField(
            model_name='expenses',
            name='owner',
            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
        ),
        migrations.DeleteModel(
            name='UserModel',
        ),
    ]


from django.urls import path

from . import views

app_name = 'livestream'

urlpatterns = [
    path('', views.index, name='index'),
    path('forward', views.forward, name='forward'),
    path('reverse', views.reverse, name='reverse'),
    path('right', views.right, name='right'),
    path('left', views.left, name='left'),
    path('forward1', views.forward1, name='forward1'),
    path('reverse1', views.reverse1, name='reverse1'),
    path('right1', views.right1, name='right1'),
    path('left1', views.left1, name='left1'),
    path('stop', views.stop, name='stop'),
    path('checkfor', views.checkfor, name='checkfor'),
    path('checkback', views.checkback, name='checkback'),
]


import os.path as op
from io import StringIO

import numpy as np
import pandas as pd
import pytest

import cooler
from cooler.create import (
    BadInputError,
    aggregate_records,
    sanitize_pixels,
    sanitize_records,
    validate_pixels,
)

testdir = op.dirname(op.realpath(__file__))
datadir = op.join(testdir, "data")

columns = [
    "chrom1",
    "pos1",
    "strand1",
    "chrom2",
    "pos2",
    "strand2",
    "name",
    "pair_type",
    "triu",
]

valid_data = """chr1\t1\t+\tchr2\t100\t-\t.\tLL\t1
chr2\t99\t+\tchr1\t13\t-\t.\tLL\t0
chr2\t13\t+\tchr2\t60\t-\t.\tLL\t1
chr1\t200\t+\tchr2\t50\t-\t.\tLL\t1
chr3\t11\t+\tchr3\t40\t-\t.\tLL\t1
chr1\t234\t+\tchr3\t30\t-\t.\tLL\t1
chr3\t3\t+\tchr2\t20\t-\t.\tLL\t0
chr2\t23\t+\tchr3\t11\t-\t.\tLL\t1
chr1\t123\t+\tchr1\t200\t-\t.\tLL\t1
"""

nuisance_chroms = """chr1\t222\t+\tchr9\t200\t-\t.\tLL\t1
chr9\t222\t+\tchr9\t200\t-\t.\tLL\t1"""
oob_lower = """chr1\t-1\t+\tchr1\t10\t+\t.\tLL\t1"""
oob_upper = """chr1\t123\t+\tchr1\t301\t+\t.\tLL\t1"""

binsize = 10
chromsizes = pd.Series(index=["chr1", "chr2", "chr3"], data=[300, 300, 300])
bins = cooler.util.binnify(chromsizes, binsize)

def _insert_lines(d, new):
    lines = d.split("\n")
    for line in new.split("\n"):
        lines.insert(np.random.randint(len(lines)), line)
    return "\n".join(lines)

def test_sanitize_records():

    chunk = pd.read_csv(StringIO(valid_data), sep="\t", names=columns)
    with pytest.raises(ValueError):
        sanitize_records(
            bins,
            schema="doesnotexist",
            validate=True,
            tril_action="reflect",
            is_one_based=True,
            sort=True,
        )(chunk.copy())

    chunk = pd.read_csv(StringIO(valid_data), sep="\t", names=columns)
    sanitize_records(
        bins,
        schema="pairs",
        validate=True,
        tril_action="reflect",
        is_one_based=True,
        sort=True,
    )(chunk.copy())

    # variable-length bins
    chunk = pd.read_csv(StringIO(valid_data), sep="\t", names=columns)
    sanitize_records(
        pd.DataFrame({
            'chrom': ['chr1', 'chr1', 'chr2', 'chr2', 'chr3'],
            'start': [0, 150, 0, 100, 0],
            'end': [150, 300, 100, 300, 300],
        }),
        schema="pairs",
        validate=True,
        tril_action="reflect",
        is_one_based=True,
        sort=True,
    )(chunk.copy())

    # input with already enum-encoded chromosomes (decode_chroms=False)
    text = """0\t1\t+\t1\t100\t-\t.\tLL\t1
1\t99\t+\t0\t13\t-\t.\tLL\t0
1\t13\t+\t1\t60\t-\t.\tLL\t1
0\t200\t+\t1\t50\t-\t.\tLL\t1
2\t11\t+\t2\t40\t-\t.\tLL\t1
0\t234\t+\t2\t30\t-\t.\tLL\t1
2\t3\t+\t1\t20\t-\t.\tLL\t0
1\t23\t+\t2\t11\t-\t.\tLL\t1
0\t123\t+\t-1\t200\t-\t.\tLL\t1
"""
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    sanitize_records(
        bins,
        schema="pairs",
        decode_chroms=False,
        validate=True,
        tril_action="reflect"
    )(chunk.copy())
    # fails on string chromosomes
    chunk = pd.read_csv(StringIO(valid_data), sep="\t", names=columns)
    with pytest.raises(BadInputError):
        sanitize_records(
            bins,
            schema="pairs",
            decode_chroms=False,
            validate=True,
            tril_action="reflect"
        )(chunk.copy())

    # empty chunk
    out = sanitize_records(
        bins,
        schema="pairs",
        validate=True,
        tril_action="reflect"
    )(chunk.iloc[0:0])
    assert len(out) == 0

def test_sanitize_records_triu_action():
    text = valid_data
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    out = sanitize_records(bins, schema="pairs", validate=True, tril_action="reflect")(
        chunk.copy()
    )
    is_tril = ~np.array(out["triu"], dtype=bool)
    is_tril_ix = out.index[is_tril]
    assert np.all(out.loc[is_tril_ix, "chrom1"] == chunk.loc[is_tril_ix, "chrom2"])
    assert np.all(out.loc[is_tril_ix, "chrom2"] == chunk.loc[is_tril_ix, "chrom1"])
    assert np.all(out.loc[is_tril_ix, "strand1"] == "+")

    text = valid_data
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    out = sanitize_records(bins, schema="pairs", validate=True, tril_action="drop")(
        chunk.copy()
    )
    is_tril = ~np.array(out["triu"], dtype=bool)
    is_tril_ix = out.index[is_tril]
    assert np.all(out.loc[is_tril_ix, "chrom1"] == chunk.loc[is_tril_ix, "chrom2"])
    assert np.all(out.loc[is_tril_ix, "chrom2"] == chunk.loc[is_tril_ix, "chrom1"])
    assert np.all(out.loc[is_tril_ix, "strand1"] == "+")
    assert len(out) == chunk["triu"].sum()

    func = sanitize_records(bins, schema="pairs", validate=True, tril_action="raise")
    text = valid_data
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    with pytest.raises(BadInputError):
        func(chunk)

def test_sanitize_records_with_strand_column():
    text = valid_data
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    out = sanitize_records(
        bins,
        schema="pairs",
        validate=True,
        tril_action="reflect",
        sided_fields=("chrom", "pos", "strand"),
    )(chunk.copy())
    is_tril = ~np.array(out["triu"], dtype=bool)
    assert np.all(out.loc[is_tril, "chrom1"] == chunk.loc[is_tril, "chrom2"])
    assert np.all(out.loc[is_tril, "chrom2"] == chunk.loc[is_tril, "chrom1"])
    assert np.all(out.loc[is_tril, "strand1"] == "-")

def test_sanitize_records_with_nuisance_records():
    text = _insert_lines(valid_data, nuisance_chroms)
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    out = sanitize_records(bins, schema="pairs", validate=True, tril_action="reflect")(
        chunk.copy()
    )
    assert ("chr9" not in out["chrom1"]) and ("chr9" not in out["chrom2"])

def test_sanitize_records_with_bad_records():
    func = sanitize_records(bins, schema="pairs", validate=True, tril_action="reflect")

    text = _insert_lines(valid_data, oob_lower)
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    with pytest.raises(BadInputError):
        func(chunk)

    text = _insert_lines(valid_data, oob_upper)
    chunk = pd.read_csv(StringIO(text), sep="\t", names=columns)
    with pytest.raises(BadInputError):
        func(chunk)

def test_sanitize_pixels():
    bins = cooler.binnify(
        cooler.util.read_chromsizes(op.join(datadir, "toy.chrom.sizes")), 1
    )
    chunk = pd.read_csv(
        op.join(datadir, "toy.symm.upper.1.zb.coo"),
        sep='\t',
        names=['bin1_id', 'bin2_id', 'count']
    )
    chunk['foo1'] = 4
    chunk['foo2'] = 2
    sanitize_pixels(
        bins,
    )(chunk.copy())

    # one-based bin IDs
    out = sanitize_pixels(
        bins,
        is_one_based=True,
    )(chunk.copy())
    assert (out['bin1_id'] == chunk['bin1_id'] - 1).all()

    # tril action: reflect (after swapping bin1, bin2)
    tril_chunk = chunk.copy()
    tril_chunk['bin2_id'] = chunk['bin1_id']
    tril_chunk['bin1_id'] = chunk['bin2_id']
    out = sanitize_pixels(
        bins,
        tril_action="reflect",
        sided_fields=['foo'],
    )(tril_chunk.copy())
    assert len(out) == len(chunk)
    assert (out['foo2'] == chunk['foo1']).all()
    assert (out['foo1'] == chunk['foo2']).all()
    assert (out['bin1_id'] == chunk['bin1_id']).all()
    assert (out['bin2_id'] == chunk['bin2_id']).all()

    # tril action: drop
    out = sanitize_pixels(
        bins,
        tril_action="drop",
    )(tril_chunk.copy())
    assert len(out) == 0

    # tril action: raise
    with pytest.raises(BadInputError):
        sanitize_pixels(
            bins,
            tril_action="raise",
        )(tril_chunk.copy())

def test_validate_pixels():
    bins = cooler.binnify(
        cooler.util.read_chromsizes(op.join(datadir, "toy.chrom.sizes")), 1
    )
    chunk = pd.read_csv(
        op.join(datadir, "toy.symm.upper.1.zb.coo"),
        sep='\t',
        names=['bin1_id', 'bin2_id', 'count']
    )
    validator = validate_pixels(
        len(bins),
        boundscheck=True,
        triucheck=True,
        dupcheck=True,
        ensure_sorted=True
    )
    validator(chunk.copy())
    validator(chunk.to_dict(orient='series'))

    # wrongly assume zero-based, producing -1 bins IDs
    chunk_ = sanitize_pixels(
        bins,
        is_one_based=True,
    )(chunk.copy())
    with pytest.raises(BadInputError):
        validator(chunk_)

    # out-of-bounds bin ID
    chunk_ = chunk.copy()
    chunk_.at[-1, 'bin1_id'] = len(bins) + 1
    with pytest.raises(BadInputError):
        validator(chunk_)

    # pass in non-triu data
    tril_chunk = chunk.copy()
    tril_chunk['bin2_id'] = chunk['bin1_id']
    tril_chunk['bin1_id'] = chunk['bin2_id']
    with pytest.raises(BadInputError):
        validator(tril_chunk)

    # pass in duplicates
    with pytest.raises(BadInputError):
        validator(pd.concat([chunk, chunk], ignore_index=True))

def test_aggregate_records():
    bins = cooler.binnify(
        cooler.util.read_chromsizes(op.join(datadir, "toy.chrom.sizes")), 1
    )
    records = pd.read_csv(
        op.join(datadir, "toy.pairs"),
        sep='\t',
        names=[
            "read_id",
            "chrom1", "pos1",
            "chrom2", "pos2",
            "strand1", "strand2",
            "value"
        ]
    )
    sanitizer = sanitize_records(
        bins,
        schema="pairs",
        validate=False,
        tril_action="reflect",
        is_one_based=False,
        sort=False,
    )
    chunk = sanitizer(records)

    aggregator = aggregate_records()
    aggregator(chunk)


import pandas as pd
import streamlit as st
import base64
import pyperclip
import tabulate

def main():
    st.title("Display Top 5 Rows of Excel File")
    st.write("")

    # File upload
    uploaded_file = st.file_uploader("Choose an Excel file", type=["xls", "xlsx"])

    if uploaded_file is not None:
        try:
            # Load the first sheet of the Excel file into a Pandas dataframe
            df = pd.read_excel(uploaded_file, sheet_name=0)

            # Display the top 5 rows of the dataframe
            st.write(df.head(5))

            # Download link
            csv = df.head(5).to_csv(index=False)
            b64 = base64.b64encode(csv.encode()).decode()
            st.markdown('### Download Output')
            href = f'Download CSV File'
            st.markdown(href, unsafe_allow_html=True)

            # Copy table to clipboard
            st.markdown('### Copy Table')
            if st.button("Copy table to clipboard"):
                pyperclip.copy(df.head(5).to_clipboard(index=False, sep = '\t'))
                st.success("Table copied to clipboard!")
        except Exception as e:
            st.write("Error: {}".format(str(e)))

if __name__ == "__main__":
    main()