# module
# autor: MolokovAlex
# lisence: GPL
# coding: utf-8
# from sys import getsizeof
import os
from datetime import datetime
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import END, N, NSEW, Menu
import tkinter.messagebox as mb
import sqlite3 as sqlite
import pandas as pd
import numpy as np
import sqlite3 as sql3

import moduleDBClass as mdbc
import moduleImport as mi
import skladConfig as scfg
import moduleSQLite as msql

import modulеIncomeExpenditureGUI as mieGUI
import modulеEditGUI as meGUI
import moduleExport as me
import moduleSpecification as ms

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.protocol("WM_DELETE_WINDOW", self.confirm_delete)
        self.widthscreen = self.winfo_screenwidth()#-30    # размеры экрана
        self.heigthscreen = 640 #window.winfo_screenheight()-30
        self.geometry('{}x{}+5+5'.format(self.widthscreen, self.heigthscreen))

        self.frame_Logger = tk.LabelFrame(master=self, text="Log", relief=tk.SUNKEN, borderwidth=3, height=20)
        self.frame_Logger.pack(fill=tk.X, side=tk.TOP, ipadx=5, ipady=5, padx=10, pady=5)
        self.scroll_logger_x = tk.Scrollbar(self.frame_Logger, orient=tk.HORIZONTAL)
        self.scroll_logger_y = tk.Scrollbar(self.frame_Logger, orient=tk.VERTICAL)
        self.text_box = tk.Text(master=self.frame_Logger, xscrollcommand=self.scroll_logger_x.set, yscrollcommand=self.scroll_logger_y.set, height= 20)
        self.scroll_logger_x.config(command=self.text_box.xview)
        self.scroll_logger_y.config(command=self.text_box.yview)
        self.text_box.grid(row=0, column=0, sticky=tk.W + tk.E)
        self.scroll_logger_x.grid(row=1, column=0, sticky=tk.W + tk.E)
        self.scroll_logger_y.grid(row=0, column=1) #, sticky=tk.N + tk.S)
        self.frame_Logger.columnconfigure(0, weight=1)
        self.frame_Logger.rowconfigure(0, weight=0)

    def confirm_delete(self) -> None:
    #     message = "Вы уверены, что хотите закрыть это окно?"
    #     if mb.askyesno(message=message, parent=self):
        # сохраняем изменненный DataFame в файл перед закрытием основного окна
        # me.Save_DataFrame_in_PickleFile(df=scfg.df1, namefile=scfg.nameFile_DBC_pickle)
        # me.Save_DataFrame_in_ExcelFile(df=scfg.df1, namefile=scfg.nameFile_DBC_excel)
        me.Save_DataFrame_in_PickleFile()
        self.destroy()
        return None

    def createMainMenu(self) -> None:
        self.mainmenu = Menu(self)
        self.config(menu=self.mainmenu)

        self.db_import_menu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label='Импорт из xls', menu=self.db_import_menu)

        self.db_import_menu.add_command(label='Импорт Components', command=lambda modeWind='import', viewWind = 'DBC': self.open_Window_Import_Component(modeWindow = modeWind, viewWindow = viewWind))
        self.db_import_menu.add_command(label='Импорт спецификаций', command=lambda modeWind='import', viewWind = 'DBS': self.open_Window_Import_Component(modeWindow = modeWind, viewWindow = viewWind))

        self.db_export_menu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label='Экспорт в xls', menu=self.db_export_menu)
        self.db_export_menu.add_command(label='Экспорт Components', command=self.open_Window_Export)
        self.db_export_menu.add_command(label='Экспорт спецификаций', command=self.open_Window_Export)

        self.editmenu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label='Правка БД', menu=self.editmenu)
        self.editmenu.add_command(label='Редактирование Components', command=self.open_Window_Edit_Component)
        self.editmenu.add_command(label='Редактирование спецификаций', command=self.open_Window_Edit_Specification)

        self.arrivalmenu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label='Приход на склад', menu= self.arrivalmenu)
        self.arrivalmenu.add_command(label='Приход', command=self.open_Window_income_Component)
        self.arrivalmenu.add_command(label='История приходов', command=self.clicked)

        self.expensemenu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label='Расход из склада', menu= self.expensemenu)
        self.expensemenu.add_command(label='Расход', command=self.open_Window_expenditure_Component)
        self.expensemenu.add_command(label='История расходов', command=self.clicked)

        self.specmenu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label='Спецификации', menu=self.specmenu)
        self.specmenu.add_command(label='Новая', command=self.clicked)
        self.specmenu.add_command(label='Редактирование', command=self.clicked)
        self.specmenu.add_command(label='Удаление', command=self.clicked)
        self.specmenu.add_command(label='Проводка спецификации', command=self.clicked)

        self.helpmenu = Menu(self.mainmenu, tearoff=0)
        self.mainmenu.add_cascade(label="Справка", menu=self.helpmenu)
        self.helpmenu.add_command(label="Помощь")
        self.helpmenu.add_command(label="О программе")

        return None

    def open_Window_Export(self) -> None:
        """
        открытие окна экспорта
        """
        we = me.WindowExport(self)
        we.grab_set()                      #  чтобы окно получало все события
        return None

    def open_Window_expenditure_Component(self) -> None:
        """
        открытие окна для операции расхода компонента на различные цели
        """
        # viewDB - отображение в окне БД:
        # 'DBC' = DataBaseComponents
        # 'DBS' = DataBaseSpecification
        # 'DBE' - DataBaseExpenditure - БД расхода компонентов (expenditure)
        # modeWindow - внешний вид и расположени кнопок окна в режимах:
        # modeWindow = 'edit'
        # modeWindow = 'comp_in_spec'
        # modeWindow = 'expenditure'  - режим окна Расход компонента
        # modeWindow = 'income'  - режим окна Приход компонента
        we = mieGUI.WindowExpenditure(self, viewDB = 'DBE', modeWindow = 'expenditure')
        we.grab_set()                      #  чтобы окно получало все события
        # self.text_box.insert(tk.END, "open_WindowExpenditure"+"\n")

        return None

    def open_Window_income_Component(self) -> None:
        """
        открытие окна для операции расхода компонента на различные цели
        """
        # viewDB - отображение в окне БД:
        # 'DBC' = DataBaseComponents
        # 'DBS' = DataBaseSpecification
        # 'DBE' - DataBaseExpenditure - БД расхода компонентов (expenditure)
        # modeWindow - внешний вид и расположени кнопок окна в режимах:
        # modeWindow = 'edit'
        # modeWindow = 'comp_in_spec'
        # modeWindow = 'expenditure'  - режим окна Расход компонента
        # modeWindow = 'income'  - режим окна Приход компонента
        we = mieGUI.WindowExpenditure(self, viewDB = 'DBI', modeWindow = 'income')
        we.grab_set()                      #  чтобы окно получало все события
        # self.text_box.insert(tk.END, "open_WindowExpenditure"+"\n")

        return None

    def open_Window_Edit_Specification(self) -> None:
        # viewWindow = 'DBC' = DataBaseComponents
        # 'DBS' = DataBaseSpecification
        # modeWindow = 'edit'
        # modeWindow = 'comp_in_spec'
        # wec = meGUI.WindowEditComponent(self, modeWindow = 'edit', viewDB='DBS')
        # wec.grab_set()                      #  чтобы окно получало все события
        wior = ms.Window_Choice_Specification(self)
        select = wior.open()
        wes = ms.Window_Edit_Specification(self, id_select=select)
        self.text_box.insert(tk.END, "open_WindowEdit_Specification"+"\n")
        return None

    def open_Window_Edit_Component(self):
        # viewWindow = 'DBC' = DataBaseComponents
        # 'DBS' = DataBaseSpecification
        # modeWindow = 'edit'
        # modeWindow = 'comp_in_spec'
        wec = meGUI.WindowEditComponent(self, modeWindow = 'edit', viewDB='DBC')
        wec.grab_set()                      #  чтобы окно получало все события
        self.text_box.insert(tk.END, "open_WindowEdit_Component"+"\n")
        return None

    def open_Window_Import_Component(self, modeWindow, viewWindow) -> None:
        """
        сюда приходим из меню 'Импорт Components'
        Функция открытия универсального окна Импрта или Перемещния
        Вход:
        # визуальное отображение окна для БД компонентов или БД спецификаций :
        # viewWindow = DBC = DataBaseComponents
        # viewWindow = DBS = DataBaseSpecification
        # режим работы окна - или "перемещнние " или "импорт"
        # modeWindow = 'remove'
        # modeWindow == 'import

        """
        mW = modeWindow
        vW = viewWindow
        wior = mi.Window_Import_OR_Remove(self, modeWindow = mW, viewWindow = vW)
        # wig.grab_set()                      #  чтобы окно получало все события
        self.text_box.insert(tk.END, "open_Window_Import_Group"+"\n")
        return None

    def clicked(self):
        return None

def Unpack_String_DataFrame(DataFrameTree: pd.DataFrame, index: str) -> None:
    """
    Универсальная Распаковка строки таблцицы DataFrama на поля(столбцы), т.е. SerialFrame
    список полей- какие найдутся в DataFrame
    плюс поля:
    'UnitsName' - наименование ед изм - возмем по коду 'id_code_item' из DBCU
    'index'
    # 'PathDistanation' - путь списания компонента в спецификацию - возмем по коду 'id_code_parent' из DBS

    Выход:
    словарь типа {'название поля/столбца': содержимое}

    """
    # будущий результат работы функции - словать типа {'название поля/столбца': содержимое}
    upsdf = {}
    # список названий всех полей/столбцов в DataFrame
    # в pandas
    nameColunms = DataFrameTree.columns.values.tolist()

    #  для каждого наименования столбца извлекаем содержимое  value и помещаем в выходной словарь
    for itemNameColunm in nameColunms:
        value = DataFrameTree.loc[index, itemNameColunm]
        upsdf[itemNameColunm] = value

        if (itemNameColunm == 'id_code_item') | (itemNameColunm == 'amount'):
            if isinstance(value, str) :
                if (value == ''):
                    upsdf[itemNameColunm] = '0'
            else:
                if value.empty:
                    upsdf[itemNameColunm] = '0'
    # поле индекса тоже должно быть
    upsdf['index'] = DataFrameTree.index

    # извлекем наименование ед изм - возмем по коду 'id_code_item' из DBCU
    a = scfg.df_DBCU
    unitsCodeSF = scfg.df_DBCU[scfg.df_DBCU['id_code_item'] == upsdf['id_code_item']]['code_units']
    # если такой компонент ('id_code_item') отсутствет в БД ед изм - проверим это
    if unitsCodeSF.empty: unitsCode = '1699'
    else : unitsCode = unitsCodeSF.item()
    upsdf['UnitsName'] = scfg.UnitsCodeName[unitsCode]

    # # извлекем путь списания компонента в спецификацию - возмем по коду 'id_code_parent' из DBS
    # if (upsdf['id_code_parent'] !=''):
    #     # self.idCodeDistanation = id_item_group
    #     nameGroup = scfg.df_DB_Specification[scfg.df_DB_Specification['id_code_e']==upsdf['id_code_parent']]['name']
    #     ValuePathDistanation= nameGroup.item()
    #     id_code_parent = scfg.df_DB_Specification[scfg.df_DB_Specification['id_code_e']==upsdf['id_code_parent']]['id_code_parent']
    #     while (id_code_parent.item() != '10000'):
    #         id_item = id_code_parent.item()
    #         nextNameGroup = scfg.df_DB_Specification[scfg.df_DB_Specification['id_code_e']==id_item]['name']
    #         a= nextNameGroup.item()
    #         ValuePathDistanation = a + '/' + ValuePathDistanation
    #         #  перейдем к слудущему родителю
    #         id_code_parent = scfg.df_DB_Specification[scfg.df_DB_Specification['id_code_e']==id_item]['id_code_parent']
    # upsdf['PathDistanation'] = ValuePathDistanation

    return upsdf

