import datetime
from django.test import TestCase
from financial_planning.factories import (
    FinancialPlanningFactory,
    RegularCostFactory
)
from patrimony.factories import ActiveFactory
from protection.factories import (
    PrivatePensionFactory,
    ProtectionManagerFactory,
    LifeInsuranceFactory,
    EmergencyReserveFactory,
)
from protection.models import (
    PrivatePension, ReserveInLack,
    LifeInsurance, EmergencyReserve,
    ActualPatrimonySuccession, IndependencePatrimonySuccession,
)
from client.factories import ActiveClientFactory
from lib.tests import test_all_create_historic

def _create_reserve_in_lack():
    financial_planning = FinancialPlanningFactory(cdi=0.1213, ipca=0.0750)
    protection_manager = ProtectionManagerFactory(
        financial_planning=financial_planning)
    reserve_in_lack = protection_manager.reserve_in_lack
    reserve_in_lack.value_0_to_24_mounth = 13000
    reserve_in_lack.value_24_to_60_mounth = 10000
    reserve_in_lack.value_60_to_120_mounth = 5000
    reserve_in_lack.value_120_to_240_mounth = 5000

    return reserve_in_lack

class EmergencyReserveTest(TestCase):

    def setUp(self):
        financial_planning = FinancialPlanningFactory()
        self.active_manager = financial_planning.patrimony.activemanager
        patrimony = financial_planning.patrimony
        self.emergency_reserve = EmergencyReserveFactory(
            mounth_of_protection=12,
            patrimony=patrimony,
            cost_manager=financial_planning.cost_manager)

        for active in self.active_manager.actives.all():
            active.delete()

        cost_manager = financial_planning.cost_manager

        for regular_cost in cost_manager.regular_costs.all():
            regular_cost.delete()

        for arrearage in patrimony.arrearages.all():
            arrearage.delete()

        regular_costs = [{'value': 500}, {'value': 1500}, {'value': 2500}]

        for regular_cost in regular_costs:
            RegularCostFactory(**regular_cost, cost_manager=cost_manager)

    def test_necessery_value(self):
        self.assertEqual(self.emergency_reserve.necessery_value, 54000)

    def test_risk_gap_on_limit(self):
        ActiveFactory(value=54000, active_manager=self.active_manager)
        self.assertEqual(self.emergency_reserve.risk_gap, 0)

    def test_risk_gap_bigger_limit(self):
        ActiveFactory(value=59000, active_manager=self.active_manager)
        self.assertEqual(self.emergency_reserve.risk_gap, 0)

    def test_risk_gap_less_limit(self):
        ActiveFactory(value=51000, active_manager=self.active_manager)
        self.assertEqual(self.emergency_reserve.risk_gap, 3000)

class ReserveInLackTest(TestCase):
    def setUp(self):
        self.reserve_in_lack = _create_reserve_in_lack()

    def test_patrimony_necessery_in_period(self):
        self.assertAlmostEqual(
            self.reserve_in_lack.patrimony_necessery_in_period(
                24, 13000), 192124.8373901789)

    def test_patrimony_necessery_total(self):
        self.assertAlmostEqual(self.reserve_in_lack.
                               patrimony_necessery_total, 595624.31498015427)

class ProtectionManagerTest(TestCase):

    def setUp(self):
        active_client = ActiveClientFactory(
            birthday=datetime.datetime(1967, 1, 1))
        financial_planning = FinancialPlanningFactory(
            cdi=0.1213, ipca=0.075, active_client=active_client)
        self.protection_manager = ProtectionManagerFactory(
            financial_planning=financial_planning)
        self.protection_manager.private_pensions.all().update(
            value=20000, annual_investment=2000)
        for life_insurance in self.protection_manager.life_insurances.all():
            life_insurance.delete()

        for private_pension in self.protection_manager.private_pensions.all():
            private_pension.delete()

        life_insurances = [
            {'value_to_pay_annual': 2000, 'has_year_end': False},
            {'value_to_pay_annual': 2000, 'has_year_end': True,
                'year_end': 2020, },
            {'value_to_pay_annual': 1000, 'has_year_end': True,
                'year_end': 2023, }]

        for life_insurance in life_insurances:
            LifeInsuranceFactory(**life_insurance,
                                 protection_manager=self.protection_manager)

        private_pensions = [
            {'annual_investment': 5000}, {'annual_investment': 3000},
            {'annual_investment': 2000}, {'annual_investment': 8000},
        ]

        for private_pension in private_pensions:
            PrivatePensionFactory(protection_manager=self.protection_manager,
                                  **private_pension)

    def test_life_insurances_flow(self):
        data = [5000.0, 5000.0, 5000.0, 5000.0, 3000.0, 3000.0, 3000.0, 2000.0,
                2000.0, 2000.0]
        self.assertEqual(self.protection_manager.life_insurances_flow(), data)

    def test_private_pensions_total(self):
        self.assertEqual(self.protection_manager.private_pensions_total(),
                         18000)

    def test_flow(self):
        data = [23000.0, 23000.0, 23000.0, 23000.0, 21000.0, 21000.0, 21000.0,
                20000.0, 20000.0, 20000.0]
        self.assertEqual(self.protection_manager.flow(), data)

class ActualPatrimonySuccessionTest(TestCase):

    def setUp(self):
        reserve_in_lack = _create_reserve_in_lack()
        protection_manager = reserve_in_lack.protection_manager

        for private_pension in protection_manager.private_pensions.all():
            private_pension.delete()

        for life_insurance in protection_manager.life_insurances.all():
            life_insurance.delete()

        private_pensions = [
            {'value': 20000, 'annual_investment': 2000},
            {'value': 4000, 'annual_investment': 200},
        ]

        for private_pension in private_pensions:
            PrivatePensionFactory(**private_pension,
                                  protection_manager=protection_manager)

        life_insurances = [
            {'value_to_pay_annual': 2000, 'value_to_recive': 500000,
                'actual': True},
            {'value_to_pay_annual': 2000, 'value_to_recive': 200000,
                'actual': False},
            {'value_to_pay_annual': 1000, 'value_to_recive': 300000,
                'actual': True}
        ]

        for life_insurance in life_insurances:
            LifeInsuranceFactory(**life_insurance,
                                 protection_manager=protection_manager)

        self.actual_patrimony_succession = protection_manager.\
            actual_patrimony_succession
        self.actual_patrimony_succession.itcmd_tax = 0.06
        self.actual_patrimony_succession.oab_tax = 0.05
        self.actual_patrimony_succession.other_taxes = 0.02
        self.protection_manager = protection_manager

    def test_private_pension_total(self):
        self.assertEqual(self.actual_patrimony_succession.
                         private_pension_total(), 24000)

    def test_dont_have_life_insurance(self):
        for life_insurance in self.protection_manager.life_insurances.all():
            life_insurance.delete()
        self.assertEqual(self.actual_patrimony_succession.
                         life_insurance_to_recive_total(), 0)

    def test_life_insurance_to_recive_total(self):
        self.assertEqual(self.actual_patrimony_succession.
                         life_insurance_to_recive_total(), 800000)

    def test_patrimony_total(self):
        self.assertAlmostEqual(self.actual_patrimony_succession.
                               patrimony_total(), 322788.03)

    def test_patrimony_necessery_to_itcmd(self):
        self.assertAlmostEqual(self.actual_patrimony_succession.
                               patrimony_necessery_to_itcmd, 19367.2818)

    def test_patrimony_necessery_to_itcmd_with_joint_account(self):
        self.actual_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(self.actual_patrimony_succession.
                               patrimony_necessery_to_itcmd, 9683.6409)

    def test_patrimony_necessery_to_oab(self):
        self.assertAlmostEqual(
            self.actual_patrimony_succession.
            patrimony_necessery_to_oab,
            16139.401500000002)

    def test_patrimony_necessery_to_oab_with_joint_account(self):
        self.actual_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(
            self.actual_patrimony_succession.
            patrimony_necessery_to_oab,
            8069.700750000001)

    def test_patrimony_to_other_taxes(self):
        self.assertAlmostEqual(
            self.actual_patrimony_succession.
            patrimony_to_other_taxes,
            6455.7606000000005)

    def test_patrimony_to_other_taxes_joint_account(self):
        self.actual_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(
            self.actual_patrimony_succession.
            patrimony_to_other_taxes,
            3227.8803000000003)

    def test_patrimony_total_to_sucession(self):
        self.assertAlmostEqual(
            self.actual_patrimony_succession.
            patrimony_total_to_sucession,
            41962.443900000006)

    def test_patrimony_necessery_to_sucession_joint_account(self):
        self.actual_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(
            self.actual_patrimony_succession.
            patrimony_total_to_sucession,
            20981.221950000003)

    def test_patrimony_free_of_taxes(self):
        self.assertEqual(self.actual_patrimony_succession.
                         patrimony_free_of_taxes, 824000)

    def test_leftover_after_sucession(self):
        self.assertAlmostEqual(self.actual_patrimony_succession.
                               leftover_after_sucession, 782037.5561)

    def test_need_for_vialicia(self):
        self.assertAlmostEqual(self.actual_patrimony_succession.
                               need_for_vialicia, 509201.2711198457)

class IndependencePatrimonySuccessionTest(TestCase):

    def setUp(self):
        active_client = ActiveClientFactory(
            birthday=datetime.datetime(1967, 1, 1))
        financial_planning = FinancialPlanningFactory(
            active_client=active_client, ipca=0.075)
        protection_manager = ProtectionManagerFactory(
            financial_planning=financial_planning)
        reserve_in_lack = _create_reserve_in_lack()
        protection_manager = reserve_in_lack.protection_manager
        protection_manager.financial_planning = financial_planning

        for private_pension in protection_manager.private_pensions.all():
            private_pension.delete()

        for life_insurance in protection_manager.life_insurances.all():
            life_insurance.delete()

        private_pensions = [
            {'value': 20000, 'annual_investment': 2000, 'rate': 0.1213},
            {'value': 4000, 'annual_investment': 200, 'rate': 0.09},
            {'value': 4000, 'annual_investment': 200, 'rate': 0.09},
        ]

        self.private_pensions_array = []

        for private_pension in private_pensions:
            element = PrivatePensionFactory(
                **private_pension, protection_manager=protection_manager)
            self.private_pensions_array.append(element)

        life_insurances = [
            {'value_to_pay_annual': 2000, 'value_to_recive': 500000,
                'actual': True},
            {'value_to_pay_annual': 2000, 'value_to_recive': 200000,
                'actual': False},
            {'value_to_pay_annual': 1000, 'value_to_recive': 300000,
                'actual': True},
            {'value_to_pay_annual': 1000, 'value_to_recive': 300000,
                'actual': True},
        ]

        for life_insurance in life_insurances:
            LifeInsuranceFactory(**life_insurance,
                                 protection_manager=protection_manager)

        self.future_patrimony_succession =\
            protection_manager.future_patrimony_succession
        self.future_patrimony_succession.itcmd_tax = 0.06
        self.future_patrimony_succession.oab_tax = 0.05
        self.future_patrimony_succession.other_taxes = 0.02
        self.protection_manager = protection_manager

    def test_private_pension_total(self):
        self.assertAlmostEqual(self.future_patrimony_succession.
                               private_pension_total(), 68297.050164)

    def test_private_pension_individual(self):
        self.assertAlmostEqual(self.private_pensions_array[0].
                               value_moniterized(), 54847.2658609)

    def test_dont_have_life_insurance(self):
        for life_insurance in self.protection_manager.life_insurances.all():
            life_insurance.delete()
        self.assertEqual(self.future_patrimony_succession.
                         life_insurance_to_recive_total(), 0)

    def test_life_insurance_to_recive_total(self):
        self.assertEqual(self.future_patrimony_succession.
                         life_insurance_to_recive_total(), 1300000)

    def test_patrimony_total(self):
        self.assertEqual(self.future_patrimony_succession.patrimony_total(),
                         9054063.617092194)

    def test_patrimony_necessery_to_itcmd(self):
        self.assertAlmostEqual(
            self.future_patrimony_succession.patrimony_necessery_to_itcmd,
            543243.8170255317)

    def test_patrimony_necessery_to_itcmd_with_joint_account(self):
        self.future_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(self.future_patrimony_succession.
                               patrimony_necessery_to_itcmd,
                               271621.90851276583)

    def test_patrimony_necessery_to_oab(self):
        self.assertAlmostEqual(self.future_patrimony_succession.
                               patrimony_necessery_to_oab, 452703.1808546097)

    def test_patrimony_necessery_to_oab_with_joint_account(self):
        self.future_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(
            self.future_patrimony_succession.
            patrimony_necessery_to_oab,
            226351.59042730485)

    def test_patrimony_to_other_taxes(self):
        self.assertAlmostEqual(
            self.future_patrimony_succession.
            patrimony_to_other_taxes,
            181081.2723418439)

    def test_patrimony_to_other_taxes_joint_account(self):
        self.future_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(
            self.future_patrimony_succession.
            patrimony_to_other_taxes,
            90540.63617092195)

    def test_patrimony_total_to_sucession(self):
        self.assertAlmostEqual(
            self.future_patrimony_succession.
            patrimony_total_to_sucession,
            1177028.2702219852)

    def test_patrimony_necessery_to_sucession_joint_account(self):
        self.future_patrimony_succession.protection_manager.\
            financial_planning.active_client.bank_account.joint_account = True
        self.assertAlmostEqual(
            self.future_patrimony_succession.
            patrimony_total_to_sucession,
            588514.1351109926)

    def test_patrimony_free_of_taxes(self):
        self.assertAlmostEqual(
            self.future_patrimony_succession.
            patrimony_free_of_taxes,
            1368297.0501640132)

    def test_leftover_after_sucession(self):
        self.assertAlmostEqual(self.future_patrimony_succession.
                               leftover_after_sucession, 191268.77994202799)

    def test_need_for_vialicia(self):
        self.assertAlmostEqual(
            self.future_patrimony_succession.need_for_vialicia,
            8649708.0820540674)

