import os
import pytest

from path import Path

from . import initialize_git_repo_and_commit, prepare_project

DIST_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../dist'))

# Test if package can be imported to allow testing on
# conda-forge where ``pytest-virtualenv`` is not available.
try:
    import pytest_virtualenv  # noqa: F401
    HAS_PYTEST_VIRTUALENV = True
except ImportError:
    HAS_PYTEST_VIRTUALENV = False

@pytest.mark.skipif(not HAS_PYTEST_VIRTUALENV,
                    reason="pytest_virtualenv not available. See #228")
def test_source_distribution(virtualenv):
    sdists = Path(DIST_DIR).files(match="*.tar.gz") if Path(DIST_DIR).exists() else []
    if not sdists:
        pytest.skip("no source distribution available")
    assert len(sdists) == 1

    virtualenv.run("pip install %s" % sdists[0])
    assert "scikit-build" in virtualenv.installed_packages()

    prepare_project("hello-no-language", virtualenv.workspace, force=True)
    initialize_git_repo_and_commit(virtualenv.workspace, verbose=False)

    virtualenv.run("python setup.py bdist_wheel")

@pytest.mark.skipif(not HAS_PYTEST_VIRTUALENV,
                    reason="pytest_virtualenv not available. See #228")
def test_wheel(virtualenv):
    wheels = Path(DIST_DIR).files(match="*.whl") if Path(DIST_DIR).exists() else []
    if not wheels:
        pytest.skip("no wheel available")
    assert len(wheels) == 1

    virtualenv.run("pip install %s" % wheels[0])
    assert "scikit-build" in virtualenv.installed_packages()

    prepare_project("hello-no-language", virtualenv.workspace, force=True)
    initialize_git_repo_and_commit(virtualenv.workspace, verbose=False)

    virtualenv.run("python setup.py bdist_wheel")


import argparse
import os
import os.path

import pandas

def main():
    parser = argparse.ArgumentParser(description='Quick helper for getting model accuracies', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('inputs', nargs = '+', help='input CSVs')
    parser.add_argument('--nrows', help='num lines', type = int, default=None)
    args = parser.parse_args()

    for p in args.inputs:
        try:
            df = pandas.read_csv(p, nrows = args.nrows)
        except EOFError:
            print(f"{os.path.abspath(p).split('.')[0]} EOF")
        else:
            print(f"{os.path.abspath(p).split('.')[0]} {df['model_correct'].mean() * 100:.2f}%")

if __name__ == "__main__":
    main()


from ast import Try
from dataclasses import replace
from os import rename
import sys
import time
from unicodedata import decimal
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from sqlalchemy import create_engine, text
from sqlalchemy.orm import Session

class CodigoTestado3():
    def limparPreco(preco):
            if preco == None or preco == '':
                return -1
            try:
                preco = preco.replace('R$ ','')
                preco = preco.replace(',','.')
                preco = float(preco)
            except:
                preco = -1
            return preco

    # FUNCÕES PAGUE MENOS
    def coletar_preco_paguemenos(medicamento, driver):
        driver.get(medicamento['link'])
        try:
            preco = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/div[1]/div/div/div/div[4]/div/div/div/section/div/div/div/div[1]/div[2]/div/div[3]/div/div[5]/div/div[1]/div[1]/div/div[2]/div/div[2]/span/span'))
            )
            preco = preco.text
        except:
            try:
                preco = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/div[1]/div/div/div/div[4]/div/div/div/section/div/div/div/div[1]/div[2]/div/div[3]/div/div[5]/div/div/div[1]/div/div[2]/div/div/span/span'))
                )
                preco = preco.text
            except:
                preco = '-1'
        medicamento['preco'] = CodigoTestado3.limparPreco(preco)

    def coletar_paguemenos(driver):
        medicamentos_paguemenos = [
           # {
            #    'idfarmacia': 1,
             #   'idmedicamento': 1,

              #  'preco': -1
            #}, #dipirona
            {
                'idfarmacia': 1,
                'idmedicamento': 2,
                'link': 'https://www.paguemenos.com.br/advil-400mg-leve-8-pague-6-capsulas/p',
                'preco': -1
            }, #advil
            {
                'idfarmacia': 1,
                'idmedicamento': 3,
                'link': 'https://www.paguemenos.com.br/engov-com-12-comprimidos/p',
                'preco': -1
            }, #engov
            {
                'idfarmacia': 1,
                'idmedicamento': 4,
                'link': 'https://www.paguemenos.com.br/neosaldina-com-10-drageas/p',
                'preco': -1
            }, #neosaldina
            {
                'idfarmacia': 1,
                'idmedicamento': 5,
                'link': 'https://www.paguemenos.com.br/dorflex-36-comprimidos/p',
                'preco': -1
            }, #dorflex
            {
                'idfarmacia': 1,
                'idmedicamento': 6,
                'link': 'https://www.paguemenos.com.br/novalgina-1g-10-comprimidos/p',
                'preco': -1
            }, #novalgina
            {
                'idfarmacia': 1,
                'idmedicamento': 7,
                'link': 'https://www.paguemenos.com.br/sal-de-fruta-eno-efervescente-2-saches-de-5g/p',
                'preco': -1
            }, #eno
            {
                'idfarmacia': 1,
                'idmedicamento': 8,
                'link': 'https://www.paguemenos.com.br/neosoro-solucao-nasal-adulto-com-30-ml/p',
                'preco': -1
            }, #neosoro
            {
                'idfarmacia': 1,
                'idmedicamento': 9,
                'link': 'https://www.paguemenos.com.br/merthiolate-spray-30ml/p',
                'preco': -1
            }, #mertthiolate
            {
                'idfarmacia': 1,
                'idmedicamento': 10,
                'link': 'https://www.paguemenos.com.br/estomazil-em-po-sem-sabor-5g-com-6-envelope/p',
                'preco': -1
            }, #estomazil
            {
                'idfarmacia': 1,
                'idmedicamento': 11,
                'link': 'https://www.paguemenos.com.br/allegra-60mg-com-10-comprimidos/p',
                'preco': -1
            }, #allegra
            {
                'idfarmacia': 1,
                'idmedicamento': 12,
                'link': 'https://www.paguemenos.com.br/descongestionante-vick-vaporub-30g/p',
                'preco': -1
            }, #vic vaborrub
            {
                'idfarmacia': 1,
                'idmedicamento': 13,
                'link': 'https://www.paguemenos.com.br/polaramine-2mg-caixa-com-20-comprimidos/p',
                'preco': -1
            }, #polaramine
            {
                'idfarmacia': 1,
                'idmedicamento': 14,
                'link': 'https://www.paguemenos.com.br/dramin-b6-com-30-comprimidos/p',
                'preco': -1
            }, #dramin
            {
                'idfarmacia': 1,
                'idmedicamento': 15,
                'link': 'https://www.paguemenos.com.br/espironolactona-25mg-com-30-comprimidos-generico-geolab/p',
                'preco': -1
            }, #espironolactona
            {
                'idfarmacia': 1,
                'idmedicamento': 16,
                'link': 'https://www.paguemenos.com.br/insulina-novolin-r-10ml/p',
                'preco': -1
            } #insulina
        ]
        for medicamento in medicamentos_paguemenos:
            CodigoTestado3.coletar_preco_paguemenos(medicamento, driver)
        return medicamentos_paguemenos

    def registrarDados(lista, sessao):
        for preco in lista:
            sessao.execute(text("INSERT INTO preco (numpreco, preco, idfarmacia, idmedicamento) VALUES (now(), :preco, :idfarmacia, :idmedicamento)"), preco)


# -*- coding: utf-8 -*-
__author__ = 'apsmi'

import asynchat, socket, struct, pickle

IN_BUF_SIZE  = 128 * (2**10) # размер  входящего буфера сокета
OUT_BUF_SIZE = 128 * (2**10) # размер исходящего буфера сокета

LEN_TERM = 4

# сокет, принимающий соединение от клиентов
class Client(asynchat.async_chat):

    def __init__(self, addr):
        asynchat.async_chat.__init__(self)
        self.ibuffer = []
        self.obuffer = b""
        self.imes = [] #b""

        # создаем сокет
        self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.bind(('', 0))
        client_port = self.socket.getsockname()[1]

        # подключаемся к диспетчеру, отправляем ему свой клиентский порт
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind(('', 0))
        sock.sendto(struct.pack('L', client_port), addr)

        # получем серверный udp порт
        buf, _ = sock.recvfrom(4)
        server_port = struct.unpack('L',buf)[0]
        sock.close()

        self.ac_in_buffer_size = IN_BUF_SIZE
        self.ac_out_buffer_size = OUT_BUF_SIZE

        self.addr = (addr[0], server_port)
        self.set_terminator(LEN_TERM)
        self.state = "len"

    def handle_close(self):
        #print(self.socket.getsockname())
        self.close()

    def writable(self):
        return len(self.obuffer) > 0

    def handle_write(self):
        sent = self.sendto(self.obuffer, self.addr)
        self.obuffer = self.obuffer[sent:]

    def collect_incoming_data(self, data):
        self.ibuffer.append(data)

    def found_terminator(self):
        dataframe = b"".join(self.ibuffer)
        self.ibuffer = []
        if self.state == "len":
            self.state = "data"
            length = struct.unpack('L',dataframe)[0]
            self.set_terminator(length)
        elif self.state == "data":
            self.state = "len"
            self.set_terminator(LEN_TERM)
            self.imes.append(pickle.loads(dataframe))
            if self.imes == "exit":
                self.close()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Модуль класса управления ресурсом проекта.

Описание ресурсного файла проекта информационной системы:

<имя файла> :=   *.pro
<описание проекта информационной системы> =
[
{<описание проекта текущей информационной системы>},
{<описание проекта импортируемой информационной системы 1> }, Е ,
{ <описание проекта импортируемой информационной системы N> }
] //список

<описание проекта текущей информационной системы> =
{
 'имя корневой папки проекта'     : <значение папки> ,
 '__py__' : <имя корневого пакета модулей питона, создаваемых в рамках текущего проекта>
'__ftl__' : <значение папки шаблонов форм>
'__mth__' : <значение папки методов>
'__env__' : <словарь дополнительных глобальных атрибутов проекта>
} // словарь

<значение папки> =
[
{'имя папки':<значение папки> / <тип ресурса> значения: 'tab' / 'var' / 'win' / 'mnu' / 'svb' / 'frm ' / 'src'}, Е {}
] //список словарей

<значение папки шаблонов форм> =
[
{'имя папки' : <значение папки> / <тип ресурса> значения: 'ftl'}, Е {}
] //список словарей

<значение папки методов> =
[
{'имя папки' : <значение папки> / <тип ресурса> значения: 'mth'}, Е {}
] //список словарей

<описание проекта импортируемой информационной системы> =
{  'имя корневой папки проекта'     : <значение папки> }                                   // словарь