# def viewTreeComponents(treeComp:ttk.Treeview, DataFrameTree: pd.DataFrame, id_parent):
def viewTreeComponents(treeComp:ttk.Treeview, id_parent: int) -> None:
    """
    отображение ветки в дереве Компонентов
    Вход:
    treeF:ttk.Treeview - объект дерева из формы
    DataFrameTree: pd.DataFrame - БД которую надо отобразить
    parent - id_code_item группы(ветки) дерева
    """
    stringDF = {}
    # очистим все дерево компонентов
    for i in treeComp.get_children(): treeComp.delete(i)

    # заполним дерево TreeComponent названиями данными из DBC у которых родителем является группа id_parent из DBG
    connectionDBFile = sql3.connect(scfg.DBSqlite)
    cursorDB = connectionDBFile.cursor()
    with connectionDBFile:
        # вычисли максимальное значение id в таблице DBС
        # cursorDB.execute("""SELECT MAX(id) FROM DBC;""")
        # maxxx3 = cursorDB.fetchone()
        # maxx2 = maxxx3[0]

         # получим названия столбцов БД
        cursorDB.execute('PRAGMA table_info("DBC")')
        column_names = [i[1] for i in cursorDB.fetchall()]
        column_names.append('name_unit')

        # вытащим строки - получим из DBC у которых id_parent =id_parent
        cursorDB.execute("""SELECT DBC.*, DBU.name FROM DBC JOIN DBU ON DBU.id = DBC.id_unit WHERE DBC.id_parent=? ;""", (id_parent,))
        # cursorDB.execute("""SELECT DBC.name, DBC.amount, DBU.name FROM DBC, DBU WHERE DBU.id = DBC.id_unit ;""")#, (id_parent,))
        # cursorDB.execute("""SELECT DBC.*, DBU.name FROM DBC, DBU WHERE DBU.id = DBC.id_unit AND DBC.id_parent=? ;""", (id_parent,))
        rows_from_DBС = cursorDB.fetchall()

    if(connectionDBFile):
            connectionDBFile.close()

        # сделаем словарь {ключ_название_столбца_таблицы: содержимое_ячейки_столбца} и заполняем элемент дерева
    for item_tupple in rows_from_DBС:
        stringDF = {}
        stringDF = { k:v for k,v in zip (column_names,item_tupple )}
        # print(stringDF)    # {'id': 1, 'name': 'Склад'}
        if stringDF['id_parent'] ==0:
            index_code_parent=''
        else:
            index_code_parent = str(stringDF['id_parent'])
        treeComp.insert('', 'end',  stringDF['id'], text=stringDF['name'], values=[stringDF['id'], stringDF['amount'], stringDF['name_unit'], stringDF['min_rezerve'], stringDF['articul_1C'], stringDF['code_1C'], stringDF['name_1C'], stringDF['id_parent'], 0])

    return None

def viewTreeGroupSpec(treeF:ttk.Treeview, DataFrameTree: pd.DataFrame) -> None:

    a=0
    stringDF = {}
    # очищаем дерево
    for i in treeF.get_children(): treeF.delete(i)
    for lvl in scfg.listOfLevel:
        # выдать всех у кого в родителях код lvl
        df2 = DataFrameTree[DataFrameTree['id_code_lvl'] == lvl]
        if not(df2.empty):
            for indx in df2.index:
                stringDF = Unpack_String_DataFrame(DataFrameTree, indx)
                if lvl == 'lvl01':
                    id_code_parent = ''
                else:
                    id_code_parent = DataFrameTree.loc[indx, 'id_code_parent']
                index_code_parent = id_code_parent
                id_code_e = int(stringDF['id_code_e'])
                # treeF.insert(index_code_parent, 'end',  id_code_item, text=name, values=[id_code_item, amount, code_units, min_rezerve, articul_1C, code_1C, name_1C, id_code_parent, id_code_lvl])
                treeF.insert(index_code_parent, 'end',  id_code_e, text=stringDF['name'], values=[stringDF['id_code_item'], stringDF['amount'],  stringDF['id_code_parent'], stringDF['id_code_lvl']])

def viewTreeGroupDBGC(treeF:ttk.Treeview):#, DataFrameTree: pd.DataFrame):

    stringDF = {}
    # очищаем дерево
    for i in treeF.get_children(): treeF.delete(i)

    # заполним дерево TreeGroup названиями групп из DBG

    connectionDBFile = sql3.connect(scfg.DBSqlite)
    cursorDB = connectionDBFile.cursor()
    with connectionDBFile:
        # вычисли максимальное значение id родителя в таблице DBG
        # cursorDB.execute("""SELECT MAX(id_parent) FROM DBG;""")
        # maxxx = cursorDB.fetchone()
        # maxx = maxxx[0]

        # вычисли максимальное значение id в таблице DBG
        # cursorDB.execute("""SELECT MAX(id) FROM DBG;""")
        # maxxx3 = cursorDB.fetchone()
        # maxx2 = maxxx3[0]

        # получим названия столбцов БД
        cursorDB.execute('PRAGMA table_info("DBG")')
        column_names = [i[1] for i in cursorDB.fetchall()]
        # print(column_names)
        # ['id', 'name', 'id_parent']

        # пройдемся по всем индексам БД и
        # for item_id in range (1, maxx2+1, 1):
        #     # вытащим строку - получим из DBG названия у которых id =item_id
        #     cursorDB.execute("""SELECT * FROM DBG WHERE id=?;""", (item_id,))
        #     row_from_DBG = cursorDB.fetchall()
            # print(row_from_DBG)    # [(1, 'Склад', 0)]
        cursorDB.execute("""SELECT * FROM DBG ORDER BY id_parent;""")
        rows_from_DBG = cursorDB.fetchall()
            # if row_from_DBG:
                # сделаем словарь {ключ_название_столбца_таблицы: содержимое_ячейки_столбца} и заполняем элемент дерева
        for item_tupple in rows_from_DBG:
            stringDF = {}
            stringDF = { k:v for k,v in zip (column_names,item_tupple )}
            # print(stringDF)    # {'id': 1, 'name': 'Склад'}
            if stringDF['id_parent'] ==0:
                index_code_parent=''
            else:
                index_code_parent = str(stringDF['id_parent'])
            # treeF.insert(index_code_parent, 'end',  id_code_item, text=stringDF['name'], values=[stringDF['id_code_item'], stringDF['amount'], UnitsName, stringDF['min_rezerve'], stringDF['articul_1C'], stringDF['code_1C'], stringDF['name_1C'], stringDF['id_code_parent'], stringDF['id_code_lvl']])
            treeF.insert(index_code_parent, 'end',  stringDF['id'], text=stringDF['name'], values=[stringDF['id'], 0, '', 0, '', '', '', stringDF['id_parent'], 0])

        # item_id_parent = 1
        # cursorDB.execute("""SELECT * FROM DBG WHERE id_parent=?;""", (item_id_parent,))
        # row_from_DBG = cursorDB.fetchall()
        # print(row_from_DBG)
        # # [(1, 'Склад', 0)]
        # # сделаем словарь и заполняем дерево
        # for item_tupple in row_from_DBG:
        #     stringDF = {}
        #     stringDF[column_names[0]] = item_tupple[0]
        #     stringDF[column_names[1]] = item_tupple[1]
        #     stringDF[column_names[2]] = item_tupple[2]
        #     print(stringDF)
        #     # {'id': 1, 'name': 'Склад'}
        #     if stringDF['id_parent'] ==0:
        #         index_code_parent=''
        #     else:
        #         index_code_parent = str(stringDF['id_parent'])
        #     # treeF.insert(index_code_parent, 'end',  id_code_item, text=stringDF['name'], values=[stringDF['id_code_item'], stringDF['amount'], UnitsName, stringDF['min_rezerve'], stringDF['articul_1C'], stringDF['code_1C'], stringDF['name_1C'], stringDF['id_code_parent'], stringDF['id_code_lvl']])
        #     treeF.insert(index_code_parent, 'end',  stringDF['id'], text=stringDF['name'], values=[stringDF['id'], 0, '', 0, '', '', '', stringDF['id_parent'], 0])

    if(connectionDBFile):
            connectionDBFile.close()

def viewTreeGroupDBGS(treeF:ttk.Treeview)-> None:
    """
    отображение таблицы DBGS в форме на компоненте Treeview
    """
    # очищаем дерево
    for i in treeF.get_children(): treeF.delete(i)

    # заполним дерево TreeGroup названиями групп из DBGS
    connectionDB = sql3.connect(scfg.DBSqlite)
    cursorDB = connectionDB.cursor()
    with connectionDB:
        cursorDB.execute("""SELECT * FROM DBGS ORDER BY id_parent;""")
        rows_from_DBGS = cursorDB.fetchall()
            # if row_from_DBG:
        for item_tupple in rows_from_DBGS:
            id, name, id_parent = item_tupple
            if id_parent == 0: index_code_parent=''
            else: index_code_parent = id_parent
            # stringDF = {}
            # stringDF = { k:v for k,v in zip (column_names,item_tupple )}
            # print(stringDF)    # {'id': 1, 'name': 'Склад'}
            # if stringDF['id_parent'] ==0:
            #     index_code_parent=''
            # else:
            #     index_code_parent = str(stringDF['id_parent'])
            # treeF.insert(index_code_parent, 'end',  id_code_item, text=stringDF['name'], values=[stringDF['id_code_item'], stringDF['amount'], UnitsName, stringDF['min_rezerve'], stringDF['articul_1C'], stringDF['code_1C'], stringDF['name_1C'], stringDF['id_code_parent'], stringDF['id_code_lvl']])
            # treeF.insert(index_code_parent, 'end',  stringDF['id'], text=stringDF['name'], values=[stringDF['id'], 0, '', 0, '', '', '', stringDF['id_parent'], 0])
            treeF.insert(index_code_parent, 'end',  id, text=name, values=[id, 0, '', 0, '', '', '', id_parent, 0])

    if(connectionDB):
            connectionDB.close()

def Setting_TreeView(treeF:ttk.Treeview, form):
    """
    Установка и настройка столбцов компонента TreeView
    Визуальная настройка

    """

    col = scfg.columns_DB_components.copy()
    col.remove('name')
    treeF["columns"]=col

    # treeF.heading('#0', text='NameID')
    # treeF.heading('#1', text='id_code_item')
    # treeF.heading('#2', text='amount')
    # treeF.heading('#3', text='code_units')
    # treeF.heading('#4', text='min_rezerve')
    # treeF.heading('#5', text='articul_1C')
    # treeF.heading('#6', text='code_1C')
    # treeF.heading('#7', text='name_1C')
    # treeF.heading('#8', text='id_code_parent')
    # treeF.heading('#9', text='id_code_lvl')
            # Specify attributes of the columns
    # treeF.column('#0', width=200,stretch=tk.YES)
    # treeF.column('#1', width=60,stretch=tk.YES)
    # treeF.column('#2', width=60,stretch=tk.YES)
    # treeF.column('#3', width=60,stretch=tk.YES)
    # treeF.column('#4', width=60, stretch=tk.YES)
    # treeF.column('#5', width=60, stretch=tk.YES)
    # treeF.column('#6', width=60, stretch=tk.YES)
    # treeF.column('#7', width=60, stretch=tk.YES)
    # treeF.column('#8', width=60, stretch=tk.YES)
    # treeF.column('#9', width=60, stretch=tk.YES)

    # treeF["columns"]=scfg.columns_DB_components.copy()
    # a = scfg.columns_DB_components.copy()

    for i in col:
            treeF.heading(i, text=i)
            treeF.column(i, width=scfg.widthColunmsTreeWindowEditComponent[i], stretch=True)
    treeF.heading('#0', text='NameID')
    # treeF.column('#0', width=300,stretch=tk.YES)

    if form == 'short':
        # отобразим визуально только те столбцы, которые заложены в конфигуоационный модуль
        treeF["displaycolumns"]=scfg.displayColumnsShort
        treeF.column('#0', width=200,stretch=tk.YES)
    elif form == 'full':
        treeF["displaycolumns"]=scfg.displayColumnsFull
        treeF.column('#0', width=400,stretch=tk.YES)
    elif form =="choice_specification":
        treeF["displaycolumns"]=scfg.displayColumnsShort
        treeF.column('#0', width=400,stretch=tk.YES)
    else :
        treeF["displaycolumns"]=scfg.displayColumnsE
    return None

    # mask = (scfg.df1['id_code_lvl'] != 'lvl01') & (scfg.df1['id_code_lvl'] != 'lvl02') & (scfg.df1['id_code_lvl'] != 'lvl03') & (scfg.df1['id_code_lvl'] != 'lvl04') & (scfg.df1['id_code_lvl'] != 'lvl05') & (scfg.df1['id_code_lvl'] != 'lvl06')
    # df2 = scfg.df1.loc[mask]     # выдать всех у кого в родителях
    # if not(df2.empty):
    #         for indx in df2.index:
    #             id_group =  int(scfg.df1.loc[indx, 'id_code_item'])
    #             name_group = scfg.df1.loc[indx, 'name']
    #             id_code_parent = scfg.df1.loc[indx, 'id_code_parent']
    #             id_code_lvl = scfg.df1.loc[indx, 'id_code_lvl']
    #             amount = scfg.df1.loc[indx, 'amount']
    #             treeF.insert(id_code_parent, 'end',  id_group, text=name_group, values=[id_group, id_code_parent, id_code_lvl, amount])

        # self.tree.insert('', 'end', 10, text='Разъемы', values=0)
        # self.tree.insert('', 'end', 11, text='Наконечники НКИ', values=0)
        # self.tree.insert(10, 'end', 1001, text='DIN', values=0)
        # self.tree.insert(10, 'end', 1002, text='DВ', values=0)
        # self.tree.insert(11, 'end', 1101, text='НКИ', values=0)
        # self.tree.insert(11, 'end', 1102, text='НВИ', values=0)

    return None