class PrivatePensionTest(TestCase):

    def setUp(self):
        protection_manager = ProtectionManagerFactory()
        self.private_pension = protection_manager.private_pensions.first()

    def test_active_type_when_create(self):
        self.assertEqual(self.private_pension.active_type.name, 'PREVIDÊNCIA')

    def test_active_type_if_deleted(self):
        self.private_pension.active_type.delete()
        self.assertEqual(self.private_pension.active_type.name, 'PREVIDÊNCIA')

    def test_active_type_if_deleted_and_save(self):
        self.private_pension.active_type.delete()
        self.private_pension.active_type.save()
        self.assertEqual(self.private_pension.active_type.name, 'PREVIDÊNCIA')

    def test_active_type_if_changed_name(self):
        self.private_pension.active_type.name = 'Other name'
        self.private_pension.save()
        self.assertEqual(self.private_pension.active_type.name, 'PREVIDÊNCIA')

class HistoricalProtectionCreateTest(TestCase):

    def test_all_models(self):
        models = [ReserveInLack, LifeInsurance, PrivatePension,
                  ActualPatrimonySuccession, IndependencePatrimonySuccession]
        test_all_create_historic(self, models, ProtectionManagerFactory)

    # This method is to correct pylint error
    def emergency_reserve_case(self, model):
        financial_planning = FinancialPlanningFactory()
        patrimony = financial_planning.patrimony
        self.assertEqual(0, model.history.count())
        EmergencyReserveFactory(patrimony=patrimony,
                                cost_manager=financial_planning.cost_manager)
        self.assertEqual(1, model.history.count())

    def test_emergency_reserve(self):
        self.emergency_reserve_case(EmergencyReserve)


# Предлагаем пользователю ввести исходные данные. Переводим последовательность в список и число в тип "число". Исключаем ошибки ввода
try:
    array = list(map(int, input("Введите последовательность чисел через пробел: ").split()))
    if len(array) == 1:
        print("Ошибка! Вы ввели только одно число. Пожалуйста, перезапустите код и введите несколько чисел ЧЕРЕЗ ПРОБЕЛ!")
        exit()
except ValueError:
    print("Ошибка! Вы ввели символы, отличные от чисел и пробелов. Пожалуйста, перезапустите код и введите только числа через пробел!")
    exit()
try:
    element = int(input("Введите одно любое число: "))
except ValueError:
    print("Ошибка! Вы ввели символы, отличные от числа. Пожалуйста, перезапустите код и введите на этом шаге ОДНО ЧИСЛО!")
    exit()

# Добавляем число element в последовательность (список) array
array.append(element)

# Функция "быстрой сортировки" списка по возрастанию с применением случайной выборки ведущего элемента
import random
def qsort_random(array, left, right):
    p = random.choice(array[left:right + 1])
    i, j = left, right
    while i <= j:
        while array[i] < p:
            i += 1
        while array[j] > p:
            j -= 1
        if i <= j:
            array[i], array[j] = array[j], array[i]
            i += 1
            j -= 1
    if j > left:
       qsort_random(array, left, j)
    if right > i:
       qsort_random(array, i, right)
    return array

# Применяем функцию "быстрой сортировки"
array_sorted = qsort_random(array, 0, len(array) - 1)

# Функция "двоичного поиска" индекса элемента, стоящего до элемента element, в отсортированном списке array (+условия задачи)
def binary_search(array_sorted, element, left, right):
    middle = (right + left) // 2
    if array_sorted[middle] == element:
        # исключим вероятность, что поиск нашел не первое вхождение числа element, дойдем до первого вхождения
        while array_sorted[middle] == array_sorted[middle - 1]:
          middle = middle - 1
        # пропишем случай, когда в списке нет чисел меньше искомого числа element
        if middle == 0:
            return f"Элемента, меньшего, чем {element}, во введенной последовательности нет. Задача не имеет решения."
        # пропишем случай, когда большего или равного искомому числу element чисел в списке нет
        elif middle == len(array_sorted) - 1:
            return f"Элемента, большего, чем {element}, во введенной последовательности нет. Задача не имеет решения."
        # пропишем случай, когда число element дублировало самое большое число последовательности, но такое число в начальной последовательности было одно
        elif middle == len(array_sorted) - 2 and array_sorted[len(array_sorted) - 2] == array_sorted[len(array_sorted) - 1]:
            return f"Элемента, большего, чем {element}, во введенной последовательности нет. Задача не имеет решения."
        # и, наконец, когда учли все частные случаи, найдем индекс элемента, идущего до числа element в отсортированной последовательности
        else:
            index = middle - 1
            return f"Ответ: '{index}' - номер позиции элемента, который меньше введенного числа {element}, а следующий за ним элемент больше или равен этому числу."

    elif element < array_sorted[middle]:
        return binary_search(array_sorted, element, left, middle - 1)
    else:
        return binary_search(array_sorted, element, middle + 1, right)

# Применяем функцию "двоичного поиска" и выводим ответ
print(binary_search(array_sorted, element, 0, len(array_sorted) - 1))


import cv2
import numpy as np

class Helper:
    """
    Helper class for image operations.
    """

    @staticmethod
    def apply_transparency_mask(image):
        """
        Sets any black pixels to transparent.
        :param image: Image to set transparency
        :type image: numpy.ndarray
        :rtype: numpy.ndarray
        """

        if image.shape[2] == 3:

            b_channel, g_channel, r_channel = cv2.split(image)

            alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255

            image = cv2.merge((b_channel, g_channel, r_channel, alpha_channel))

        image[np.all(image == [0, 0, 0, 255], axis=2)] = [0, 0, 0, 0]

        return image

    @staticmethod
    def scale_image(image, scale):
        """
        Uses nearest neighbour scaling to scale an image by a given scaling factor.
        :param image: Image to scale
        :type image: numpy.ndarray
        :param scale: scale factor to scale image.
        :type scale: float
        :return: Returns resized image
        :rtype: numpy.ndarray
        """
        return cv2.resize(image, (0, 0), fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST)


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

matplotlib.use('TkAgg')
data = pd.read_csv('../data/2015.csv')
fig, ax = plt.subplots()
fig.patch.set_visible(False)
ax.axis('off')

# print(by_region)
""" Question: What is most important for happiness score? """
rank = []
for col in data.columns[5:10]:
    series = data[col].to_numpy()
    happy = data['Happiness Score'].to_numpy()
    reg = sp.stats.linregress(series, happy)
    row = {'Criterion' : col, 'Correlation' : reg.rvalue,
           '(Slope, Intercept)' : (reg.slope, reg.intercept)}
    rank.append(row)

df = pd.DataFrame(rank)
df.sort_values(['Correlation'], ascending = False, inplace = True)
table = ax.table(cellText = df.values,
                 colLabels = df.columns,
                 loc = 'center')
ax.axis('off')
plt.show()


from collections import Counter

def solution(a):
    if len(a) < 4:
        return 0
    counter = Counter(a)
    answer = 0
    for x in counter.keys():
        if counter[x] < answer:
            continue
        i = 0
        cnt = 0
        while i < len(a) - 1:
            if (a[i] == a[i + 1]) or (a[i] != x and a[i + 1] != x):
                i += 1
            else:
                i += 2
                cnt += 1
        answer = max(answer, cnt)
    return answer * 2


import datetime

from django.shortcuts import render, redirect
from googleapiclient.discovery import build

from smir.models import UserCredentials
from .mqtt import client
from .utils import refresh_token

def index(request):
    if request.user.is_authenticated:
        try:
            UserCredentials.objects.get(user=request.user)
            return redirect('/profile')
        except UserCredentials.DoesNotExist:
            return redirect('user_face_data')

    else:
        return redirect('/login')

def my_login(request):
    return render(request, 'login.html')

def profile(request):
    creds = refresh_token(request.user.username)
    service = build('calendar', 'v3', credentials=creds)

    # Call the Calendar API
    time = (datetime.datetime.utcnow() - datetime.timedelta(days=2)).isoformat() + 'Z'  # 'Z' indicates UTC time
    print('Getting the upcoming 10 events')
    events_result = service.events().list(calendarId='primary', timeMin=time,
                                          maxResults=10, singleEvents=True,
                                          orderBy='startTime').execute()
    events = events_result.get('items', [])
    print(events)
    if not events:
        print('No upcoming events found.')
    for event in events:
        start = event['start'].get('dateTime', event['start'].get('date'))
        print(start, event['summary'])

    task_service = build('tasks', 'v1', credentials=creds)

    # Call the Tasks API
    results = task_service.tasklists().list(maxResults=10).execute()
    items = results.get('items', [])
    user_tasks = []
    if not items:
        print('No task lists found.')
    else:
        print('Task lists:')
        for item in items:
            print(u'{0} ({1})'.format(item['title'], item['id']))
            tasks = task_service.tasks().list(tasklist=item['id']).execute()
            for task in tasks['items']:
                user_tasks.append(task['title'])
        print(user_tasks)
    return render(request, 'profile.html', {'events': events})

def user_get_data(request):
    refresh_token(request.user.username)
    client.publish(topic='camera/signup', payload=request.user.username)
    return render(request, 'profile.html')


import copy
import os
from collections import OrderedDict
from typing import TYPE_CHECKING, Any, Mapping, Optional, Union

if TYPE_CHECKING:
    from ...processing_utils import ProcessorMixin
    from ...utils import TensorType

from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfig
from ...utils import logging

logger = logging.get_logger(__name__)

CLIP_PRETRAINED_CONFIG_ARCHIVE_MAP = {
    "openai/clip-vit-base-patch32": "https://huggingface.co/openai/clip-vit-base-patch32/resolve/main/config.json",
    # See all CLIP models at https://huggingface.co/models?filter=clip
}