<значение папки> =
{
'type':  <тип импортируемой информационной системы>
'name':  <имя импортируемой информационной системы>
 '__py__':  <имя корневого пакета модулей питона, созданных в импортируемой информационной системе>
'link':  <тип связи импортируемой информационной системы: определим тип связи  импортируемой системы как ССЫЛКА, если информационные ресурсы импортируемой системы расположены НЕ в директории информационных ресурсов текущей системы; определим тип связи  импортируемой системы как КОПИЯ, если информационные ресурсы импортируемой системы расположены в директории информационных ресурсов текущей системы; 1 - ССЫЛКА, 0 - КОПИЯ>
'path':  <путь к файлу *.pro, содержащему описание структуры импортируемой информационной системы; если link=1, то указан полный путь, он дополняется значением ключа __py__ и используется при сборке, если link=0, то при сборке значение этого ключа не используется, а используется ключ __py__ для получения пути для сборки ресурсов>
}

Пример текущей информационной системы:
{'__py__':'icmodule','бухучет':
    [ { 'базы данных':
           [{'первичные документы':
                                  [{'приходные':[{'ордер1':'tab'},{'фактура1':'tab'},{'счет-фактура1':'tab'}]},
                                   {'расходные':[{'ордер2':'tab'},{'фактура2':'tab'},{'счет-фактура2':'tab'}]}
                                  ]
             },
             {'прочие':[{}, Е {}]}
           ]
        },
        {'переменные':[{},Е{}]}
    ]
}

<словарь дополнительных глобальных атрибутов проекта> =
{
'имя переменной' : <значение переменной хранимого типа>
}