# class WindowTree(tk.Toplevel):
#     def __init__(self, parent, modeWindow, viewDB):
#         # визуальное отображение универсального окна дерева групп для БД компонентов или БД спецификаций :
#         # viewDB = DBC = DataBaseComponents
#         # viewDB = DBS = DataBaseSpecification
#         # режим работы окна - или "перемещнние " или "импорт"
#         # modeWindow = 'remove'
#         # modeWindow == 'import
#         # modeWindow = 'expenditure'  - режим окна Расход компонента

#         super().__init__(parent)
#         # self.geometry("1024x600")
#         opts = { 'ipadx': 3, 'ipady': 3 , 'sticky': 'nswe' }

#         if  (viewDB == 'DBS') and (modeWindow == 'expenditure'):
#             self.label_to = tk.Label(self, text="В какую спецфикацию переместить ? ")
#         self.label_to.grid(row=0, column=0, **opts)

#         self.frame_tableTreeGroup = tk.LabelFrame(master=self, text="Группы", relief=tk.SUNKEN, borderwidth=3)   #, height=50)
#         self.frame_tableTreeGroup.grid(row=1, column=0,columnspan=2, **opts)

#         if  (viewDB == 'DBS') and (modeWindow == 'expenditure'):
#             self.btn_Remove = tk.Button(master=self, height=3, text="Сюда", command=self.fn_removComponent)
#         self.btn_Remove.grid(row=2, column=0, **opts)
#         self.btn_Cansel = tk.Button(master=self, height=3, text="Отмена", command=self.destroy)
#         self.btn_Cansel.grid(row=2, column=1, **opts)

#         self.treeGroup = ttk.Treeview(self.frame_tableTreeGroup, show="tree headings", height= 15)#, columns=col) #self.columns)
#         self.treeGroup.grid(row=0, column=1, rowspan=4, **opts)

#         Setting_TreeView(self.treeGroup, form = 'short')

#         self.ysb = ttk.Scrollbar(self.frame_tableTreeGroup, orient=tk.VERTICAL, command=self.treeGroup.yview)
#         self.treeGroup.configure(yscroll=self.ysb.set)
#         self.ysb.grid(row=0, column=2, rowspan=4, **opts)

#         self.treeGroup.bind('<<TreeviewSelect>>', self.on_select)

#         self.new_parent = 0
#         self.sel = 0

#         # DBC = DataBaseComponents
#         # DBS = DataBaseSpecification
#         if viewDB == 'DBC':
#             dataFrame_in = scfg.df_DBC
#             if not(dataFrame_in.empty):
#                 viewTreeGroup(self.treeGroup, dataFrame_in)       # отобразим данные из памяти DataFrame в TreeGroup с родителями

#         elif viewDB == 'DBS':
#             dataFrame_in = scfg.df_DBS
#             if not(dataFrame_in.empty):
#                 viewTreeGroupSpec(self.treeGroup, dataFrame_in)       # отобразим данные из памяти DataFrame в TreeGroup с родителями
#         return None

#     def open(self):
#         self.grab_set()
#         self.wait_window()
#         usr = self.new_parent
#         return usr

#     def fn_removComponent(self):
#         self.new_parent = self.sel[0]
#         self.destroy()
#         return None

#     def on_select(self, event):
#         self.sel = self.treeGroup.selection()

    # def fn_add_groupComponents(self):
    #     sql_insert_data_in_tableDBGroupComponent = 'INSERT INTO DBGroupComponent (code_group, name_group) values(?, ?)'
    #     if self.flagSelection:
    #         name_group=self.ent_NameComponent.get()
    #         data = []
    #         connectionDBFile = sqlite.connect(scfg.nameFile_DB)
    #         cursorDB = connectionDBFile.cursor()
    #         with connectionDBFile:
    #             sel = self.tree.selection()
    #             id_item=int(sel[0])
    #             code_group, flag_oversize_number_child = self.next_code_in_parent(id_item)
    #             if not(flag_oversize_number_child):
    #                 data.append(code_group)
    #                 data.append(name_group)
    #                 cursorDB.execute(sql_insert_data_in_tableDBGroupComponent, data)
    #                 connectionDBFile.commit()
    #             else:
    #                 msg = "Число подгрупп в родительской группе не должно быть больше 15"
    #                 mb.showerror("Ошибка", msg)
    #     return None

    # def next_code_in_parent(self, id_itemf):
    #     """
    #     генерация нового кода для элемета в родительской группе
    #     """
    #     #Считаем таблицы из файла БД и положим их в памятть
    #     # DBGroupF, flag_copyTableInMemory = dbcm.copy_FileDBGroupComponent_In_ListDBGroup(scfg.nameFile_DB)
    #     # for j in range (0, len(DBGroupF), 1):
    #     #         if DBGroupF[j].code_group ==
    #     flag_oversize_number_child_f = False
    #     next_id_item = id_itemf
    #     while next_id_item != '':
    #         id_itemf = next_id_item
    #         next_id_item = self.tree.next(id_itemf)
    #         print (id_itemf, ' - ', next_id_item)

    #     cg = []
    #     cg = mdbc.Unpack_codegroup(int(id_itemf))
    #     if cg[0]>=0x10 and cg[1]==0 and cg[2]==0 and cg[3]==0 and cg[4]==0: # если это группа верхнего уровня
    #         increment_item_in_parent = 0x010000
    #     elif cg[1]!=0 and cg[2]==0 and cg[3]==0 and cg[4]==0: # если это группа второго уровня
    #         increment_item_in_parent = 0x001000
    #     elif cg[2]!=0 and cg[3]==0 and cg[4]==0: # если это группа третьего уровня
    #         increment_item_in_parent = 0x000100
    #     elif cg[3]!=0 and cg[4]==0: # если это группа четвертого уровня
    #         increment_item_in_parent = 0x000010
    #     elif cg[4]!=0: # если это группа пятого уровня
    #         increment_item_in_parent = 0x000001
    #     new_code = int(id_itemf)+increment_item_in_parent
    #     flag_oversize_number_child_f = False
    #     # число детей в родительской группе не должно быть больше 15 (номер 0 - родитель)
    #     if (increment_item_in_parent == 0x010000) and (new_code >= 0xFA0000):
    #         new_code = id_itemf
    #         flag_oversize_number_child_f = True
    #     # elif (increment_item_in_parent == 0x001000) and (new_code >= 0x00E000)
    #     #     new_code = id_itemf
    #     #     flag_oversize_number_child_f = True
    #     return new_code, flag_oversize_number_child_f

    # def fn_edit_groupComponent(self):
    #     sql_update_query_in_tableDBGroupComponent = 'UPDATE DBGroupComponent SET name_group = ? WHERE code_group = ?'
    #     if self.flagSelection:
    #         var=self.ent_NameComponent.get()
    #         connectionDBFile = sqlite.connect(scfg.nameFile_DB)
    #         cursorDB = connectionDBFile.cursor()
    #         with connectionDBFile:
    #             sel = self.tree.selection()
    #             data = []
    #             #dic = self.tree.item(sel[0])
    #             name_group=var          #dic['text']
    #             code_group=int(sel[0])
    #             data.append(name_group)
    #             data.append(code_group)
    #             cursorDB.execute(sql_update_query_in_tableDBGroupComponent, data)
    #             connectionDBFile.commit()
    #         self.ent_NameComponent.delete(0, END)
    #         for i in self.tree.get_children(): self.tree.delete(i)      # очистим все дерево
    #         viewTreeGroup(self.tree)       # отобразим данные из памяти DBGroup в Tree
    #     else:
    #         mb.showinfo('Ошибка', 'Вы ничего не выделили!!!')
    #     self.flagSelection = False
    #     return None

    # def fn_delete_groupComponents(self):
    #     sql_delete_single_data_in_tableDBGroupComponent = 'DELETE FROM DBGroupComponent WHERE code_group = ?;'
    #     if self.flagSelection:
    #         connectionDBFile = sqlite.connect(scfg.nameFile_DB)
    #         cursorDB = connectionDBFile.cursor()
    #         with connectionDBFile:
    #             sel = self.tree.selection()
    #             data = int(sel[0])
    #             print(data)
    #             print(type(data))
    #             cursorDB.execute(sql_delete_single_data_in_tableDBGroupComponent, (data,))
    #             connectionDBFile.commit()
    #         for i in self.tree.get_children(): self.tree.delete(i)      # очистим все дерево
    #         viewTreeGroup(self.tree)       # отобразим данные из памяти DBGroup в Tree
    #     else:
    #         mb.showinfo('Ошибка', 'Вы ничего не выделили!!!')
    #     self.flagSelection = False
    #     self.ent_NameComponent.delete(0, END)
    #     return None

    # def on_select(self, event):
    #     #print(event)
    #     sel = self.tree.selection()
    #     print(sel)
    #     print(sel[0])
    #     # self.tree.see(sel[0])                 # не работает- не понято !!!!!!!!!
    #     dic = self.tree.item(sel[0])
    #     print(dic['text'])
    #     self.ent_NameComponent.delete(0, END)
    #     self.ent_NameComponent.insert(0, dic['text'])
    #     self.flagSelection = True

    #     return None

    # def confirm_delete(self):
    #     message = "Вы уверены, что хотите закрыть это окно?"
    #     if mb.askyesno(message=message, parent=self):
    #         self.destroy()

# class WindowImportComponent(tk.Toplevel):
#     def __init__(self, parent):
#         super().__init__(parent)
#         #self.protocol("WM_DELETE_WINDOW", self.confirm_delete)
#         self.frame_wig = tk.LabelFrame (master=self, text="Импорт групп", relief=tk.SUNKEN, borderwidth=3, height=50)
#         self.frame_wig.pack(fill=tk.X, side=tk.TOP, ipadx=5, ipady=5, padx=10, pady=10)
#         self.btn_wig = tk.Button(master=self.frame_wig, text="Импорт групп", command=self.press_Button_ImportGroup)
#         self.btn_wig.pack(fill=tk.X, expand=0, side=tk.TOP, ipadx=5, ipady=5)

#         self.frame_tableTree = tk.Frame(master=self, relief=tk.SUNKEN, borderwidth=3, height=50)
#         self.frame_tableTree.pack(fill=tk.X, side=tk.TOP, ipadx=5, ipady=5, padx=10, pady=5)
#         # Set the treeview
#         self.columns = ('NameID', 'id_code_item',  'id_code_parent',   'id_code_lvl', 'amount')