class CLIPTextConfig(PretrainedConfig):
    r"""
    This is the configuration class to store the configuration of a [`CLIPModel`]. It is used to instantiate an CLIP
    model according to the specified arguments, defining the model architecture. Instantiating a configuration with the
    defaults will yield a similar configuration to that of the CLIP
    [openai/clip-vit-base-patch32](https://huggingface.co/openai/clip-vit-base-patch32) architecture.

    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
    documentation from [`PretrainedConfig`] for more information.

    Args:
        vocab_size (`int`, *optional*, defaults to 49408):
            Vocabulary size of the CLIP text model. Defines the number of different tokens that can be represented by
            the `inputs_ids` passed when calling [`CLIPModel`].
        hidden_size (`int`, *optional*, defaults to 512):
            Dimensionality of the encoder layers and the pooler layer.
        intermediate_size (`int`, *optional*, defaults to 2048):
            Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder.
        num_hidden_layers (`int`, *optional*, defaults to 12):
            Number of hidden layers in the Transformer encoder.
        num_attention_heads (`int`, *optional*, defaults to 8):
            Number of attention heads for each attention layer in the Transformer encoder.
        max_position_embeddings (`int`, *optional*, defaults to 77):
            The maximum sequence length that this model might ever be used with. Typically set this to something large
            just in case (e.g., 512 or 1024 or 2048).
        hidden_act (`str` or `function`, *optional*, defaults to `"quick_gelu"`):
            The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`,
            `"relu"`, `"selu"` and `"gelu_new"` ``"quick_gelu"` are supported. layer_norm_eps (`float`, *optional*,
            defaults to 1e-5): The epsilon used by the layer normalization layers.
        attention_dropout (`float`, *optional*, defaults to 0.0):
            The dropout ratio for the attention probabilities.
        dropout (`float`, *optional*, defaults to 0.0):
            The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler.
        initializer_range (`float`, *optional*, defaults to 0.02):
            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
        initializer_factor (`float``, *optional*, defaults to 1):
            A factor for initializing all weight matrices (should be kept to 1, used internally for initialization
            testing).

    Example:

    ```python
    >>> from transformers import CLIPTextConfig, CLIPTextModel

    >>> # Initializing a CLIPTextConfig with openai/clip-vit-base-patch32 style configuration
    >>> configuration = CLIPTextConfig()

    >>> # Initializing a CLIPTextModel (with random weights) from the openai/clip-vit-base-patch32 style configuration
    >>> model = CLIPTextModel(configuration)

    >>> # Accessing the model configuration
    >>> configuration = model.config
    ```"""
    model_type = "clip_text_model"

    def __init__(
        self,
        vocab_size=49408,
        hidden_size=512,
        intermediate_size=2048,
        num_hidden_layers=12,
        num_attention_heads=8,
        max_position_embeddings=77,
        hidden_act="quick_gelu",
        layer_norm_eps=0.00001,
        dropout=0.0,
        attention_dropout=0.0,
        initializer_range=0.02,
        initializer_factor=1.0,
        pad_token_id=1,
        bos_token_id=0,
        eos_token_id=2,
        **kwargs
    ):
        super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)

        self.vocab_size = vocab_size
        self.hidden_size = hidden_size
        self.intermediate_size = intermediate_size
        self.dropout = dropout
        self.num_hidden_layers = num_hidden_layers
        self.num_attention_heads = num_attention_heads
        self.max_position_embeddings = max_position_embeddings
        self.layer_norm_eps = layer_norm_eps
        self.hidden_act = hidden_act
        self.initializer_range = initializer_range
        self.initializer_factor = initializer_factor
        self.attention_dropout = attention_dropout

    @classmethod
    def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig":

        config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs)

        # get the text config dict if we are loading from CLIPConfig
        if config_dict.get("model_type") == "clip":
            config_dict = config_dict["text_config"]

        if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type:
            logger.warning(
                f"You are using a model of type {config_dict['model_type']} to instantiate a model of type "
                f"{cls.model_type}. This is not supported for all configurations of models and can yield errors."
            )

        return cls.from_dict(config_dict, **kwargs)

class CLIPVisionConfig(PretrainedConfig):
    r"""
    This is the configuration class to store the configuration of a [`CLIPModel`]. It is used to instantiate an CLIP
    model according to the specified arguments, defining the model architecture. Instantiating a configuration with the
    defaults will yield a similar configuration to that of the CLIP
    [openai/clip-vit-base-patch32](https://huggingface.co/openai/clip-vit-base-patch32) architecture.

    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
    documentation from [`PretrainedConfig`] for more information.

    Args:
        hidden_size (`int`, *optional*, defaults to 768):
            Dimensionality of the encoder layers and the pooler layer.
        intermediate_size (`int`, *optional*, defaults to 3072):
            Dimensionality of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder.
        num_hidden_layers (`int`, *optional*, defaults to 12):
            Number of hidden layers in the Transformer encoder.
        num_attention_heads (`int`, *optional*, defaults to 12):
            Number of attention heads for each attention layer in the Transformer encoder.
        image_size (`int`, *optional*, defaults to 224):
            The size (resolution) of each image.
        patch_size (`int`, *optional*, defaults to 32):
            The size (resolution) of each patch.
        hidden_act (`str` or `function`, *optional*, defaults to `"quick_gelu"`):
            The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`,
            `"relu"`, `"selu"` and `"gelu_new"` ``"quick_gelu"` are supported. layer_norm_eps (`float`, *optional*,
            defaults to 1e-5): The epsilon used by the layer normalization layers.
        dropout (`float`, *optional*, defaults to 0.0):
            The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler.
        attention_dropout (`float`, *optional*, defaults to 0.0):
            The dropout ratio for the attention probabilities.
        initializer_range (`float`, *optional*, defaults to 0.02):
            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
        initializer_factor (`float``, *optional*, defaults to 1):
            A factor for initializing all weight matrices (should be kept to 1, used internally for initialization
            testing).

    Example:

    ```python
    >>> from transformers import CLIPVisionConfig, CLIPVisionModel

    >>> # Initializing a CLIPVisionConfig with openai/clip-vit-base-patch32 style configuration
    >>> configuration = CLIPVisionConfig()

    >>> # Initializing a CLIPVisionModel (with random weights) from the openai/clip-vit-base-patch32 style configuration
    >>> model = CLIPVisionModel(configuration)

    >>> # Accessing the model configuration
    >>> configuration = model.config
    ```"""

    model_type = "clip_vision_model"

    def __init__(
        self,
        hidden_size=768,
        intermediate_size=3072,
        num_hidden_layers=12,
        num_attention_heads=12,
        num_channels=3,
        image_size=224,
        patch_size=32,
        hidden_act="quick_gelu",
        layer_norm_eps=0.00001,
        dropout=0.0,
        attention_dropout=0.0,
        initializer_range=0.02,
        initializer_factor=1.0,
        **kwargs
    ):
        super().__init__(**kwargs)

        self.hidden_size = hidden_size
        self.intermediate_size = intermediate_size
        self.dropout = dropout
        self.num_hidden_layers = num_hidden_layers
        self.num_attention_heads = num_attention_heads
        self.num_channels = num_channels
        self.patch_size = patch_size
        self.image_size = image_size
        self.initializer_range = initializer_range
        self.initializer_factor = initializer_factor
        self.attention_dropout = attention_dropout
        self.layer_norm_eps = layer_norm_eps
        self.hidden_act = hidden_act

    @classmethod
    def from_pretrained(cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs) -> "PretrainedConfig":

        config_dict, kwargs = cls.get_config_dict(pretrained_model_name_or_path, **kwargs)

        # get the vision config dict if we are loading from CLIPConfig
        if config_dict.get("model_type") == "clip":
            config_dict = config_dict["vision_config"]

        if "model_type" in config_dict and hasattr(cls, "model_type") and config_dict["model_type"] != cls.model_type:
            logger.warning(
                f"You are using a model of type {config_dict['model_type']} to instantiate a model of type "
                f"{cls.model_type}. This is not supported for all configurations of models and can yield errors."
            )

        return cls.from_dict(config_dict, **kwargs)

class CLIPConfig(PretrainedConfig):
    r"""
    [`CLIPConfig`] is the configuration class to store the configuration of a [`CLIPModel`]. It is used to instantiate
    CLIP model according to the specified arguments, defining the text model and vision model configs. Instantiating a
    configuration with the defaults will yield a similar configuration to that of the CLIP
    [openai/clip-vit-base-patch32](https://huggingface.co/openai/clip-vit-base-patch32) architecture.

    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
    documentation from [`PretrainedConfig`] for more information.

    Args:
        text_config_dict (`dict`, *optional*):
            Dictionary of configuration options used to initialize [`CLIPTextConfig`].
        vision_config_dict (`dict`, *optional*):
            Dictionary of configuration options used to initialize [`CLIPVisionConfig`].
        projection_dim (`int`, *optional*, defaults to 512):
            Dimentionality of text and vision projection layers.
        logit_scale_init_value (`float`, *optional*, defaults to 2.6592):
            The inital value of the *logit_scale* paramter. Default is used as per the original CLIP implementation.
        kwargs (*optional*):
            Dictionary of keyword arguments.

    Example:

    ```python
    >>> from transformers import CLIPConfig, CLIPModel

    >>> # Initializing a CLIPConfig with openai/clip-vit-base-patch32 style configuration
    >>> configuration = CLIPConfig()

    >>> # Initializing a CLIPModel (with random weights) from the openai/clip-vit-base-patch32 style configuration
    >>> model = CLIPModel(configuration)

    >>> # Accessing the model configuration
    >>> configuration = model.config

    >>> # We can also initialize a CLIPConfig from a CLIPTextConfig and a CLIPVisionConfig

    >>> # Initializing a CLIPText and CLIPVision configuration
    >>> config_text = CLIPTextConfig()
    >>> config_vision = CLIPVisionConfig()

    >>> config = CLIPConfig.from_text_vision_configs(config_text, config_vision)
    ```"""

    model_type = "clip"
    is_composition = True

    def __init__(
        self,
        text_config_dict=None,
        vision_config_dict=None,
        projection_dim=512,
        logit_scale_init_value=2.6592,
        **kwargs
    ):
        super().__init__(text_config_dict=text_config_dict, vision_config_dict=vision_config_dict, **kwargs)

        if text_config_dict is None:
            text_config_dict = {}
            logger.info("text_config_dict is None. Initializing the CLIPTextConfig with default values.")

        if vision_config_dict is None:
            vision_config_dict = {}
            logger.info("vision_config_dict is None. initializing the CLIPVisionConfig with default values.")

        self.text_config = CLIPTextConfig(**text_config_dict)
        self.vision_config = CLIPVisionConfig(**vision_config_dict)

        self.projection_dim = projection_dim
        self.logit_scale_init_value = logit_scale_init_value
        self.initializer_factor = 1.0

    @classmethod
    def from_text_vision_configs(cls, text_config: CLIPTextConfig, vision_config: CLIPVisionConfig, **kwargs):
        r"""
        Instantiate a [`CLIPConfig`] (or a derived class) from clip text model configuration and clip vision model
        configuration.

        Returns:
            [`CLIPConfig`]: An instance of a configuration object
        """

        return cls(text_config_dict=text_config.to_dict(), vision_config_dict=vision_config.to_dict(), **kwargs)

    def to_dict(self):
        """
        Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`].

        Returns:
            `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
        """
        output = copy.deepcopy(self.__dict__)
        output["text_config"] = self.text_config.to_dict()
        output["vision_config"] = self.vision_config.to_dict()
        output["model_type"] = self.__class__.model_type
        return output