Переменные и значения попадают в окружение проекта автоматически.
"""

import re
import os.path
import wx

from ic.dlg import dlgfunc
from ic.log import log

from ic.interfaces import resManager
from ic.utils import util
from ic.utils import resfunc
import ic

__version__ = (0, 1, 1, 1)

_ = wx.GetTranslation

# Константы

DEFAULT_PRJ_NAME = 'new_prj'

# Типы ресурсов ('tab','var','win','mnu','svb','frm')

class icPrjRes(resManager.icResourceManagerInterface):
    """
    Класс управления ресурсом проекта.
    """
    def __init__(self):
        """
        Конструктор.
        """
        resManager.icResourceManagerInterface.__init__(self)

        # Файл проекта
        self.prj_file_name = None

        # Структура проекта
        self._prj = []

    def setResFileName(self, res_filename=None):
        self.prj_file_name = res_filename

    def newPrj(self, prj_name, py_pack=None, prj_template=None):
        """
        Создание нового проекта по умолчанию.

        :param prj_name: Имя проекта.
        :param py_pack: Макет модулей питона.
        :param prj_template: Шаблон для создания проекта.
        """
        # Файл проекта
        prj_res = {}
        if prj_template is None:
            prj_template = self._newPrjTemplate()
        prj_res[prj_name] = prj_template
        prj_res['__py__'] = py_pack
        prj_res['__env__'] = {'AutoLogin': 'admin',
                              'AutoPassword': '',
                              'db_auth': '0',
                              'db_engine': 'PostgreSQLDB',
                              'convert_unicode': 'UTF-8',
                              'dbname': None,
                              'host': '127.0.0.1',
                              'user': 'admin',
                              'sys_table_name': 'resource_tab',
                              'password': '',
                              'port': '5432',
                              'dbstore': '.acc',
                              }
        # Добавить в основную структуру
        self._prj = [prj_res]
        return prj_res

    def _newPrjTemplate(self):
        """
        Шаблон нового проекта по умолчанию.
        """
        return [{'DB': []},
                {'Tables': []},
                {'Menu': []},
                {'System': []},
                {'Forms': []},
                {'Metadata': []},
                ]

    def openPrj(self, prj_filename):
        """
        Открыть файл проекта.
        """
        path, name = os.path.split(prj_filename)
        ic.set_ini_file(path)
        self.prj_file_name = prj_filename
        if os.path.isfile(self.prj_file_name) and os.path.exists(self.prj_file_name):
            prj = util.readAndEvalFile(self.prj_file_name, bRefresh=True)
            self._prj = self._prepareDataPrj(prj)

    # Один метод под двумя именами
    load = openPrj

    def savePrj(self):
        """
        Сохранить проект.
        """
        if not self.prj_file_name:
            self.prj_file_name = dlgfunc.getFileDlg(None, u'Создание проекта',
                                                  u'Project file (*.pro)|*.pro')
        if self.prj_file_name:
            prj_path = os.path.dirname(self.prj_file_name.strip())
            if (not os.path.isdir(prj_path)) or \
               (not self._prj[0]['__py__']):
                # Если директории проекта не существует, то
                # сохранить ее в __py__
                self._prj[0]['__py__'] = prj_path
            return self._save_prj(self.prj_file_name.strip(), self._prepareDataPrj(self._prj))
        return False

    # Один метод под двумя именами
    save = savePrj

    def _prepareDataPrj(self, project):
        """
        Подготовка данных проекта для записи/чтения.
        """
        if isinstance(project, dict):
            project = dict([(key.strip(), self._prepareDataPrj(value)) for key, value in project.items()])
        elif isinstance(project, list):
            project = [self._prepareDataPrj(value) for value in project]
        elif isinstance(project, tuple):
            project = tuple([self._prepareDataPrj(value) for value in project])
        elif isinstance(project, str):
            project = project.strip()
        return project

    def _save_prj(self, prj_filename, project=None):
        """
        Непосредственное сохранение проекта.

        :param prj_filename: Имя файла проекта.
        :param project: Структура проекта.
        :return: Возвращает результат выполнения True/False.
        """
        if project is None:
            project = self._prepareDataPrj(self._prj)
        ok = resfunc.saveResourceText(prj_filename.strip(), project)
        # Кроме того, что сохраняем проект, еще делаем его пакетом
        resfunc.createInitFile(os.path.dirname(prj_filename.strip()))
        return ok

    def getPrjRes(self):
        return self._prj

    def addFolder(self, new_folder_name, dst_folder_name, cur_folder=None):
        """
        Добавить папку.

        :param new_folder_name: Имя новой папки.
        :param dst_folder_name: Имя папки или проекта,
            в которую будет добавляться новая папка.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: Результат добавления True|False.
        """
        if cur_folder is None:
            cur_folder = self.getPrjRoot()
        # Если имя папки==имя проекта, то просто добавить
        # папку в проект
        if dst_folder_name == self.getPrjRootName():
            self.getPrjRoot().append({new_folder_name: []})
            return True

        ok = False
        for folder in cur_folder:
            folder_name = list(folder.keys())[0]
            # Проверять только папки
            if isinstance(folder[folder_name], list):
                if folder_name == dst_folder_name:
                    folder[folder_name].append({new_folder_name: []})
                    ok = True
                    return ok
                else:
                    add = self.addFolder(new_folder_name, dst_folder_name, folder[folder_name])
                    if add:
                        return add
        return ok

    def addRes(self, new_res_name, res_type, dst_folder_name, cur_folder=None):
        """
        Добавить ресурс.

        :param new_res_name: Имя нового ресурса.
        :param res_type: Тип ресурса ('tab','var','win','mnu','svb','frm').
        :param dst_folder_name: Имя папки или проекта,
            в которую будет добавляться новая папка.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: Результат добавления True|False.
        """
        if cur_folder is None:
            cur_folder = self.getPrjRoot()
        ok = False
        for folder in cur_folder:
            folder_name = list(folder.keys())[0]
            # Проверять только папки
            if isinstance(folder[folder_name], list):
                if folder_name == dst_folder_name:
                    folder[folder_name].append({new_res_name: res_type})
                    return True
                else:
                    add = self.addRes(new_res_name, res_type, dst_folder_name, folder[folder_name])
                    if add:
                        return add
        return ok

    def delFolder(self, del_folder_name, cur_folder=None):
        """
        Удалить папку с именем.

        :param del_folder_name: Имя удаляемой папки.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: True-успешное удаление. False-не удален.
        """
        if cur_folder is None:
            cur_folder = self.getPrjRoot()
        del_ok = False
        for i_folder in range(len(cur_folder)):
            folder = cur_folder[i_folder]
            folder_name = list(folder.keys())[0]
            # Проверять только папки
            if isinstance(folder[folder_name], list):
                if folder_name == del_folder_name:
                    del cur_folder[i_folder]
                    return True
                else:
                    delete_ok = self.delFolder(del_folder_name, folder[folder_name])
                    if delete_ok:
                        return delete_ok
        return del_ok

    def getFolder(self, folder_name, cur_folder=None):
        """
        Взять папку с именем.

        :param folder_name: Имя папки.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: Список папки в ресурсе проекта.
        """
        if cur_folder is None:
            cur_folder = self.getPrjRoot()
        for i_folder in range(len(cur_folder)):
            folder = cur_folder[i_folder]
            cur_folder_name = list(folder.keys())[0]
            # Проверять только папки
            if isinstance(folder[cur_folder_name], list):
                if cur_folder_name == folder_name:
                    return cur_folder[i_folder]
                else:
                    find_fld = self.getFolder(folder_name, folder[cur_folder_name])
                    if find_fld is not None:
                        return find_fld
        return None

    def getFolderBody(self, folder_name, cur_folder=None):
        """
        Взять содержимое папки с именем.

        :param folder_name: Имя папки.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: Список папки в ресурсе проекта.
        """
        if cur_folder is None:
            cur_folder = self.getPrjRoot()
        for i_folder in range(len(cur_folder)):
            folder = cur_folder[i_folder]
            cur_folder_name = list(folder.keys())[0]
            # Проверять только папки
            if isinstance(folder[cur_folder_name], list):
                if cur_folder_name == folder_name:
                    return cur_folder[i_folder][folder_name]
                else:
                    find_fld = self.getFolderBody(folder_name, folder[cur_folder_name])
                    if find_fld is not None:
                        return find_fld
        return None

    def delRes(self, res_name, res_type=None, cur_folder=None):
        """
        Удалить ресурс по имени и типу.

        :param res_name: Имя ресурса.
        :param res_type: Тип ресурса, если None,
            то проверка на тип не производится.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: True-успешное удаление. False-не удален.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()
        del_ok = False
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            cur_res_name = list(res.keys())[0]
            # Проверять только папки
            if isinstance(res[cur_res_name], list):
                find_res = self.delRes(res_name, res_type, res[cur_res_name])
                if find_res:
                    return find_res
            else:
                if cur_res_name == res_name and res[cur_res_name] == res_type:
                    del cur_folder[i_res]
                    return True
                elif cur_res_name == res_name and not res_type:
                    del cur_folder[i_res]
                    return True
        return del_ok

    def getResRef(self, res_name, res_type=None, cur_folder=None):
        """
        Получить кортеж указания ресурса по имени и типу.

        :param res_name: Имя ресурса.
        :param res_type: Тип ресурса, если None,
            то проверка на тип не производится.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: Кортеж (Имя ресурса, тип ресурса) или None в случае ошибки.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()
        ret_res = None
        for res in cur_folder:
            cur_res_name = list(res.keys())[0]
            # Проверять только папки
            if isinstance(res[cur_res_name], list):
                find_res = self.getResRef(res_name, res_type, res[cur_res_name])
                if find_res:
                    return find_res
            else:
                if cur_res_name == res_name and res[cur_res_name] == res_type:
                    return cur_res_name, res[cur_res_name]
                elif cur_res_name == res_name and res_type is None:
                    return cur_res_name, res[cur_res_name]

        if ret_res is None:
            log.warning(u'Не найден ресурс <%s.%s> %s' % (res_name, res_type, str(cur_folder)))
        return ret_res

    def getImportSystems(self):
        """
        Список импортируемых подсистем.
        """
        return self._prj[1:]

    def getPyPackage(self):
        """
        Пакет модулей питона текущего проекта.
        """
        return self._prj[0]['__py__']

    def getPrjRootName(self):
        """
        Имя корневой папки проекта.
        """
        root = self._prj[0]
        names = [key for key in root.keys() if not key.startswith('_')]
        return names[0]

    def setPrjRootName(self, new_prj_root_name):
        """
        Имя корневой папки проекта.
        """
        new_prj_root_name = new_prj_root_name
        root = self._prj[0]
        names = [key for key in root.keys() if not key.startswith('_')]
        old_prj_root_name = names[0]
        prj_root = root[old_prj_root_name]
        del self._prj[0][old_prj_root_name]
        self._prj[0][new_prj_root_name] = prj_root

    def getPrjRoot(self):
        """
        Корневая папка проекта.
        """
        if not self._prj:
            self.newPrj(DEFAULT_PRJ_NAME)
        return self._prj[0][self.getPrjRootName()]

    def getPyPackageImportSys(self, import_sys):
        """
        Пакет модулей питона импортироуемой системы.
        """
        return None

    def addPackage(self, package_path, new_package_name=None):
        """
        Добавить пакет модулей в дерево проектов.

        :param package_path: Путь пакета.
        :param new_package_name: Имя нового пакета.
        :return: Результат добавления True|False.
        """
        cur_package_path = package_path
        if new_package_name:
            cur_package_path = os.path.join(cur_package_path, new_package_name)
        return resfunc.createInitFile(cur_package_path)

    def addModule(self, module_name, package_path):
        """
        Добавить модуль в дерево проектов.

        :param module_name: Имя модуля.
        :param package_path: Путь пакета.
        """
        pass

    def renameRes(self, old_name, new_name, cur_folder=None):
        """
        Переименовать ресурс/папку.

        :param old_name: Старое имя.
        :param new_name: Новое имя.
        :param cur_folder: Текущая папка,  если None,
            то берется папка проекта.
        :return: Возвращает результат выполнения переименования.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()
        rename_res = False
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            res_name = list(res.keys())[0]
            if res_name == old_name:
                cur_folder[i_res] = {new_name: res[res_name]}
                return True
            elif isinstance(res[res_name], list):
                # Если это папка, то обработать все подпапки
                rename_res = self.renameRes(old_name, new_name, res[res_name])
                if rename_res:
                    return rename_res
        return rename_res

    def newSubSys(self, subsys_name, subsys_prj_filename, py_pack):
        """
        Создать новую импортируемую подсистему.

        :param subsys_name: Имя импортируемой подсистемы.
        :param subsys_prj_filename: Файл импортируемой подсистемы.
        :param py_pack: Пакет импортируемой подсистмы.
        """
        imp_sys = {'name': subsys_name,
                   'type': 'icSubSys',
                   '__py__': py_pack,
                   'link': 0,
                   'path': subsys_prj_filename}
        # Добавить в проект
        self._prj.append(imp_sys)
        return imp_sys

    def isResORFolderByName(self, name, cur_folder=None):
        """
        Проверка, есть ли ресурс или папка с таким именем в проекте.

        :param name: Имя.
        :return: Возвращает результат операции True/False.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()
        find = False
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            res_name = list(res.keys())[0]
            if res_name == name:
                return True
            elif isinstance(res[res_name], list):
                # Если это папка, то обработать все подпапки
                find_folder = self.isResORFolderByName(name, res[res_name])
                if find_folder:
                    return find_folder
        return find

    def isResByNameANDType(self, name, res_type=None, cur_folder=None):
        """
        Проверка, есть ли ресурс с таким именем и типом в проекте.

        :param name: Имя.
        :param res_type: Строковое определение типа ресурса 'tab','frm',...
            Если тип None, то проверка по типу не делается.
        :return: Возвращает результат операции True/False.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()
        find = False
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            cur_res_name = list(res.keys())[0]
            cur_res_type = res[cur_res_name]
            if isinstance(res[cur_res_name], list):
                # Если это папка, то обработать все подпапки
                find_folder = self.isResByNameANDType(name, res_type, res[cur_res_name])
                if find_folder:
                    return find_folder
            elif cur_res_name == name and cur_res_type == res_type:
                return True
            elif cur_res_name == name and res_type is None:
                return True
        return find

    def getResNameListByType(self, res_type, cur_folder=None):
        """
        Список имен ресурсов в проекте по их типу.

        :param res_type: Строковое определение типа ресурса 'tab','frm',...
        :return: Возвращает список имен ресурсов заданного типа.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()

        find_list = []
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            cur_res_name = list(res.keys())[0]
            cur_res_type = res[cur_res_name]
            if isinstance(res[cur_res_name], list):
                # Если это папка, то обработать все подпапки
                find_folder = self.getResNameListByType(res_type, res[cur_res_name])
                if find_folder:
                    find_list += find_folder
            elif cur_res_type == res_type:
                find_list.append(cur_res_name)
        return find_list

    def getResNameListByTypes(self, res_types, cur_folder=None):
        """
        Список имен ресурсов в проекте по их типу.

        :param res_types: Кортеж строковых определение типа ресурса 'tab','frm',...
        :return: Возвращает список имен ресурсов заданных типов.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()

        find_list = []
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            cur_res_name = list(res.keys())[0]
            cur_res_type = res[cur_res_name]
            if isinstance(res[cur_res_name], list):
                # Если это папка, то обработать все подпапки
                find_folder = self.getResNameListByTypes(res_types, res[cur_res_name])
                if find_folder:
                    find_list += find_folder
            elif cur_res_type in res_types:
                find_list.append(cur_res_name)
        return find_list

    def getResNamesByTypes(self, *res_types):
        """
        Список имен ресурсов в проекте по их типу.

        :param res_types: Кортеж строковых определение типа ресурса 'tab','frm',...
        :return: Возвращает список имен ресурсов заданных типов.
        """
        return self.getResNameListByTypes(*res_types)

    def getResFileNamesByResPattern(self, res_pattern, cur_folder=None):
        """
        Список имен файлов ресурсов по шаблону ресурса.

        :param res_pattern: Кортеж строковых определений шаблонов ресурса '.*\.tab',...
        :return: Список имен файлов ресурсов по шаблону ресурса.
        """
        if cur_folder is None:
            # Отсечь импортитруемые подсистемы
            cur_folder = self.getPrjRoot()

        find_list = []
        for i_res in range(len(cur_folder)):
            res = cur_folder[i_res]
            res_name = list(res.keys())[0]
            res_type = res[res_name]
            if isinstance(res[res_name], list):
                # Если это папка, то обработать все подпапки
                find_folder = self.getResFileNamesByResPattern(res_pattern, res[res_name])
                if find_folder:
                    find_list += find_folder
            else:
                res_file_name = u''
                try:
                    res_file_name = res_name+'.'+res_type
                    if [pattern for pattern in res_pattern if re.match(pattern, res_file_name)]:
                        # Если имя файла подходит под какойлибо шаблон,
                        # то добавитьв выходной список
                        find_list.append(res_file_name)
                except:
                    log.fatal(u'Ошибка поиска файла <%s> по шаблону <%s>' % (res_file_name, res_pattern))
        return find_list

    def getObjectsByResPattern(self, *res_pattern):
        """
        Получить список кортежей (тип объекта,имя объекта) по шаблону ресурса.

        :param res_pattern: Кортеж строковых определений шаблонов ресурса '.*\.tab',...
        :return: Список кортежей (тип объекта,имя объекта) по шаблону ресурса.
        """
        obj_list = []
        res_file_names = self.getResFileNamesByResPattern(res_pattern)
        prj_dir = os.path.dirname(self.prj_file_name)
        for res_file_name in res_file_names:
            full_res_file_name = os.path.join(prj_dir, res_file_name)
            spc = util.readAndEvalFile(full_res_file_name, bRefresh=True)
            obj = (spc['type'], spc['name'], spc['description'])
            obj_list.append(obj)
        return obj_list

    def getObjNamesByResPattern(self, *res_pattern):
        """
        Имена объектов по шаблону ресурсов.
        """
        return [obj[1] for obj in self.getObjectsByResPattern(*res_pattern)]

    def getObjectsInResByType(self, res_filename, obj_type, cur_obj=None):
        """
        Поиск объектов в ресурсе по типу.

        :param res_filename: Имя файла ресурса.
        :param OBjType_: Тип объекта, например 'icButton'.
        :return: Список кортежей формата:
            [('тип объекта','имя объекта','описание'),...]
        """
        if cur_obj is None:
            spc = util.readAndEvalFile(res_filename, bRefresh=True)
            cur_obj = spc[list(spc.keys())[0]]

        find_list = []
        try:
            if cur_obj is None:
                # Ресурс пустой
                return find_list
            if cur_obj['type'] == obj_type:
                find_list.append((cur_obj['type'], cur_obj['name'], cur_obj['description']))
            if 'child' in cur_obj and cur_obj['child']:
                for child in cur_obj['child']:
                    find_grp = self.getObjectsInResByType(res_filename, obj_type, child)
                    find_list += find_grp
        except:
            log.fatal(u'Search error in function getObjectsInResByType: %s, %s, %s' % (res_filename, obj_type, cur_obj))
        return find_list

    def getObjectsInResByTypes(self, res_filename, obj_types, cur_obj=None):
        """
        Поиск объектов в ресурсе по типу.

        :param res_filename: Имя файла ресурса.
        :param OBjTypes_: Кортеж типов объектов, например ('icButton',).
        :return: Список кортежей формата:
            [('тип объекта','имя объекта','описание'),...]
        """
        if cur_obj is None:
            spc = util.readAndEvalFile(res_filename, bRefresh=True)
            cur_obj = spc[list(spc.keys())[0]]

        find_list = []
        try:
            if cur_obj is None:
                # Ресурс пустой
                return find_list
            if cur_obj['type'] in obj_types:
                find_list.append((cur_obj['type'], cur_obj['name'], cur_obj['description']))
            if 'child' in cur_obj and cur_obj['child']:
                for child in cur_obj['child']:
                    find_grp = self.getObjectsInResByTypes(res_filename, obj_types, child)
                    find_list += find_grp
        except:
            log.fatal(u'Search error in function getObjectsInResByTypes: (%s, %s, %s)' % (res_filename,
                                                                                obj_types, cur_obj))
        return find_list

    def getObjByResPatternANDType(self, res_pattern, obj_type):
        """
        Получить список кортежей (тип объекта,имя объекта) по шаблону ресурса и типу объекта.

        :param res_pattern: Кортеж строковых определений шаблонов ресурса '.*\.tab',...
        :param obj_type: Тип объекта. Например 'icButton'.
        :return: Список кортежей (тип объекта,имя объекта) по шаблону ресурса и типу объекта.
        """
        obj_list = []
        res_file_names = self.getResFileNamesByResPattern(res_pattern)
        prj_dir = os.path.dirname(self.prj_file_name)
        for res_file_name in res_file_names:
            full_res_file_name = os.path.join(prj_dir, res_file_name)
            obj_lst = self.getObjectsInResByType(full_res_file_name, obj_type)
            obj_list += obj_lst
        return obj_list

    def getObjByResPatternANDTypes(self, res_pattern, obj_types):
        """
        Получить список кортежей (тип объекта,имя объекта) по шаблону ресурса и типу объекта.

        :param res_pattern: Кортеж строковых определений шаблонов ресурса '.*\.tab',...
        :param obj_types: Кортеж типов объектов, например ('icButton',).
        :return: Список кортежей (тип объекта,имя объекта) по шаблону ресурса и типу объекта.
        """
        obj_list = []
        res_file_names = self.getResFileNamesByResPattern(res_pattern)
        prj_dir = os.path.dirname(self.prj_file_name)
        for res_file_name in res_file_names:
            full_res_file_name = os.path.join(prj_dir, res_file_name)
            obj_lst = self.getObjectsInResByTypes(full_res_file_name, obj_types)
            obj_list += obj_lst
        return obj_list

    def isModByName(self, module_name):
        """
        Проверить, есть ли модуль с таким именем.

        :param module_name: Имя модуля.
        :return: Возвращает результат операции True/False.
        """
        return False

    def isImpSubSys(self, name):
        """
        Проверить, является ли name именем импортируемой подсистемы.

        :param name: Имя некого ресурса.
        :return: Возвращает True/False.
        """
        return bool([sub_sys for sub_sys in self.getImportSystems() if sub_sys['name'] == name])

    def getImpSubSysIdx(self, name):
        """
        Возвращает индекс импортируемой подсистемы по имени.

        :param name: Имя подсистемы.
        :return: Индекс в структуре ресурсного файла импортируемой подсистемы
            с именем name или -1, если такая подсистема в описании не найдена.
        """
        find_idx = -1
        try:
            name_list = ['']+[sub_sys['name'] for sub_sys in self.getImportSystems()]
            find_idx = name_list.index(name)
        except ValueError:
            log.fatal()
            find_idx = -1

        return find_idx

    def delImpSubSys(self, name, bAutoSave=True):
        """
        Удалить из файла *.pro импортируемую подсистему по имени.

        :param name: Имя подсистемы.
        :param bAutoSave: Автоматически сохранить файл *.pro после удаления.
        :return: Возвращает True/False.
        """
        try:
            sub_sys_idx = self.getImpSubSysIdx(name)
            if sub_sys_idx > 0:
                del self._prj[sub_sys_idx]
            if bAutoSave:
                self.save()
            return True
        except:
            log.fatal()
            return False

    def getPrjEnv(self):
        """
        Получить словарь дополнительных атрибутов проекта.
        """
        if '__env__' in self._prj[0]:
            return self._prj[0]['__env__']
        return {}

    def setPrjEnv(self, env):
        """
        Установить словарь дополнительных атрибутов проекта.
        """
        self._prj[0]['__env__'] = env