#         self.tree = ttk.Treeview(self.frame_tableTree, show="tree headings", columns=self.columns)
#             # Set the heading (Attribute Names)
#         self.tree.heading('#0', text='NameID')
#         self.tree.heading('#1', text='id_code_item')
#         self.tree.heading('#2', text='id_code_parent')
#         self.tree.heading('#3', text='id_code_group')
#         self.tree.heading('#4', text='amount')

#         self.ysb = ttk.Scrollbar(self.frame_tableTree, orient=tk.VERTICAL, command=self.tree.yview)
#         self.tree.configure(yscroll=self.ysb.set)
#             # Specify attributes of the columns (We want to stretch it!)
#         self.tree.column('#0', stretch=tk.YES)
#         self.tree.column('#1', stretch=tk.YES)
#         self.tree.column('#2', stretch=tk.YES)
#         self.tree.column('#3', stretch=tk.YES)
#         self.tree.column('#4', stretch=tk.YES)

#         self.tree.grid(row=0, column=0, sticky=tk.W + tk.E)
#         self.ysb.grid(row=0, column=1, sticky=tk.N + tk.S)

#         self.frame_tableTree.columnconfigure(0, weight=1)
#         self.tree.bind('<<TreeviewSelect>>', self.on_select)

#         if not(scfg.df1.empty):
#             viewTreeGroup(self.tree, scfg.df1)        # отобразим данные из памяти DataFrame в Tree

#     def on_select(self, event):
#         print(event)
#         print(self.tree.selection())
#         return None

#     def press_Button_ImportGroup(self):
#         mi.Load_DBGroup_From_XLS_pandas(scfg.nameFile_pu)
#         viewTreeGroup(self.tree, scfg.df1)       # отобразим данные из памяти DBGroup в Tree
#         return None

    # def confirm_delete(self):
    #     message = "Вы уверены, что хотите закрыть это окно?"
    #     if mb.askyesno(message=message, parent=self):
    #         self.destroy()

    # def fn_addGroup_Components(self):
    #     # запомним 'id_code_item' элемента из treeGroup
    #     id_code_item = self.treeGroup.selection()
    #     # получим от родителя  строку 'id_code_parent'
    #     df2 = scfg.df1[scfg.df1['id_code_item'] == id_code_item[0]]['id_code_parent']
    #     id_code_parent = df2.item()
    #     # получаем новое наименование из self.ent_NameComponent
    #     newNameComponent = self.ent_NameComponent.get()
    #     # сгенерим для него уникальный код
    #     codeItem = mdbc.getCode()
    #     # получим от родителя  строку 'id_code_lvl'
    #     df2 = scfg.df1[scfg.df1['id_code_item'] == id_code_item[0]]['id_code_lvl']
    #     id_lvl = df2.item()

    #     # сформируем строку для DataFrame
    #     new_row = {'name':newNameComponent, 'id_code_lvl': id_lvl, 'id_code_item': codeItem, 'id_code_parent':id_code_parent, 'amount':0} #append row to the dataframe
    #     # scfg.df1 = scfg.df1.append(new_row, ignore_index=True)
    #     # пересоздадим добавление строки в DataFrame  как рекомендует Pandas 1.4.0. 22jan2022
    #     df_new_row = pd.DataFrame(new_row , index=[0])
    #     scfg.df1 = pd.concat([scfg.df1, df_new_row])
    #     #  переиндексируем DataFrame
    #     scfg.df1 = scfg.df1.reset_index(drop=True)
    #     # очищаем дерево
    #     for i in self.tree2.get_children(): self.tree2.delete(i)
    #     # и выводим его заново
    #     viewTreeGroup(self.treeGroup, scfg.df1)
    #     # сохраняем изменненный DataFame в файл
    #     mi.Save_DataFrame_in_PickleFile()
    #     mi.Save_DataFrame_in_ExcelFile()

    #     return None

# def fn_renameGroup_Component(self):
    #     # запомним 'id_code_item' элемента из treeGroup
    #     id_code_item = self.treeGroup.selection()[0]
    #     # получаем выделенный элемент
    #     # sel = self.tree2.selection()
    #     # получаем индекс и 'id_code_item' выделенного элемента
    #     df2 = scfg.df1[scfg.df1['id_code_item'] == id_code_item]
    #     indx = df2.index
    #     # получаем измененное наименование из self.ent_NameComponent
    #     newNameComponent = self.ent_NameComponent.get()
    #     # изменяем наименоевание в DataFrame по индексу
    #     scfg.df1.loc[indx, 'name'] = newNameComponent
    #     # и выводим его заново
    #     viewTreeGroup(self.treeGroup, scfg.df1)
    #     self.treeGroup.see(id_code_item)
    #     self.treeGroup.selection_set(id_code_item)
    #     viewTreeComponents(self.tree2, scfg.df1, id_code_item)
    #     # сохраняем изменненный DataFame в файл
    #     mi.Save_DataFrame_in_PickleFile()
    #     mi.Save_DataFrame_in_ExcelFile()
    #     return None

# def fn_deleteGroup_Components(self):
    #     # запомним id_code_item выделенной строки в treeGroup
    #     id_code_item = self.treeGroup.selection()
    #     # постмотрим, есть ли у выделенного родителя потомки
    #     df2 = scfg.df1[scfg.df1['id_code_parent'] == id_code_item[0]]
    #     # пустая ли таблица df2?
    #     if df2.empty:
    #         df2 = scfg.df1[scfg.df1['id_code_item'] == id_code_item[0]]
    #         indx = df2.index
    #         # удаляем его из DataFrame по индексу
    #         scfg.df1 = scfg.df1.drop(index=indx)
    #         #  переиндексируем DataFrame
    #         scfg.df1 = scfg.df1.reset_index(drop=True)
    #         # очищаем дерево
    #         for i in self.tree2.get_children(): self.tree2.delete(i)
    #         # for i in self.treeGroup.get_children(): self.treeGroup.delete(i)
    #         # и выводим его заново
    #         viewTreeGroup(self.treeGroup, scfg.df1)
    #         # сохраняем изменненный DataFame в файл
    #         mi.Save_DataFrame_in_PickleFile()
    #         mi.Save_DataFrame_in_ExcelFile()
    #     else:
    #         message = "Группа компонентов не пуста!"
    #         mb.askyesno(message=message, parent=self)
    #         self.destroy()
    #     return None

# def fn_removeGroup_Components(self):
    #     # запомним 'id_code_item' элемента из treeGroup
    #     id_code_item = self.treeGroup.selection()
    #     # получаем индекс по 'id_code_item' выделенного элемента
    #     df2 = scfg.df1[scfg.df1['id_code_item'] == id_code_item[0]]
    #     indx = df2.index
    #     # выводим окно в котором спрашваем куда в дереве переместить
    #     # в ответ получаем  'id_code_parent' нового родителя
    #     new_id_code_parent = self.open_Window_Remove_Component()
    #     # проверим - если этот код родителя тот же самый selTreeGroup - ничего не делаем
    #     if (new_id_code_parent != id_code_item[0]) and (new_id_code_parent != 0):
    #         # изменяем код родителя компонента в DataFrame по индексу
    #         scfg.df1.loc[indx, 'id_code_parent'] = new_id_code_parent
    #         # очищаем дерево
    #         for i in self.tree2.get_children(): self.tree2.delete(i)
    #         # for i in self.treeGroup.get_children(): self.treeGroup.delete(i)
    #         # и выводим его заново
    #         viewTreeGroup(self.treeGroup, scfg.df1)
    #         # сохраняем изменненный DataFame в файл
    #         mi.Save_DataFrame_in_PickleFile()
    #         mi.Save_DataFrame_in_ExcelFile()
    #     return None


from pathlib import Path
from bs4 import BeautifulSoup
import requests
import time
import asyncio
from concurrent.futures import ProcessPoolExecutor
from functools import partial

def get_term_names(start, end):
    return [str(int(i/3)) + "0" + str((int(i) % 3) + 1) for i in range(start*3, end*3)]

def get_term_subjects(term):
    return [option.get("value") for option in BeautifulSoup(requests.post(
        "https://suis.sabanciuniv.edu/prod/bwckctlg.p_disp_cat_term_date",
        {
            "call_proc_in": "bwckctlg.p_disp_dyn_ctlg",
            "cat_term_in": term
        }
    ).content, "html.parser").find("select", attrs={"name": "sel_subj"}).find_all("option")]

def get_term_catalog(term):
    return requests.post(
        "https://suis.sabanciuniv.edu/prod/bwckctlg.p_display_courses",
        {
            "term_in": term,
            "call_proc_in": "bwckctlg.p_disp_dyn_ctlg",
            "sel_crse_start": "",
            "sel_crse_end": "",
            "sel_title": "",
            "sel_levl": "",
            "sel_schd": "",
            "sel_coll": "",
            "sel_divs": "",
            "sel_dept": "",
            "sel_to_cred": "",
            "sel_from_cred": "",
            "sel_attr": "",
            "sel_subj": ["dummy"] + get_term_subjects(term),
        }).content

def get_and_save(term):
    print("starting", term)
    chrono = time.perf_counter()
    catalog = get_term_catalog(term)
    print("got", term, "in", str(time.perf_counter() - chrono), "seconds")

    path = Path(__file__).parent / "../Catalogs/Raws" / (term + ".html")
    with path.open(mode="wb+") as f:
        f.write(catalog)

        return True

async def main():
    with ProcessPoolExecutor(3) as pool:
        loop = asyncio.get_running_loop()
        runners = [loop.run_in_executor(pool, partial(get_and_save, term)) for term in get_term_names(int(input("start year: ")), int(input("end year (excluded): ")))]
        crs = asyncio.gather(*runners)

if __name__ == "__main__":
    asyncio.run(main())


from typing import List

def merge_sort(arl: List, sort_type: str):
    '''
    Sortiramo listu s elemtnima tipa int ili float koristeći merge sort algoritam.

    Args:
        arl (List): Lista koju želimo sortirati.
        sort_type (str): Tip sortiranja ("asc" za uzlazno ili "desc" za silazno).

    Returns:
        List: Sortirana lista.
    '''
    assert sort_type in ["asc", "desc"], "Krivi tip sortiranja, mora biti 'asc' ili 'desc'!"

    if len(arl) == 1:
        return arl
    else:
        left, right = split_in_middle(arl)
        left = merge_sort(left, sort_type)
        right = merge_sort(right, sort_type)

    return merge(left, right, sort_type)

def merge(left: List, right: List, sort_type: str):
    '''
    Spaja dvije sortirane liste u jednu sortiranu listu.

    Args:
        left (List): Lijeva sortirana lista.
        right (List): Desna sortirana lista.
        sort_type (str): Tip sortiranja ("asc" za uzlazno ili "desc" za silazno).

    Returns:
        List: Spojene sortirane liste.
    '''
    merged = []
    lip, rip = 0, 0

    while lip < len(left) and rip < len(right):
        if sort_type == "asc":
            if left[lip] < right[rip]:
                merged.append(left[lip])
                lip += 1
            else:
                merged.append(right[rip])
                rip += 1
        else:
            if left[lip] > right[rip]:
                merged.append(left[lip])
                lip += 1
            else:
                merged.append(right[rip])
                rip += 1

    merged.extend(left[lip:])
    merged.extend(right[rip:])

    return merged

def split_in_middle(ar: List):
    '''
    Dijeli listu na dva dijela.

    Args:
        ar (List): Lista koju želimo podijeliti.

    Returns:
        Tuple: Tuple s dvije liste.
    '''
    middle = len(ar) // 2
    left = ar[:middle]
    right = ar[middle:]

    return left, right