class CLIPOnnxConfig(OnnxConfig):
    @property
    def inputs(self) -> Mapping[str, Mapping[int, str]]:
        return OrderedDict(
            [
                ("input_ids", {0: "batch", 1: "sequence"}),
                ("pixel_values", {0: "batch", 1: "num_channels", 2: "height", 3: "width"}),
                ("attention_mask", {0: "batch", 1: "sequence"}),
            ]
        )

    @property
    def outputs(self) -> Mapping[str, Mapping[int, str]]:
        return OrderedDict(
            [
                ("logits_per_image", {0: "batch"}),
                ("logits_per_text", {0: "batch"}),
                ("text_embeds", {0: "batch"}),
                ("image_embeds", {0: "batch"}),
            ]
        )

    @property
    def atol_for_validation(self) -> float:
        return 1e-4

    def generate_dummy_inputs(
        self,
        processor: "ProcessorMixin",
        batch_size: int = -1,
        seq_length: int = -1,
        framework: Optional["TensorType"] = None,
    ) -> Mapping[str, Any]:

        text_input_dict = super().generate_dummy_inputs(
            processor.tokenizer, batch_size=batch_size, seq_length=seq_length, framework=framework
        )
        image_input_dict = super().generate_dummy_inputs(
            processor.feature_extractor, batch_size=batch_size, framework=framework
        )
        return {**text_input_dict, **image_input_dict}

    @property
    def default_onnx_opset(self) -> int:
        return 14


#!/usr/bin/python3
""" Addition """

def add_integer(a, b):
    """
    A and B must be ints or floats
    otherwise TypeError raise.
    A and B must be casted if they are floats.
    Returns an int.
    """
    if isinstance(a, float):
        a = int(a)
    if isinstance(b, float):
        b = int(b)
    if not (isinstance(a, int) or isinstance(a, float)):
        raise TypeError("a must be an integer")
    if not (isinstance(b, int) or isinstance(b, float)):
        raise TypeError("b must be an integer")
    return (a + b)


"""Wrapper around a Power BI endpoint."""
from __future__ import annotations

import asyncio
import logging
import os
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Union

import aiohttp
import requests
from aiohttp import ServerTimeoutError
from langchain_core.pydantic_v1 import BaseModel, Field, root_validator, validator
from requests.exceptions import Timeout

logger = logging.getLogger(__name__)

BASE_URL = os.getenv("POWERBI_BASE_URL", "https://api.powerbi.com/v1.0/myorg")

if TYPE_CHECKING:
    from azure.core.credentials import TokenCredential

class PowerBIDataset(BaseModel):
    """Create PowerBI engine from dataset ID and credential or token.

    Use either the credential or a supplied token to authenticate.
    If both are supplied the credential is used to generate a token.
    The impersonated_user_name is the UPN of a user to be impersonated.
    If the model is not RLS enabled, this will be ignored.
    """

    dataset_id: str
    table_names: List[str]
    group_id: Optional[str] = None
    credential: Optional[TokenCredential] = None
    token: Optional[str] = None
    impersonated_user_name: Optional[str] = None
    sample_rows_in_table_info: int = Field(default=1, gt=0, le=10)
    schemas: Dict[str, str] = Field(default_factory=dict)
    aiosession: Optional[aiohttp.ClientSession] = None

    class Config:
        """Configuration for this pydantic object."""

        arbitrary_types_allowed = True

    @validator("table_names", allow_reuse=True)
    def fix_table_names(cls, table_names: List[str]) -> List[str]:
        """Fix the table names."""
        return [fix_table_name(table) for table in table_names]

    @root_validator(pre=True, allow_reuse=True)
    def token_or_credential_present(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        """Validate that at least one of token and credentials is present."""
        if "token" in values or "credential" in values:
            return values
        raise ValueError("Please provide either a credential or a token.")

    @property
    def request_url(self) -> str:
        """Get the request url."""
        if self.group_id:
            return f"{BASE_URL}/groups/{self.group_id}/datasets/{self.dataset_id}/executeQueries"  # noqa: E501 # pylint: disable=C0301
        return f"{BASE_URL}/datasets/{self.dataset_id}/executeQueries"  # noqa: E501 # pylint: disable=C0301

    @property
    def headers(self) -> Dict[str, str]:
        """Get the token."""
        if self.token:
            return {
                "Content-Type": "application/json",
                "Authorization": "Bearer " + self.token,
            }
        from azure.core.exceptions import (
            ClientAuthenticationError,  # pylint: disable=import-outside-toplevel
        )

        if self.credential:
            try:
                token = self.credential.get_token(
                    "https://analysis.windows.net/powerbi/api/.default"
                ).token
                return {
                    "Content-Type": "application/json",
                    "Authorization": "Bearer " + token,
                }
            except Exception as exc:  # pylint: disable=broad-exception-caught
                raise ClientAuthenticationError(
                    "Could not get a token from the supplied credentials."
                ) from exc
        raise ClientAuthenticationError("No credential or token supplied.")

    def get_table_names(self) -> Iterable[str]:
        """Get names of tables available."""
        return self.table_names

    def get_schemas(self) -> str:
        """Get the available schema's."""
        if self.schemas:
            return ", ".join([f"{key}: {value}" for key, value in self.schemas.items()])
        return "No known schema's yet. Use the schema_powerbi tool first."

    @property
    def table_info(self) -> str:
        """Information about all tables in the database."""
        return self.get_table_info()

    def _get_tables_to_query(
        self, table_names: Optional[Union[List[str], str]] = None
    ) -> Optional[List[str]]:
        """Get the tables names that need to be queried, after checking they exist."""
        if table_names is not None:
            if (
                isinstance(table_names, list)
                and len(table_names) > 0
                and table_names[0] != ""
            ):
                fixed_tables = [fix_table_name(table) for table in table_names]
                non_existing_tables = [
                    table for table in fixed_tables if table not in self.table_names
                ]
                if non_existing_tables:
                    logger.warning(
                        "Table(s) %s not found in dataset.",
                        ", ".join(non_existing_tables),
                    )
                tables = [
                    table for table in fixed_tables if table not in non_existing_tables
                ]
                return tables if tables else None
            if isinstance(table_names, str) and table_names != "":
                if table_names not in self.table_names:
                    logger.warning("Table %s not found in dataset.", table_names)
                    return None
                return [fix_table_name(table_names)]
        return self.table_names

    def _get_tables_todo(self, tables_todo: List[str]) -> List[str]:
        """Get the tables that still need to be queried."""
        return [table for table in tables_todo if table not in self.schemas]

    def _get_schema_for_tables(self, table_names: List[str]) -> str:
        """Create a string of the table schemas for the supplied tables."""
        schemas = [
            schema for table, schema in self.schemas.items() if table in table_names
        ]
        return ", ".join(schemas)

    def get_table_info(
        self, table_names: Optional[Union[List[str], str]] = None
    ) -> str:
        """Get information about specified tables."""
        tables_requested = self._get_tables_to_query(table_names)
        if tables_requested is None:
            return "No (valid) tables requested."
        tables_todo = self._get_tables_todo(tables_requested)
        for table in tables_todo:
            self._get_schema(table)
        return self._get_schema_for_tables(tables_requested)

    async def aget_table_info(
        self, table_names: Optional[Union[List[str], str]] = None
    ) -> str:
        """Get information about specified tables."""
        tables_requested = self._get_tables_to_query(table_names)
        if tables_requested is None:
            return "No (valid) tables requested."
        tables_todo = self._get_tables_todo(tables_requested)
        await asyncio.gather(*[self._aget_schema(table) for table in tables_todo])
        return self._get_schema_for_tables(tables_requested)

    def _get_schema(self, table: str) -> None:
        """Get the schema for a table."""
        try:
            result = self.run(
                f"EVALUATE TOPN({self.sample_rows_in_table_info}, {table})"
            )
            self.schemas[table] = json_to_md(result["results"][0]["tables"][0]["rows"])
        except Timeout:
            logger.warning("Timeout while getting table info for %s", table)
            self.schemas[table] = "unknown"
        except Exception as exc:  # pylint: disable=broad-exception-caught
            logger.warning("Error while getting table info for %s: %s", table, exc)
            self.schemas[table] = "unknown"

    async def _aget_schema(self, table: str) -> None:
        """Get the schema for a table."""
        try:
            result = await self.arun(
                f"EVALUATE TOPN({self.sample_rows_in_table_info}, {table})"
            )
            self.schemas[table] = json_to_md(result["results"][0]["tables"][0]["rows"])
        except ServerTimeoutError:
            logger.warning("Timeout while getting table info for %s", table)
            self.schemas[table] = "unknown"
        except Exception as exc:  # pylint: disable=broad-exception-caught
            logger.warning("Error while getting table info for %s: %s", table, exc)
            self.schemas[table] = "unknown"

    def _create_json_content(self, command: str) -> dict[str, Any]:
        """Create the json content for the request."""
        return {
            "queries": [{"query": rf"{command}"}],
            "impersonatedUserName": self.impersonated_user_name,
            "serializerSettings": {"includeNulls": True},
        }

    def run(self, command: str) -> Any:
        """Execute a DAX command and return a json representing the results."""
        logger.debug("Running command: %s", command)
        response = requests.post(
            self.request_url,
            json=self._create_json_content(command),
            headers=self.headers,
            timeout=10,
        )
        if response.status_code == 403:
            return (
                "TokenError: Could not login to PowerBI, please check your credentials."
            )
        return response.json()

    async def arun(self, command: str) -> Any:
        """Execute a DAX command and return the result asynchronously."""
        logger.debug("Running command: %s", command)
        if self.aiosession:
            async with self.aiosession.post(
                self.request_url,
                headers=self.headers,
                json=self._create_json_content(command),
                timeout=10,
            ) as response:
                if response.status == 403:
                    return "TokenError: Could not login to PowerBI, please check your credentials."  # noqa: E501
                response_json = await response.json(content_type=response.content_type)
                return response_json
        async with aiohttp.ClientSession() as session:
            async with session.post(
                self.request_url,
                headers=self.headers,
                json=self._create_json_content(command),
                timeout=10,
            ) as response:
                if response.status == 403:
                    return "TokenError: Could not login to PowerBI, please check your credentials."  # noqa: E501
                response_json = await response.json(content_type=response.content_type)
                return response_json

def json_to_md(
    json_contents: List[Dict[str, Union[str, int, float]]],
    table_name: Optional[str] = None,
) -> str:
    """Converts a JSON object to a markdown table."""
    if len(json_contents) == 0:
        return ""
    output_md = ""
    headers = json_contents[0].keys()
    for header in headers:
        header.replace("[", ".").replace("]", "")
        if table_name:
            header.replace(f"{table_name}.", "")
        output_md += f"| {header} "
    output_md += "|\n"
    for row in json_contents:
        for value in row.values():
            output_md += f"| {value} "
        output_md += "|\n"
    return output_md

def fix_table_name(table: str) -> str:
    """Add single quotes around table names that contain spaces."""
    if " " in table and not table.startswith("'") and not table.endswith("'"):
        return f"'{table}'"
    return table


"""
homeassistant.components.alarm_control_panel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Component to interface with a alarm control panel.
"""
import logging
import os

from homeassistant.components import verisure
from homeassistant.const import (
    ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
    SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY)
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent

DOMAIN = 'alarm_control_panel'
SCAN_INTERVAL = 30

ENTITY_ID_FORMAT = DOMAIN + '.{}'

# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
    verisure.DISCOVER_SENSORS: 'verisure'
}

SERVICE_TO_METHOD = {
    SERVICE_ALARM_DISARM: 'alarm_disarm',
    SERVICE_ALARM_ARM_HOME: 'alarm_arm_home',
    SERVICE_ALARM_ARM_AWAY: 'alarm_arm_away',
    SERVICE_ALARM_TRIGGER: 'alarm_trigger'
}

ATTR_CODE = 'code'
ATTR_CODE_FORMAT = 'code_format'

ATTR_TO_PROPERTY = [
    ATTR_CODE,
    ATTR_CODE_FORMAT
]