def test():
    """
    Функция тестирования.
    """
    prj_res = icPrjRes()
    prj_res.newPrj('root', None, None, None)
    print(prj_res.getPrjRes())
    prj_res.addRes('tab1', 'tab', u'Формы')
    print(prj_res.getPrjRes())

if __name__ == '__main__':
    test()


# savers
from sqlalchemy import exc

from src import db_manager

def save_page_to_db(page):
    try:
        db_manager.session.add(page)
        db_manager.session.commit()
    except exc.SQLAlchemyError as e:
        db_manager.handel_exception(e, True, 'save_page', page.url)
    return True

def save_site_to_db(site):
    try:
        db_manager.session.add(site)
        db_manager.session.commit()
    except exc.SQLAlchemyError as e:
        db_manager.handel_exception(e, True, 'save_site', site.domain)
    return True

def save_link_to_db(link):
    try:
        db_manager.session.add(link)
        db_manager.session.commit()
    except exc.SQLAlchemyError as e:
        db_manager.handel_exception(e, True, 'save_link', link.to_page)
    return True

def save_image_to_db(image):
    try:
        db_manager.session.add(image)
        db_manager.session.commit()
    except exc.SQLAlchemyError as e:
        db_manager.handel_exception(e, True, 'save_image', image.url)
    return True

def save_page_image_to_db(page_image):
    try:
        db_manager.session.add(page_image)
        db_manager.session.commit()
    except exc.SQLAlchemyError as e:
        db_manager.handel_exception(e, True, 'save_page_image', page_image.image_id)
    return True

def save_page_data_to_db(page_data):
    try:
        db_manager.session.add(page_data)
        db_manager.session.commit()
    except exc.SQLAlchemyError as e:
        db_manager.handel_exception(e, True, 'save_page_data', page_data.page_id)
    return True

### saving documents

def save_documents_to_db(doc_array, page_id):
    for doc in doc_array:
        save_document_to_db(doc, page_id)

    return True

def save_document_to_db(url, page_id):
    return True

### saving images

def save_images_to_db(img_array, page_id):
    for img in img_array:
        save_document_to_db(img, page_id)

    return True


from pathlib import Path
import shelve

class PID():
    P = Path('C:\\','Users','leouh', 'Documents', 'Rb_Controller')
    def __init__(self):
        with shelve.open('config') as config:
            self.cfg = dict(config)
        self.Ts = 1/self.cfg['freq']
        if self.cfg['ki']:
            self.taui = self.cfg['kp']/self.cfg['ki']
        self.taud = self.cfg['kd']/self.cfg['kp']

    integral_error = 0
    integral_error2 = 0
    prev_t = 0
    prev_t2 = 0

    upper_lim = 28
    lower_lim = 0

    settlecount = 0
    active_controller = 1

    def settle_update(self, t, t_target,error,slope):
        within_error = error and self.cfg['max_fluctuations'] > abs(t_target - t)
        within_slope = slope and self.cfg['settle_slope'] >= abs(t - self.prev_t) / self.Ts

        if within_error or within_slope:
            self.settlecount += 1
        else:
            self.settlecount = 0

    def settle_check(self,slope,timed):
        if slope and timed:
            res = self.settlecount > self.cfg['settle_wait_time']*self.cfg['freq'] or \
                self.settlecount > self.cfg['slope_length']*self.cfg['freq']
        elif slope:
            res = self.settlecount > self.cfg['slope_length']*self.cfg['freq']
        elif timed:
            res = self.settlecount > self.cfg['settle_wait_time']*self.cfg['freq']
        else:
            res = False
        return res

    def swap_controller(self,to):
        if to == self.active_controller:
            return
        if to == 1:
            self.integral_error = self.integral_error2*self.cfg['ki2']/self.cfg['ki']
        if to == 2:
            self.integral_error2 = self.integral_error*self.cfg['ki']/self.cfg['ki2']
        self.active_controller = to

    # Simple PID controller. Explicitly dealing with wind-up
    def update(self, t, t_target):
        error = t_target - t
        p = self.cfg['kp'] * error
        i = self.cfg['ki'] * self.integral_error * self.Ts
        derivative = t - self.prev_t
        d = self.cfg['kd'] * derivative / self.Ts
        self.prev_t = t
        pidout = p + i + d
        if self.lower_lim < pidout < self.upper_lim:
            self.integral_error += error
        else:
            self.integral_error = 0
        return max(min(pidout,self.upper_lim),self.lower_lim)

    def update2(self, t, t_target):
        error = t_target - t
        p = self.cfg['kp2'] * error
        i = self.cfg['ki2'] * self.integral_error2 * self.Ts
        derivative = t - self.prev_t2
        d = self.cfg['kd2'] * derivative / self.Ts
        self.prev_t2 = t
        pidout = p + i + d
        if self.lower_lim < pidout < self.upper_lim:
            self.integral_error2 += error
        else:
            self.integral_error2 = 0
        return max(min(pidout,self.upper_lim),self.lower_lim)


# -*- coding: utf-8 -*-

# Automatic provisioning of wireguard keypair resources.

import nixops.util
import nixops.resources
import logging
from typing import Mapping, Optional, Sequence

logger = logging.getLogger(__name__)

class WgKeypairOptions(nixops.resources.ResourceOptions):
    """Definition of wireguard keypair options."""

    name: str
    enable: bool
    dns: Sequence[str]
    mtu: Optional[int]
    listenPort: int
    persistentKeepalive: Optional[int]
    usePresharedKey: bool
    syncState: bool
    interfaceName: str
    table: Optional[str]
    preUp: str
    preDown: str
    postUp: str
    postDown: str
    baseIpv4: Mapping[str, int]
    addNoWgHosts: bool

class WgKeypairDefinition(nixops.resources.ResourceDefinition):
    """Definition of a wireguard keypair resource."""

    config: WgKeypairOptions

    @classmethod
    def get_type(cls) -> str:
        return "wg-keypair"

    @classmethod
    def get_resource_type(cls) -> str:
        return "wgKeypair"

    def __init__(self, name: str, config: nixops.resources.ResourceEval):
        super().__init__(name, config)
        self.kp_name: str = self.config.name
        self.enable: bool = self.config.enable
        self.dns: Sequence[str] = self.config.dns
        self.mtu: Optional[int] = self.config.mtu
        self.listen_port: int = self.config.listenPort
        self.keepalive: Optional[int] = self.config.persistentKeepalive
        self.use_psk: bool = self.config.usePresharedKey
        self.sync_state: bool = self.config.syncState
        self.interface_name: str = self.config.interfaceName
        self.table: Optional[str] = self.config.table
        self.pre_up: str = self.config.preUp
        self.pre_down: str = self.config.preDown
        self.post_up: str = self.config.postUp
        self.post_down: str = self.config.postDown
        self.base_ipv4: Mapping[str, int] = self.config.baseIpv4
        self.add_no_wg_hosts: bool = self.config.addNoWgHosts