#!/bin/bash/python
# Author: Ragy Haddad <ragy@deepbiometherapeutics.com>
import sys,os
import pandas as pd
import numpy as np
from tokenizer import Tokenizer
from torch.utils.data import Dataset as torchDataset
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader as torchDataLoader
from torch.nn.utils.rnn import pad_sequence
import torch
from rdkit import Chem
# Dataset functionality for custom batch loading
class Dataset:
    def __init__(self,input_table,sep='\t'):
        self.df = pd.read_csv(input_table,sep=sep)

        self.t = Tokenizer()
        if 'SMILES' in self.df.columns:
            self.smiles = self.df['SMILES']
        elif 'smiles' in self.df.columns:
            self.smiles = self.df['smiles']
        elif 'Smiles' in self.df.columns:
            self.smiles = self.df['Smiles']
        else:
            self.smiles = self.df.iloc[:,0] # Column Zero is smiles if none of the above

        self.cans = [Chem.MolToSmiles(Chem.MolFromSmiles(smi),True) for smi in self.smiles]
        self.smiles = pd.DataFrame(self.cans).iloc[:,0]
        # print(self.smiles)
        # exit()
    # Format Batch
    def format_df(self,input_df,return_labels=False,shifted_targets=True,padding=False,label_encoding=False,return_length=True):
        data = None
        if shifted_targets and label_encoding == False:
            src = [self.t.smiles_to_2d(r,padding=padding,add_start_token=True) for r in input_df]
            trg = [self.t.smiles_to_2d(r,padding=padding,add_start_token=False) for r in input_df]
        if shifted_targets and label_encoding:
            src = [self.t.smiles_to_int(r,padding=padding,add_start_token=True) for r in input_df]
            trg = [self.t.smiles_to_int(r,padding=padding,add_start_token=False) for r in input_df]
        if return_labels:
            labels = [self.t.smiles_to_int(r,padding=padding,add_start_token=False) for r in input_df] # Labels do not have starting token
            src,trg,labels = np.array(src),np.array(trg),np.array(labels)
            data = (src,trg,labels)
        else:
            src,trg = np.array(src),np.array(trg)
            data = (src,trg)
        if return_length:
            l_src = np.array([len(x) + 2 for x in input_df]) # Add 2 to lengths for sos_token and end_token
            l_trg = np.array([len(x) + 1 for x in input_df]) # Add 1 to lengths for eos_token
            data = data + (l_src,l_trg)
        return data
    # Load Batches
    def load_batches(self,batch_size,epoch_shuffle=True,padding=False,return_labels=False,label_encoding=False,shifted_targets=True,return_length=False):
        if epoch_shuffle:
            self.smiles = self.smiles.sample(frac=1)
        i = 0
        while i < len(self.df.index.values):
            smiles = self.smiles.iloc[i : i + batch_size]

            data = self.format_df(smiles,padding=padding,return_labels=return_labels,label_encoding=label_encoding,return_length=return_length)
            i += batch_size
            yield data

    def num_smiles(self):
        return len(self.smiles)


from typing import TYPE_CHECKING, Any, List, Type

from tortoise.backends.base.schema_generator import BaseSchemaGenerator
from tortoise.converters import encoders

if TYPE_CHECKING:  # pragma: nocoverage
    from tortoise.backends.mssql import MSSQLClient
    from tortoise.models import Model

class MSSQLSchemaGenerator(BaseSchemaGenerator):
    DIALECT = "mssql"
    TABLE_CREATE_TEMPLATE = "CREATE TABLE [{table_name}] ({fields}){extra};"
    FIELD_TEMPLATE = "[{name}] {type} {nullable} {unique}{primary}{default}"
    INDEX_CREATE_TEMPLATE = "CREATE INDEX [{index_name}] ON [{table_name}] ({fields});"
    GENERATED_PK_TEMPLATE = "[{field_name}] {generated_sql}"
    FK_TEMPLATE = (
        "{constraint}FOREIGN KEY ([{db_column}])"
        " REFERENCES [{table}] ([{field}]) ON DELETE {on_delete}"
    )
    M2M_TABLE_TEMPLATE = (
        "CREATE TABLE [{table_name}] (\n"
        "    {backward_key} {backward_type} NOT NULL,\n"
        "    {forward_key} {forward_type} NOT NULL,\n"
        "    {backward_fk},\n"
        "    {forward_fk}\n"
        "){extra};"
    )

    def __init__(self, client: "MSSQLClient") -> None:
        super().__init__(client)
        self._field_indexes = []  # type: List[str]
        self._foreign_keys = []  # type: List[str]

    def quote(self, val: str) -> str:
        return f"[{val}]"

    def _table_comment_generator(self, table: str, comment: str) -> str:
        return ""

    def _column_comment_generator(self, table: str, column: str, comment: str) -> str:
        return ""

    def _column_default_generator(
        self,
        table: str,
        column: str,
        default: Any,
        auto_now_add: bool = False,
        auto_now: bool = False,
    ) -> str:
        default_str = " DEFAULT"
        if not (auto_now or auto_now_add):
            default_str += f" {default}"
        if auto_now_add:
            default_str += " CURRENT_TIMESTAMP"
        return default_str

    def _escape_default_value(self, default: Any):
        return encoders.get(type(default))(default)  # type: ignore

    def _get_index_sql(self, model: "Type[Model]", field_names: List[str], safe: bool) -> str:
        return super(MSSQLSchemaGenerator, self)._get_index_sql(model, field_names, False)

    def _get_table_sql(self, model: "Type[Model]", safe: bool = True) -> dict:
        return super(MSSQLSchemaGenerator, self)._get_table_sql(model, False)

    def _create_fk_string(
        self,
        constraint_name: str,
        db_column: str,
        table: str,
        field: str,
        on_delete: str,
        comment: str,
    ) -> str:
        constraint = f"CONSTRAINT [{constraint_name}] " if constraint_name else ""
        fk = self.FK_TEMPLATE.format(
            constraint=constraint,
            db_column=db_column,
            table=table,
            field=field,
            on_delete=on_delete,
        )
        if constraint_name:
            self._foreign_keys.append(fk)
            return ""
        return fk

    def _create_string(
        self,
        db_column: str,
        field_type: str,
        nullable: str,
        unique: str,
        is_primary_key: bool,
        comment: str,
        default: str,
    ) -> str:
        if nullable == "":
            unique = ""
        return super(MSSQLSchemaGenerator, self)._create_string(
            db_column=db_column,
            field_type=field_type,
            nullable=nullable,
            unique=unique,
            is_primary_key=is_primary_key,
            comment=comment,
            default=default,
        )

    def _get_inner_statements(self) -> List[str]:
        extra = self._foreign_keys + list(dict.fromkeys(self._field_indexes))
        self._field_indexes.clear()
        self._foreign_keys.clear()
        return extra


from django.contrib import admin
from config_app.models import SiteConfig

# Register your models here.
@admin.register(SiteConfig)
class SiteConfig(admin.ModelAdmin):
    MAX_OBJECTS = 1

    def has_add_permission(self, request):
        if self.model.objects.count() >= self.MAX_OBJECTS:
            return False
        return super().has_add_permission(request)


#!/usr/bin/env python

import angr
import claripy

success_addr = 0x101ab3
failure_addr = 0x101ac1
base_addr = 0x100000

project = angr.Project("./cave", main_opts = {"base_addr" : base_addr})

state = project.factory.entry_state()
simgr = project.factory.simulation_manager(state)

simgr.explore(find=success_addr, avoid=failure_addr)

if len(simgr.found) > 0:
    for found in simgr.found:
        print(found.posix.dumps(0))


import json
import os
import unittest

from transactions_api.main import app

class TestTransaction(unittest.TestCase):

    def setUp(self):
        self.app = app.test_client()

    def test_insert_transaction(self):
        title_number = os.environ['TEST_TITLE']
        application_referenece = os.environ['TEST_APPLICATION']
        data = {"appn_trans_code": "C", "appn_trans_value": 123,
                "fee_categ_code": "2", "lr_appn_ref": application_referenece, "title_no": title_number,
                "trans_proc_curr": "Y"}
        post_response = self.app.post('/insert-transaction', data=json.dumps(data),
                                      headers={'Content-Type': 'application/json', 'Accept': 'application/json'})
        self.assertEqual(post_response.status_code, 200)


from typing import List

# 两边扫描，暴力求解
class Solution_1:
    def twoSum(self, nums: List[int], target: int) -> List[int]:

        lens = len(nums)
        # flag = False

        for r1 in range(0, lens):
            for r2 in range(r1+1, lens):
                if nums[r1] + nums[r2] == target:
                    # flag = True
                    return [r1, r2]


#
# @lc app=leetcode id=215 lang=python3
#
# [215] Kth Largest Element in an Array
#

# @lc code=start
from heapq import heapify, heappop
from typing import List

class Solution:
    '''
    - nums is not sorted.
    - goal: find kth largest element in the sorted array.

    do it without sorting.
    approach: using a min heap to pop out the minimum number n - k times.

    so that the final pop will be our answer.
    '''

    def findKthLargest(self, nums: List[int], k: int) -> int:
        # time: O(k + k log n)
        # space: o(n)
        n = len(nums)
        minHeap = nums[:]
        heapify(minHeap)
        for _ in range(n - k):
            heappop(minHeap)
        return heappop(minHeap)

# @lc code=end

nums = [3, 2, 1, 5, 6, 4]
k = 2
nums = [3, 2, 3, 1, 2, 4, 5, 5, 6]
k = 4
nums = [2, 1]
k = 1
sol = Solution()
ans = sol.findKthLargest(nums, k)
print(f'ans: {ans}')


import asyncio
from src.peer import PeerConnection, PeerState

class PeersManager:
    def __init__(self, queue, info_hash, peer_id, piece_manager,
                 on_block_cb=None,
                 max_download_peers=35, max_upload_peers=35):
        self.max_download_peers = max_download_peers
        self.max_upload_peers = max_upload_peers
        self.download_peers = []
        self.upload_peers = []
        self.peer_id = peer_id
        self.peers = queue
        self.info_hash = info_hash
        self.piece_manager = piece_manager
        self.on_block_cb = on_block_cb

    async def start_download(self):
        await self.update_download()

    async def start_upload(self):
        server = await asyncio.start_server(self.new_connection_handle,
                                            '0.0.0.0', 6889)
        addr = server.sockets[0].getsockname()
        async with server:
            await server.serve_forever()

    async def new_connection_handle(self, reader, writer):
        peer = PeerConnection(reader, writer, self.info_hash, self.peer_id,
                              self.piece_manager, self.on_block_cb,
                              self.update_upload)
        my_state = [PeerState.Interested, PeerState.Choke]
        peer_state = [PeerState.Choke]
        peer_future = asyncio.ensure_future(peer.start(my_state, peer_state))
        self.upload_peers.append(peer)

    async def update_download(self):
        for i, peer in enumerate(self.download_peers):
            if PeerState.Stopped in peer.my_state:
                del self.download_peers[i]

        while len(self.download_peers) < self.max_download_peers:
            ip, port = await self.peers.get()
            reader, writer = await asyncio.wait_for(
                asyncio.open_connection(ip, port), 30)
            peer = PeerConnection(reader, writer, self.info_hash, self.peer_id,
                                  self.piece_manager, self.on_block_cb,
                                  self.update_download)
            my_state = [PeerState.Interested, PeerState.Choke]
            peer_state = [PeerState.Choke]
            peer_future = asyncio.ensure_future(
                peer.start(my_state, peer_state))
            self.download_peers.append(peer)

    async def update_upload(self):
        for i, peer in enumerate(self.upload_peers):
            if PeerState.Stopped in peer.my_state:
                del self.upload_peers[i]


import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
import nltk
from nltk.sentiment import SentimentIntensityAnalyzer
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import matplotlib.pyplot as plt
import seaborn as sns
from wordcloud import WordCloud
import warnings