def setup(hass, config):
    """ Track states and offer events for sensors. """
    component = EntityComponent(
        logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL,
        DISCOVERY_PLATFORMS)

    component.setup(config)

    def alarm_service_handler(service):
        """ Maps services to methods on Alarm. """
        target_alarms = component.extract_from_service(service)

        if ATTR_CODE not in service.data:
            code = None
        else:
            code = service.data[ATTR_CODE]

        method = SERVICE_TO_METHOD[service.service]

        for alarm in target_alarms:
            getattr(alarm, method)(code)

    descriptions = load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    for service in SERVICE_TO_METHOD:
        hass.services.register(DOMAIN, service, alarm_service_handler,
                               descriptions.get(service))

    return True

def alarm_disarm(hass, code=None, entity_id=None):
    """ Send the alarm the command for disarm. """
    data = {}
    if code:
        data[ATTR_CODE] = code
    if entity_id:
        data[ATTR_ENTITY_ID] = entity_id

    hass.services.call(DOMAIN, SERVICE_ALARM_DISARM, data)

def alarm_arm_home(hass, code=None, entity_id=None):
    """ Send the alarm the command for arm home. """
    data = {}
    if code:
        data[ATTR_CODE] = code
    if entity_id:
        data[ATTR_ENTITY_ID] = entity_id

    hass.services.call(DOMAIN, SERVICE_ALARM_ARM_HOME, data)

def alarm_arm_away(hass, code=None, entity_id=None):
    """ Send the alarm the command for arm away. """
    data = {}
    if code:
        data[ATTR_CODE] = code
    if entity_id:
        data[ATTR_ENTITY_ID] = entity_id

    hass.services.call(DOMAIN, SERVICE_ALARM_ARM_AWAY, data)

def alarm_trigger(hass, code=None, entity_id=None):
    """ Send the alarm the command for trigger. """
    data = {}
    if code:
        data[ATTR_CODE] = code
    if entity_id:
        data[ATTR_ENTITY_ID] = entity_id

    hass.services.call(DOMAIN, SERVICE_ALARM_TRIGGER, data)

# pylint: disable=no-self-use
class AlarmControlPanel(Entity):
    """ ABC for alarm control devices. """

    @property
    def code_format(self):
        """ regex for code format or None if no code is required. """
        return None

    def alarm_disarm(self, code=None):
        """ Send disarm command. """
        raise NotImplementedError()

    def alarm_arm_home(self, code=None):
        """ Send arm home command. """
        raise NotImplementedError()

    def alarm_arm_away(self, code=None):
        """ Send arm away command. """
        raise NotImplementedError()

    def alarm_trigger(self, code=None):
        """ Send alarm trigger command. """
        raise NotImplementedError()

    @property
    def state_attributes(self):
        """ Return the state attributes. """
        state_attr = {
            ATTR_CODE_FORMAT: self.code_format,
            }
        return state_attr


#  1.Write a Python program to get a single string from two given strings, separated by a space, and
# swap the first two characters of each string

def get_string(a, b):
    word1 = a[:2] + b[2:]
    word2 = b[:2] + a[2:]
    return word1+ " "+word2
print(get_string("cynthia","ishimwe"))

#  10.Write a Python function to remove all vowels in a string
def remove_vowels(name):
    vowels =('a','i','u','o','e')
    empty = " "
    for i in name:
        if i not in vowels:
            empty += i
    return empty
name = "beautiful"
print(remove_vowels(name))

# 7. Given a list of numbers, use list comprehension to
# remove all odd numbers from the list:
# numbers = [3,5,45,97,32,22,10,19,39,43]

def remove_odd_nums(numbers):

    newArray = [x for x in numbers if x%2 ==0]
    return newArray
numbers = [3,5,45,97,32,22,10,19,39,43]
print(remove_odd_nums(numbers))

#  4.Write a Python function that takes two lists and
# returns True if they have at least one common member.

def common_members(a,b):

    for i in a:
        for x in b:
         if i ==x:
             return True
         else:
             False

a = [10,20,30,40,50]
b = [20,70,80,90,50]
print (common_members(a,b))

# 9. Use a nested list comprehension to find all of the numbers from 1-1000
# that are divisible by any single digit besides 1 (2-9)

def divisible_nums():
    newNums = [num for num in range(1, 1001) if (num % i == 0 for i in range(2, 10))]
    return newNums
print(divisible_nums())

# 5.Write a Python program to convert a list to a list of dictionaries.
# Sample lists: ["Black", "Red", "Maroon", "Yellow"],
# ["#000000", "#FF0000", "#800000", "#FFFF00"]

def color_dictionary(a,b):
 a=["Black", "Red", "Maroon", "Yellow"]
 b=["#000000", "#FF0000", "#800000", "#FFFF00"]
list_of_dicts = dict(zip(a,b))
print(color_dictionary(a,b))

# Write a Python program to check whether all dictionaries in a list are empty or not

list1 = [{}, {}, {}]
list2 = [{}, {"key": "value"}, {}]

def dict(dict_list):
    return all(not d for d in dict_list)

print(dict(list1))
print(dict (list2))

# Write a Python program that accepts a comma-separated sequence of words as input
# and prints the distinct words in sorted form (alphanumerically).
def words (words):
    words_list = words.split(",")
    output = sorted(words_list)
    for i in output:
        print(i)

words("wel,helllo,my,name,hopper")


from flask import Flask, request, send_file, render_template, jsonify
from time import sleep, time
from queue import Queue
import pandas as pd
import threading
import pickle
from geobr import read_municipality, read_municipal_seat
from os import path
import uuid
import sys
import subprocess
from os.path import exists, realpath
import json
import base64

sys.setrecursionlimit(1024)

# Init global variables
queue = Queue()
max_threads = 2
threads = [None]*max_threads
outputs = [None]*max_threads
images  = [None]*max_threads
user_execution = {}
pd_df = None

start_time = time()

def read_csvs(pd_df: pd.DataFrame) -> pd.DataFrame:
    altura_idade = {
        -1: -1,
        0: 0,
        None: 0,
        'Muito baixa estatura para idade': 1,
        'Baixa estatura para idade': 2,
        'Estatura adequada para a idade': 3,
    }

    imc_idade = {
        -1: -1,
        0: 0,
        None: 0,
        'Magreza acentuada': 1,
        'Magreza': 2,
        'Eutrofia': 3,
        'Risco de sobrepeso': 4,
        'Sobrepeso': 5,
        'Obesidade': 6
    }

    raca_cor = {
        '01': 1, '02': 2, '03': 3, '04': 4, '05': 5, 'X': 0, '99': 99,
        0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 99: 99, None: 0, -1: -1
    }
    pd_df = pd.read_csv(realpath('./')+'/xaa', encoding='latin-1', sep=';')

    pd_df.drop(['CO_ACOMPANHAMENTO', 'CO_PESSOA_SISVAN', 'ST_PARTICIPA_ANDI',
                'NO_MUNICIPIO', 'DS_FASE_VIDA', 'DS_RACA_COR',
                'PESO X IDADE', 'PESO X ALTURA', 'CO_SISTEMA_ORIGEM_ACOMP',
                'SISTEMA_ORIGEM_ACOMP', 'NU_COMPETENCIA',
                'DS_ESCOLARIDADE', 'DS_POVO_COMUNIDADE'], axis=1, inplace=True)
    pd_df['NU_PESO'] = pd_df['NU_PESO'].apply(lambda x: float(x.replace(',', '.')) if isinstance(x, str) else -1)
    pd_df['NU_ALTURA'] = pd_df['NU_ALTURA'].apply(lambda x: float(x.replace(',', '.')) if isinstance(x, str) else -1)
    pd_df['DS_IMC'] = pd_df['DS_IMC'].apply(lambda x: float(x.replace(',', '.')) if isinstance(x, str) else -1)
    pd_df['DS_IMC_PRE_GESTACIONAL'] = pd_df['DS_IMC_PRE_GESTACIONAL'].apply(lambda x: int(float(x.replace(',', '.'))*100) if isinstance(x, str) else -1)
    pd_df['SG_SEXO'] = pd_df['SG_SEXO'].apply(lambda x: False if x=='F' else True)
    pd_df['SG_SEXO'] = pd_df['SG_SEXO'].astype('bool')
    pd_df['CO_CNES'] = pd_df['CO_CNES'].astype('category')
    pd_df['DT_ACOMPANHAMENTO'] =  pd.to_datetime(pd_df['DT_ACOMPANHAMENTO'], format='%d/%m/%Y')
    pd_df['NU_PESO'] = pd_df['NU_PESO'].astype('float16')
    pd_df['NU_ALTURA'] = pd_df['NU_ALTURA'].astype('float16')
    pd_df['DS_IMC'] = pd_df['DS_IMC'].astype('float16')
    pd_df['DS_IMC_PRE_GESTACIONAL'] = pd_df['DS_IMC_PRE_GESTACIONAL'].astype('int16')
    pd_df['CO_POVO_COMUNIDADE'] = pd_df['CO_POVO_COMUNIDADE'].astype('category')
    pd_df['CO_ESCOLARIDADE'] = pd_df['CO_ESCOLARIDADE'].astype('category')
    pd_df['CRI. ALTURA X IDADE'].fillna(-1, inplace=True)
    pd_df['CRI. ALTURA X IDADE'] = pd_df['CRI. ALTURA X IDADE'].apply(lambda x: altura_idade[x]).astype('int8')
    pd_df['ADO. ALTURA X IDADE'].fillna(-1, inplace=True)
    pd_df['ADO. ALTURA X IDADE'] = pd_df['ADO. ALTURA X IDADE'].apply(lambda x: altura_idade[x]).astype('int8')
    pd_df['CRI. IMC X IDADE'].fillna(-1, inplace=True)
    pd_df['CRI. IMC X IDADE'] = pd_df['CRI. IMC X IDADE'].apply(lambda x: imc_idade[x]).astype('int8')
    pd_df['ADO. IMC X IDADE'].fillna(-1, inplace=True)
    pd_df['ADO. IMC X IDADE'] = pd_df['ADO. IMC X IDADE'].apply(lambda x: imc_idade[x]).astype('int8')
    pd_df['CO_ESTADO_NUTRI_ADULTO'] = pd_df['CO_ESTADO_NUTRI_ADULTO'].astype('category')
    pd_df['CO_ESTADO_NUTRI_IDOSO'] = pd_df['CO_ESTADO_NUTRI_IDOSO'].astype('category')
    pd_df['CO_ESTADO_NUTRI_IMC_SEMGEST'] = pd_df['CO_ESTADO_NUTRI_IMC_SEMGEST'].astype('category')
    pd_df['NU_FASE_VIDA'] = pd_df['NU_FASE_VIDA'].astype('category')
    pd_df['CO_RACA_COR'].fillna(-1, inplace=True)
    pd_df['CO_RACA_COR'] = pd_df['CO_RACA_COR'].apply(lambda x: raca_cor[x]).astype('int8')
    pd_df['NU_IDADE_ANO'].fillna(-1, inplace=True)
    pd_df['NU_IDADE_ANO'] = pd_df['NU_IDADE_ANO'].apply(lambda x: -1 if x == None else x)
    pd_df['NU_IDADE_ANO'] = pd_df['NU_IDADE_ANO'].astype('int8')
    pd_df['SG_UF'] = pd_df['SG_UF'].astype('category')

    count = 0

    required_files = ['xab', 'xac', 'xad', 'xae', 'xaf', 'xag', 'xah', 'xai', 'xaj', 'xak', 'xal', 'xam', 'xan', 'xao']
    if(not all([exists(realpath('./')+'/'+f) for f in required_files])):
        print("ERROR: some files are missing, try running: python3 setup.py")
        exit()

    for splitted_file in required_files:
        temp_pd_df = pd.read_csv(realpath('.')+'/'+splitted_file,
                                sep=';', encoding='latin-1')
        temp_pd_df.drop(['CO_ACOMPANHAMENTO', 'CO_PESSOA_SISVAN', 'ST_PARTICIPA_ANDI',
                    'NO_MUNICIPIO', 'DS_FASE_VIDA', 'DS_RACA_COR',
                    'PESO X IDADE', 'PESO X ALTURA', 'CO_SISTEMA_ORIGEM_ACOMP',
                    'SISTEMA_ORIGEM_ACOMP', 'NU_COMPETENCIA',
                    'DS_ESCOLARIDADE', 'DS_POVO_COMUNIDADE'], axis=1, inplace=True)
        temp_pd_df['NU_PESO'] = temp_pd_df['NU_PESO'].apply(lambda x: float(x.replace(',', '.')) if isinstance(x, str) else -1)
        temp_pd_df['NU_ALTURA'] = temp_pd_df['NU_ALTURA'].apply(lambda x: float(x.replace(',', '.')) if isinstance(x, str) else -1)
        temp_pd_df['DS_IMC'] = temp_pd_df['DS_IMC'].apply(lambda x: float(x.replace(',', '.')) if isinstance(x, str) else -1)
        temp_pd_df['DS_IMC_PRE_GESTACIONAL'] = temp_pd_df['DS_IMC_PRE_GESTACIONAL'].apply(lambda x: int(float(x.replace(',', '.'))*100) if isinstance(x, str) else -1)
        temp_pd_df['SG_SEXO'] = temp_pd_df['SG_SEXO'].apply(lambda x: False if x=='F' else True)
        temp_pd_df['SG_SEXO'] = temp_pd_df['SG_SEXO'].astype('bool')
        temp_pd_df['CO_CNES'] = temp_pd_df['CO_CNES'].astype('category')
        temp_pd_df['DT_ACOMPANHAMENTO'] =  pd.to_datetime(pd_df['DT_ACOMPANHAMENTO'], format='%d/%m/%Y')
        temp_pd_df['NU_PESO'] = temp_pd_df['NU_PESO'].astype('float16')
        temp_pd_df['NU_ALTURA'] = temp_pd_df['NU_ALTURA'].astype('float16')
        temp_pd_df['DS_IMC'] = temp_pd_df['DS_IMC'].astype('float16')
        temp_pd_df['DS_IMC_PRE_GESTACIONAL'] = temp_pd_df['DS_IMC_PRE_GESTACIONAL'].astype('int16')
        temp_pd_df['CO_POVO_COMUNIDADE'] = temp_pd_df['CO_POVO_COMUNIDADE'].astype('category')
        temp_pd_df['CO_ESCOLARIDADE'] = temp_pd_df['CO_ESCOLARIDADE'].astype('category')
        temp_pd_df['CRI. ALTURA X IDADE'].fillna(-1, inplace=True)
        temp_pd_df['CRI. ALTURA X IDADE'] = temp_pd_df['CRI. ALTURA X IDADE'].apply(lambda x: altura_idade[x]).astype('int8')
        temp_pd_df['ADO. ALTURA X IDADE'].fillna(-1, inplace=True)
        temp_pd_df['ADO. ALTURA X IDADE'] = temp_pd_df['ADO. ALTURA X IDADE'].apply(lambda x: altura_idade[x]).astype('int8')
        temp_pd_df['CRI. IMC X IDADE'].fillna(-1, inplace=True)
        temp_pd_df['CRI. IMC X IDADE'] = temp_pd_df['CRI. IMC X IDADE'].apply(lambda x: imc_idade[x]).astype('int8')
        temp_pd_df['ADO. IMC X IDADE'].fillna(-1, inplace=True)
        temp_pd_df['ADO. IMC X IDADE'] = temp_pd_df['ADO. IMC X IDADE'].apply(lambda x: imc_idade[x]).astype('int8')
        temp_pd_df['CO_ESTADO_NUTRI_ADULTO'] = temp_pd_df['CO_ESTADO_NUTRI_ADULTO'].astype('category')
        temp_pd_df['CO_ESTADO_NUTRI_IDOSO'] = temp_pd_df['CO_ESTADO_NUTRI_IDOSO'].astype('category')
        temp_pd_df['CO_ESTADO_NUTRI_IMC_SEMGEST'] = temp_pd_df['CO_ESTADO_NUTRI_IMC_SEMGEST'].astype('category')
        temp_pd_df['NU_FASE_VIDA'] = temp_pd_df['NU_FASE_VIDA'].astype('category')
        temp_pd_df['CO_RACA_COR'].fillna(-1, inplace=True)
        temp_pd_df['CO_RACA_COR'] = temp_pd_df['CO_RACA_COR'].apply(lambda x: raca_cor[x]).astype('int8')
        temp_pd_df['NU_IDADE_ANO'].fillna(-1, inplace=True)
        temp_pd_df['NU_IDADE_ANO'] =  temp_pd_df['NU_IDADE_ANO'].apply(lambda x: -1 if x == None else x)
        temp_pd_df['NU_IDADE_ANO'] =  temp_pd_df['NU_IDADE_ANO'].astype('int8')
        temp_pd_df['SG_UF'] = temp_pd_df['SG_UF'].astype('category')
        pd_df = pd.concat([pd_df, temp_pd_df], copy=False, ignore_index=True)
        del temp_pd_df
        count += 1
        print(count,'/ 14')

    with open('./df.pickle', 'wb') as handle:
        pickle.dump(pd_df, handle, protocol=pickle.HIGHEST_PROTOCOL)

    return pd_df