class WgKeypairState(nixops.resources.ResourceState[WgKeypairDefinition]):
    """State of a wireguard keypair resource."""

    kp_name: str = nixops.util.attr_property("wgKeypair.name", None, str)
    enable: bool = nixops.util.attr_property("wgKeypair.enable", False, bool)
    dns: Sequence[str] = nixops.util.attr_property("wgKeypair.dns", [], "json")
    mtu: Optional[int] = nixops.util.attr_property("wgKeypair.mtu", None, int)
    addr: str = nixops.util.attr_property("wgKeypair.addr", None, str)
    private: str = nixops.util.attr_property("wgKeypair.private", None, str)
    public: str = nixops.util.attr_property("wgKeypair.public", None, str)
    listen_port: int = nixops.util.attr_property("wgKeypair.listenPort", None, int)
    keepalive: Optional[int] = nixops.util.attr_property(
        "wgKeypair.keepalive", None, int
    )
    use_psk: bool = nixops.util.attr_property("wgKeypair.usePresharedKey", True, bool)
    psk: str = nixops.util.attr_property("wgKeypair.presharedKey", None, str)
    sync_state: bool = nixops.util.attr_property("wgKeypair.syncState", False, bool)
    interface_name: str = nixops.util.attr_property(
        "wgKeypair.interfaceName", None, str
    )
    table: Optional[str] = nixops.util.attr_property("wgKeypair.table", None, str)
    pre_up: str = nixops.util.attr_property("wgKeypair.preUp", "", str)
    pre_down: str = nixops.util.attr_property("wgKeypair.preDown", "", str)
    post_up: str = nixops.util.attr_property("wgKeypair.postUp", "", str)
    post_down: str = nixops.util.attr_property("wgKeypair.postDown", "", str)
    base_ipv4: Mapping[str, int] = nixops.util.attr_property(
        "wgKeypair.baseIpv4", {}, "json"
    )
    add_no_wg_hosts: bool = nixops.util.attr_property(
        "wgKeypair.addNoWgHosts", True, bool
    )

    @classmethod
    def get_type(cls) -> str:
        return "wg-keypair"

    def __init__(self, depl: nixops.deployment.Deployment, name: str, id):
        nixops.resources.ResourceState.__init__(self, depl, name, id)

    @property
    def resource_id(self) -> str:
        return self.kp_name

    def get_definition_prefix(self) -> str:
        return "resources.wgKeypair."

    def create(
        self,
        defn: WgKeypairDefinition,
        check: bool,
        allow_reboot: bool,
        allow_recreate: bool,
    ) -> None:
        self.kp_name = f"nixops-{self.depl.uuid}-{defn.name}"
        self.enable = defn.enable
        self.dns = defn.dns
        self.mtu = defn.mtu
        self.listen_port = defn.listen_port
        self.keepalive = defn.keepalive
        self.use_psk = defn.use_psk
        self.sync_state = defn.sync_state
        self.interface_name = defn.interface_name
        self.table = defn.table
        self.pre_up = defn.pre_up
        self.pre_down = defn.pre_down
        self.post_up = defn.post_up
        self.post_down = defn.post_down
        self.base_ipv4 = defn.base_ipv4
        self.add_no_wg_hosts = defn.add_no_wg_hosts

        self.state = self.UP

    def destroy(self, wipe: bool = False) -> bool:
        if not self.depl.logger.confirm(
            f"are you sure you want to destroy wireguard keypair resource (wg-link) ‘{self.name}’?"
        ):
            return False
        if wipe:
            self.warn("wipe is not supported")
        self.log(f"destroying {self.name} (resource id: {self.kp_name})...")
        return True


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import argparse, codecs, sys

# Parseur de ligne de commande
parser = argparse.ArgumentParser(description="Sorts or inverts lines or characters from a file.")
parser.add_argument('-f', help="input file")
# seul -l ou -c est permis
lorc = parser.add_mutually_exclusive_group()
lorc.add_argument('-l', help='line sort (default)', action='store_true')
lorc.add_argument('-c', help='character sort', action='store_true')
parser.add_argument('mode', help='either "sort" or "invert"')
args = parser.parse_args()

# Lecture du fichier
lines = []
try:
	with codecs.open(args.f, 'r', encoding='utf8') as f:
		for line in f.readlines():
			# on élimine les retours à la ligne en vue de l'éventuel tri
			lines.append(line.rstrip('\n'))
except IOError:
	sys.exit('Error: file not found')

# Opérations sur le texte
# (si le paramètre -c est spécificié, chaque ligne est aussi
#	 triée ou inversée; le paramètre -l n'est jamais vérifié,
#  mais l'utilisateur peut l'utiliser pour se "rassurer")
if args.mode == 'sort':
	# tri selon l'ordre de Python
	if args.c:
		for i in range(0, len(lines)):
			lines[i] = ''.join(sorted(lines[i]))
	lines.sort()
elif args.mode == 'invert':
	# inversion
	# (c'est peu efficace de procéder à l'inversion explicitement,
	#  mais c'est plus clair, et 'sort' est bien pire de toute façon!)
	if args.c:
		for i in range(0, len(lines)):
			lines[i] = lines[i][::-1]
	lines.reverse()
else:
	# si un mode erroné est spécifié, les lignes ne sont pas modifiées
	sys.exit("Error: unrecognized mode (must be either 'sort' or 'invert')")

# Impression
for line in lines:
	sys.stdout.write(line+'\n')


# Проанализировать зарплаты КМДА csv файлы за 2019 год найти средние минимальные максимальные построить график

import matplotlib.pyplot as plt

def get_data(filename):
    with open(filename, 'r', encoding='utf8') as file:
        data = {}
        file.readline()
        for row in file:
            row_array = row.rstrip().split(';')
            data[row_array[0]] = float(row_array[9].replace('₴', '').replace(' ', '').replace(',', '.'))
        return data

def draw_diagram(data):
    left_edges = [0, 10, 20, 30, 40, 50, 60, 70, 80]
    bar_width = 10

    plt.bar(left_edges, data.values(), bar_width, color=('r', 'g', 'b', 'm', 'k'))

    plt.xlabel('Сотрудник')

    plt.ylabel('Зарплата')

    plt.xticks([0, 10, 20, 30, 40, 50, 60, 70, 80], data.keys())
    plt.xticks(rotation=90)
    #
    plt.yticks([0, 5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000])

    plt.subplots_adjust(bottom=0.4)
    plt.show()

if __name__ == '__main__':
    data = get_data('berezen-2019.csv')
    salaries = data.values()

    max_salary = max(salaries)
    min_salary = min(salaries)
    average_salary = round(sum(salaries) / len(salaries), 2)

    print(max_salary, min_salary, average_salary)

    draw_diagram(data)


from fractions import Fraction
from wick.index import Idx
from wick.operator import FOperator, Tensor
from wick.expression import Term, Expression, AExpression
from wick.wick import apply_wick
from wick.convenience import E1, E2, commute

i = Idx(0, "occ")
a = Idx(0, "vir")
j = Idx(1, "occ")
b = Idx(1, "vir")

T1 = E1("t", ["occ"], ["vir"])
T2 = E2("t", ["occ"], ["vir"])
T = T1 + T2

L1 = E1("L", ["vir"], ["occ"])
L2 = E2("L", ["vir"], ["occ"])
L = L1 + L2

# ov block
operators = [FOperator(a, True), FOperator(i, False)]
pvo = Expression([Term(1, [], [Tensor([i, a], "")], operators, [])])

PT = commute(pvo, T)
PTT = commute(PT, T)
mid = pvo + PT + Fraction('1/2')*PTT
full = L*mid
out = apply_wick(full)
out.resolve()
final = AExpression(Ex=out)
print("P_{ov} = ")
print(final)

# vv block
operators = [FOperator(a, True), FOperator(b, False)]
pvv = Expression([Term(1, [], [Tensor([b, a], "")], operators, [])])

PT = commute(pvv, T)
PTT = commute(PT, T)
mid = pvv + PT + Fraction('1/2')*PTT
full = L*mid
out = apply_wick(full)
out.resolve()
final = AExpression(Ex=out)
final.sort_tensors()
print("P_{vv} = ")
print(final)

# oo block
operators = [FOperator(j, False), FOperator(i, True)]
poo = Expression([Term(-1, [], [Tensor([j, i], "")], operators, [])])

PT = commute(poo, T)
PTT = commute(PT, T)
mid = poo + PT + Fraction('1/2')*PTT
full = L*mid
out = apply_wick(full)
out.resolve()
final = AExpression(Ex=out)
final.sort_tensors()
print("P_{oo} = ")
print(final)

# vo block
operators = [FOperator(i, True), FOperator(a, False)]
pvo = Expression([Term(1, [], [Tensor([a, i], "")], operators, [])])

PT = commute(pvo, T)
PTT = commute(PT, T)
mid = pvo + PT + Fraction('1/2')*PTT
full = mid + L*mid
out = apply_wick(full)
out.resolve()
final = AExpression(Ex=out)
final.sort_tensors()
print("P_{vo} = ")
print(final)


import unittest
import shutil
import tempfile
import os
import logging
logging.getLogger().setLevel(logging.ERROR)

import heppy.framework.context as context
if context.name != 'bare':
    from simple_example_noindexing_cfg import config
    from heppy.utils.debug_tree import create_tree, remove_tree
    from heppy.framework.looper import Looper
    from ROOT import TFile

@unittest.skipIf(context.name=='bare', 'ROOT not available')
class TestNoIndexing(unittest.TestCase):

    def setUp(self):
        self.fname = create_tree()
        rootfile = TFile(self.fname)
        self.nevents = rootfile.Get('test_tree').GetEntries()
        self.outdir = tempfile.mkdtemp()

    def tearDown(self):
        shutil.rmtree(self.outdir)

    def test_all_events_processed(self):
        loop = Looper( self.outdir, config,
                       nEvents=None,
                       nPrint=0 )
        loop.loop()
        loop.write()
        logfile = open('/'.join([self.outdir, 'log.txt']))
        nev_processed = None
        for line in logfile:
            if line.startswith('number of events processed:'):
                nev_processed = int(line.split(':')[1])
        logfile.close()
        self.assertEqual(nev_processed, self.nevents)
        # checking the looper itself.
        self.assertEqual(loop.nEvProcessed, self.nevents)

    def test_skip(self):
        first = 10
        loop = Looper( self.outdir, config,
                       nEvents=None,
                       firstEvent=first,
                       nPrint=0 )
        loop.loop()
        loop.write()
        # input file has 200 entries
        # we skip 10 entries, so we process 190.
        self.assertEqual(loop.nEvProcessed, self.nevents-first)

    def test_process_event(self):
        '''Test that indeed, calling loop.process(iev) raises
        TypeError if the events backend does not support indexing.
        '''
        loop = Looper( self.outdir, config,
                       nEvents=None,
                       nPrint=0 )
        self.assertRaises(TypeError, loop.process, 10)

if __name__ == '__main__':

    unittest.main()


# this class is meant to create a menu floater that moves across the screen vertically and in random positions

#importing librairies
import copy
import random

import pygame

import TestTubeGame