class HealthcareDataExtractorAnalyzer:
    def __init__(self):
        self.healthcare_data = pd.DataFrame(columns=['title', 'content'])

    def web_scraping(self, url):
        response = requests.get(url)
        soup = BeautifulSoup(response.content, 'html.parser')
        data = self.extract_data_from_html(soup)
        self.healthcare_data = self.healthcare_data.append(
            data, ignore_index=True)

    def extract_data_from_html(self, soup):
        title = soup.find('h1').text.strip()
        content = soup.find('div', class_='article-content').text.strip()
        return {'title': title, 'content': content}

    def data_collection(self):
        urls = ['https://example.com/healthcare-data',
                'https://example.com/clinical-trials']
        for url in urls:
            self.web_scraping(url)
        self.healthcare_data.drop_duplicates(inplace=True)

    def data_cleaning_processing(self):
        self.healthcare_data.dropna(inplace=True)
        self.healthcare_data['content'] = self.healthcare_data['content'].apply(
            self.clean_text)

    def clean_text(self, text):
        text = re.sub(r'[^\w\s]', '', text.lower())
        stop_words = set(stopwords.words('english'))
        tokens = nltk.word_tokenize(text)
        filtered_text = [word for word in tokens if word not in stop_words]
        return ' '.join(filtered_text)

    def nlp_analysis(self):
        pass

    def sentiment_analysis(self):
        sid = SentimentIntensityAnalyzer()
        self.healthcare_data['sentiment_score'] = self.healthcare_data['content'].apply(
            lambda x: sid.polarity_scores(x)['compound'])

    def topic_modeling(self):
        vectorizer = TfidfVectorizer()
        tfidf_matrix = vectorizer.fit_transform(
            self.healthcare_data['content'])
        lda = LatentDirichletAllocation(n_components=10, random_state=42)
        lda.fit(tfidf_matrix)
        topics = lda.transform(tfidf_matrix)
        self.healthcare_data['topic'] = topics.argmax(axis=1)

    def data_visualization(self):
        wordcloud = WordCloud(width=800, height=400).generate(
            ' '.join(self.healthcare_data['content']))
        plt.figure(figsize=(12, 8))
        plt.imshow(wordcloud, interpolation='bilinear')
        plt.axis('off')
        plt.show()
        plt.figure(figsize=(12, 6))
        sns.barplot(
            x=self.healthcare_data['sentiment_score'], y=self.healthcare_data['title'])
        plt.xlabel('Sentiment Score')
        plt.ylabel('Article Title')
        plt.title('Sentiment Analysis')
        plt.show()

    def generate_insights(self):
        pass

    def automate_extraction_analysis(self):
        pass

if __name__ == "__main__":
    warnings.filterwarnings("ignore")
    analyzer = HealthcareDataExtractorAnalyzer()
    analyzer.data_collection()
    analyzer.data_cleaning_processing()
    analyzer.nlp_analysis()
    analyzer.sentiment_analysis()
    analyzer.topic_modeling()
    analyzer.data_visualization()
    analyzer.generate_insights()
    analyzer.automate_extraction_analysis()


from django.db.models import fields
from authApp.models.nomina import Nomina,ESTADOS_CHOICES
from authApp.models.empleado import Empleado
from authApp.models.novedad import Novedad
from authApp.models.tiponovedad import Tiponovedad
from authApp.serializers.empleadoSerializer import EmpleadoSerializer
from rest_framework import serializers

class NominaSerializer(serializers.ModelSerializer):
    estado_nom=serializers.ChoiceField(choices=ESTADOS_CHOICES)
    class Meta:
        model = Nomina
        fields = ['codigo_nom','codigo_emp','estado_nom','fechainicio_nom','fechafin_nom','salariobase_nom','salariodevengo_nom','salariodeduccion_nom','salariototal_emp']

    def create(self,validated_data):
        nominaInstancia=  Nomina.objects.create(**validated_data)
        return nominaInstancia

    def update(self,instance,validate_data):
        instance.estado_nom = validate_data.get("estado_nom",instance.estado_nom)
        instance.fechainicio_nom = validate_data.get("fechainicio_nom",instance.fechainicio_nom)
        instance.fechafin_nom = validate_data.get("fechafin_nom",instance.fechafin_nom)
        instance.salariobase_nom = validate_data.get("salariobase_nom",instance.salariobase_nom)
        instance.salariodevengo_nom = validate_data.get("salariodevengo_nom",instance.salariodevengo_nom)
        instance.salariodeduccion_nom = validate_data.get("salariodeduccion_nom",instance.salariodeduccion_nom)
        instance.save()
        return instance

    def to_representation(self, obj):
        nomina = Nomina.objects.get(codigo_nom=obj.codigo_nom)
        empleado =Empleado.objects.get(codigo_emp=obj.codigo_emp)
        novedad =Novedad.objects.get(codigo_nom=obj.codigo_nom,codigo_emp=obj.codigo_emp)
        tiponovedad=Tiponovedad.objects.get(codigo_tipnov=obj.codigo_tipnov)
        return {
                    'codigo_nom' : nomina.codigo_nom,
                    'empleado':{ 'codigo_emp' : empleado.codigo_emp,
                                 'nombre_emp' : empleado.nombre_emp
                               },
                    'estado':   nomina.estado_nom,
                    'fechainicio_nom' : nomina.fechainicio_nom,
                    'fechafin_nom':  nomina.fechafin_nom,

                    'novedad':{ 'codigo_nov' : novedad.codigo_nov,
                                'nombre_tipnov':tiponovedad.nombre_tipnov,
                                'valor_nov' : novedad.valor_nov
                               },
                    'salariobase_nom' :  nomina.salariobase_nom,
                    'salariodevengo_nom' :  nomina.salariodevengo_nom,
                    'salariodeduccion_nom' :  nomina.salariodeduccion_nom,
                    'salariototal_emp':  nomina.salariototal_emp

               }


"""Dual Attention Network"""
import torch
import torch.nn as nn
import torch.nn.functional as F

from .segbase import SegBaseModel

__all__ = ['DANet', 'get_danet', 'get_danet_resnet50_citys',
           'get_danet_resnet101_citys', 'get_danet_resnet152_citys']

class DANet(SegBaseModel):
    r"""Pyramid Scene Parsing Network

    Parameters
    ----------
    nclass : int
        Number of categories for the training dataset.
    backbone : string
        Pre-trained dilated backbone network type (default:'resnet50'; 'resnet50',
        'resnet101' or 'resnet152').
    norm_layer : object
        Normalization layer used in backbone network (default: :class:`mxnet.gluon.nn.BatchNorm`;
        for Synchronized Cross-GPU BachNormalization).
    aux : bool
        Auxiliary loss.
    Reference:
        Jun Fu, Jing Liu, Haijie Tian, Yong Li, Yongjun Bao, Zhiwei Fang,and Hanqing Lu.
        "Dual Attention Network for Scene Segmentation." *CVPR*, 2019
    """

    def __init__(self, nclass, backbone='resnet50', aux=True, pretrained_base=True, **kwargs):
        super(DANet, self).__init__(nclass, aux, backbone, pretrained_base=pretrained_base, **kwargs)
        self.head = _DAHead(2048, nclass, aux, **kwargs)

        self.__setattr__('exclusive', ['head'])

    def forward(self, x):
        size = x.size()[2:]
        _, _, c3, c4 = self.base_forward(x)
        outputs = []
        x = self.head(c4)
        x0 = F.interpolate(x[0], size, mode='bilinear', align_corners=True)
        outputs.append(x0)

        if self.aux:
            x1 = F.interpolate(x[1], size, mode='bilinear', align_corners=True)
            x2 = F.interpolate(x[2], size, mode='bilinear', align_corners=True)
            outputs.append(x1)
            outputs.append(x2)
        return outputs