if path.exists('./df.pickle'):
    with open('./df.pickle', 'rb') as handle:
        try:
            pd_df = pickle.load(handle)
        except ModuleNotFoundError:
            pd_df = pd.read_pickle(handle)
else:
    pd_df = read_csvs(pd_df)

def create_selectors() -> None:
    estado_cidade = {}
    for val in read_municipal_seat().values:
        if(not val[3] in estado_cidade):
            estado_cidade.update({val[3]: []})
        else:
            if '.' in str(val[0]):
                val[0] = str(val[0])[:str(val[0]).index('.')]
            estado_cidade[val[3]].append({val[1]: str(val[0])})
    with open('estado_cidade_codigo.json', 'w') as f:
        json.dump(estado_cidade, f)

if not path.exists('./estado_cidade_codigo.json'):
    create_selectors()

end_time = time()
time_taken = end_time - start_time
print("Time taken to start cached pandas: {:.2f} seconds".format(time_taken))

def thread_filter(filters: dict, id_thread: int, queue: Queue) -> dict:
    # Using global variables
    global pd_df
    global outputs
    global images

    pd_copy = None
    pd_copy = pd_df.copy(deep=True)
    outputs[id_thread-1] = pd_copy

    print('filters:', filters, 'columns', pd_copy.columns)

    # print('len', len(pd_copy))

    # If Brasil is selected, do not apply state filter
    if(filters['state'] != 'BR' and filters['state'] != ''):
        pd_copy = pd_copy[pd_copy['SG_UF'] == filters['state']]
        print('1')
    # print('len', len(pd_copy))
    if(filters['city'] != ''):
        pd_copy = pd_copy[pd_copy['CO_MUNICIPIO_IBGE'] == int(filters['city'][:-1])]
        print('2')
    # print('len', len(pd_copy))

    # Weight range filter
    if(filters['minWeight']):
        pd_copy = pd_copy[pd_copy['NU_PESO'] > filters['minWeight']]
        print('3')
    if(filters['maxWeight']):
        pd_copy = pd_copy[pd_copy['NU_PESO'] < filters['maxWeight']]
        print('4')

    # print(pd_copy['NU_PESO'].values.tolist())
    # pd_copy['NU_PESO'] = pd_copy['NU_PESO'].dropna()
    pd_copy['NU_PESO'] = pd_copy['NU_PESO'].astype('float32')

    # Height range filter
    if(filters['minHeight']):
        pd_copy = pd_copy[pd_copy['NU_ALTURA'] > filters['minHeight']]
        print('5')
    if(filters['maxHeight']):
        pd_copy = pd_copy[pd_copy['NU_ALTURA'] < filters['maxHeight']]
        print('6')

    # pd_copy['NU_ALTURA'] = pd_copy['NU_ALTURA'].dropna()

    # Date range filter
    if(filters['minDate']):
        pd_copy = pd_copy[pd_copy['DT_ACOMPANHAMENTO'] > filters['minDate']]
        print('7')
    if(filters['maxDate']):
        pd_copy = pd_copy[pd_copy['DT_ACOMPANHAMENTO'] < filters['maxDate']]
        print('8')

    # print('len', len(pd_copy))

    # Age range filter
    if(filters['minAge']):
        print('9')
        pd_copy = pd_copy[pd_copy['NU_IDADE_ANO'] > filters['minAge']]
    if(filters['maxAge']):
        print('10')
        pd_copy = pd_copy[pd_copy['NU_IDADE_ANO'] < filters['maxAge']]

    pd_copy['DS_IMC'] = pd_copy['DS_IMC'].astype('int32')

    # IMC range filter
    if(filters['minIMC']):
        print('11')
        pd_copy = pd_copy[pd_copy['DS_IMC'] > filters['minIMC']]
    if(filters['maxIMC']):
        print('12')
        pd_copy = pd_copy[pd_copy['DS_IMC'] < filters['maxIMC']]

    # CNES filter
    if(filters['CNES']):
        print('13')
        pd_copy = pd_copy[pd_copy['CO_CNES'] == filters['CNES']]

    # School level filter
    if(filters['education']):
        print('14')
        pd_copy = pd_copy[pd_copy['CO_ESCOLARIDADE'] == filters['education']]

    # Genre filter
    if(filters['genre']):
        genre = filters['genre']
        if genre != 'Ambos':
            print('15')
            if genre == 'Masculino':
                pd_copy = pd_copy[pd_copy['SG_SEXO'] == True]
            else:
                pd_copy = pd_copy[pd_copy['SG_SEXO'] == False]

    # Color/race
    if(filters['etnicity']):
        print('16')
        pd_copy = pd_copy[pd_copy['CO_RACA_COR'] == filters['genre']]

    if(filters['community']):
        print('17')
        pd_copy = pd_copy[pd_copy['CO_POVO_COMUNIDADE'] == filters['community']]

    # if(filters['group']):
    #     group = filters['group']
    #     if group != 'Todos':
    #         if group == 'Criança':
    #             pd_copy = pd_copy[pd_copy['SG_SEXO'] == 1]
    #         elif group == 'Adulto':
    #             pd_copy = pd_copy[pd_copy['SG_SEXO'] == 0]
    #         else:
    #             # Idoso

    cidade = None
    try:
        cidade = read_municipality(code_muni=int(filters['city']), year=2010)
    except:
       images[id_thread-1] = 'undefined muni'
       if(cidade != None):
            print('dei except')
            return {'msg': 'error: undefined muni'}

    # print('len', len(pd_copy))

    image_uuid = uuid.uuid4().__str__()
    images[id_thread-1] = image_uuid
    queue.put(cidade)

    # print('new file at', realpath('.')+'/matplotimages/'+str(images[id_thread-1]))
    if(filters['state'] == 'BR'):
        with open(realpath('.')+'/matplotimages/'+str(images[id_thread-1]), 'wb') as imagefile:
            pickle.dump(pd_copy, imagefile)
        subprocess.run(["python3", f"{realpath('.')}/national_map.py", str(image_uuid)])
        return {'msg': 'success'}

    with open(realpath('.')+'/matplotimages/'+str(images[id_thread-1]), 'wb') as imagefile:
        pickle.dump(cidade, imagefile)

    # Outside with because it will run faster than the file is closed
    subprocess.run(["python3", f"{realpath('.')}/image_builder.py", 'cidade', str(image_uuid)])

    with open(realpath('.')+'/citiesjsons/'+str(images[id_thread-1]) + '.json', 'w') as jsonfile:
        # json.dump(pd_copy.describe().to_json(), jsonfile)
        # print(pd_copy.describe())
        # print(pd_copy['NU_PESO'].describe())
        jsonfile.write(pd_copy.describe().to_json())

    with open(realpath('.')+'/citiesjsons/'+str(images[id_thread-1]) + 'CNES.json', 'w') as jsonfile:
        jsonfile.write(pd_copy['CO_CNES'].value_counts().to_json())

    return {'msg': 'success'}