class Menu_Floater:

    def __init__(self,img, direction):
        self.image = img
        self.current_image = copy.copy(self.image)
        self.direction = direction
        self.angle = 0
        self.s = 1
        self.sp = 1
        self.reset()

    #Method that chooses a random x value and sets the image to it
    def reset(self):
        self.x = random.randint(0, TestTubeGame.WIDTH - self.current_image.get_width())
        self.angle = 0
        self.s = random.randint(0,5)
        self.sp = random.randint(1,15)
        self.current_image = pygame.transform.scale(self.image, (random.randint(int(TestTubeGame.WIDTH // 40), int(
            TestTubeGame.WIDTH // 20)), random.randint(int(TestTubeGame.HEIGHT // 40), int(TestTubeGame.HEIGHT // 20))))
        if self.direction:
            self.y = TestTubeGame.HEIGHT
        else:
            self.y = 0 - self.current_image.get_height()

    # Method that moves the image vertically
    def move(self):
        if self.direction:
            self.y -= self.sp
        else:
            self.y += self.sp

    #Method that spins the object
    def spin(self):
        rotated_image = pygame.transform.rotate(self.current_image, self.angle)
        self.angle += self.s
        return rotated_image

    #Method that draw the object
    def draw(self):
        TestTubeGame.WINDOW.blit(self.spin(), (self.x, self.y))
        self.move()
        self.overpass()

    # Method that checks for overpass
    def overpass(self):
        if self.x > TestTubeGame.WIDTH or self.x < 0 or self.y < 0 - self.current_image.get_height() or self.y > TestTubeGame.HEIGHT:
            self.reset()


# LMGP Visualization
#
#
#

import numpy as np
import matplotlib.pyplot as plt
import torch

def plot_ls(model, constraints_flag = True):
    #
    # plot latent values

    zeta = torch.tensor(model.zeta, dtype = torch.float64)
    #A = model.nn_model.weight.detach()
    perm = model.perm
    levels = model.num_levels_per_var
    #positions = torch.matmul(zeta, A.T)   # this gives the position of each combination in latent space

    positions = model.nn_model(zeta, transform = lambda x: x) #3-torch.exp(x)
    if positions.ndim > 2:
        positions = positions.mean(axis = 0)
    else:
        positions = positions.detach()

    if positions.ndim > 2:
        positions = positions.mean(axis = 0)

    # applying the constrains
    if constraints_flag:
        positions = constrains(positions)

    positions = positions.detach().numpy()

    # plt.rcParams.update({'font.size': 19})
    # fig,axs = plt.subplots(figsize=(8.5,6))
    # colors = {0:'blue', 1:'r', 2:'g', 3:'c', 4:'m', 5:'k', 6:'y'}
    # # loop over the number of variables
    # for j in range(len(levels)):

    #     for i in range(levels[j]):
    #         index = torch.where(perm[:,j] == i)
    #         col = list(map(lambda x: colors[x], np.ones(index[0].numpy().shape) * i))
    #         axs.scatter(positions[index][...,0], positions[index][...,1], label = 'level' + str(i+1), c = col)
    #         #axs.set_title('Variable ' + str(j), fontsize = 15)
    #         axs.set_xlabel(r'$z_1$', fontsize = 25)
    #         axs.set_ylabel(r'$z_2$', fontsize = 25)
    #         axs.legend()
    #         tempxi = np.min(positions[...,0])-0.2 * (np.abs(np.min(positions[...,0])) +5)
    #         tempxx = np.max(positions[...,0]) + 0.2 * (np.abs(np.max(positions[...,0])) +5)
    #         tempyi = np.min(positions[...,1])-0.2 * (np.abs(np.min(positions[...,1])) +5)
    #         tempyx = np.max(positions[...,1]) + 0.2 * (np.abs(np.max(positions[...,1])) +5)
    #         axs.set_xlim(tempxi, tempxx)
    #         axs.set_ylim(tempyi, tempyx)

    #         #fig.tight_layout()
    # #plt.tight_layout()
    # #plt.autoscale()
    return positions

def constrains(z):
    n = z.shape[0]
    z = z - z[0,:]

    if z[1,0] < 0:
        z[:, 0] *= -1

    rot = torch.atan(-1 * z[1,1]/z[1,0])
    R = torch.tensor([ [torch.cos(rot), -1 * torch.sin(rot)], [torch.sin(rot), torch.cos(rot)]])

    z = torch.matmul(R, z.T)
    z = z.T
    if z.shape[1] > 2 and z[2,1] < 0:
        z[:, 1] *= -1

    return z


from datetime import datetime, timedelta

import pandas as pd
from framework.configuration.configuration import Configuration
from framework.logger.providers import get_logger

from clients.azure_gateway_client import AzureGatewayClient
from clients.email_gateway_client import EmailGatewayClient
from domain.usage import ReportDateRange
from services.event_service import EventService

logger = get_logger(__name__)

def element_at(_list, index):
    try:
        return _list[index]
    except:
        return None

REPORT_EMAIL_SUBJECT = 'Azure Usage'
REPORT_SORT_KEY = 'Cost'
REPORT_COLUMNS = [
    'Cost',
    'CostUSD',
    'Currency',
    'Product'
]

REPORT_GROUP_KEYS = [
    'Product',
    'Currency'
]

class UsageService:
    def __init__(
        self,
        configuration: Configuration,
        email_client: EmailGatewayClient,
        azure_client: AzureGatewayClient,
        event_service: EventService
    ):
        self.__email_client = email_client
        self.__azure_client = azure_client
        self.__event_service = event_service

        self.__recipient = configuration.azure_usage.get('recipient')

    def __format_date(self, date):
        return date.strftime('%Y-%m-%d')

    async def send_cost_management_report(
        self,
        range_key: str
    ) -> dict:
        logger.info(f'Generating usage report')

        start_date, end_date = self.__get_date_range(
            range_key=range_key)

        logger.info(f'Range: {start_date} to {end_date}')

        content = await self.__azure_client.get_cost_management_data(
            start_date=start_date,
            end_date=end_date)

        data = content.get('data')

        df = pd.DataFrame(data)[REPORT_COLUMNS]

        df = (df
              .groupby(
                  by=REPORT_GROUP_KEYS,
                  as_index=False)
              .sum())

        df = df.sort_values(
            by=REPORT_SORT_KEY,
            ascending=False)

        table = df.to_dict(
            orient='records')

        logger.info('Sending datatable email gateway request')

        event_request, endpoint = self.__email_client.get_datatable_email_request(
            recipient=self.__recipient,
            subject=f'{REPORT_EMAIL_SUBJECT}: {range_key}',
            data=table)

        await self.__event_service.dispatch_email_event(
            endpoint=endpoint,
            message=event_request.to_dict())

        return {'table': table}

    def __get_date_range(
        self,
        range_key: str
    ):
        logger.info(f"Parsing range for date range type: '{range_key}'")
        now = datetime.utcnow()

        if range_key is None:
            logger.info(f'Returning default report date range')
            return (
                self.__format_date(now),
                self.__format_date(now)
            )

        if range_key.startswith(ReportDateRange.LastNDays):
            days = element_at(range_key.split('_'), 1)

            if days is None:
                raise Exception("Range key must be in the format 'days_n'")
            if not days.isdigit():
                raise Exception("Range day parameter is not of type 'int'")

            return (
                self.__format_date(now - timedelta(days=int(days))),
                self.__format_date(now)
            )

        if range_key == ReportDateRange.MonthToDate:
            start = datetime(
                year=now.year,
                month=now.month,
                day=1)

            return (
                self.__format_date(start),
                self.__format_date(now)
            )

        if range_key == ReportDateRange.YearToDate:
            start = datetime(
                year=now.year,
                month=1,
                day=1)

            return (
                self.__format_date(start),
                self.__format_date(now)
            )

        raise Exception(f"'{range_key}' is not a valid report date range key")


import datetime as dt
from dateutil import parser
import os
import pandas as pd
import numpy as np
from scipy import interpolate
from matplotlib import mlab
from selenium import webdriver
import bs4

from timeout import timeout

class DECStation:
    def __init__(self, number, name, lon, lat):
        self.number = number
        self.name = name
        self.lon = lon
        self.lat = lat

    def get_station_url(self):
        """ Get url for a particular station"""
        url =  'http://www.nyaqinow.net/StationReportFast.aspx?&ST_ID=%s' %self.number

        return url

def get_stations():
    """Get the stations"""
    all_stations = {

        #DEC group 1
        #Long Island
        'Babylon': DECStation(46, 'Babylon', -73.41919, 40.74529),
        'Eisenhower Park': DECStation(53, 'Eisenhower Park', -73.58549, 40.74316),
        'Suffolk County': DECStation(36, 'Suffolk County', -73.05754, 40.82799),

        #DEC group 2
        #Manhattan
        'CCNY': DECStation(73, 'CCNY', -73.94825, 40.81976),
        'IS 143': DECStation(56, 'IS 143', -73.93059, 40.84888),
        'PS 19': DECStation(75, 'PS 19', -73.98446, 40.73000),
        'Division Street': DECStation(60, 'Division Street', -73.99518, 40.71436),

        #Staten Island
        'Fresh Kills West': DECStation(61, 'Fresh Kills West', -74.19832, 40.58027),
        'Port Richmond': DECStation(80, 'Port Richmond', -74.13719, 40.63307),
        'Susan Wagner': DECStation(49, 'Susan Wagner', -74.12525, 40.59664),

        #Bronx
        'IS 52': DECStation(24, 'IS 52', -73.9020, 40.8162),
        'IS 74': DECStation(8, 'IS 74', -73.88553, 40.81551),
        'NYBG': DECStation(57, 'NYBG', -73.87809, 40.86790),

        #Queens
        'Maspeth': DECStation(13, 'Maspeth', -73.89313, 40.72698),
        'Queens College': DECStation(62, 'Queens College', -73.82153, 40.73614),

        #Brooklyn
        'PS 274': DECStation(6, 'PS 274', -73.92769, 40.69454),
        'PS 314': DECStation(10, 'PS 314', -74.01871, 40.64182),

        #DEC group 3
        #North
        'White Plains': DECStation(34, 'White Plains', -73.76366, 41.05192),
        'Millbrook': DECStation(25, 'Millbrook', -73.74136, 41.78555)

    }

    return all_stations

def parse_to_float(x):
    try:
        return float(x)
    except:
        return np.nan

def get_station_raw_data(stations, start_date, end_date):
    """
    Download the station data from airnow website
    """

    # Defaults
    website_cols = ['Date Time', 'O3', 'PM25C', 'SO2', 'CO']
    polished_names = ['Date Time', 'station', 'lon', 'lat', 'PM25', 'O3', 'SO2', 'CO']

    # Load into one dataframe
    all_data = pd.DataFrame()

    chrome_bin = os.environ.get('GOOGLE_CHROME_SHIM')
    if chrome_bin:
        options = webdriver.ChromeOptions()
        options.binary_location = chrome_bin
        driver = webdriver.Chrome(chrome_options = options)
    else:
        driver = webdriver.Chrome()

    for name, station in stations.items():

        # Navigate to the webpage
        url = station.get_station_url()

        driver.get(url)
        driver.find_element_by_id('btnGenerateReport').click()

        # Scrape the content
        content = driver.page_source

        soup = bs4.BeautifulSoup(content)
        table = soup.find(attrs={'id': 'C1WebGrid1'})

        df = pd.read_html(str(table), header=0, flavor='bs4')[0]

        # Keep columns and parse
        cols_keep = list(set(df.columns).intersection(set(website_cols)))
        df = df[cols_keep]

        df['Date Time'] = df['Date Time'].map(pd.to_datetime)
        col_nulls = {}
        for col in df.columns:
            if col != 'Date Time':
                df[col] = df[col].map(parse_to_float)
                col_nulls[col] = pd.isnull(df[col])

        df_nulls = pd.DataFrame(col_nulls)
        all_nulls = df_nulls.apply(min, axis = 1)

        # Filter out bad dates and NaNs
        df_filtered = df[-(all_nulls | pd.isnull(df['Date Time']))]

        # Add missing columns
        cols_add = set(website_cols) - set(df_filtered.columns)
        for col in cols_add:
            df_filtered[col] = np.nan

        df_filtered['station'] = name
        df_filtered['lon'] = station.lon
        df_filtered['lat'] = station.lat

        df_filtered.rename(columns = {'PM25C': 'PM25'}, inplace = True)

        all_data = all_data.append(df_filtered, ignore_index=True)

    driver.quit()

    return all_data

def calculate_stations_aqi_data(station_data, breakpoints, aq_variables):
    """
    24 hours for PM2.5, 1 hours for O3
    """

    station_grouped = station_data.groupby(['station', 'lon', 'lat'])

    stations_PM25_24hr = station_grouped.agg({'PM25':
        lambda x: np.mean(x.tail(1))})
    stations_O3_1hr = station_grouped.agg({'O3':
        lambda x: np.mean(x.tail(1)) * 1000})  # x 1000 to get to ppb
    stations_O3_8hr = station_grouped.agg({'O3':
        lambda x: np.mean(x.tail(8)) * 1000})  # x 1000 to get to ppb

    stations_PM25_24hr.columns = ['PM25_24hr']
    stations_O3_1hr.columns = ['O3_1hr']
    stations_O3_8hr.columns = ['O3_8hr']

    stations_out = stations_PM25_24hr.join(stations_O3_1hr).join(stations_O3_8hr)

    stations_out['AQI'] = stations_out.apply(lambda x: calculate_aqi(x, breakpoints), axis=1)

    stations_out.reset_index(level=[0,1,2], inplace=True)
    stations_out = stations_out[['station', 'lon', 'lat', 'PM25_24hr', 'O3_8hr', 'AQI']]
    stations_out.columns = ['station', 'lon', 'lat', 'PM25', 'O3', 'AQI']

    stations_out = pd.melt(stations_out, id_vars=['station', 'lon', 'lat'], value_vars=aq_variables)
    stations_out = stations_out.dropna()

    return stations_out

def calculate_aqi(station_obs, breakpoints):
    """
    Given a station's cross-sectional data, calculate AQI
    """

    aqi = 0
    for name, value in station_obs.iteritems():
        aqi = max(aqi, calculate_score(value, breakpoints, name))

    return aqi

def calculate_score(value, breakpoints, name):
    """
    Return the score for a scale
    """

    if np.isnan(value):
        return 0
    if value < 0:
        value = 0

    ndx = breakpoints[breakpoints[name] > value].index[0]

    if ndx == 0:
        return 0

    index_l = breakpoints.ix[ndx - 1, 'Index']
    index_h = breakpoints.ix[ndx, 'Index']
    conc_l = breakpoints.ix[ndx - 1, name]
    conc_h = breakpoints.ix[ndx, name]

    out = (float(index_h - index_l) / float(conc_h - conc_l)) * \
          float(value - conc_l) + index_l

    return 0 if np.isnan(out) else out

def get_interpolated_grid_data(station_data, aq_variables, data_dir = '/app/static/'):
    """
    Given a melted dataframe of cross-sectional station data
    (pertaining to one time stamp), output the corresponding grid data
    """

    locs_file = os.path.join(data_dir, 'grid_locs.csv')
    locs = pd.read_csv(locs_file)

    lon_locs = np.unique(locs['c_lon'].values)
    lat_locs = np.unique(locs['c_lat'].values)

    locs_data = locs[['gr_id']]

    # For each air quality variable, interpolate across the grid given available stations
    for aq_v in aq_variables:

        station_data_aqv = station_data[station_data['variable'] == aq_v]

        #
        # Find nearest station
        #

        nearest_station = interpolate.griddata((station_data_aqv['lon'].values, station_data_aqv['lat'].values),
                                               station_data_aqv['station'].values,
                                               (locs['c_lon'].values, locs['c_lat'].values), method='nearest')

        nearest_station_df = pd.DataFrame({'gr_id': locs['gr_id'].values,
                                           'station': nearest_station,
                                           'c_lon': locs['c_lon'].values, 'c_lat': locs['c_lat'].values})

        nearest_station_df = pd.merge(nearest_station_df, station_data_aqv, on='station')

        #
        # Interpolate using Delaunay triangulation, filling the holes with nearest neighbor
        #

        # lon x lat - melted lons change first
        aq_v_interpolated = mlab.griddata(station_data_aqv['lat'].values, station_data_aqv['lon'].values,
                                          station_data_aqv['value'].values, lat_locs, lon_locs, interp='linear')

        # Out of area locations
        out_of_area_locs = pd.melt(pd.DataFrame(aq_v_interpolated.mask))
        out_of_area_locs = locs_data['gr_id'][out_of_area_locs['value']].values

        aq_v_data = aq_v_interpolated.data

        # For grid points that are out of range of triangulation, use closest station
        for ooa_loc in out_of_area_locs:
            near_station_dat = nearest_station_df[nearest_station_df['gr_id'] == ooa_loc]

            xx = lon_locs.searchsorted(near_station_dat['c_lon'])
            yy = lat_locs.searchsorted(near_station_dat['c_lat'])

            aq_v_data[xx, yy] = near_station_dat['value']

        new_col = pd.melt(pd.DataFrame(aq_v_data))

        locs_data[aq_v] = new_col['value']

    return locs_data

def predict_stations_data(stations_dat, forecast_periods):
    """
    Predict the stations data into the future
    """
    last_time = stations_dat['Date Time'].max()
    stations_grouped = stations_dat.groupby(['station', 'lat', 'lon'])

    all_forecasts = pd.DataFrame()

    for fp in range(1, forecast_periods + 1):
        station_preds = stations_grouped.apply(predict_station).reset_index(drop=True)
        station_preds['Date Time'] = last_time + dt.timedelta(hours=fp)

        all_forecasts = all_forecasts.append(station_preds)

    return all_forecasts

def predict_station(var_series):
    """
    Predict the next in the time series
    """
    last_value = var_series[-1:]

    return last_value

def get_breakpoints(data_dir = '/app/static'):
    breaks_file = os.path.join(data_dir, 'breakpoints.csv')
    breakpoints = pd.read_csv(breaks_file)

    return breakpoints

@timeout(90)
def main():
    """
    Main function: times out after 90 seconds
    """
    print('Begin main')

    aq_variables = ['PM25', 'O3', 'AQI']
    hist_periods = 5
    forecast_periods = 7

    all_stations = get_stations()
    breakpoints = get_breakpoints()

    #Dates for current period
    end_date = dt.date.today()
    start_date = end_date - dt.timedelta(1)

    print('Get station data')

    station_data_raw = get_station_raw_data(all_stations, start_date, end_date)

    print('Finished getting station data')

    stations_ffilled = station_data_raw.groupby('station').fillna(method='ffill')
    stations_ffilled['station'] = station_data_raw['station']

    stations_predictions = predict_stations_data(stations_ffilled, forecast_periods)

    all_station_data = stations_ffilled.append(stations_predictions)

    time_stamps = all_station_data['Date Time'].unique()[
                    -(hist_periods+forecast_periods):]

    all_grid_data = pd.DataFrame()

    print('Calculating AQI and Interpolating over grid')
    for ts in time_stamps:
        station_time = all_station_data[all_station_data['Date Time'] <= ts]

        # Current station data
        stations_output = calculate_stations_aqi_data(station_time, breakpoints, aq_variables)

        # Interpolate the grid data
        current_grid_data = get_interpolated_grid_data(stations_output, aq_variables)

        current_grid_data['time'] = ts
        all_grid_data = all_grid_data.append(current_grid_data)

    print('Finished main')

    return all_grid_data


import  requests

ship = "10/"
resp = requests.get("https://swapi.co/api/starships/"+ship)
print(resp.status_code)
data = resp.json()

print(str(data['name']))
print("Peliculas:")
for var in data['films']:
    url = str(var)
    pelis = requests.get(url)
    pelis = pelis.json()
    print(str(pelis['title']))


#! /usr/bin/env python

import sys
import argparse
import csv

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('input', metavar='INPUT', type=argparse.FileType('rb'), help="csv file")
    parser.add_argument('output', metavar='OUTPUT', type=argparse.FileType('wb'), help="yml file")

    args = parser.parse_args()

    csvreader = csv.reader(args.input)
    column_names = next(csvreader)
    i = 0
    f = args.output
    for row in csvreader:
        f.write(str(i) + ":\n")
        i += 1
        j = 0
        for attr in row:
            if len(attr) == 0:
                print("WARNING! Entry #" + str(i) + "'s \"" + column_names[j] + "\" is null")
            f.write("  " + column_names[j] + ": " + attr + "\n")
            j += 1

if __name__ == '__main__':
    sys.exit(main())


#!/usr/bin/env python

#
#   A class to control mu-del converters
#
#   Incomplete
#   7DEC11 - Kyle Eberhart

import telnetlib
import logging
from multiprocessing import Process
from multiprocessing import Queue as Q
import queue
import time

class ConvProcess(object):
    '''
    A converter controller that runs in a seperate process, for smoother
    GUI operation. in_queue is how you send commands, out_queue is where
    data comes back.
    '''

    def __init__(self, **kwargs):
        '''
        Initialize our queues and other startup tasks.
        '''
        self.in_queue = Q()
        self.out_queue = Q()
        self.process = None
        self.address = kwargs.get('address', None)
        self.port = kwargs.get('port', None)
        self.converter_target = None

    def connect(self):
        '''
        start the converter communication process, feed it some queues.
        '''
        self.process = Process(target=self._connect,
                               args=(self.in_queue,
                                     self.out_queue))
        self.process.daemon = 1
        self.process.start()

    def command(self, message):
        '''
        send a command to the converter, using the in_q.
        '''
        self.in_queue.put(message)

    def disconnect(self):
        '''
        disconnect from the converter and terminate the process.
        '''
        self.in_queue.put('disconnect')

    def kill_process(self):
        '''
        kill the child process.
        '''
        self.in_queue.put('kill')
        self.process.join()
        self.process = None
        self.converter_target = None

    def _connect(self, in_q, out_q):
        '''
        The converter connection and processing loop.
        '''
        self.converter_target = Converter(address=self.address,
                                          port=self.port)
        self.converter_target.connect()
        while True:
            try:
                conv_command = in_q.get_nowait()
                if conv_command == 'disconnect':
                    self.converter_target.disconnect()
                    out_q.put("Requesting converter process termination.")
                elif conv_command == 'kill':
                    break
                elif 'freq' in conv_command:
                    self.converter_target.setFreq(conv_command[1])
                elif 'atten' in conv_command:
                    self.converter_target.setAtten(conv_command[1])
                elif 'mute' in conv_command:
                    if conv_command[1]:
                        self.converter_target.setMute()
                    else:
                        self.converter_target.unsetMute()
            except Queue.Empty:
                try:
                    if self.converter_target is not None:
                        self.converter_target.getStatus()
                        out_q.put({'freq' : self.converter_target.frequency,
                                   'atten' : self.converter_target.attenuation,
                                   'status' : self.converter_target.statusCode,
                                   'mute' : self.converter_target.mute})
                except EOFError:
                    out_q.put("Status attempt failed!")
                    self.converter_target.disconnect()
                    out_q.put("Requesting converter process termination.")
            time.sleep(1)

    def __del__(self):
        '''
        clean up correctly if possible.
        '''
        if self.process:
            self.disconnect()
            self.kill_process()

class Converter(object):

    def __init__(self, address='192.168.1.3', port=4004):
        self.logger = logging.getLogger(__name__)
        self.address = address
        self.port = port
        self.target = None
        self.errorMsg = None

    def __repr__(self):
        return "<MuDelConverter('%s', '%s')" % (self.address, self.port)

    def connect(self):
        '''
        connect to the converter, and determine the converter type
        '''
        self.target = telnetlib.Telnet(self.address, self.port)
        self.target.write('<?\r'.encode('ascii'))
        self.status = self.target.read_until(b'randomString', 2).decode('ascii')

        if 'MDC-1627F1K-7' in self.status:
            self.type = 'MDC-1627F1K-7'
        elif 'MDC-2125F1K-72' in self.status:
            self.type = 'MDC-2125F1K-72'
        elif 'MUC-7-1627-F1K' in self.status:
            self.type = 'MUC-7-1627-F1K'
        else:
            self.errorMsg = "Converter model unknown: %s" % self.status
            self.logger.debug(self.errorMsg)
            raise RuntimeError(self.errorMsg)

    def disConnect(self):
        '''
        disconnect from the converter
        '''
        self.target.close()
        self.target = None

    def getStatus(self):
        if self.target is None:
            self.connect()
        self.target.write('<S\r'.encode('ascii'))
        self.status = self.target.read_until(b'SomeCrazyString', 2).decode('ascii')
        if self.type == 'MDC-1627F1K-7' or self.type == 'MUC-7-1627-F1K':
            myStatus = self.status[1:].split(',')
            self.frequency = (float(myStatus[0]) + 1600000) / 1000
            self.attenuation =  (float(myStatus[1]) / 5)
            if int(myStatus[2]) is 1:
                self.statusCode = "Normal Operation"
            elif int(myStatus[2]) is 2:
                self.statusCode = "Synth Lock Lost"
            elif int(myStatus[2]) is 3:
                self.statusCode = "Synth 2 Lock Lost"
            elif int(myStatus[2]) is 4:
                self.statusCode = "Synth 3 Lock Lost"
            elif int(myStatus[2]) is 5:
                self.statusCode = "Local Osc Lock Lost"
            elif int(myStatus[2]) is 6:
                self.statusCode = "Aux Input 2 Alarm"
            elif int(myStatus[2]) is 7:
                self.statusCode = "Aux Input 3 Alarm"
            elif int(myStatus[2]) is 8:
                self.statusCode = "Aux Input 4 Alarm"
            elif int(myStatus[2]) is 9:
                self.statusCode = "Reference Osc Lost"
            else:
                self.statusCode = "Unknown"
            self.mute = bool(int(myStatus[3][0:1]))

        if self.type == 'MDC-2125F1K-72':
            myStatus = self.status[1:].split(',')
            self.frequency = (float(myStatus[0]) + 2100000) / 1000
            self.attenuation =  (float(myStatus[1]) / 5)
            if int(myStatus[2]) is 1:
                self.statusCode = "Normal Operation"
            elif int(myStatus[2]) is 2:
                self.statusCode = "Synth Lock Lost"
            elif int(myStatus[2]) is 3:
                self.statusCode = "Synth 2 Lock Lost"
            elif int(myStatus[2]) is 4:
                self.statusCode = "Synth 3 Lock Lost"
            elif int(myStatus[2]) is 5:
                self.statusCode = "Local Osc Lock Lost"
            elif int(myStatus[2]) is 6:
                self.statusCode = "Aux Input 2 Alarm"
            elif int(myStatus[2]) is 7:
                self.statusCode = "Aux Input 3 Alarm"
            elif int(myStatus[2]) is 8:
                self.statusCode = "Aux Input 4 Alarm"
            elif int(myStatus[2]) is 9:
                self.statusCode = "Reference Osc Lost"
            else:
                self.statusCode = "Unknown"
            self.mute = None

        return {'Freq': self.frequency, 'Atten': self.attenuation, 'Code': self.statusCode, 'Mute': self.mute}

    def setFreq(self, freq):
        '''
        set the converter frequency
        '''
        if self.target is None:
            self.connect()
        if self.type == 'MDC-1627F1K-7' or self.type == 'MUC-7-1627-F1K':
            stepValue = (int((float(freq) * 1000)) - 1600000)
            if stepValue < 0:
                stepValue = 0
            if stepValue > 1100000:
                stepValue = 1100000
            self.target.write('<X1{}\r'.format(stepValue).encode('ascii'))
            self.target.read_until(b'SomeCrazyString', 2).decode('ascii')
        elif self.type == 'MDC-2125F1K-72':
            stepValue = (int((float(freq) * 1000)) - 2100000)
            if stepValue < 0:
                stepValue = 0
            if stepValue > 400000:
                stepValue = 400000
            self.target.write('<{}\r'.format(stepValue).encode('ascii'))
            self.target.read_until(b'SomeCrazyString', 2).decode('ascii')
        else:
            self.errorMsg = "Unknown converter type, no freq change"
            self.logger.debug(self.errorMsg)
            raise RuntimeError(self.errorMsg)

    def setAtten(self, atten):
        if self.target is None:
            self.connect()
        if self.type == 'MDC-1627F1K-7' or self.type == 'MUC-7-1627-F1K':
            stepValue = int(float(atten) * 5)
            if stepValue < 0:
                stepValue = 0
            if stepValue > 150:
                stepValue = 150
            self.target.write('<A1{}\r'.format(stepValue).encode('ascii'))
            self.target.read_until(b'SomeCrazyString', 2).decode('ascii')
        elif self.type == 'MDC-2125F1K-72':
            stepValue = int(float(atten) * 5)
            if stepValue < 0:
                stepValue = 0
            if stepValue > 150:
                stepValue = 150
            self.target.write('<A{}\r'.format(stepValue).encode('ascii'))
            self.target.read_until(b'SomeCrazyString', 2).decode('ascii')
        else:
            self.errorMsg = "Unknown converter type, no atten change"
            raise RuntimeError(self.errorMsg)

    def setMute(self):
        if self.target is None:
            self.connect()
        if self.type == 'MDC-2125F1K-72':
            self.errorMsg = "This D/C doesn't support muting"
            raise RuntimeError(self.errorMsg)
        self.target.write('<M1\r'.encode('ascii'))
        self.target.read_until(b'SomeCrazyString', 2).decode('ascii')

    def unsetMute(self):
        if self.target is None:
            self.connect()
        if self.type == 'MDC-2125F1K-72':
            self.errorMsg = "This D/C doesn't support muting"
            raise RuntimeError(self.errorMsg)
        self.target.write('<M0\r'.encode('ascii'))
        self.target.read_until(b'SomeCrazyString', 2).decode('ascii')

    def setConfig(self, **kwargs):
        '''
        configure the whole converter in one bang
        '''
        if 'Freq' in kwargs:
            self.setFreq(kwargs['Freq'])
        if 'Atten' in kwargs:
            self.setAtten(kwargs['Atten'])
        if 'Mute' in kwargs:
            if kwargs['Mute'] is True:
                self.setMute()
            if kwargs['Mute'] is False:
                self.unsetMute()

    def close(self):
        if self.target is not None:
            self.disConnect()

if __name__ == "__main__":
    # run a test, or just set things up...
    import argparse
    import sys

    logging.basicConfig(filename='Mudelconverter.log',
                        filemode='w',
                        level=logging.INFO)

    parser = argparse.ArgumentParser(description='Configure a MuDel Converter',
                                    formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-f', '--freq', help='Set the frequency in MHz.')
    parser.add_argument('-a', '--atten', help='Set the attenuation in dB.')
    parser.add_argument('-m', '--mute', help='Toggle the mute.')
    parser.add_argument('dest', help='IP address of the target device.')
    args = parser.parse_args()
    config = vars(args)

    if config['dest'] is not None:
        try:
            ip, port = config['dest'].split(':')
        except ValueError as err:
            print('\nIt doesn\'t seem like a port was specified.')
            print('\txxx.xxx.xxx.xxx:ppp')
            print('Where xxx is the IP octet and ppp is the port number.\n')
            sys.exit()
        try:
            converter = Converter(ip, port)
            converter.connect()
            print('\n')
#            print(converter.status)
        except RuntimeError as err:
            print('\nConnection to converter failed!!!')
            print(err)
            print('\n')
            sys.exit()
        try:
            converter.getStatus()
            print('---- Current Status ----')
            print('Freq:  {} MHz'.format(converter.frequency))
            print('Atten: {} dB'.format(converter.attenuation))
            print('LO:    {}'.format(converter.statusCode))
            print('Mute:  {}'.format(converter.mute))
            print('\n')
        except RuntimeError as err:
            print('\nStatus fetch failed!!!')
            print(err)
            print('\n')
            sys.exit()

    if config['freq'] is not None:
        # set the frequency, check the input formatting first.
        converter.setFreq(config['freq'])

    if config['atten'] is not None:
        # set the attenuation, check the input formatting first.
        converter.setAtten(config['atten'])

    if config['mute'] is not None:
        # always unmute the converter.
        converter.unsetMute()

    converter.getStatus()
    print('---- Final Status ----')
    print('Freq:  {} MHz'.format(converter.frequency))
    print('Atten: {} dB'.format(converter.attenuation))
    print('LO:    {}'.format(converter.statusCode))
    print('Mute:  {}'.format(converter.mute))
    print('\n')

    converter.close()
    sys.exit()


import torch
from torch import nn
import torch.nn.functional as F

class FastText(nn.Module):
    def __init__(self, num_tags, vocab_size, embed_size, input_dropout_rate,
                 embed_type='rand', use_bigram=False, bigram_vocab_size=0, bigram_embed_size=0):
        super(FastText, self).__init__()
        self.embed_type = embed_type
        self.use_bigram = use_bigram

        hidden_size = embed_size
        self.embedding = nn.Embedding(vocab_size, embed_size)

        if use_bigram:
            hidden_size += bigram_embed_size * 2
            self.bigram_embedding = nn.Embedding(bigram_vocab_size, bigram_embed_size)

        if embed_type == 'static':
            for param in self.embedding.parameters():
                param.requires_grad = False

            if use_bigram:
                for param in self.bigram_embedding.parameters():
                    param.requires_grad = False

        self.linear = nn.Linear(hidden_size, num_tags)

        self.in_dropout = nn.Dropout(input_dropout_rate)

        self.ce_loss = nn.CrossEntropyLoss()

    def init_embedding(self, pretrained_embeddings):
        self.embedding.weight.data.copy_(torch.from_numpy(pretrained_embeddings))

    def init_bigram_embedding(self, pretrained_embeddings):
        self.bigram_embedding.weight.data.copy_(torch.from_numpy(pretrained_embeddings))

    def forward(self, tokens, masks, bigram, decode=True, tags=None):
        masks = masks.unsqueeze(2)

        embed = self.embedding(tokens)
        if self.use_bigram:
            embed_bi = torch.cat([self.bigram_embedding(bigram[:, :, i]) for i in range(bigram.size()[2])], dim=2)
            embed = torch.cat((embed, embed_bi), dim=2)
        embed = self.in_dropout(embed)

        context = torch.mul(embed, masks)
        context = context.mean(1)

        out = self.linear(context)

        if decode:
            out = F.softmax(out, dim=1)
            out = torch.argmax(out, dim=1)
            pred = out.cpu().numpy()
            return pred
        else:
            loss = self.ce_loss(out, tags)
            return loss