class _PositionAttentionModule(nn.Module):
    """ Position attention module"""

    def __init__(self, in_channels, **kwargs):
        super(_PositionAttentionModule, self).__init__()
        self.conv_b = nn.Conv2d(in_channels, in_channels // 8, 1)
        self.conv_c = nn.Conv2d(in_channels, in_channels // 8, 1)
        self.conv_d = nn.Conv2d(in_channels, in_channels, 1)
        self.alpha = nn.Parameter(torch.zeros(1))
        self.softmax = nn.Softmax(dim=-1)

    def forward(self, x):
        batch_size, _, height, width = x.size()
        feat_b = self.conv_b(x).view(batch_size, -1, height * width).permute(0, 2, 1)
        feat_c = self.conv_c(x).view(batch_size, -1, height * width)
        attention_s = self.softmax(torch.bmm(feat_b, feat_c))
        feat_d = self.conv_d(x).view(batch_size, -1, height * width)
        feat_e = torch.bmm(feat_d, attention_s.permute(0, 2, 1)).view(batch_size, -1, height, width)
        out = self.alpha * feat_e + x

        return out

class _ChannelAttentionModule(nn.Module):
    """Channel attention module"""

    def __init__(self, **kwargs):
        super(_ChannelAttentionModule, self).__init__()
        self.beta = nn.Parameter(torch.zeros(1))
        self.softmax = nn.Softmax(dim=-1)

    def forward(self, x):
        batch_size, _, height, width = x.size()
        feat_a = x.view(batch_size, -1, height * width)
        feat_a_transpose = x.view(batch_size, -1, height * width).permute(0, 2, 1)
        attention = torch.bmm(feat_a, feat_a_transpose)
        attention_new = torch.max(attention, dim=-1, keepdim=True)[0].expand_as(attention) - attention
        attention = self.softmax(attention_new)

        feat_e = torch.bmm(attention, feat_a).view(batch_size, -1, height, width)
        out = self.beta * feat_e + x

        return out

class _DAHead(nn.Module):
    def __init__(self, in_channels, nclass, aux=True, norm_layer=nn.BatchNorm2d, norm_kwargs=None, **kwargs):
        super(_DAHead, self).__init__()
        self.aux = aux
        inter_channels = in_channels // 4
        self.conv_p1 = nn.Sequential(
            nn.Conv2d(in_channels, inter_channels, 3, padding=1, bias=False),
            norm_layer(inter_channels, **({} if norm_kwargs is None else norm_kwargs)),
            nn.ReLU(True)
        )
        self.conv_c1 = nn.Sequential(
            nn.Conv2d(in_channels, inter_channels, 3, padding=1, bias=False),
            norm_layer(inter_channels, **({} if norm_kwargs is None else norm_kwargs)),
            nn.ReLU(True)
        )
        self.pam = _PositionAttentionModule(inter_channels, **kwargs)
        self.cam = _ChannelAttentionModule(**kwargs)
        self.conv_p2 = nn.Sequential(
            nn.Conv2d(inter_channels, inter_channels, 3, padding=1, bias=False),
            norm_layer(inter_channels, **({} if norm_kwargs is None else norm_kwargs)),
            nn.ReLU(True)
        )
        self.conv_c2 = nn.Sequential(
            nn.Conv2d(inter_channels, inter_channels, 3, padding=1, bias=False),
            norm_layer(inter_channels, **({} if norm_kwargs is None else norm_kwargs)),
            nn.ReLU(True)
        )
        self.out = nn.Sequential(
            nn.Dropout(0.1),
            nn.Conv2d(inter_channels, nclass, 1)
        )
        if aux:
            self.conv_p3 = nn.Sequential(
                nn.Dropout(0.1),
                nn.Conv2d(inter_channels, nclass, 1)
            )
            self.conv_c3 = nn.Sequential(
                nn.Dropout(0.1),
                nn.Conv2d(inter_channels, nclass, 1)
            )

    def forward(self, x):
        feat_p = self.conv_p1(x)
        feat_p = self.pam(feat_p)
        feat_p = self.conv_p2(feat_p)

        feat_c = self.conv_c1(x)
        feat_c = self.cam(feat_c)
        feat_c = self.conv_c2(feat_c)

        feat_fusion = feat_p + feat_c

        outputs = []
        fusion_out = self.out(feat_fusion)
        outputs.append(fusion_out)
        if self.aux:
            p_out = self.conv_p3(feat_p)
            c_out = self.conv_c3(feat_c)
            outputs.append(p_out)
            outputs.append(c_out)

        return tuple(outputs)

def get_danet(dataset='citys', backbone='resnet50', pretrained=False,
              root='~/.torch/models', pretrained_base=True, **kwargs):
    r"""Dual Attention Network

    Parameters
    ----------
    dataset : str, default pascal_voc
        The dataset that model pretrained on. (pascal_voc, ade20k)
    pretrained : bool or str
        Boolean value controls whether to load the default pretrained weights for model.
        String value represents the hashtag for a certain version of pretrained weights.
    root : str, default '~/.torch/models'
        Location for keeping the model parameters.
    pretrained_base : bool or str, default True
        This will load pretrained backbone network, that was trained on ImageNet.
    Examples
    --------
    >>> model = get_danet(dataset='pascal_voc', backbone='resnet50', pretrained=False)
    >>> print(model)
    """
    acronyms = {
        'pascal_voc': 'pascal_voc',
        'pascal_aug': 'pascal_aug',
        'ade20k': 'ade',
        'coco': 'coco',
        'citys': 'citys',
    }
    from ..data.dataloader import datasets
    model = DANet(datasets[dataset].NUM_CLASS, backbone=backbone, pretrained_base=pretrained_base, **kwargs)
    if pretrained:
        from .model_store import get_model_file
        device = torch.device(kwargs['local_rank'])
        model.load_state_dict(torch.load(get_model_file('danet_%s_%s' % (backbone, acronyms[dataset]), root=root),
                              map_location=device))
    return model

def get_danet_resnet50_citys(**kwargs):
    return get_danet('citys', 'resnet50', **kwargs)

def get_danet_resnet101_citys(**kwargs):
    return get_danet('citys', 'resnet101', **kwargs)

def get_danet_resnet152_citys(**kwargs):
    return get_danet('citys', 'resnet152', **kwargs)

if __name__ == '__main__':
    img = torch.randn(2, 3, 480, 480)
    model = get_danet_resnet50_citys()
    outputs = model(img)


import torch
import numpy as np

from model_utils.decoders import FPNDecoder
from model_utils.decoders import UNetDecoder
from model_utils.segmentation import EncoderDecoder
from model_utils.segmentation.backbones import ResNetBackbone

def segmentation(models, stack, device, indexes, class_amount, window):

    with torch.no_grad():
        window.progressBar.show()
        progress = 0
        average_preds = torch.zeros((stack.shape[0], class_amount, stack.shape[1], stack.shape[2])).to(device)
        stack = stack / 256.
        stack -= stack.mean()
        stack /= stack.std()
        stack = stack / 255

        model_name = str(models[0])
        model = init_segmentation_model(model_name, class_amount, device=device)

        for model_index, model_weights in enumerate(models):
            model.load_state_dict(torch.load(model_weights, map_location=device)["model"])
            model = model.to(device)
            model.eval()
            for i in range(stack.shape[0]):
                if i not in indexes and indexes != []:
                    progress += 1
                    continue
                progress += 1
                window.progressBar.setValue(int(progress / (len(models)*stack.shape[0])*100))
                image = stack[i, :, :]
                image = np.expand_dims(image, axis=(0, 1))
                image = torch.from_numpy(image).to(device).float()
                out = model(image)
                th = 0.3
                preds = out.gt(th)
                average_preds[i, :, :, :] += preds[0, :, :, :]

        tensor_pred = average_preds / len(models)
        tensor_pred = tensor_pred.gt(0.5)
        if class_amount == 1:
            numpy_pred = tensor_pred[:, 0, :, :].cpu().detach().numpy()
        else:
            numpy_pred = tensor_pred.cpu().detach().numpy()
        torch.cuda.empty_cache()
        return numpy_pred

def init_segmentation_model(model_name, n_classes, device='cuda'):

    if "resnet18" in model_name.lower():
        resnet_num = "resnet18"
    elif "resnet34" in model_name.lower():
        resnet_num = "resnet34"
    elif "resnet50" in model_name.lower():
        resnet_num = "resnet50"
    else:
        raise NotImplementedError

    resnet_backbone = ResNetBackbone(n_classes, resnet_num)
    if 'unet' in model_name.lower():
        mdl = EncoderDecoder(2, resnet_backbone, UNetDecoder(resnet_backbone.shape_dict[resnet_num], final_channels=n_classes))
    elif 'fpn' in model_name.lower():
        mdl = EncoderDecoder(2, resnet_backbone, FPNDecoder(resnet_backbone.shape_dict[resnet_num], final_channels=n_classes))
    else:
        raise NotImplementedError

    mdl = mdl.to(device)

    return mdl


import MemePy
from typing import Dict, Any
import json
import io

TEMPLATES = {}

def get_templates() -> Dict[str, int]:
    '''
        Возвращает список возможных шаблонов для мемов
    '''
    result = {}
    memes = MemePy.MemeLibJsonDecoder.generate_standard_meme_dict()

    for meme in memes.keys():
        result[meme] = memes[meme].count_non_optional()

    return result

def generate(template, *params) -> Any:
    params = list(params)

    for i in range(len(params)):
        while '_' in params[i]:
            params[i] = params[i].replace('_', ' ')

    meme_pill = MemePy.MemeGenerator.get_meme_image(template, params)
    output = io.BytesIO()
    meme_pill.save(output, format='png')

    return output.getvalue()

TEMPLATES = get_templates()


from __future__ import absolute_import
import sys
sys.path.append('./')

import time
import itertools
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from PIL import Image
import cv2

import torch
from unittest import TestCase

from tps_spatial_transformer import TPSSpatialTransformer

class TestTPSSpatialTransformer(TestCase):

  control_points_per_side = 6

  def test_forward(self):

    # specify the input control points with the shape [3, 6, 2]
    test_input_ctrl_pts = np.array([
      [
        [-0.1, 0.4], [0.5, 0.1], [0.9, 0.4],
        [-0.1, 0.9], [0.5, 0.6], [0.9, 0.9]
      ],
      [
        [0.1, 0.1], [0.5, 0.4], [0.9, 0.1],
        [0.1, 0.6], [0.5, 0.9], [0.9, 0.6]
      ],
      [
        [0.1, 0.1], [0.5, 0.1], [0.9, 0.1],
        [0.1, 0.9], [0.5, 0.9], [0.9, 0.9],
      ]
    ], dtype=np.float32)
    source_control_points = torch.from_numpy(test_input_ctrl_pts)

    # preprocess the input image to match the pytorch's format.
    test_im = Image.open('./test_image.jpg').resize((128, 128))
    test_image_array = np.array(test_im).astype('float32')
    test_image_array = np.array([test_image_array, test_image_array, test_image_array])
    test_images = torch.from_numpy(test_image_array)
    test_images = test_images.permute((0,3,1,2))

    target_height, target_width = 32, 100
    margin = 0.05

    print('initialize module')
    beg_time = time.time()
    tps = TPSSpatialTransformer(
      output_image_size=(target_height, target_width),
      num_control_points=6,
      margins=(margin, margin))
    past_time = time.time() - beg_time
    print('initialization takes %.02fs' % past_time)

    target_control_points = tps.target_control_points
    target_control_points_array = target_control_points.numpy()
    target_image, source_coordinate = tps(test_images, source_control_points)
    source_coordinate_array = source_coordinate.numpy()
    grid = source_coordinate.view(-1, target_height, target_width, 2)
    target_image = target_image.permute((0,2,3,1)).numpy()

    if True:
      plt.figure()
      plt.subplot(3,4,1)
      plt.scatter(test_input_ctrl_pts[0,:,0], test_input_ctrl_pts[0,:,1])
      plt.subplot(3,4,2)
      plt.scatter(target_control_points_array[:,0], target_control_points_array[:,1])
      plt.subplot(3,4,3)
      plt.scatter(source_coordinate_array[0,:,0], source_coordinate_array[0,:,1], marker='+')
      plt.subplot(3,4,4)
      plt.imshow(target_image[0].astype(np.uint8))

      plt.subplot(3,4,5)
      plt.scatter(test_input_ctrl_pts[1,:,0], test_input_ctrl_pts[1,:,1])
      plt.subplot(3,4,6)
      plt.scatter(target_control_points_array[:,0], target_control_points_array[:,1])
      plt.subplot(3,4,7)
      plt.scatter(source_coordinate_array[1,:,0], source_coordinate_array[1,:,1], marker='+')
      plt.subplot(3,4,8)
      plt.imshow(target_image[1].astype(np.uint8))

      plt.subplot(3,4,9)
      plt.scatter(test_input_ctrl_pts[2,:,0], test_input_ctrl_pts[2,:,1])
      plt.subplot(3,4,10)
      plt.scatter(target_control_points_array[:,0], target_control_points_array[:,1])
      plt.subplot(3,4,11)
      plt.scatter(source_coordinate_array[2,:,0], source_coordinate_array[2,:,1], marker='+')
      plt.subplot(3,4,12)
      plt.imshow(target_image[2].astype(np.uint8))

      plt.show()
      plt.savefig('plot.png')

if __name__ == '__main__':
  test_tps = TestTPSSpatialTransformer()
  test_tps.test_forward()


import pandas
from sklearn import model_selection
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/iris.csv"
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
dataset = pandas.read_csv(url, names=names)

print(dataset.shape)
print(dataset.head(20))
print(dataset.describe())
print(dataset.groupby('class').size())

models = [
    ('LR', LogisticRegression(solver='liblinear', multi_class='ovr')),
    ('LDA', LinearDiscriminantAnalysis()),
    ('KNN', KNeighborsClassifier()),
    ('CART', DecisionTreeClassifier()),
    ('NB', GaussianNB()),
    ('SVM', SVC(gamma='auto'))
]

# Split-out validation dataset
array = dataset.values
X = array[:, 0:4]
Y = array[:, 4]
validation_size = 0.20
seed = 7

X_train, X_validation, Y_train, Y_validation = model_selection.train_test_split(
    X, Y, test_size=validation_size, random_state=seed
)

# evaluate each model in turn
results = []
names = []
for name, model in models:
    kfold = model_selection.KFold(n_splits=10, random_state=seed)
    cv_results = model_selection.cross_val_score(model, X_train, Y_train, cv=kfold, scoring='accuracy')
    results.append(cv_results)
    names.append(name)
    msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
    print(msg)

# knn = KNeighborsClassifier()
# knn.fit(X_train, Y_train)
# predictions = knn.predict(X_validation)
# print(accuracy_score(Y_validation, predictions))
# print(confusion_matrix(Y_validation, predictions))
# print(classification_report(Y_validation, predictions))


import os
import logging
import re
import pinecone
from slack_bolt.async_app import AsyncApp
from slack_bolt.adapter.asgi.async_handler import AsyncSlackRequestHandler
from slack_sdk.oauth.installation_store import FileInstallationStore
from slack_bolt.oauth import OAuthFlow
from slack_bolt.oauth.oauth_settings import OAuthSettings

from conversation import create_conversation

PINECONE_API_KEY = os.environ.get("PINECONE_API_KEY")
PINECONE_INDEX_NAME = os.environ.get("PINECONE_INDEX_NAME", '')
PINECONE_ENVIRONMENT = os.environ.get("PINECONE_ENVIRONMENT", '')

# SLACK_CLIENT_ID = os.environ.get("SLACK_CLIENT_ID")
# SLACK_CLIENT_SECRET = os.environ.get("SLACK_CLIENT_SECRET")
SLACK_INSTALLATION_BASE = os.environ.get("SLACK_INSTALLATION_BASE", '/data')

# if not SLACK_CLIENT_ID:
#     raise ValueError("SLACK_CLIENT_ID environment variable not set.")
# if not SLACK_CLIENT_SECRET:
#     raise ValueError("SLACK_CLIENT_SECRET environment variable not set.")

# OAuth redirect: slack/oauth_redirect
# Ref: https://slack.dev/bolt-python/concepts#authenticating-oauth
app = AsyncApp(
    # oauth_flow=OAuthFlow(
    #     settings=OAuthSettings(
    #         scopes=["channels:history", "users:read", "app_mentions:read", "chat:write"],
    #         installation_store=FileInstallationStore(base_dir=SLACK_INSTALLATION_BASE),  # A simple File based installation store
    #     )
    # )
)

@app.event("app_mention")
async def handle_mention(body, say, logger):
    logger.info(body)

    evt = body.get('event', {})

    channel_id = evt.get('channel')
    thread_ts = evt.get('thread_ts') if 'thread_ts' in evt else evt.get('ts')

    replies = await get_replies(channel_id, thread_ts)
    text = replies[-1].get('text')
    replies = replies[:-1]  # the last one is the one we just received
    resp = await get_ai_response(replies=replies, question=text)

    await say(resp, thread_ts=thread_ts)

async def convert_ids_to_usernames(text):
    user_ids = re.findall('<@(U.*?)>', text)
    for user_id in user_ids:
        username = await get_user_name(user_id)
        text = text.replace(f'<@{user_id}>', f'@{username}')
    return text

async def get_replies(channel_id, thread_ts):
    conversation_replies = await app.client.conversations_replies(channel=channel_id, ts=thread_ts)
    replies = conversation_replies.get('messages', [])
    replies = [
        {
            'user': await get_user_name(r.get('user')),
            'text': await convert_ids_to_usernames(r.get('text')),
        } for r in replies]
    return replies

async def get_user_name(user_id):
    user_info = await app.client.users_info(user=user_id)
    user_name = user_info.get('user', {}).get('name')
    return user_name

async def get_ai_response(replies, question):
    pinecone.init(
        api_key=PINECONE_API_KEY,
        environment=PINECONE_ENVIRONMENT,
    )
    system_prompt_str = None
    # FIXME: how to pass the path?
    with open('system_prompt.txt', 'r', encoding='utf-8') as f:
        system_prompt_str = f.read()

    chat_history = []
    for reply in replies:
        chat_history.append((reply['user'], reply['text']))

    conversation = create_conversation(
        system_prompt_str=system_prompt_str,
        chat_history=chat_history
        )
    return conversation(question)

api = AsyncSlackRequestHandler(app)

def start_server(port=9000):
    app.start(port=port, path='/slack')

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    start_server()


from django import forms
from django.forms.widgets import TextInput, EmailInput
from django.utils.translation import ugettext_lazy as _

from C4CApplication.models.branch import Branch

class CreateBranchForm(forms.Form):
    name = forms.CharField(
        widget=TextInput(
            attrs={'autofocus':'true', 'placeholder':_("branch name")}
        ), label= _("Name of the branch ")
    )

    branch_town = forms.CharField(
        widget=TextInput(
            attrs={'placeholder':_('town(s) of the branch')}
        ), label=_("Name of the town ")
    )

    branch_off = forms.EmailField(
        widget=EmailInput(
            attrs={'placeholder':_('branch_officer@mail.com')}
        ), label=_("Branch officer mail")
    )

    street = forms.CharField(
        required=False,
        widget=TextInput(
            attrs={'placeholder':_('street')}
        ),
        label=_("Street of the branch "),
    )

    zip = forms.CharField(
        required=False,
        widget=TextInput(
            attrs={'placeholder':_('postal code')}
        ),
        label=_("Zip of the branch "),
    )

    town = forms.CharField(
        required=False,
        widget=TextInput(
            attrs={'placeholder':_('town')}
        ),
        label=_("Town of the branch "),
    )

    def clean(self):
        """
        Overrides clean from super to add an error if 'other' has been checked,
        but nothing was provided in the text field.
        """
        cleaned_data = super(CreateBranchForm, self).clean()
        b_name = cleaned_data.get("name")
        list_branch = Branch.objects.filter(name=b_name)

        if len(list_branch) !=0 :
            self.add_error("name", forms.ValidationError(_("A branch already exist with this name."), code='invalid'))

        return cleaned_data


import datetime as dt

def date_range(start_date, end_date, increment=dt.timedelta(hours=24)):
    cur_date = start_date

    while cur_date < end_date:
        yield cur_date
        cur_date += increment

def month_range(start, end):
    cur = dt.date(start.year, start.month, 1)
    while cur < end:
        yield cur
        year = cur.year + cur.month // 12
        month = (cur.month % 12) + 1
        cur = dt.date(year, month, 1)


from datetime import datetime
import pymongo

class Log:
    def __init__(self):
        pass

    def write_log(self, sessionID, log_message):
        self.file_object = open("conversationLogs/"+sessionID+".txt", 'a+')
        self.now = datetime.now()
        self.date = self.now.date()
        self.current_time = self.now.strftime("%H:%M:%S")
        self.file_object.write(
            str(self.date) + "/" + str(self.current_time) + "\t\t" + log_message + "\n")
        self.file_object.close()

    def write_mongodb(self, sessionID, log_message):
        self.client = pymongo.MongoClient("mongodb://localhost:27017/")
        self.db = self.client['chatbot_log']
        self.collection = self.db['conversation_logs']
        self.comment = {"sessionID" : sessionID,
                        "time_stamp" : datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                        "message" : log_message
                        }
        self.collection.insert(self.comment)


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from caffe2.python import core
from hypothesis import given
import caffe2.python.hypothesis_test_util as hu
import hypothesis.strategies as st
import numpy as np

class TestClipTensorByScalingOp(hu.HypothesisTestCase):

    @given(n=st.integers(5, 8), d=st.integers(2, 4),
           threshold=st.floats(0.1, 10),
           inplace=st.booleans(),
           **hu.gcs_cpu_only)
    def test_clip_tensor_by_scaling(self, n, d, threshold, inplace, gc, dc):

        tensor = np.random.rand(n, d).astype(np.float32)
        val = np.array(np.linalg.norm(tensor))

        def clip_tensor_by_scaling_ref(tensor_data, val_data):
            if val_data > threshold:
                ratio = threshold / float(val_data)
                tensor_data = tensor_data * ratio

            return [tensor_data]

        op = core.CreateOperator(
            "ClipTensorByScaling",
            ["tensor", "val"],
            ['Y'] if not inplace else ["tensor"],
            threshold=threshold,
        )

        self.assertReferenceChecks(
            device_option=gc,
            op=op,
            inputs=[tensor, val],
            reference=clip_tensor_by_scaling_ref,
        )

if __name__ == "__main__":
    import unittest
    unittest.main()


import pytest

from flaky import (
    flaky,
)

from web3._utils.module_testing import (  # noqa: F401
    EthModuleTest,
    ParityModuleTest,
    ParityPersonalModuleTest,
    ParitySetModuleTest,
    ParityTraceModuleTest,
    Web3ModuleTest,
)
from web3._utils.module_testing.eth_module import (
    UNKNOWN_ADDRESS,
)

# some tests appear flaky with Parity v1.10.x
MAX_FLAKY_RUNS = 3

class ParityWeb3ModuleTest(Web3ModuleTest):
    def _check_web3_clientVersion(self, client_version):
        assert client_version.startswith('Parity-Ethereum/')

class ParityEthModuleTest(EthModuleTest):
    @pytest.mark.xfail(reason='Parity returns a gas value even when a function will revert')
    def test_eth_estimate_gas_revert_with_msg(self, web3, revert_contract, unlocked_account):
        super().test_eth_estimate_gas_revert_with_msg(web3, revert_contract, unlocked_account)

    def test_eth_estimate_gas_revert_without_msg(
        self,
        web3,
        revert_contract,
        unlocked_account,
    ) -> None:
        with pytest.raises(ValueError, match="The execution failed due to an exception."):
            txn_params = revert_contract._prepare_transaction(
                fn_name="revertWithoutMessage",
                transaction={
                    "from": unlocked_account,
                    "to": revert_contract.address,
                },
            )
            web3.eth.estimate_gas(txn_params)

    @pytest.mark.xfail(reason='Parity dropped "pending" option in 1.11.1')
    def test_eth_getBlockByNumber_pending(self, web3):
        super().test_eth_getBlockByNumber_pending(web3)

    def test_eth_uninstall_filter(self, web3):
        pytest.xfail('eth_uninstallFilter calls to parity always return true')
        super().test_eth_uninstall_filter(web3)

    def test_eth_uninstallFilter_deprecated(self, web3):
        pytest.xfail('eth_uninstallFilter calls to parity always return true')
        super().test_eth_uninstallFilter_deprecated(web3)

    @pytest.mark.xfail(reason='Parity is not setup to auto mine')
    def test_eth_replace_transaction_already_mined(self, web3, unlocked_account):
        super().test_eth_replace_transaction_already_mined(web3, unlocked_account)

    @flaky(max_runs=MAX_FLAKY_RUNS)
    def test_eth_get_transaction_receipt_unmined(self, web3, unlocked_account):
        # Parity diverges from json-rpc spec and retrieves pending block
        # transactions with get_transaction_receipt.
        txn_hash = web3.eth.send_transaction({
            'from': unlocked_account,
            'to': unlocked_account,
            'value': 1,
            'gas': 21000,
            'gasPrice': web3.eth.gas_price,
        })
        receipt = web3.eth.get_transaction_receipt(txn_hash)
        assert receipt is not None
        assert receipt['blockHash'] is None

    @pytest.mark.xfail(reason="Parity matches None to asbent values")
    def test_eth_get_logs_with_logs_none_topic_args(self, web3):
        super().test_eth_get_logs_with_logs_none_topic_args(web3)

    @flaky(max_runs=MAX_FLAKY_RUNS)
    def test_eth_call_old_contract_state(self, web3, math_contract, unlocked_account):
        start_block = web3.eth.get_block('latest')
        block_num = start_block.number
        block_hash = start_block.hash

        math_contract.functions.increment().transact({'from': unlocked_account})

        # This isn't an incredibly convincing test since we can't mine, and
        # the default resolved block is latest, So if block_identifier was ignored
        # we would get the same result. For now, we mostly depend on core tests.
        # Ideas to improve this test:
        #  - Enable on-demand mining in more clients
        #  - Increment the math contract in all of the fixtures, and check the value in an old block

        block_hash_call_result = math_contract.functions.counter().call(block_identifier=block_hash)
        block_num_call_result = math_contract.functions.counter().call(block_identifier=block_num)
        latest_call_result = math_contract.functions.counter().call(block_identifier='latest')
        default_call_result = math_contract.functions.counter().call()

        assert block_hash_call_result == 0
        assert block_num_call_result == 0
        assert latest_call_result == 0
        assert default_call_result == 0

        # retrieve this right before using - Parity tests might hit a race otherwise
        pending_call_result = math_contract.functions.counter().call(block_identifier='pending')
        # should be '1' on first flaky run, '2' on second, or '3' on third
        if pending_call_result not in range(1, MAX_FLAKY_RUNS + 1):
            raise AssertionError("pending call result was %d!" % pending_call_result)

    def test_eth_get_logs_without_logs(self, web3, block_with_txn_with_log):
        # Test with block range

        filter_params = {
            "fromBlock": 0,
            "toBlock": block_with_txn_with_log['number'] - 1,
        }
        result = web3.eth.get_logs(filter_params)
        assert len(result) == 0

        # the range is wrong, parity returns error message
        filter_params = {
            "fromBlock": block_with_txn_with_log['number'],
            "toBlock": block_with_txn_with_log['number'] - 1,
        }
        with pytest.raises(ValueError):
            web3.eth.get_logs(filter_params)

        # Test with `address`

        # filter with other address
        filter_params = {
            "fromBlock": 0,
            "address": UNKNOWN_ADDRESS,
        }
        result = web3.eth.get_logs(filter_params)
        assert len(result) == 0

        # Test with multiple `address`

        # filter with other address
        filter_params = {
            "fromBlock": 0,
            "address": [UNKNOWN_ADDRESS, UNKNOWN_ADDRESS],
        }
        result = web3.eth.get_logs(filter_params)
        assert len(result) == 0

    @pytest.mark.xfail(reason='eth_signTypedData has not been released in Parity')
    def test_eth_sign_typed_data(self, web3, unlocked_account_dual_type):
        super().test_eth_sign_typed_data(web3, unlocked_account_dual_type)

    @pytest.mark.xfail(reason='eth_signTypedData has not been released in Parity')
    def test_invalid_eth_sign_typed_data(self, web3, unlocked_account_dual_type):
        super().test_invalid_eth_sign_typed_data(web3, unlocked_account_dual_type)

class ParityTraceModuleTest(ParityTraceModuleTest):
    @pytest.mark.xfail(reason="TODO: tracing not working on v2.5.13")
    def test_trace_block(self, web3):
        super().test_trace_block(web3)

    @pytest.mark.xfail(reason="TODO: tracing not working on v2.5.13")
    def test_trace_transaction(self, web3):
        super().test_trace_transaction(web3)

    @pytest.mark.xfail(reason="TODO: tracing not working on v2.5.13")
    def test_trace_filter(self, web3):
        super().test_trace_filter(web3)

class ParitySetModuleTest(ParitySetModuleTest):
    pass

class ParityModuleTest(ParityModuleTest):
    pass