app = Flask('Lineu')
@app.route('/data', methods=['POST'])
def get_slash():
    while(all(threads)):
        print('Waiting while all threads are busy:', threads)
        sleep(0.2)

    id_thread = -1

    # Find first not None in threads array
    for i, thr in enumerate(threads):
        if thr == None:
            id_thread = i
            print('New thread in:', i)
            break

    if id_thread == -1:
        return 'System is unavailable'

    # Verify if request.json is a valid format (only asks a state or city)
    t = threading.Thread(target=thread_filter, args=(request.json, id_thread, queue))
    threads.append(t)

    t.start()
    t.join()
    # output = outputs[id_thread-1]

    if(images[id_thread-1] == 'undefined muni'):
        return 'Undefined Municipality'

    # Free threads and outputs
    outputs[id_thread-1] = None
    threads[id_thread-1] = None

    # print(images)
    while(not exists(realpath('.')+'/matplotimages/'+images[id_thread-1]+'.png')):
        print('to dormindo')
        sleep(1)

    # Probably there's a better way to transfer a file to buffer without using PIL
    # img = Image.open('./'+images[id_thread-1]+'.png')
    # buffer = io.BytesIO()
    # img.save(buffer, 'png')
    # buffer.seek(0)
    # data = buffer.read()
    # data = base64.b64encode(data).decode()
    data = None
    with open(realpath('.')+'/matplotimages/'+ images[id_thread-1] + '.png', 'rb') as f:
        data = f.read()

    data = base64.b64encode(data).decode()

    json_data = None
    if(exists(realpath('.')+'/citiesjsons/'+ images[id_thread-1] + '.json')):
        with open(realpath('.')+'/citiesjsons/'+ images[id_thread-1] + '.json', 'r') as j:
            json_data = j.read()

    cnes_data = None
    if(exists(realpath('.')+'/citiesjsons/'+ images[id_thread-1] + 'CNES.json')):
        with open(realpath('.')+'/citiesjsons/'+ images[id_thread-1] + 'CNES.json', 'r') as j:
            cnes_data = j.read()

    response = jsonify({'msg': 'success', 'format': 'png', 'data': json_data, 'image': data, 'cnes': cnes_data})
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response
    # return send_file(f'{images[id_thread-1]}.png', mimetype='image/png')
    return f"<img src='data:application/html;base64,'/>"
    return render_template('oi.html')

@app.route('/municipalities', methods=['GET'])
def get_municipalities():
    response = send_file('estado_cidade_codigo.json', mimetype='application/json')
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/frontend/scripts.js', methods=['GET'])
def scripts():
    return send_file('./frontend/scripts.js', mimetype='application/json')

@app.route('/frontend/static/Lineu.png', methods=['GET'])
def lineu_logo():
    return send_file('./frontend/static/Lineu.png', mimetype='image/png')

# @app.route('/frontend/static/<path:path>')
# def serve_static(path):
#     return send_from_directory('static', path)

# Adicionar HOST e PORT vindos do .env
app.run(port=5050)


import sys
import logging
import argparse
import os
import shutil
import importlib.util
import torch
import gym
import copy

from torch.utils.tensorboard import SummaryWriter
from envs.model.agent import Agent
from method.trainer import MPRLTrainer
from method.memory import ReplayMemory
from method.explorer import Explorer
from policies.policy_factory import policy_factory

def set_random_seeds(seed):
    """
    Sets the random seeds for pytorch cpu and gpu
    """
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.set_num_threads(8)  # !!!
    return None

def main(args):
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_id
    set_random_seeds(args.randomseed)

    # configure paths
    make_new_dir = True
    if os.path.exists(args.output_dir):
        if args.overwrite:
            shutil.rmtree(args.output_dir)
        else:
            key = input('Output directory already exists! Overwrite the folder? (y/n)')
            if key == 'y' and not args.resume:
                shutil.rmtree(args.output_dir)
            else:
                make_new_dir = False
                exit(0)
    if make_new_dir:
        base_config = os.path.join(os.path.join(os.path.split(args.config)[0], os.pardir), 'config.py')
        os.makedirs(args.output_dir)
        shutil.copy(args.config, os.path.join(args.output_dir, 'config.py'))
        shutil.copy(base_config, os.path.join(args.output_dir, 'base_config.py'))

    args.config = os.path.join(args.output_dir, 'config.py')
    log_file = os.path.join(args.output_dir, 'output.log')
    rl_weight_file = os.path.join(args.output_dir, 'rl_model.pth')

    # 仅仅知道模块名字和路径的情况下import模块
    spec = importlib.util.spec_from_file_location('config', args.config)
    if spec is None:
        parser.error('Config file not found.')
    config = importlib.util.module_from_spec(spec)  # 通过传入模块的spec返回新的被导入的模块对象
    spec.loader.exec_module(config)

    # configure logging
    mode = 'w'
    file_handler = logging.FileHandler(log_file, mode=mode)  # 输出日志信息到磁盘文件
    stdout_handler = logging.StreamHandler(sys.stdout)
    level = logging.INFO if not args.debug else logging.DEBUG
    logging.basicConfig(level=level, handlers=[stdout_handler, file_handler],
                        format='%(asctime)s, %(levelname)s: %(message)s',
                        datefmt="%Y-%m-%d %H:%M:%S")
    logging.info('Current config content is :{}'.format(config))
    device = torch.device("cuda:0" if torch.cuda.is_available() and args.gpu else "cpu")
    if torch.cuda.is_available() and args.gpu:
        logging.info('Using gpu: %s' % args.gpu_id)
    else:
        logging.info('Using device: cpu')

    writer = SummaryWriter(log_dir=args.output_dir)

    # configure environment
    env = gym.make('CrowdSim-v0')
    agent = Agent()
    human_df = env.human_df

    # configure policy
    policy_config = config.PolicyConfig()
    policy = policy_factory[policy_config.name]()  # model_predictive_rl
    if not policy.trainable:
        parser.error('Policy has to be trainable')
    policy.set_device(device)
    policy.configure(policy_config, human_df)

    # read training parameters
    train_config = config.TrainConfig(args.debug)
    rl_learning_rate = train_config.train.rl_learning_rate
    num_batches = train_config.train.num_batches
    num_episodes = train_config.train.num_episodes
    sample_episodes = train_config.train.sample_episodes
    warmup_episodes = train_config.train.warmup_episodes
    evaluate_episodes = train_config.train.evaluate_episodes
    target_update_interval = train_config.train.target_update_interval
    evaluation_interval = train_config.train.evaluation_interval
    capacity = train_config.train.capacity
    epsilon_start = train_config.train.epsilon_start
    epsilon_end = train_config.train.epsilon_end
    epsilon_decay = train_config.train.epsilon_decay
    checkpoint_interval = train_config.train.checkpoint_interval

    # configure trainer and explorer
    memory = ReplayMemory(capacity)
    model = policy.get_value_estimator()
    batch_size = train_config.trainer.batch_size
    optimizer = train_config.trainer.optimizer

    # choose Graph or Vanilla
    trainer = MPRLTrainer(model, policy.state_predictor, memory, device, policy, writer, batch_size, optimizer,
                          env.human_num,
                          reduce_sp_update_frequency=train_config.train.reduce_sp_update_frequency,
                          freeze_state_predictor=train_config.train.freeze_state_predictor,
                          detach_state_predictor=train_config.train.detach_state_predictor,
                          share_graph_model=policy_config.model_predictive_rl.share_graph_model)

    explorer = Explorer(env, agent, device, writer, memory, policy.gamma, target_policy=policy)

    logging.info('We use random-exploration methods to warm-up.')
    trainer.update_target_model(model)

    # reinforcement learning
    policy.set_env(env)
    agent.set_policy(policy)
    agent.print_info()
    env.set_agent(agent)
    trainer.set_learning_rate(rl_learning_rate)

    # fill the memory pool with some experience
    agent.policy.set_epsilon(1)
    explorer.run_k_episodes(k=warmup_episodes, phase='train', args=args, update_memory=True, plot_index=-1)  # 100
    logging.info('Warm-up finished!')
    logging.info('Experience set size: %d/%d\n', len(memory), memory.capacity)

    episode = 0
    best_val_reward = -1
    best_val_model = None

    while episode < num_episodes:
        # epsilon-greedy
        if episode < epsilon_decay:
            epsilon = epsilon_start + (epsilon_end - epsilon_start) / epsilon_decay * episode
        else:
            epsilon = epsilon_end
        agent.policy.set_epsilon(epsilon)

        # sample k episodes into memory and optimize over the generated memory
        explorer.run_k_episodes(k=sample_episodes, phase='train', args=args, update_memory=True, plot_index=-1)

        explorer.log('train', episode)
        trainer.optimize_batch(num_batches, episode)
        logging.info(f"ep {episode} training is finished. epsilon={epsilon}\n")

        episode += 1

        if episode % target_update_interval == 0:
            trainer.update_target_model(model)
        # evaluate the model
        if episode % evaluation_interval == 0:
            average_reward, _, _, _ ,_,_ = explorer.run_k_episodes(k=evaluate_episodes, phase='val', args=args,
                                                              plot_index=-1)
            explorer.log('val', episode // evaluation_interval)

            if episode % checkpoint_interval == 0 and average_reward > best_val_reward:
                logging.info("Best reward model has been changed.")
                best_val_reward = average_reward
                best_val_model = copy.deepcopy(policy.get_state_dict())
            # test after every evaluation to check how the generalization performance evolves
            if args.test_after_every_eval:
                explorer.run_k_episodes(k=1, phase='test', args=args, plot_index=episode)
                explorer.log('test', episode // evaluation_interval)

        if episode != 0 and episode % checkpoint_interval == 0:
            current_checkpoint = episode // checkpoint_interval - 1
            save_every_checkpoint_rl_weight_file = rl_weight_file.split('.')[0] + '_' + str(current_checkpoint) + '.pth'
            policy.save_model(save_every_checkpoint_rl_weight_file)

    # # test with the best val model
    if best_val_model is not None:
        policy.load_state_dict(best_val_model)
        torch.save(best_val_model, os.path.join(args.output_dir, 'best_val.pth'))
        logging.info('Save the best val model with the reward: {}'.format(best_val_reward))

if __name__ == '__main__':
    parser = argparse.ArgumentParser('Parse configuration file')
    parser.add_argument('--config', type=str, default='configs/infocom_benchmark/mp_separate_dp.py')
    parser.add_argument('--output_dir', type=str, default='logs/debug')  # output_xxxx
    parser.add_argument('--overwrite', default=False, action='store_true')

    parser.add_argument('--weights', type=str)
    parser.add_argument('--gpu_id', type=str, default='-1')
    parser.add_argument('--gpu', default=False, action='store_true')

    parser.add_argument('--debug', default=False, action='store_true')  # 开启debug模式
    parser.add_argument('--test_after_every_eval', default=False, action='store_true')
    parser.add_argument('--randomseed', type=int, default=0)

    parser.add_argument('--vis_html', default=False, action='store_true')
    parser.add_argument('--plot_loop', default=False, action='store_true')
    parser.add_argument('--moving_line', default=False, action='store_true')
    sys_args = parser.parse_args()

    main(sys_args)


import pickle

d = dict()

file_l = ['trans_ben.pickle','trans_lec.pickle','trans_hin.pickle','trans_sch.pickle']
res_f = 'all_trans.pickle'

file_l = ['trans_sch1.pickle','trans_sch2.pickle']
res_f = 'trans_sch.pickle'

for file in file_l:

	try:
		2
		with open(file, 'rb') as f:
			li = pickle.load(f) # or however you load the file
	except EOFError:
		continue

	for trans in li:
		#(state, action, reward, new_state, done)
		pattern = "%.2f"
		floats = [pattern % i for i in trans[1]]
		key = str(trans[2]) +'_' +"".join(floats[:2])
		if not key in d:
			d[key] = trans

result = []

for pair in d.items():
	result.append(pair[1])

print("LENGTH OF BUFFER %d" % len(result))

with open(res_f,'wb') as wfp:
	pickle.dump(result, wfp)


"""
@Author Jordan Dubreuil 04/23/2023
Unit testing for Dequeque Abstract Data Type.
"""
from dequeue import *
import unittest
import io
import sys
from unittest.mock import patch

class TestDequeque(unittest.TestCase):
    # Tests Display of Dequeque
    def test_display(self):
        my_instance = Dequeque()
        my_instance.addStart("pizza")
        my_instance.addEnd("taco")
        captured_output = io.StringIO()
        sys.stdout = captured_output
        my_instance.display()
        sys.stdout = sys.__stdout__
        self.assertEqual(captured_output.getvalue().strip(), "['pizza', 'taco']")

    # Tests the IsEmpty Method of Dequeque
    def test_IsEmpty(self):
        my_instance = Dequeque()
        self.assertTrue(my_instance.IsEmpty())
        my_instance.addEnd('pizza')
        self.assertFalse(my_instance.IsEmpty())

    # Tests addStart Method of Dequeque
    def test_addStart(self):
        my_instance = Dequeque()
        my_instance.addStart("cheese")
        my_instance.addStart("ramen")
        my_instance.addStart("cookie")
        self.assertEqual(my_instance.food, ['cookie','ramen','cheese'])

    # Tests the addEnd Method of Dequeque
    def test_addEnd(self):
        my_instance = Dequeque()
        my_instance.addEnd("cheese")
        my_instance.addEnd("ramen")
        my_instance.addEnd("cookie")
        self.assertEqual(my_instance.food, ['cheese','ramen','cookie'])

if __name__ == '__main__':
    unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(TestDequeque))


# -*- coding: utf-8 -*-
"""
Created on Thu Mar 28 13:34:22 2019

@author: holmes
"""

import os
import sys
from PIL import Image
import numpy as np

from inception_module import inception_module as incept_net

image_dir_parent_train = r"/path/to/datasets/plantclef2019"
image_dir_parent_test = r"/path/to/datasets/plantclef2019"
train_file = r"training_and_validation_list/clef2019_multilabel_train_256046.txt"
test_file = r"training_and_validation_list/clef2019_multilabel_test_256046.txt"

# model to restore
checkpoint_model = r"inception_v4.ckpt"
# save dir for checkpoint
checkpoint_save_dir = r"checkpoints_adam_multilabel"

batch = 64
input_size = (299,299,3)
numclasses = 10000
learning_rate = 0.0001
iterbatch = 4
max_iter = 500000
val_freq = 500
val_iter = 200

# construct and run the network
network = incept_net(
        batch = batch,
        iterbatch = iterbatch,
        numclasses = numclasses,
        input_size = input_size,
        image_dir_parent_train = image_dir_parent_train,
        image_dir_parent_test = image_dir_parent_test,
        train_file = train_file,
        test_file = test_file,
        checkpoint_model = checkpoint_model,
        save_dir = checkpoint_save_dir,
        learning_rate = learning_rate,
        max_iter = max_iter,
        val_freq = val_freq,
        val_iter = val_iter)

"""
LAYERS NAME
[ 'Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3',
      'Mixed_3a', 'Mixed_4a', 'Mixed_5a', 'Mixed_5b', 'Mixed_5c', 'Mixed_5d',
      'Mixed_5e', 'Mixed_6a', 'Mixed_6b', 'Mixed_6c', 'Mixed_6d', 'Mixed_6e',
      'Mixed_6f', 'Mixed_6g', 'Mixed_6h', 'Mixed_7a', 'Mixed_7b', 'Mixed_7c',
      'Mixed_7d','AuxLogits','Logits']

"""


__copyright__ = "Copyright (C) 2019 NXP Semiconductors"
__license__ = "MIT"

from django.contrib import admin
from .models import ImageDatabase, LogsDatabase

class Image(admin.ModelAdmin):
    fields = (
        'id',
        'name',
        'face',
        'thumbnail'
    )

    readonly_fields = (
        'id',
        'thumbnail',
    )

class ImageTimestamp(admin.ModelAdmin):
    fields = (
        'id',
        'name',
        'timestamp',
        'thumbnail',
        'known',
    )

    readonly_fields = (
        'id',
        'name',
        'timestamp',
        'thumbnail',
        'known',
    )

# Register your models here.
admin.site.register(ImageDatabase, Image)
admin.site.register(LogsDatabase, ImageTimestamp)


import re
from pathlib import Path

regex = re.compile(r'(^---\n\n)', flags=re.M)

for rmd_pth in Path().glob('*.Rmd'):
    contents = rmd_pth.read_text()
    if '_common.R' in contents:
        continue
    if regex.search(contents):
        contents = regex.sub("""\
---

```{r setup, include=FALSE}
source("_common.R")
```

""", contents)
        rmd_pth.write_text(contents)


"""
Logging passed information to csv files format.

Author: Nicoline Louise Thomsen
"""

import csv
import datetime

class Logger():

    def __init__(self):

        time = str(datetime.datetime.now())[11:19]
        dateid = time.replace(':', '')

        # file_name = 'logs/data_' + dateid + '.csv'
        file_name = 'logs/data.csv'
        log = open(file_name, 'w+', newline='')  # w+ mode truncates (clears) the file (new file for every test)
        self.logger = csv.writer(log, dialect = 'excel')

        self.logger.writerow(['Time', 'Light_sensor_1', 'Light_sensor_2', 'last_seen'])
        # self.logger.writerow(['Time', 'Light_sensor_1', 'Light_sensor_2', 'control_input', 'base_speed'])
        # self.logger.writerow(['Time', 'left', 'right', 'error', 'control_input', 'base_speed'])

    def log_to_file(self, t, *data):

        row = [t]
        row.extend(data)

        self.logger.writerow(row)


from django.conf.urls import url

from .views import (
    InvoiceCreateAPIView,
    InvoiceListAPIView
    )

urlpatterns = [
    url(r'^$', InvoiceListAPIView.as_view(), name='list-invoices'),
    url(r'^create-invoice/$', InvoiceCreateAPIView.as_view(), name='create-invoice'),

]


import select
import socket
import pickle

def create_socket(addr) -> socket.socket:
    s = socket.socket()
    s.bind(addr)
    s.listen(5)
    s.settimeout(1)
    return s

def handle_data(data, client, clients):
    print(data)
    if data['action'] == 'msg':
        if data['to'][0] == '#':
            for cl in groups[data['to']]:
                data['flag']='сообщение из группы'
                cl.send(pickle.dumps(data))
        else:
            logins[data['to']].send(pickle.dumps(data))
    elif data['action'] == 'presence':
        logins[data['user']] = client
        print(logins.keys())
    elif data['action'] == 'quit':
        client.close()
        print(f'Клиент {client.fileno()}  отключился')
        clients.remove(client)
        return None
    elif data['action'] == 'join':
        if not groups.get(data['room']):
            groups[data['room']] = []
        groups[data['room']].append(client)
        print('Клиент присоединился к группе')

    return pickle.dumps(data)

def read(r, clients):
    responses = {}
    for client in r:
        try:
            data = client.recv(1024)
            if not data:
                raise Exception
        except:
            print(f'Клиент {client.fileno()} {client.getpeername()} отключился')
            clients.remove(client)
        else:
            responses[client] = handle_data(pickle.loads(data), client, clients)
    return responses

def send(requests, w, clients):
    for sock in requests:
        for client in w:
            try:
                client.send(requests[sock])
            except Exception as e:
                print(e)

def main_loop(addr):
    s = create_socket(addr)

    clients = []
    while True:
        try:
            client, addr = s.accept()
        except OSError as e:
            pass
        else:
            print(f'Получен запрос от клиента {str(addr)}')
            clients.append(client)
        finally:
            wait = 1
            r = []
            w = []
            try:
                r, w, e = select.select(clients, clients, [], wait)
            except Exception as e:
                print(f'Исключение {e}')
            requests = read(r, clients)
            # if requests:
            #     send(requests, w, clients)

if __name__ == '__main__':
    logins = {}
    groups = {}
    addr = ('', 8888)
    main_loop(addr)


"""Design a stop watch

1. Track amount of time elapsed between presses
    enter key

2. With each key press starting a new 'lap'
3. Print lap number, total time and lap time
4. Thus do the following:

    Find current time and store it as timestamp
      and also start of each lap

    Keep a lap counter and increment every time
      user presses ENTER

    Calculate the elapsed time by subtracting

    Handle KeyboardInterrupt exception so the
      user can quit
"""

# Time module reads the systems clock
import time
from datetime import datetime, timedelta

def time_timer():
    input()  # press Enter to begin
    print('Stopwatch started...')
    print('Press ENTER to add another lap')
    start_time = time.time()  # get the first lap's start time
    end_time = start_time
    lap_num = 1

    # start tracking the lap times
    try:
        while True:
            input()
            lap_time = round(time.time() - end_time, 2)
            total_time = round(time.time() - start_time, 2)
            print(f'Lap #{lap_num}: {total_time} ({lap_time})', end='')
            lap_num += 1
            end_time = time.time()  # reset the last lap time

    except KeyboardInterrupt:
        # Handle the ctrl-c exception to keep its error message
        # from displaying
        print('\nDone.')

def datetime_timer():
    input()  # press Enter to begin
    print('Stopwatch started...')
    print('Press ENTER to add another lap')
    start_time = datetime.now()  # get the first lap's start time
    end_time = start_time
    lap_num = 1

    try:
        while True:
            input()
            lap_time = datetime.now() - end_time
            total_time = datetime.now() - start_time
            print(f'Lap #{lap_num}: \
{str(round(total_time.seconds + (total_time.microseconds / 1000000), 2))} \
({str(round(lap_time.seconds + (lap_time.microseconds / 1000000), 2))})', end='')
            lap_num += 1
            end_time = datetime.now()

    except KeyboardInterrupt:
        print('\nDone.')

def which_timer(attempts):
    # Display the program's instructions
    print('Press ENTER to begin')
    print('Afterwards, press ENTER to click the stopwatch')
    print('Press ctrl-c to quit')

    user_input = input('Press t for time timer and dt for datetime timer: ')

    if user_input == 't':
        print(f'\nUsing timer made from TIME module because\
 the user typed t')
        time_timer()

    elif user_input == 'dt':
        print(f'\nUsing timer made from DATETIME module because\
 the user typed dt')
        datetime_timer()

    else:
        attempts += 1

        print(f'\nYou entered {user_input} which is not a valid option.\
 Please select either t or dt ONLY.')

        if attempts < 4:
            print(f'\nWARNING: ONLY {4 - attempts} attempts remaining')
            which_timer(attempts)

if __name__ == '__main__':
    attempts = 1
    which_timer(attempts)


class Solution:
    def lengthLongestPath(self, input: str) -> int:
        res = 0
        prefix = [0]
        for line in input.splitlines():
            path = line.lstrip('\t')
            depth = len(line) - len(path)
            length = prefix[depth] + len(path)
            if '.' in path:
                res = max(res, length + depth)
            else:
                if depth + 1 < len(prefix):
                    prefix[depth + 1] = length
                else:
                    prefix.append(length)
        return res