# -*- coding: utf-8 -*-
import sys
from preprocess import Channel
from workflow.cf_workflow import run as user_cf
from workflow.lfm_workflow import run as lfm
from workflow.lfm_workflow import predict as lfm_predict
from workflow.prank_workflow import run as prank
import pandas as pd
import pymysql
from sqlalchemy import create_engine

def manage():
    #arg = sys.argv[1]
    arg = "prank"
    if arg == 'preprocess':
        Channel().process()
    elif arg == 'cf':
        user_cf()
    elif arg == 'lfm':
        lfm()
    elif arg == 'prank':
        prank()
    else:
        print('Args must in ["preprocess", "cf", "lfm"，"prank"].')
    sys.exit()

def predict():
    arg = sys.argv[1]
    cars = lfm_predict(int(arg))

    # db
    db = pymysql.connect("localhost", "root", "", "rental")
    cursor = db.cursor()
    try:
        cursor.execute("DELETE FROM rt_lfm_recommendation WHERE rt_lfm_recommendation.user_id = "+str(arg))
        db.commit()
    except:
        db.rollback()
    cursor.close()
    db.close()

    engine = create_engine(
        "mysql+pymysql://{}:{}@{}/{}?charset={}".format('root', '', '127.0.0.1:3306', 'rental', 'utf8'))
    con = engine.connect()
    df = pd.DataFrame(cars)
    df.insert(0, 'user_id', arg)
    df.columns = ['user_id', 'car_id', 'rate']
    df.to_sql("rt_lfm_recommendation", con, if_exists='append', index=False)
    con.close()

    return cars is not None

if __name__ == '__main__':
    predict()


#-*-coding:utf-8-*-
#1.功能:接受客户机连接.接受客户机发来的消息,把消息加上时间发回客户端
#2.流程:
# (1)创建class
# (2)class需要绑定哪些属性
# (3)class有那些

import  socket
from time import  strftime

class TcpTimeServer:
    def __init__(self,host='',port=1234):
        self.addr =(host,port)
        self.serv=socket.socket()
        self.serv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self.serv.bind(self.addr)
        self.serv.listen(1)

    def chat(self,cli_sock):
        while True:
            data =cli_sock.recv(1024)
            if data.strip()==b'quit':
                break
            data ='[%s] %s ' % (strftime('%H:%M:%S'),data.decode())


import copy
import logging
import typing
from pathlib import Path
from typing import Optional

from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QModelIndex, QSettings, QPoint
from PyQt5.QtGui import QDropEvent, QDragEnterEvent, QKeyEvent
from PyQt5.QtWidgets import QAction, QMessageBox, QFileDialog, QMenu, QWidget, QDialog, QApplication
from basyx.aas.adapter.aasx import AASXReader, DictSupplementaryFileContainer
from basyx.aas.adapter.json import read_aas_json_file
from basyx.aas.adapter.xml import read_aas_xml_file
from basyx.aas.model import DictObjectStore, Submodel

from aas_editor.delegates import EditDelegate
from aas_editor.package import Package, StoredFile
from aas_editor.settings import FILTER_AAS_FILES, CLASSES_INFO, PACKVIEW_ATTRS_INFO, \
    FILE_TYPE_FILTERS, NOT_GIVEN, REFERABLE_INHERITORS_ATTRS
from aas_editor.settings.app_settings import NAME_ROLE, OBJECT_ROLE, PACKAGE_ROLE, \
    MAX_RECENT_FILES, ACPLT, \
    APPLICATION_NAME, OPENED_PACKS_ROLE, OPENED_FILES_ROLE, ADD_ITEM_ROLE, \
    TYPE_ROLE, \
    CLEAR_ROW_ROLE, AppSettings, COLUMN_NAME_ROLE, OBJECT_COLUMN_NAME, \
    OBJECT_VALUE_COLUMN_NAME, DEFAULT_COLUMNS_IN_PACKS_TABLE_TO_SHOW
from aas_editor.settings.shortcuts import SC_OPEN, SC_SAVE_ALL
from aas_editor.settings.icons import NEW_PACK_ICON, OPEN_ICON, OPEN_DRAG_ICON, SAVE_ICON, SAVE_ALL_ICON, \
    ADD_ICON
from aas_editor.utils import util_type
from aas_editor.utils.util import getDefaultVal, getReqParams4init
from aas_editor.utils.util_classes import ClassesInfo
from aas_editor.widgets import TreeView
from aas_editor.widgets.treeview import HeaderView
from aas_editor import dialogs

class PackHeaderView(HeaderView):
    def __init__(self, orientation, parent: Optional[QWidget] = ...) -> None:
        self.customLists = {}
        super(PackHeaderView, self).__init__(orientation, parent)

    def setCustomLists(self, value: typing.Dict["str", typing.List[str]]):
        self.customLists = value
        self.initMenu()

    def initMenu(self) -> None:
        self.menu = QMenu("Columns", self)

        showBasicColumnsAct = QAction("Show Basic Columns", self,
                                      triggered=lambda: self.showSectionWithNames(DEFAULT_COLUMNS_IN_PACKS_TABLE_TO_SHOW, only=True))
        self.menu.addAction(showBasicColumnsAct)

        allColumnsMenu = self.menu.addMenu("Select Columns")
        for i in self.actions():
            allColumnsMenu.addAction(i)

        showColumns4typeMenu = self.menu.addMenu("Show Columns for Attributes of Type")
        for cls in REFERABLE_INHERITORS_ATTRS:
            clsname = util_type.getTypeName(cls)
            sectionNames = REFERABLE_INHERITORS_ATTRS[cls]
            showColumnsAct = QAction(f"{clsname}", self,
                                     toolTip=f"Show attributes of Type: {clsname}",
                                     statusTip=f"Show attributes of Type: {clsname}",
                                     triggered=lambda: self.onShowListOfSectionsAct())
            showColumnsAct.setData(sectionNames)
            showColumns4typeMenu.addAction(showColumnsAct)

        showColumnsFromListMenu = self.menu.addMenu("Show Columns From Custom List")
        menuTip = "To manage custom lists, edit custom_column_lists.json"
        showColumnsFromListMenu.setToolTip(menuTip)
        showColumnsFromListMenu.setStatusTip(menuTip)
        for listname in self.customLists:
            sectionNames = self.customLists[listname]
            showColumnsAct = QAction(f"{listname}", self,
                                     toolTip=f"Show custom list {listname}: {sectionNames}. {menuTip}",
                                     statusTip=f"Show custom list {listname}: {sectionNames}. {menuTip}",
                                     triggered=lambda: self.onShowListOfSectionsAct())
            showColumnsAct.setData(sectionNames)
            showColumnsFromListMenu.addAction(showColumnsAct)

        self.menu.addSeparator()

        showAllColAct = QAction("Show all columns", self,
                                toolTip="Show all columns",
                                statusTip="Show all columns",
                                triggered=lambda: self.showAllSections())
        self.menu.addAction(showAllColAct)

        hideAllColAct = QAction("Hide all columns", self,
                                toolTip="Hide all columns",
                                statusTip="Hide all columns",
                                triggered=lambda: self.hideAllSections())
        self.menu.addAction(hideAllColAct)

    def onShowListOfSectionsAct(self):
        action: QAction = self.sender()
        sectionNames = action.data()
        self.showSectionWithNames(sectionNames, only=True)

    def openMenu(self, point: QPoint):
        chosenSection = self.logicalIndexAt(point)
        hideChosenSection = QAction(f"Hide column", self,
                                    toolTip=f"Hide column",
                                    statusTip=f"Hide column",
                                    triggered=lambda: self.hideSection(chosenSection))
        self.menu.addAction(hideChosenSection)
        self.menu.exec_(self.viewport().mapToGlobal(point))
        self.menu.removeAction(hideChosenSection)

class PackTreeView(TreeView):
    EMPTY_VIEW_MSG = "Drop AAS files here"
    EMPTY_VIEW_ICON = OPEN_DRAG_ICON

    def __init__(self, parent=None, **kwargs):
        self.filesObjStores = dict()
        self.scanFolderForExistFiles()
        super(PackTreeView, self).__init__(parent,
                                           emptyViewMsg=self.EMPTY_VIEW_MSG,
                                           emptyViewIcon=self.EMPTY_VIEW_ICON, **kwargs)
        PackTreeView.__instance = self
        self.recentFilesSeparator = None
        self.setAcceptDrops(True)
        self.setExpandsOnDoubleClick(False)
        self.setSelectionBehavior(self.SelectItems)
        self.setHeader(PackHeaderView(Qt.Horizontal, self))

    # Scan the folder "aas_files" and creat a dict filesObjStores of DictObjectStore elements and its names
    def scanFolderForExistFiles(self):
        path = Path.cwd()
        path = path / 'aas_files'

        if not path.is_dir():
            path.mkdir()

        aasxFiles = [file for file in path.rglob('*.aasx')]
        xmlFiles = [file for file in path.rglob('*.xml')]
        jsonFiles = [file for file in path.rglob('*.json')]
        files = aasxFiles + xmlFiles + jsonFiles

        # Read the aasx file and store it in DictObjectStore in dictionary fileObjDict.
        for file in files:
            try:
                fileType = file.suffix.lower().strip()
                if fileType == ".xml":
                    objStore = read_aas_xml_file(file.as_posix())
                elif fileType == ".json":
                    with open(file, "r") as f:  # TODO change if aas changes
                        objStore = read_aas_json_file(f)
                elif fileType == ".aasx":
                    objStore = DictObjectStore()
                    fileStore = DictSupplementaryFileContainer()  # prosto tak
                    reader = AASXReader(file.as_posix())
                    reader.read_into(objStore, fileStore)
                else:
                    raise TypeError("Wrong file type:", self.file.suffix)
                self.filesObjStores[file.name] = objStore
            except Exception as e:
                # If a package is with an error, that file will be skipped.
                logging.exception(f"Error while reading {file}: {e}. Submodels can not be read")

    @property
    def defaultNewFileTypeFilter(self):
        return AppSettings.DEFAULT_NEW_FILETYPE_FILTER.value()

    @defaultNewFileTypeFilter.setter
    def defaultNewFileTypeFilter(self, value):
        AppSettings.DEFAULT_NEW_FILETYPE_FILTER.setValue(value)

    # noinspection PyArgumentList
    def initActions(self):
        super(PackTreeView, self).initActions()
        self.addAct.setText("Add package")
        self.addAct.setEnabled(True)

        self.newPackAct = QAction(NEW_PACK_ICON, "&New AAS file", self,
                                  statusTip="Create new AAS file",
                                  triggered=lambda: self.newPackWithDialog(),
                                  enabled=True)

        self.openPackAct = QAction(OPEN_ICON, "&Open AAS file", self,
                                   shortcut=SC_OPEN,
                                   statusTip="Open AAS file",
                                   triggered=lambda: self.openPackWithDialog(),
                                   enabled=True)

        # Recent files actions
        self.recentFileActs = []
        for i in range(MAX_RECENT_FILES):
            recentFileAct = QAction("", self,
                                    statusTip=f"Open recent file",
                                    triggered=lambda: self.openRecentSlot(),
                                    visible=False)
            self.recentFileActs.append(recentFileAct)

        self.saveAct = QAction(SAVE_ICON, "Save", self,
                               statusTip="Save current file",
                               triggered=lambda: self.savePack(),
                               enabled=False)

        self.saveAsAct = QAction("Save As...", self,
                                 statusTip="Save current file as..",
                                 triggered=lambda: self.savePackAsWithDialog(),
                                 enabled=False)

        self.saveAllAct = QAction(SAVE_ALL_ICON, "&Save All", self,
                                  shortcut=SC_SAVE_ALL,
                                  statusTip="Save all files",
                                  triggered=lambda: self.saveAll(),
                                  enabled=True)

        self.closeAct = QAction("Close AAS file", self,
                                statusTip="Close current file",
                                triggered=lambda: self.closeFileWithDialog(),
                                enabled=False)

        self.closeAllAct = QAction("Close all", self,
                                   statusTip="Close all files",
                                   triggered=lambda: self.closeAllFilesWithDialog(),
                                   enabled=False)

        self.autoScrollToSrcAct = QAction("Autoscroll to source", self,
                                          # icon=AUTOSCROLL_TO_SRC_ICON,
                                          toolTip="Autoscroll to source",
                                          statusTip="Autoscroll to source",
                                          checkable=True)
        self.autoScrollToSrcAct.toggle()
        self.autoScrollFromSrcAct = QAction("Autoscroll from source", self,
                                            # icon=AUTOSCROLL_FROM_SRC_ICON,
                                            toolTip="Autoscroll from source",
                                            statusTip="Autoscroll from source",
                                            checkable=True)

        self.dictCopyExistSubmodelActs = self.initDictCopyExistSubmodelActs()

        self.autoScrollFromSrcAct.toggle()
        self.setItemDelegate(EditDelegate(self))

    def initDictCopyExistSubmodelActs(self):
        dictCopyExistSubmodelActs = {}  # {"file1": list(QAction_copySubmodel1, QAction_copySubmodel2, ...)}
        # filesObjStores contains packages and its instances
        for file, objStore in self.filesObjStores.items():
            copyExistSubmodelActs = []
            for obj in objStore:
                if isinstance(obj, Submodel):
                    if not obj.id_short == "":
                        name = obj.id_short
                    else:
                        name = obj.identification.id
                    existSubmodelAct = QAction(name, self,
                                               statusTip=f"Copy existing submodel in current package",
                                               triggered=lambda: self.onAddExistingSubmodelPushed())
                    existSubmodelAct.setData(obj)
                    copyExistSubmodelActs.append(existSubmodelAct)
            dictCopyExistSubmodelActs[file] = copyExistSubmodelActs
        return dictCopyExistSubmodelActs

    def onAddExistingSubmodelPushed(self):
        action = self.sender()
        if action:
            submodel = copy.deepcopy(action.data())
            self.treeClipboard.clear()
            self.treeClipboard.append(submodel)
            self.pasteAct.trigger()

    def onEditCreate(self, objVal=None, index=QModelIndex()) -> bool:
        """
        :param objVal: value to set in dialog input widgets
        :raise KeyError if no typehint found and no objVal was given
        """
        if not index.isValid():
            index = self.currentIndex()
        if index.isValid():
            objVal = objVal if objVal else index.data(Qt.EditRole)
            return self._onEditCreate(objVal, index)

    def _onEditCreate(self, objVal, index) -> bool:
        attribute = index.data(COLUMN_NAME_ROLE)
        parentObj = index.data(OBJECT_ROLE)
        try:
            if attribute == OBJECT_COLUMN_NAME:
                attrTypeHint = type(parentObj)
            else:
                attrTypeHint = util_type.getAttrTypeHint(type(parentObj), attribute)
        except KeyError as e:
            if objVal:
                attrTypeHint = type(objVal)
            else:
                raise KeyError("No typehint found for the given item", attribute)
        return self.replItemWithDialog(index, attrTypeHint, title=f"Edit/Create {attribute}", objVal=objVal)

    def toggleDefNewFileType(self):
        # FIXME refactor
        action = self.sender()
        if action:
            typ = action.text()
            self.defaultNewFileTypeFilter = FILE_TYPE_FILTERS[typ]

    # noinspection PyUnresolvedReferences
    def initMenu(self):
        super(PackTreeView, self).initMenu()
        self.attrsMenu.addSeparator()
        self.attrsMenu.addAction(self.openPackAct)
        self.attrsMenu.addAction(self.saveAct)
        self.attrsMenu.addAction(self.saveAsAct)
        self.attrsMenu.addAction(self.saveAllAct)
        self.attrsMenu.addAction(self.closeAct)
        self.attrsMenu.addAction(self.closeAllAct)
        self.initMenuAddExistingSubmodels()
        # self.attrsMenu.insertAction(self.addAct, self.addExistingSubmodelsAct)

        self.openInCurrTabAct.triggered.connect(
            lambda: self.openInCurrTabClicked.emit(self.currentIndex()))
        self.openInNewTabAct.triggered.connect(
            lambda: self.openInNewTabClicked.emit(self.currentIndex()))
        self.openInBackgroundAct.triggered.connect(
            lambda: self.openInBgTabClicked.emit(self.currentIndex()))
        self.openInNewWindowAct.triggered.connect(
            lambda: self.openInNewWindowClicked.emit(self.currentIndex()))

    # Create Menu for adding existing submodels.
    def initMenuAddExistingSubmodels(self):
        self.addExistSubmodelsMenu = QMenu("Add existing submodel", self.attrsMenu)
        self.addExistSubmodelsMenu.setIcon(ADD_ICON)
        self.addExistSubmodelsMenu.menuAction().setEnabled(False)
        # Add menu with a name of model.
        # dictCopyExistSubmodelActs contains the package names and the list of QActions of its submodels.
        for filename, copyPasteSubmodelActs in self.dictCopyExistSubmodelActs.items():
            nameMenu = self.addExistSubmodelsMenu.addMenu(filename)
            # In copyPasteSubmodelActs are QActions with submodels
            for copyPasteSubmodelAct in copyPasteSubmodelActs:
                nameMenu.addAction(copyPasteSubmodelAct)
        self.attrsMenu.insertMenu(self.addAct, self.addExistSubmodelsMenu)

    # This function makes the 'Add existing submodel' menu visible only if the 'submodel' element is clicked.
    def updateCopyPasteSubmodelActs(self, index: QModelIndex):
        attrName = index.data(NAME_ROLE)
        if attrName == "submodels":
            self.addExistSubmodelsMenu.menuAction().setEnabled(True)
        else:
            self.addExistSubmodelsMenu.menuAction().setEnabled(False)

    def updateActions(self, index: QModelIndex):
        super(PackTreeView, self).updateActions(index)
        self.updateCopyPasteSubmodelActs(index)

        if index.isValid():
            self.openInCurrTabAct.setEnabled(True)
            self.openInNewTabAct.setEnabled(True)
            self.openInBackgroundAct.setEnabled(True)
            self.openInNewWindowAct.setEnabled(True)

        # update save and close actions
        self.saveAct.setEnabled(self.isSaveOk())
        self.saveAct.setText(f"Save {index.data(PACKAGE_ROLE)}")
        self.saveAct.setToolTip(f"Save {index.data(PACKAGE_ROLE)}")
        self.saveAsAct.setEnabled(self.isSaveOk())
        self.saveAllAct.setEnabled(self.isSaveAllOk())
        self.closeAct.setEnabled(self.isCloseOk())
        self.closeAllAct.setEnabled(self.isCloseAllOk())

    def updateAddAct(self, index: QModelIndex):
        super().updateAddAct(index)

        attrName = index.data(NAME_ROLE)
        if attrName in Package.addableAttrs():
            addActText = ClassesInfo.addActText(Package, attrName)
            self.addAct.setEnabled(True)
            self.addAct.setText(addActText)

        # update add action
        if not index.isValid():
            self.addAct.setEnabled(True)
            self.addAct.setText("Add package")

    def isPasteOk(self, index: QModelIndex) -> bool:
        if self.treeClipboard.isEmpty() or not index.isValid():
            return False

        if super(PackTreeView, self).isPasteOk(index):
            return True

        obj2paste = self.treeClipboard.objects[-1]
        currObj = index.data(OBJECT_ROLE)

        if ClassesInfo.addType(type(currObj)) and isinstance(obj2paste, ClassesInfo.addType(type(currObj))):
            return True
        return False

    def isSaveOk(self) -> bool:
        pack = self.currentIndex().data(PACKAGE_ROLE)
        return True if pack else False

    def isCloseOk(self) -> bool:
        pack = self.currentIndex().data(PACKAGE_ROLE)
        return True if pack else False

    def isSaveAllOk(self) -> bool:
        return True if self.model().data(QModelIndex(), OPENED_PACKS_ROLE) else False

    def isCloseAllOk(self) -> bool:
        return True if self.model().data(QModelIndex(), OPENED_PACKS_ROLE) else False

    def onAddAct(self, objVal=None, parent: QModelIndex = None):
        parent = parent if parent else self.currentIndex()
        name = parent.data(NAME_ROLE)
        parentObj = parent.data(OBJECT_ROLE)

        if objVal:
            kwargs = {"parent": parent,
                      "objVal": objVal}
        else:
            kwargs = {"parent": parent}

        try:
            if not parent.isValid():
                self.newPackWithDialog()
            elif name in Package.addableAttrs():
                self.addItemWithDialog(objTypeHint=ClassesInfo.addType(Package, name), **kwargs)
            elif ClassesInfo.addType(type(parentObj)):
                self.addItemWithDialog(objTypeHint=ClassesInfo.addType(type(parentObj)), **kwargs)
            else:
                raise TypeError("Parent type is not extendable:", type(parent.data(OBJECT_ROLE)))
        except Exception as e:
            dialogs.ErrorMessageBox.withTraceback(self, str(e)).exec()

    def addItemWithDialog(self, parent: QModelIndex, objTypeHint, objVal=None,
                          title="", rmDefParams=False, **kwargs):
        if objTypeHint is Package:
            self.newPackWithDialog()
            return
        elif objTypeHint is StoredFile:
            self.addFileWithDialog(parent)
            return
        super(PackTreeView, self).addItemWithDialog(parent, objTypeHint, objVal, title, rmDefParams, **kwargs)

    def newPackWithDialog(self, filter=FILTER_AAS_FILES):
        saved = False
        file = 'new_aas_file.aasx'

        while not saved:
            file, _ = QFileDialog.getSaveFileName(self, 'Create new AAS File', file,
                                                  filter=filter,
                                                  initialFilter=self.defaultNewFileTypeFilter)
            if file:
                pack = Package()
                saved = self.savePack(pack, file)
                if saved:
                    self.model().setData(QModelIndex(), pack, ADD_ITEM_ROLE)
            else:
                # cancel pressed
                return

    def openPackWithDialog(self, filter=FILTER_AAS_FILES):
        opened = False
        file = ""
        while not opened:
            file, _ = QFileDialog.getOpenFileName(self, "Open AAS file", file,
                                                  filter=filter)
            if file:
                opened = self.openPack(file)
            else:
                # cancel pressed
                return

    def addFileWithDialog(self, parent: QModelIndex):
        opened = False
        file = ""
        while not opened:
            file, _ = QFileDialog.getOpenFileName(self, "Add file", file)
            if file:
                storedFile = StoredFile(filePath=file)
                opened = self._setItemData(parent, storedFile, ADD_ITEM_ROLE)
            else:
                # cancel pressed
                return

    def openPack(self, file: str) -> typing.Union[bool, Package]:
        try:
            try:
                pack = Package(file, failsafe=False)
            except Exception as e:
                msgBox = QMessageBox()
                msgBox.setIcon(QMessageBox.Warning)
                msgBox.setText(f"Error while reading package:\n{file}")
                msgBox.setInformativeText("The file may not comply with the official schema. For more details, please use the Tools/compliance tool to check the file. Are you sure you want to proceed with opening it? Note that some objects may be missing or incorrect.")
                msgBox.setStandardButtons(QMessageBox.Cancel | QMessageBox.Yes)
                msgBox.setDefaultButton(QMessageBox.Yes)
                msgBox.setDetailedText(f"{e}")
                ret = msgBox.exec()
                if ret == QMessageBox.Yes:
                    pack = Package(file, failsafe=True)
                else:
                    return False
            absFile = pack.file.absolute().as_posix()
            self.updateRecentFiles(absFile)
        except Exception as e:
            self.removeFromRecentFiles(file)
            dialogs.ErrorMessageBox.withTraceback(self, f"Package {file} couldn't be opened: {e}").exec()
        else:
            openedPacks = self.model().data(QModelIndex(), OPENED_FILES_ROLE)
            if Path(file).absolute() in openedPacks:
                QMessageBox.critical(self, "Error", f"Package {file} is already opened")
            else:
                self.model().setData(QModelIndex(), pack, ADD_ITEM_ROLE)
                return pack
        return False

    def savePack(self, pack: Package = None, file: str = None) -> bool:
        pack = self.currentIndex().data(PACKAGE_ROLE) if pack is None else pack
        try:
            pack.write(file)
            self.updateRecentFiles(pack.file.absolute().as_posix())
            if self.model().rowCount(QModelIndex()) == 1:
                self.setWindowModified(False)
            return True
        except (TypeError, ValueError, KeyError) as e:
            dialogs.ErrorMessageBox.withTraceback(self, f"Package couldn't be saved: {file}: {e}").exec()
        except AttributeError as e:
            dialogs.ErrorMessageBox.withTraceback(self, f"No chosen package to save: {e}").exec()
        return False

    def savePackAsWithDialog(self, pack: Package = None, filter=FILTER_AAS_FILES) -> bool:
        pack = self.currentIndex().data(PACKAGE_ROLE) if pack is None else pack
        saved = False
        file = pack.file.as_posix()
        while not saved:
            try:
                file, _ = QFileDialog.getSaveFileName(self, 'Save AAS File', file,
                                                      filter=filter)
            except AttributeError as e:
                dialogs.ErrorMessageBox.withTraceback(self, f"No chosen package to save: {e}").exec()
            else:
                if file:
                    saved = self.savePack(pack, file)
                else:
                    # cancel pressed
                    return

    def saveAll(self):
        saved = [self.savePack(pack) for pack in self.model().data(QModelIndex(), OPENED_PACKS_ROLE)]
        if all(saved):
            self.setWindowModified(False)

    def closeFileWithDialog(self):
        pack = self.currentIndex().data(PACKAGE_ROLE)
        try:
            packItem, = self.model().match(QModelIndex(), OBJECT_ROLE, pack, hits=1)
        except ValueError:
            QMessageBox.critical(self, "Not found error",
                                 f"The file to close is not found: {pack}")
            return

        if packItem.isValid():
            try:
                if self.isWindowModified():
                    dialog = QMessageBox(QMessageBox.NoIcon, f"Close {pack}",
                                         f"Do you want to save your changes in {pack} before closing?",
                                         standardButtons=QMessageBox.Save |
                                                         QMessageBox.Cancel |
                                                         QMessageBox.Discard)
                    dialog.setDefaultButton = QMessageBox.Save
                    dialog.button(QMessageBox.Save).setText("&Save&Close")
                    res = dialog.exec()
                    if res == QMessageBox.Save:
                        self.savePack()
                    elif res == QMessageBox.Cancel:
                        return
                self.closeFile(packItem)
            except AttributeError as e:
                QMessageBox.critical(self, "Error", f"No chosen package to close: {e}")

    def closeAllFilesWithDialog(self):
        if self.isWindowModified():
            dialog = QMessageBox(QMessageBox.NoIcon, f"Close all AAS files",
                                 f"Do you want to save your changes before closing? ",
                                 standardButtons=QMessageBox.Save |
                                                 QMessageBox.Cancel |
                                                 QMessageBox.Discard)
            dialog.setDefaultButton = QMessageBox.Save
            dialog.button(QMessageBox.Save).setText("&Save and Close All")
            res = dialog.exec()
            if res == QMessageBox.Save:
                for pack in self.model().data(QModelIndex(), OPENED_PACKS_ROLE):
                    self.savePack(pack)
            elif res == QMessageBox.Cancel:
                return
        self.closeAllFiles()

    def closeAllFiles(self):
        for pack in self.model().data(QModelIndex(), OPENED_PACKS_ROLE):
            packItem, = self.model().match(QModelIndex(), OBJECT_ROLE, pack, hits=1)
            self.closeFile(packItem)

    def closeFile(self, packItem: QModelIndex):
        self.model().setData(packItem, NOT_GIVEN, CLEAR_ROW_ROLE)
        if self.model().data(QModelIndex(), OPENED_PACKS_ROLE):
            self.setWindowModified(False)

    def openRecentSlot(self):
        action = self.sender()
        if action:
            self.openPack(action.data())

    def updateRecentFiles(self, file: str):
        self.removeFromRecentFiles(file)
        settings = QSettings(ACPLT, APPLICATION_NAME)
        files = settings.value('recentFiles', [])
        files.insert(0, file)
        del files[MAX_RECENT_FILES:]
        settings.setValue('recentFiles', files)

    def removeFromRecentFiles(self, file: str):
        settings = QSettings(ACPLT, APPLICATION_NAME)
        files = settings.value('recentFiles', [])
        try:
            files.remove(file)
        except ValueError:
            pass
        except AttributeError:
            files = []
        settings.setValue('recentFiles', files)

    def updateRecentFileActs(self):
        settings = QSettings(ACPLT, APPLICATION_NAME)
        files = settings.value('recentFiles', [])
        try:
            files = files[:MAX_RECENT_FILES]
        except TypeError:
            files = []

        for i, file in enumerate(files):
            if len(file) < 30:
                self.recentFileActs[i].setText(file)
            else:
                self.recentFileActs[i].setText(f"..{file[len(file) - 30:]}")
            self.recentFileActs[i].setData(file)
            self.recentFileActs[i].setVisible(True)

        for i in range(len(files), MAX_RECENT_FILES):
            self.recentFileActs[i].setVisible(False)

        self.recentFilesSeparator.setVisible(bool(files))

    def collapse(self, index: QtCore.QModelIndex) -> None:
        newIndex = index.siblingAtColumn(0)
        if not self.isExpanded(index) or not index.child(0, 0).isValid():
            if newIndex.parent() != self.rootIndex():
                newIndex = newIndex.parent()
        self.setCurrentIndex(newIndex)
        super(PackTreeView, self).collapse(newIndex)

    def keyPressEvent(self, event: QKeyEvent) -> None:
        if event.key() in (Qt.Key_Right, Qt.Key_Left):
            self.setFocus()
            currIndex = self.currentIndex()
            if event.key() == Qt.Key_Right:
                self.navigate2nextEnabledItemInRow(currIndex)
            else:
                self.navigate2nextEnabledItemInRow(currIndex, leftDirection=True)
        else:
            super(PackTreeView, self).keyPressEvent(event)

    def navigate2nextEnabledItemInRow(self, index: QModelIndex, leftDirection=False):
        delta = -1 if leftDirection else +1
        currCol = index.column()
        if index.isValid():
            visCol = self.header().visualIndex(currCol)
            i = delta
            while True:
                newLogCol = self.header().logicalIndex(visCol + i)
                nextItem = index.siblingAtColumn(newLogCol)
                if visCol + i < 0 or visCol + i >= self.header().count():
                    break
                if not self.header().isSectionHidden(newLogCol) and nextItem.flags() & Qt.ItemIsEnabled:
                    self.setCurrentIndex(index.siblingAtColumn(newLogCol))
                    break
                i += delta

    def dragEnterEvent(self, event: QDragEnterEvent):
        if event.mimeData().hasUrls:
            event.accept()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()

    def dropEvent(self, e: QDropEvent) -> None:
        for url in e.mimeData().urls():
            file = str(url.toLocalFile())
            self.openPack(file)

    def onDelClear(self):
        index = self.currentIndex()
        attribute = index.data(COLUMN_NAME_ROLE)
        if isinstance(index.data(OBJECT_ROLE), Package):
            self.closeAct.trigger()
        elif attribute in (OBJECT_COLUMN_NAME, OBJECT_VALUE_COLUMN_NAME):
            super(PackTreeView, self).onDelClear()
        else:
            parentObjType = type(index.data(OBJECT_ROLE))
            defaultVal = getDefaultVal(parentObjType, attribute)
            self._setItemData(index, defaultVal, Qt.EditRole)

    def isPasteOk(self, index: QModelIndex) -> bool:
        attrName = index.data(COLUMN_NAME_ROLE)
        if attrName in (OBJECT_COLUMN_NAME, OBJECT_VALUE_COLUMN_NAME):
            return super(PackTreeView, self).isPasteOk(index)
        else:
            if self.treeClipboard.isEmpty() or not index.isValid():
                return False

            try:
                attrTypehint = util_type.getAttrTypeHint(type(index.data(OBJECT_ROLE)), attrName, delOptional=False)
            except KeyError as e:
                logging.exception(e)
                # print(e)
                return False

            obj2paste = self.treeClipboard.objects[-1]
            targetTypeHint = attrTypehint

            try:
                if util_type.checkType(obj2paste, targetTypeHint):
                    return True
            except (AttributeError, TypeError) as e:
                logging.exception(e)
                # print(e)
            return False

    def onPaste(self):
        index = self.currentIndex()
        attrName = index.data(COLUMN_NAME_ROLE)
        if attrName in (OBJECT_COLUMN_NAME, OBJECT_VALUE_COLUMN_NAME):
            super(PackTreeView, self).onPaste()
        else:
            obj2paste = self.treeClipboard.objects[-1]
            targetParentObj = index.data(OBJECT_ROLE)
            targetTypeHint = util_type.getAttrTypeHint(type(index.data(OBJECT_ROLE)), attrName, delOptional=False)
            reqAttrsDict = getReqParams4init(type(obj2paste), rmDefParams=True)

            # if no req. attrs, paste data without dialog
            # else paste data with dialog for asking to check req. attrs
            if util_type.checkType(obj2paste, targetTypeHint):
                self._onPasteReplace(index, obj2paste, withDialog=bool(reqAttrsDict))


# python3
import sys

def swap_by_index(values, a, b):
    temp = values[a]
    values[a] = values[b]
    values[b] = temp

def selection_sort(values):
    for i in range(0, len(values)):
        min_index = i
        for j in range(i + 1, len(values)):
            if values[j] <= values[min_index]:
                min_index = j
        swap_by_index(values, i, min_index)

    return values

if __name__ == '__main__':
    print(selection_sort(
        [4, 3, 2, 20, 18, 14, 1, 4, 3, 2, 20, 18, 14, 1, 4, 3, 2, 20, 18, 14, 1, 4, 3, 2, 20, 18, 14, 1]))


import socket

import collections

def parse(range_mapping, topology, lookup=socket.gethostbyname):
    return _topology_map(_dns_map(_parse_range_mapping(range_mapping), lookup), topology)

def merge(mappings):
    res = collections.defaultdict(lambda: set())
    for mapping in mappings:
        for host, friends in mapping.items():
            res[host] = res[host] | friends
    return res

def _parse_range_mapping(ranges):
    mapping = {}
    for range in ranges:
        for host1 in range.get("endpoints"):
            for host2 in range.get("endpoints"):
                if host1 != host2:
                    mapping.setdefault(host1, set()).add(host2)
    return mapping

def _dns_map(mapping, lookup=socket.gethostbyname):
    return dict(
        (lookup(raw_host), set(lookup(raw_friend) for raw_friend in raw_friends))
        for raw_host, raw_friends in mapping.items())

def _topology_map(mapping, topology):
    res = {}
    # Fallback for case with no overlap
    for host in topology:
        res[host] = set()
    for raw_host, raw_friends in mapping.items():
        friends = (topology.get_host(raw_friend) for raw_friend in raw_friends)
        host = topology.get_host(raw_host)
        filtered_friends = set(friend for friend in friends
                               if friend.cluster == host.cluster and friend.dc == host.dc)
        res[host] = filtered_friends
    return res


import multiprocessing
import os

import gunicorn.app.base
from brochure.brochure_application import BrochureApplication
from brochure.commands.command_types import CommandType
from brochure_wsgi.brochure_wsgi_application import BrochureWSGIApplication
from brochure_wsgi.http_user_interface import HTTPUserInterfaceProvider
from brochure_wsgi.path_command_provider import GetPathCommandProvider
from brochure_wsgi.value_fetchers.environment_contact_method_fetcher import environment_contact_method_fetcher
from brochure_wsgi.value_fetchers.environment_cover_section_fetcher import environment_cover_section_fetcher
from brochure_wsgi.value_fetchers.environment_enterprise_fetcher import environment_enterprise_fetcher
from gunicorn.six import iteritems
from werkzeug.routing import Map, Rule

from cf_domain_redirect_preprocessor import get_cf_domain_redirect_preprocessor
from cf_favicon_preprocessor import get_cf_favicon_preprocessor
from cf_upgrade_to_ssl_preprocessor import get_cf_upgrade_to_ssl_preprocessor

class GunicornApplication(gunicorn.app.base.BaseApplication):
    def __init__(self, application, options=None):
        self.options = options or {}
        self.application = application
        super().__init__()

    def init(self, parser, opts, args):
        pass

    def load_config(self):
        config = dict([(key, value) for key, value in iteritems(self.options)
                       if key in self.cfg.settings and value is not None])
        for key, value in iteritems(config):
            self.cfg.set(key.lower(), value)

    def load(self):
        return self.application

if __name__ == "__main__":
    option_dictionary = {
        "bind": '%s:%s' % ('0.0.0.0', os.environ.get("PORT", "8000")),
        "workers": (multiprocessing.cpu_count() * 2) + 1,
    }
    brochure_application_command_map = Map()
    brochure_application_command_map.add(Rule("/", endpoint=lambda: CommandType.SHOW_COVER))
    get_path_command_provider = GetPathCommandProvider(url_map=brochure_application_command_map)

    domain_application = BrochureApplication(contact_method_fetcher=environment_contact_method_fetcher,
                                             cover_section_fetcher=environment_cover_section_fetcher,
                                             enterprise_fetcher=environment_enterprise_fetcher)
    user_interface_provider = HTTPUserInterfaceProvider()

    command_preprocessors = None
    favicon_preprocessor = get_cf_favicon_preprocessor()
    if os.environ.get("DEBUG", False):
        command_preprocessors = (favicon_preprocessor,)
    else:
        domain_redirect_preprocessor = get_cf_domain_redirect_preprocessor()
        upgrade_to_ssl_preprocessor = get_cf_upgrade_to_ssl_preprocessor()
        command_preprocessors = (favicon_preprocessor, domain_redirect_preprocessor, upgrade_to_ssl_preprocessor)

    brochure_wsgi_application = BrochureWSGIApplication(domain_application=domain_application,
                                                        user_interface_provider=user_interface_provider,
                                                        get_path_command_provider=get_path_command_provider,
                                                        command_preprocessors=command_preprocessors)
    GunicornApplication(application=brochure_wsgi_application,
                        options=option_dictionary).run()


from abc import ABC
import os
import sys

class PureBasicBlock:
    text: list[str]

    def __init__(self):
        self.text = list()

    def add_text(self, text):
        self.text.append(text)

class PureBasicProcedure(PureBasicBlock):
    PROCEDURE_DEFAULT = 0b0000_0001
    PROCEDURE_C = 0b0000_0010
    PROCEDURE_DLL = 0b0000_0100
    PROCEDURE_CDLL = PROCEDURE_C | PROCEDURE_DLL

    procedure_type: int

    def __init__(self, procedure_type: int):
        super().__init__()
        self.procedure_type = procedure_type

class DocumentationToken:
    token_type: PureBasicCodeBlock
    raw_content: str

    def __init__(self, token_type: PureBasicCodeBlock, raw_content: str):
        self.token_type = token_type
        self.raw_content = raw_content

def main(filename) -> int:
    if not (os.path.exists(filename) and os.path.isfile(filename)):
        print("File does not exist or is a directory !")
        return 2

    with open(filename) as f:
        lines = f.readlines()
    lines = [x.strip() for x in lines]

    tokens: list[PureBasicCodeBlock] = list()
    for line in lines:
        print(line)

if __name__ == "__main__":
    if len(sys.argv) > 1:
        exit(main(sys.argv[1]))
    else:
        print("No input file !")
        exit(1)


# coding: utf-8

# In[ ]:

def find_k(data_test,data_train,target_test,target_train,k_range):
    minMSE = -1
    for k in k_range:
        if k <= data_test.shape[0]: # make sure there are enough test samples available
            knnclf = neighbors.KNeighborsClassifier(k, weights='distance')
            knnclf.fit(data_train, target_train)

            knnpreds_test = knnclf.predict(data_test)
            # convert the predictions and targets to integers so that MSE can be calculated
            target_test = np.asarray(target_test)
            target_test_float = target_test.astype(np.float)
            knnpreds_test_float = knnpreds_test.astype(np.float)

            MSE = math.sqrt(sum((knnpreds_test_float - target_test_float)**2)) / knnpreds_test_float.shape[0]
            if minMSE == -1:
                minMSE = MSE
                return_k = k
            elif MSE < minMSE:
                minMSE = MSE
                return_k = k

    return minMSE, return_k

# In[5]:

import sqlite3
import numpy as np
import time, datetime

from sklearn.preprocessing import MinMaxScaler
from sklearn import neighbors
from sklearn.cross_validation import train_test_split
import math

today = datetime.date.today()
today = today.strftime("%Y-%m-%d")

con = sqlite3.connect('C:\\NBA\\nba.db')
cur = con.cursor()
cur2 = con.cursor()
cur3 = con.cursor()

"""
cur.execute('DROP TABLE IF EXISTS model_results')
cur.execute('''CREATE TABLE model_results
             (
                 player_id TEXT
                ,model_date TEXT
                ,model TEXT
                ,stat TEXT
                ,mse REAL
                ,params TEXT
                ,params_desc TEXT
             )''')
"""

player_list = []
cur.execute('''
            SELECT DISTINCT player_id
            FROM
            (
            SELECT player_id, COUNT(*)
            FROM records
            GROUP BY player_id
            HAVING COUNT(*) > 4
            ) tab
            ''')
for player in cur:
    player_list.append(player[0])

for p in player_list:
    cur2.execute("SELECT * FROM records WHERE player_id = '" + p + "'")

    player_records = [] # initiate empty list to eventually hold the palyer records as a numpy array

    for record in cur2:
        record = list(record)
        record = record[2:] # omit the player_id and game_id
        player_records.append(record)

    player_records = np.asarray(player_records)

    # define numerical tagets
    assists = player_records[:,0] # first column
    rebounds = player_records[:,1]
    points = player_records[:,2]
    steals = player_records[:,3]
    blocks = player_records[:,4]
    turnovers = player_records[:,5]
    made_threes = player_records[:,6]

    # define categorical targets
    assists_str = ["%.0f" % asst for asst in assists]
    rebounds_str = ["%.0f" % reb for reb in rebounds]
    points_str = ["%.0f" % point for point in points]
    steals_str = ["%.0f" % steal for steal in steals]
    blocks_str = ["%.0f" % block for block in blocks]
    turnovers_str = ["%.0f" % turnover for turnover in turnovers]
    made_threes_str = ["%.0f" % made_three for made_three in made_threes]

    # drop targets from array
    player_records = np.delete(player_records, 0, 1) # remove assists
    player_records = np.delete(player_records, 0, 1) # remove rebounds
    player_records = np.delete(player_records, 0, 1) # remove points
    player_records = np.delete(player_records, 0, 1) # remove steals
    player_records = np.delete(player_records, 0, 1) # remove blocks
    player_records = np.delete(player_records, 0, 1) # remove turnovers
    player_records = np.delete(player_records, 0, 1) # remove made_three

    for target in [assists_str,rebounds_str,points_str,steals_str,blocks_str,turnovers_str,made_threes_str]:
        if np.array_equal(target, assists_str):
            stat = 'assists'
        elif np.array_equal(target, rebounds_str):
            stat = 'rebounds'
        elif np.array_equal(target, points_str):
            stat = 'points'
        elif np.array_equal(target, steals_str):
            stat = 'steals'
        elif np.array_equal(target, blocks_str):
            stat = 'blocks'
        elif np.array_equal(target, turnovers_str):
            stat = 'turnovers'
        elif np.array_equal(target, made_threes_str):
            stat = 'made_threes'

        # split the data into randomized 80% 20% training and test split
        train, test, target_train, target_test = train_test_split(player_records, target, test_size=0.2, random_state=33)

        # normalize the train and test data based on the training data with min-max normalization
        min_max_scaler = MinMaxScaler().fit(train)
        train_norm = min_max_scaler.transform(train)
        test_norm = min_max_scaler.transform(test)

        MSE, k =  find_k(test_norm,train_norm,target_test,target_train,list(range(6))[1:]) # 1 through 5

        result = [p,today,'knn',stat,MSE,k,'K Neareast Neighbors']
        result = tuple(result)
        cur3.execute('INSERT INTO model_results VALUES(?' + ',?'*6 + ')',result)
    con.commit()
con.close()


# coding: utf-8

# In[9]:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

from bs4 import BeautifulSoup

import datetime
import pymysql

# In[10]:

def createDB(conn,dbname):
    curs = conn.cursor()
    query = """CREATE DATABASE """+dbname
    try :
        curs.execute(query)
    except :
        print('DB가 이미 존재합니다. DB_NAME : ',dbname)

    query = """ALTER DATABASE """+ dbname + """ CHARACTER SET utf8 COLLATE utf8_general_ci;"""
    curs.execute(query)
    conn.commit()

# In[11]:

def save_DB(total_list) :
    temp = keyword.replace(' ','_')
    conn = pymysql.connect(host = "", user = "root", password = "", charset = "utf8")
    dbname = 'daum_blog_'+ temp
    createDB(conn,dbname)
    curs = conn.cursor()
    curs.execute("""use """+dbname)

    query = """CREATE TABLE IF NOT EXISTS """+ temp + """(ID int, URL varchar(100), Title varchar(100), Date varchar(20), Writer varchar(50), blog_like int, Count int,Text longtext);"""
    curs.execute(query)

    query = """ALTER TABLE """ + temp +""" CHARACTER SET utf8 COLLATE utf8_general_ci;"""
    curs.execute(query)

    conn.commit()

    select_query = """SELECT * from """ + temp
    index = curs.execute(select_query)

    for value in total_list :
        url = value[0]
        title = value[1]
        date = value[2]
        writer = value[3]
        like = value[4]
        count = value[5]
        content = value[6]

        query = """insert into """ + temp + """(ID, URL, Title, Date, Writer, blog_like, Count, Text) values (%s, %s, %s, %s, %s, %s, %s, %s) ; """
        curs.execute(query, (str(index), url, title, date,writer,like,count,content))

        index = index + 1

        conn.commit()

    conn.close()
    print("FINISH")

# In[12]:

keyword = input("Keyword ? ")

start_year = input("Start Year ? ")
start_month = input("Start Month ? ")
start_day = input("Start Day ? ")

end_year = input("End Year ? ")
end_month = input("End Month ? ")
end_day = input("End Day ? ")

start_date = start_year+start_month+start_day
end_date = end_year+end_month+end_day

# In[16]:

import re

INVISIBLE_ELEMS = ('style', 'script', 'head', 'title')
RE_SPACES = re.compile(r'\s{3,}')

def visible_texts(soup):
    text = ' '.join([
        s for s in soup.strings
        if s.parent.name not in INVISIBLE_ELEMS
    ])

    return RE_SPACES.sub('  ', text)

# In[18]:

dt_start_date = datetime.datetime.strptime(start_date,"%Y%m%d").date()
dt_end_date = datetime.datetime.strptime(end_date,"%Y%m%d").date()
day_1 = datetime.timedelta(days=1)
dt_start_1 = dt_start_date

# 일수를 하루씩 잘라서 반복
while dt_start_1 <= dt_end_date :
    total_list = []
    URL_date_list = []
    page_num = 1
    print(dt_start_1)
    # 페이지 만큼 돌면서 링크 수집
    while True :
        p_url = 'https://search.daum.net/search?w=blog&m=board&lpp=10&DA=STC&q='+keyword+'&f=section&SA=daumsec&sd='+start_date+'000000&ed='+start_date+'235959&period=u&m=board&page='+str(page_num)
        driver = webdriver.Chrome('./chromedriver/chromedriver')
        driver.implicitly_wait(3)
        driver.get(p_url)

        soup = BeautifulSoup(driver.page_source,'html.parser')
        span_tags = soup.findAll("span", {"class" : "f_nb date"})
        a_tags = driver.find_elements_by_xpath("//a[@class='f_link_b']")

        # 한 페이지에 있는 링크들 전부 가져오기
        for a,d in zip(a_tags,span_tags) :
            url = a.get_attribute("href")
            if 'blog.daum' in url :
                driver = webdriver.Chrome('./chromedriver/chromedriver')
                driver.implicitly_wait(3)
                driver.get(url)
                # 페이지 변환
                frame = driver.find_element_by_name('BlogMain')
                driver.switch_to_frame(frame)
                soup = BeautifulSoup(driver.page_source,'html.parser')

                blog_title = soup.find("strong", {"class" : "cB_Title cB_TitleImage"}).text.replace('\n','').strip().encode('cp949','ignore')
                blog_title = blog_title.decode('cp949','ignore')
                print(blog_title)
                blog_date = d.text
                print(blog_date)
                writer = soup.find("span", {"class" : "cB_Name"}).text
                print(writer)
                try :
                    reply_count = driver.find_element_by_css_selector('#cContentBottom > div > ul > li').text.strip()[3:]
                except :
                    reply_count = 0
                print(reply_count)
                # 페이지 변환
                frame = driver.find_element_by_css_selector('#cContentBody > div > iframe')
                driver.switch_to_frame(frame)
                soup = BeautifulSoup(driver.page_source,'html.parser')

                # 공감 버튼이 아예 없거나 비어있다면 0으로
                if soup.find("span", {"class" : "num_empathy uoc-count"}) is not None :
                    if soup.find("span", {"class" : "num_empathy uoc-count"}).text :
                        blog_like = soup.find("span", {"class" : "num_empathy uoc-count"}).text
                    else :
                        blog_like = 0
                else :
                    blog_like = 0
                print(blog_like)

                blog_content = visible_texts(soup.find("div", {"id" : "contentDiv"})).strip()
                blog_content = blog_content.encode('cp949','ignore')
                blog_content = blog_content.decode('cp949','ignore')
                print(blog_content)
                total_list.append([url,blog_title,blog_date,writer,blog_like,reply_count,blog_content])
        # daum blog는 다음 버튼이 활성화일땐 a태그, 비활성화일땐 span태그가 페이지에 나타나도록 설계되어있음
        try :
            driver.find_elements_by_xpath("//div[@id='pagingArea']/span[1]/a[@class='ico_comm1 btn_page btn_next']").click()
            page_num += 1
        except :
            break;

     # 날짜 변환
    dt_start_1 = dt_start_1 + day_1
    temp = str(dt_start_1)
    start_date = temp[:4]+temp[5:7]+temp[8:]

    save_DB(total_list)

# In[ ]:

# conn = pymysql.connect(host = "", user = "root", password = "", charset = "utf8")
# curs = conn.cursor()
# curs.execute("use daum_blog ;")
# query = """select * from 원자력; """
# curs.execute(query)
# all_rows = curs.fetchall()
# for i in all_rows:
#     print(i)

# In[ ]:

# DB삭제시 이용
# conn = pymysql.connect(host = "", user = "root", password = "", charset = "utf8")
# curs = conn.cursor()
# query = """DROP DATABASE daum_blog; """
# curs.execute(query)


from ooflib.SWIG.common import config
from ooflib.SWIG.common.guitop import top
from ooflib.common import debug
from ooflib.common import mainthread
from ooflib.common.IO import mainmenu
from ooflib.common.IO import oofmenu
from ooflib.common.IO.GUI import gfxmenu
from ooflib.common.IO.GUI import gtklogger
from ooflib.common.IO.GUI import quit
from gi.repository import Gtk
import types

## TODO: Menu creation here is clumsy and should be cleaned up.
## Currently the "menu" arg to the SubWindow constructor is expected
## to be either an OOFMenuItem or a string.  If it's a string, a menu
## is created with that name and File/Close and File/Quit are added to
## it, and the menu is attached to the window's menu bar.  If the
## "menu" arg is an OOFMenuItem, then it is attached to the menu bar
## without modification.

## A better scheme would be for the constructor arg to always be an
## OOFMenuItem, which could be in an existing OOFMenu or not.  The
## SubWindow constructor would always create File/Close and File/Quit
## menu items if they didn't already exist.  The subclasses could
## override the callback methods if necessary.  Having
## SubWindow.__init__ create the File/Quit would mean that the hack of
## setting File.Quit.data=self.gtk would be required in far fewer
## places.

## Subclasses of SubWindow and the menu arg they pass to SubWindow.__init__:
## GUIConsole (console.py)  passes _console_menu
## ActivityViewer, passes self.menu
## GfxWindowBase (uses self.menu from GhostGfxWindow, calls
##   SubWindow.__init__ from gfxwindow.py) passes self.menu
## MessageWindow (reporter_GUI.py)   passes self.menu_name
## TutorialClassGUI (tutorialsGUI.py) passes ""

class SubWindow:
    # Base class for non-modal windows which want to be destroyed when
    # the main OOF GUI window, which from here is top().gtk, gets
    # destroyed.
    def __init__(self, title, menu=None, callback=None, guiloggable=True):
        debug.mainthreadTest()
        self.gtk = Gtk.Window(Gtk.WindowType.TOPLEVEL, title=title)
        if guiloggable:
            gtklogger.newTopLevelWidget(self.gtk, title)
            gtklogger.connect_passive(self.gtk, 'delete-event')
            gtklogger.connect_passive(self.gtk, 'configure-event')
        self.mainbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
                               spacing=2, margin=5)
        self.gtk.add(self.mainbox)

        # Checking the type is clumsy; the idea is that the caller
        # must provide either the name for the auto-generated menu, or
        # a menu to use instead.  See the TODO above.
        if type(menu)==types.StringType:
            # If no menu is provided, then build a non-logging local
            # one with 'Close' and 'Quit'.
            self.subwindow_menu = oofmenu.OOFMenuItem(
                menu, secret=1, gui_only=1, no_log=1)

            file_item = oofmenu.OOFMenuItem('File', gui_only=1, no_log=1)
            self.subwindow_menu.addItem(file_item)

            file_item.addItem(oofmenu.OOFMenuItem(
                'Close', help="Close this window.",
                callback=self.menu_close,
                no_log=1, gui_only=1, accel='w'))

            file_item.addItem(oofmenu.OOFMenuItem(
                'Quit', gui_callback=quit.queryQuit,
                no_log=1, gui_only=1,
                help="Quit the OOF application.",
                accel='q', threadable = oofmenu.UNTHREADABLE))
            # quit.queryQuit uses menuitem.data to know which window
            # to use as the base for its dialog box.
            file_item.Quit.data = self.gtk

            mainmenu.OOF.addItem(self.subwindow_menu)
            self._local_menu = menu
        elif isinstance(menu, oofmenu.OOFMenuItem):
            self.subwindow_menu = menu
            self._local_menu = None # Flag indicating menu was passed in.
        else:
            raise TypeError("Incorrect type passed as menu to SubWindow.")

        # Build the menu bar and add it to the window.
##        self.menu_bar = None
        self.accel_group = Gtk.AccelGroup()
        self.gtk.add_accel_group(self.accel_group)
        self.menu_bar = gfxmenu.gtkOOFMenuBar(
            self.subwindow_menu, accelgroup=self.accel_group,
            parentwindow=self.gtk)
        if guiloggable:
            gtklogger.setWidgetName(self.menu_bar, "MenuBar")

        self.mainbox.pack_start(self.menu_bar, fill=False, expand=False,
                                padding=0)

        # Add the "Windows" menu to the bar.
        self.windows_gtk_menu_item = gfxmenu.gtkOOFMenu(
            mainmenu.OOF.Windows, self.accel_group, parentwindow=self.gtk)
        self.menu_bar.append(self.windows_gtk_menu_item)

        self.menu_bar.connect("destroy", self.menu_bar_destroyed)

        if callback is None:
            callback = self.destroySubWindow
        top().gtk.connect("destroy", callback)

    # It is assumed, here, that if the menu bar has been destroyed,
    # the destruction of the SubWindow wrapper object is imminent,
    # so it's safe to cut the menu loose.
    def menu_bar_destroyed(self, gtk):
        if self._local_menu:
            # Disconnect the menu.
            self.subwindow_menu.clearMenu()
            mainmenu.OOF.removeItem(self._local_menu)
            self.subwindow_menu = None

    # Default close routine, callback for the default menu item.
    def menu_close(self, menuitem):
        mainthread.runBlock(self.close_thread)
    def close_thread(self):
        debug.mainthreadTest()
        self.gtk.destroy()

    def destroySubWindow(self, *args):
        debug.mainthreadTest()
        if self.gtk:
            self.gtk.destroy()
            self.gtk = 0

    # This takes arguments so it can be used as a callback.
    def raise_window(self, *args):
        debug.mainthreadTest()
        self.gtk.present_with_time(Gtk.get_current_event_time())

# used by several of the subwindows for naming window.
def oofname():
    if config.dimension() == 2:
        return "OOF2"
    elif config.dimension() == 3:
        return "OOF3D"


vowels = 'aeiou'
def numcons(str):
    longest = 0
    runningcount = 0
    for char in str:
        if char not in vowels:
            runningcount += 1
            longest = max(runningcount, longest)
        else:
            runningcount = 0

    return longest

def nvalue(str, n):
    nval = 0
    for i in range(len(str)):
        for j in range(len(str) + 1):
            if numcons(str[i:j]) >= n:
                nval += 1

    return nval

def readwrite(filename, fileoutname):
    output = []
    inputs = open(filename, 'r').readlines()[1:]
    for input in inputs:
        item = input.split(' ')
        output.append(nvalue(item[0], int(item[1])))

    fileout = open(fileoutname, 'w')
    for i in range(len(output)):
        fileout.write('Case #' + str(i+1) + ': ' + str(output[i]) + '\n')

readwrite('A-small-attempt0.in','outsmall.txt')


"""
   This is the custom function interface.
   You should not implement it, or speculate about its implementation
   class CustomFunction:
       # Returns f(x, y) for any given positive integers x and y.
       # Note that f(x, y) is increasing with respect to both x and y.
       # i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
       def f(self, x, y):

"""

class Solution:
    def findSolution(self, customfunction: 'CustomFunction', z: int) -> List[List[int]]:
        right = 1000
        ans = []

        for i in range(1,1000):
            left = 1
            while left <= right:
                mid = left + (right - left)//2
                if customfunction.f(i,mid) < z:
                    left = mid + 1
                elif customfunction.f(i,mid) > z:
                    right = mid - 1
                else:
                    ans.append([i,mid])
                    break

        return ans


from torch import nn
import torch
import numpy as np
from torch.nn import functional as F
import torch.optim

# The `lower_bound_fn' is
# from the repo: https://github.com/jorge-pessoa/pytorch-gdn/blob/master/pytorch_gdn/__init__.py,
# which is available under the MIT license:

'''MIT License

Copyright (c) 2019 Jorge Pessoa

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.'''

class lower_bound_fn(torch.autograd.Function):
    @staticmethod
    def forward(ctx, inputs, bound):
        b = torch.ones(inputs.size()) * bound
        b = b.to(inputs.device)
        ctx.save_for_backward(inputs, b)
        return torch.max(inputs, b)

    @staticmethod
    def backward(ctx, grad_output):
        inputs, b = ctx.saved_tensors

        pass_through_1 = inputs >= b
        pass_through_2 = grad_output < 0

        pass_through = pass_through_1 | pass_through_2
        return pass_through.type(grad_output.dtype) * grad_output, None

lower_bound = lower_bound_fn.apply

# This "entropy bottleneck" implementation clearly corresponds to the one mentioned in the paper below.
# `Appendix' describes each step of the entropy estimation part.

"""
> "Variational image compression with a scale hyperprior"

  > J. Ballé, D. Minnen, S. Singh, S. J. Hwang, N. Johnston

  > https://arxiv.org/abs/1802.01436
"""

# Their TensorFlow-based implementation can be found at:
# https://github.com/tensorflow/compression/blob/master/tensorflow_compression/python/layers/entropy_models.py

class EntropyBottleneck(nn.Module):
    def __init__(self, channels, init_scale=10, filters=(3, 3, 3), tail_mass=1e-9,
                 optimize_integer_offset=True, likelihood_bound=1e-9, quantize=True,
                 range_coder_precision=16):

        super(EntropyBottleneck, self).__init__()
        self.init_scale = float(init_scale)
        self.filters = tuple(int(f) for f in filters)
        self.tail_mass = float(tail_mass)
        if not 0 < self.tail_mass < 1:
            raise ValueError(
                "`tail_mass` must be between 0 and 1, got {}.".format(self.tail_mass))
        self.optimize_integer_offset = bool(optimize_integer_offset)
        self.likelihood_bound = float(likelihood_bound)
        self.range_coder_precision = int(range_coder_precision)
        self.matrices = []
        self.biases = []
        self.factors = []
        filters = (1,) + self.filters + (1,)
        scale = self.init_scale ** (1 / (len(self.filters) + 1))
        # Initializing layer parameters: matrices, biases and factors
        for i in range(len(self.filters) + 1):
            init = np.log(np.expm1(1 / scale / filters[i + 1]))
            matrix = torch.ones((channels, filters[i + 1], filters[i])) * init
            matrix = nn.Parameter(data=matrix, requires_grad=True)
            self.matrices.append(matrix)

            bias = nn.Parameter(data=torch.ones((channels, filters[i + 1], 1)).uniform_(-.5, .5), requires_grad=True)
            self.biases.append(bias)

            if i < len(self.filters):
                factor = torch.zeros((channels, filters[i + 1], 1))
                factor = nn.Parameter(data=factor, requires_grad=True)
                self.factors.append(factor)
        self.factors = nn.Parameter(data=torch.stack(self.factors), requires_grad=True)
        for i, matrix in enumerate(self.matrices):
            self.register_parameter('matrix{}'.format(i), matrix)
        for i, bias in enumerate(self.biases):
            self.register_parameter('bias{}'.format(i), bias)

            # To figure out what range of the densities to sample, we need to compute
            # the quantiles given by `tail_mass / 2` and `1 - tail_mass / 2`.
            # Since we can't take inverses of the cumulative directly, we make it an optimization
            # problem:
            # `quantiles = argmin(|logit(cumulative) - target|)`
            # where `target` is `logit(tail_mass / 2)` or `logit(1 - tail_mass / 2)`.
            # Taking the logit (inverse of sigmoid) of the cumulative makes the
            # representation of the right target more numerically stable.

            # Numerically "stable" way of computing logits of `tail_mass / 2`
            # and `1 - tail_mass / 2`.
        target = np.log(2 / self.tail_mass - 1)
        self.target = torch.tensor([-target, 0, target])
        self.quantize = quantize

    def logits_cumulative(self, inputs):
        logits = inputs
        for i in range(len(self.filters) + 1):
            matrix = self.__getattr__('matrix{}'.format(i))
            matrix = F.softplus(matrix)
            logits = torch.matmul(matrix, logits)
            bias = self.__getattr__('bias{}'.format(i))
            logits += bias

            if i < len(self.factors):
                factor = self.factors[i]
                factor = torch.tanh(factor)
                logits += factor * torch.tanh(logits)
        return logits

    def forward(self, x):
        # x : Shape of the input tensor is used to get the number of channel.
        # Convert to (channels, 1, batch) format by commuting channels to front
        x = x.permute(1, 0, 2, 3)
        shape = x.shape
        x = torch.reshape(x, (shape[0], 1, -1)).float()

        if self.quantize:
            if self.training:
                x = x + torch.rand_like(x) - 0.5  # during training, adding noise for differentiability.
            else:
                x = torch.round(x)
                # during evaluation, the data is quantized and the entropies are discrete (Shannon entropies)

        # Evaluate densities.
        # We can use the special rule below to only compute differences in the left
        # tail of the sigmoid.
        lower = self.logits_cumulative(x - 0.5)
        upper = self.logits_cumulative(x + 0.5)

        # Flip signs if we can move more towards the left tail of the sigmoid.
        sign = torch.sign(lower.add(upper))
        # Calculating the pmf
        likelihood = torch.abs(torch.sigmoid(sign * upper) - torch.sigmoid(sign * lower))
        if self.likelihood_bound > 0:
            likelihood = lower_bound(likelihood, self.likelihood_bound)

        x = torch.reshape(x, shape)
        # Convert back to input tensor shape.
        x = x.permute(1, 0, 2, 3)
        likelihood = torch.reshape(likelihood, shape)
        likelihood = likelihood.permute(1, 0, 2, 3)

        return x, likelihood


#!/usr/bin/env python3
from datetime import datetime
from psutil import disk_usage, sensors_battery
from psutil._common import bytes2human
from socket import gethostname, gethostbyname
from subprocess import check_output
from sys import stdout
from time import sleep

def write(data):
    stdout.write("%s\n" % data)
    stdout.flush()

def refresh():
    disk = bytes2human(disk_usage("/").free)
    ip = gethostbyname(gethostname())
    try:
        ssid = check_output("iwgetid -r", shell=True).strip().decode("utf-8")
        ssid = "(%s)" % ssid
    except Exception:
        ssid = "None"
    bluetooth = check_output(
        "systemctl status bluetooth | grep Status",
        shell=True).strip().decode("utf-8")
    battery = int(sensors_battery().percent)
    status = "Charging" if sensors_battery().power_plugged else "Discharging"
    date = datetime.now().strftime("%h %d %A %I:%M")
    format = "Space: %s | Internet: %s %s | Bluetooth %s | Battery: %s%% %s | Date: %s"
    write(format % (disk, ip, ssid, bluetooth, battery, status, date))

if __name__ == "__main__":
    refresh()


'''**********************************************************************************
Given an integer array nums of unique elements, return all possible subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
**********************************************************************************'''

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []
        #res.append([])
        for i in range(0,len(nums)+1):
            x = itertools.combinations(nums,i)
            for i in x:
                res.append(list(i))
        print(res)
        return res


import subprocess
import os
from sys import stderr

def configure(MODEL, LAYOUT, VARIENT):
    """Configure a user's keyboard"""
    if MODEL != "OEM":
        with open("/usr/share/X11/xkb/rules/base.lst", "r") as xkb_conf:
            kcd = xkb_conf.read()
        kcd = kcd.split("\n")
        for each1 in enumerate(kcd):
            kcd[each1[0]] = kcd[each1[0]].split()
        try:
            os.remove("/etc/default/keyboard")
        except FileNotFoundError:
            pass
        xkbm = ""
        xkbl = ""
        xkbv = ""
        for each1 in kcd:
            if " ".join(each1[1:]) == MODEL:
                xkbm = each1[0]
            elif " ".join(each1[1:]) == LAYOUT:
                xkbl = each1[0]
            elif " ".join(each1[1:]) == VARIENT:
                xkbv = each1[0]
        with open("/etc/default/keyboard", "w+") as xkb_default:
            xkb_default.write("""XKBMODEL=\"%s\"
XKBLAYOUT=\"%s\"
XKBVARIANT=\"%s\"
XKBOPTIONS=\"\"

BACKSPACE=\"guess\"
""" % (xkbm, xkbl, xkbv))
        subprocess.Popen(["udevadm", "trigger", "--subsystem-match=input",
                          "--action=change"], stdout=stderr.buffer)


import math
import heapq

def calculate_distance(position1, position2):
    # Check if the input types are correct
    if not (isinstance(position1, tuple) or isinstance(position1, list)) or len(position1) != 2:
        print(f"Invalid position1: {position1}")
        return
    if not (isinstance(position2, tuple) or isinstance(position2, list)) or len(position2) != 2:
        print(f"Invalid position2: {position2}")
        return

    # Calculate Euclidean distance between two positions
    if position2 is None:
        return float('100')  # Return infinity or another appropriate default value

    x1, y1 = position1
    x2, y2 = position2
    return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)

def find_nearest_ball(grid, robot_position, balls, red_crosses):
    #print("finding nearest ball")
    # Find the nearest ball to the robot's position
    min_distance = float('inf')
    nearest_ball = None

    for ball in balls:
        if ball not in red_crosses:  # Exclude red crosses
            distance = calculate_distance(robot_position, ball)
            if distance is not None and distance < min_distance:
                min_distance = distance
                nearest_ball = ball
    print("nearest ball: ",nearest_ball )

    return nearest_ball

def reconstruct_path(came_from, start, goal):
    print(goal)
    current = tuple(goal)
    path = []
    while current != tuple(start):
        path.append(list(current))
        if current not in came_from:
            print(f"KeyError: {current} not found in came_from")
            break
        current = came_from[current]
    path.append(list(start))
    path.reverse()
    return path

def astar(grid, start, goal):

    open_set = []
    heapq.heappush(open_set, (0, start))
    came_from = {}
    cost_so_far = {}
    came_from[tuple(start)] = None
    cost_so_far[tuple(start)] = 0

    while open_set:
        current = heapq.heappop(open_set)[1]
        current_tuple = tuple(current)
        if current == goal:

            return came_from, cost_so_far, True

        for neighbor in get_neighbors(grid, current):
            neighbor_tuple = tuple(neighbor)
            new_cost = cost_so_far[current_tuple] + 1
            if neighbor_tuple not in cost_so_far or new_cost < cost_so_far[neighbor_tuple]:
                cost_so_far[neighbor_tuple] = new_cost
                priority = new_cost + calculate_distance(neighbor, goal)
                heapq.heappush(open_set, (priority, neighbor))
                came_from[neighbor_tuple] = current_tuple

    return came_from, cost_so_far, goal

def get_neighbors(grid, position):
    # Get valid neighboring positions in the grid
    x, y = position
    neighbors = []

    grid_height = len(grid)

    # Check horizontal and vertical neighbors
    for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
        nx, ny = x + dx, y + dy
        if (0 <= nx < len(grid[0])) and (0 <= ny < grid_height) and (grid[grid_height-ny-1][nx] != 1):
            neighbors.append((nx, ny))

    # Check diagonal neighbors
    for dx, dy in [(-1, -1), (-1, 1), (1, -1), (1, 1)]:
        nx, ny = x + dx, y + dy
        if (0 <= nx < len(grid[0])) and (0 <= ny < grid_height) and (grid[grid_height-ny-1][nx] != 1):
            neighbors.append((nx, ny))

    return neighbors


# EXTERNAL LIBS
from src.domain.enums.region import Region
from src.infrastructures.env_config import config
from src.repositories.base_repositories.mongo_db.base import MongoBaseRepository

class UserPortfoliosRepository(MongoBaseRepository):
    database = config("MONGODB_DATABASE_NAME")
    collection = config("MONGODB_USER_COLLECTION")

    # TODO - FILTER PORTFOLIO BY THE ACTIVE OR INACTIVE STATUS

    @classmethod
    async def get_default_portfolio_created_at_by_region(
        cls, unique_id: str, region: Region
    ):
        region_portfolios = region.value.lower()

        portfolio_created_at = await cls.find_one(
            query={"unique_id": unique_id},
            project={
                f"portfolios.default.{region_portfolios}.created_at": 1,
                "_id": 0,
            },
        )

        created_at = (
            portfolio_created_at.get("portfolios", {})
            .get("default", {})
            .get(region_portfolios, {})
            .get("created_at")
        )

        timestamp_created_at = created_at.timestamp() * 1000
        return timestamp_created_at

    @classmethod
    async def get_all_portfolios_list(cls, unique_id: str):

        stock_portfolios_response = await cls.find_one(
            query={"unique_id": unique_id}, project={"portfolios": 1, "_id": 0}
        )

        if stock_portfolios_response is None:
            response = {"default": {}, "vnc_portfolios": {}}
            return response

        stock_portfolios = stock_portfolios_response.get("portfolios")

        return stock_portfolios

    @classmethod
    async def get_portfolios_by_region(cls, unique_id: str, region: str):
        region_portfolios = region.lower()

        stock_portfolios_response = await cls.find_one(
            query={"unique_id": unique_id},
            project={
                f"portfolios.vnc.{region_portfolios}": 1,
                f"portfolios.default.{region_portfolios}": 1,
                "_id": 0,
            },
        )

        region_default = (
            stock_portfolios_response.get("portfolios", {})
            .get("default", {})
            .get(region_portfolios)
        )
        region_vnc = (
            stock_portfolios_response.get("portfolios", {})
            .get("vnc", {})
            .get(region_portfolios)
        )

        if not region_default and region_vnc:
            response = {"default": {}, "vnc_portfolios": {}}
            return response

        stock_portfolios_response = stock_portfolios_response.get("portfolios")

        return stock_portfolios_response

    @classmethod
    async def get_portfolios_by_type(
        cls, unique_id: str, portfolio_classification: str
    ):
        classification_type = portfolio_classification.lower()

        stock_portfolios_response = await cls.find_one(
            query={"unique_id": unique_id},
            project={f"portfolios.{classification_type}": 1, "_id": 0},
        )

        classification_response = stock_portfolios_response.get("portfolios").get(
            classification_type
        )

        if classification_response is None:
            response = {f"{classification_type}": {}}
            return response

        portfolio_result = stock_portfolios_response.get("portfolios").get(
            f"{classification_type}"
        )

        stock_portfolios_response = {
            f"{classification_type}": portfolio_result,
        }

        return stock_portfolios_response

    @classmethod
    async def get_portfolios_by_type_and_region(
        cls, unique_id: str, portfolio_classification: str, region: str
    ):
        classification_type = portfolio_classification.lower()
        region_portfolios = region.lower()

        stock_portfolios_response = await cls.find_one(
            query={"unique_id": unique_id},
            project={
                f"portfolios.{classification_type}.{region_portfolios}": 1,
                "_id": 0,
            },
        )

        portfolios_response = (
            stock_portfolios_response.get("portfolios")
            .get(classification_type, {})
            .get(region_portfolios)
        )

        if portfolios_response is None:
            response = {f"{classification_type}": {}}
            return response

        portfolio_result = (
            stock_portfolios_response.get("portfolios")
            .get(f"{classification_type}")
            .get(f"{region_portfolios}")
        )

        stock_portfolios_response = {
            f"{classification_type}": {
                f"{region_portfolios}": portfolio_result,
            }
        }

        return stock_portfolios_response


'''
This script demonstrate how to optimize the hyperparameters for a
Gaussian process based on the marginal likelihood. Optimization is
performed in two ways, first with a grid search method and then with a
downhill simplex method.
'''
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fmin
from rbf.gauss import gpexp
np.random.seed(3)

# True signal which we want to recover. This is a exponential function
# with mean=0.0, variance=2.0, and time-scale=0.1. For graphical
# purposes, we will only estimate the variance and time-scale.
a,b,c = 0.0, 2.0, 0.1
gp  = gpexp((a, b, c))

n = 500 # number of observations
time = np.linspace(-5.0, 5.0, n)[:,None] # observation points
data = gp.sample(time) # signal which we want to describe

# find the optimal hyperparameter with a brute force grid search
b_search = 10**np.linspace(-2, 2, 30)
c_search = 10**np.linspace(-2, 1, 30)
likelihoods = np.zeros((30, 30))
for i, b_test in enumerate(b_search):
  for j, c_test in enumerate(c_search):
    gp = gpexp((0.0, b_test, c_test))
    likelihoods[i, j] = gp.likelihood(time, data)

# find the optimal hyperparameters with a positively constrained
# downhill simplex method
def fmin_pos(func, x0, *args, **kwargs):
  '''fmin with positivity constraint'''
  def pos_func(x, *blargs):
    return func(np.exp(x), *blargs)

  out = fmin(pos_func, np.log(x0), *args, **kwargs)
  out = np.exp(out)
  return out

def objective(x,t,d):
  '''objective function to be minimized'''
  gp = gpexp((0.0,x[0],x[1]))
  return -gp.likelihood(t,d)

# maximum likelihood estimate
b_mle, c_mle = fmin_pos(objective, [1.0, 1.0], args=(time, data))

# plot the results
fig, axs = plt.subplots(2, 1, figsize=(6, 6))
ax = axs[0]
ax.grid(True)
ax.plot(time[:,0], data, 'k.', label='observations')
ax.set_xlim((-5.0, 5.0))
ax.set_ylim((-5.0, 7.0))
ax.set_xlabel('time', fontsize=10)
ax.set_ylabel('observations', fontsize=10)
ax.tick_params(labelsize=10)
ax.text(0.55, 0.925, r"$\bar{u}(x) = a$", transform=ax.transAxes)
ax.text(0.55, 0.85, r"$C_u(x,x') = b\times\exp(-|x - x'|/c)$", transform=ax.transAxes)
ax.text(0.55, 0.775, r"$a = %s$, $b = %s$, $c = %s$" % (a, b, c), transform=ax.transAxes)

ax = axs[1]
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('variance ($b$)', fontsize=10)
ax.set_ylabel('time-scale ($c$)', fontsize=10)
ax.tick_params(labelsize=10)
p = ax.contourf(b_search, c_search, likelihoods.T, np.linspace(-5000.0, -200.0, 11), cmap='viridis')
cbar = plt.colorbar(p, ax=ax)
ax.plot([b], [c], 'ro', markersize=10, mec='none', label='truth')
ax.plot([b_mle], [c_mle], 'ko', markersize=10, mec='none', label='max likelihood')
ax.legend(fontsize=10, loc=2)
cbar.set_label('log likelihood', fontsize=10)
cbar.ax.tick_params(labelsize=10)
ax.grid(True)
plt.tight_layout()
plt.savefig('../figures/gauss.f.png')
plt.show()


from tkinter import *
from googletrans import Translator
#from tkinter import messagebox
import webbrowser
window = Tk()
window.geometry("1600x900")
window.title("Translator")

main_menu = Menu()
window.config(menu=main_menu)

def programmer():
	programmer = Toplevel(window)
	programmer.geometry("900x600")
	programmer.title("About Programmer")
	programmer_l = Label(programmer,text="About  Pogrammer",font="Stencil 20")
	programmer_l.pack()
	programmer_about = Label(programmer,text="My name is Sunnatjon, my surname is Arslonov.\n I'm 16 years old. I know HTML-70%, CSS-30%, BOOTSTRAP-20%, PYTHON-50%. \nI mostly write codes in Python. I want to become a FullStack developer \nin the future",font="Franklin 15 bold")
	programmer_about.pack(padx="50",pady="70")
	programmer_page = Label(programmer,text="👇🏻 My page on social networks 👇🏻",font="Franklin 18 bold")
	programmer_page.pack()

	def tg_link():
		url = "https://t.me/sunnatjonpy"
		webbrowser.open_new(url)
	def ins_link():
		url = "https://www.instagram.com/sunnatjon.py/"
		webbrowser.open_new(url)
	def fc_link():
		url = "https://www.facebook.com/profile.php?id=100088538125935"
		webbrowser.open_new(url)
	tg= Button(programmer,text="Telegram",command=tg_link).place(x="200",y="370",width="100",height="50")
	ins= Button(programmer,text="Instagram",command=ins_link).place(x="400",y="370",width="100",height="50")
	fc = Button(programmer,text="Facebook",command=fc_link).place(x="600",y="370",width="100",height="50")

def tg_linkk():
		url = "https://t.me/mohirdev22"
		webbrowser.open_new(url)

def about():
	about = Toplevel(window)
	about.geometry("900x400")
	about.title("About the Program")
	about_l = Label(about,text="About  the  Program",font="Stencil 20")
	about_l.pack()
	program_about = Label(about,text="The program is written using the Python programming language,\n and this program is a Desktop program. This program is compiled using\n Python's <Tkinter>, <Googletrans> modules.\n The code of the program is more than 250, in which various functions are located ",font="Franklin 15 bold")
	program_about.pack(padx="50",pady='110')

def prog_func():
	func = Toplevel(window)
	func.geometry("900x400")
	func.title("Function the Program")
	func_l = Label(func,text="Function  the  Program",font="Stencil 20")
	func_l.pack()
	func_about = Label(func,text="The main function of the program is to translate the text. \nYou can select the language from which to translate by pressing\n the <From which language> button and select the language to be translated \nby pressing the <To which language> button,\n then enter text. You can get information by choosing one of the menus.",font="Franklin 15 bold")
	func_about.pack(padx="50",pady="100")

def use():
	using = Toplevel(window)
	using.geometry("1200x500")
	using.title("Use the Program")
	using_l = Label(using,text="Using  the  Program",font="Stencil 20")
	using_l.pack()
	using_1_button = Label(using,text="1.FROM WHiCH LANGUAGE  button    --- ",font="Arial 14 bold")
	using_1_button_t = Label(using,text="With this button, you choose from which language you want to translate",font="Franklin 13 ")
	using_2_button = Label(using,text="2.TO WHICH LANGUAGE button    --- ",font="Arial 14 bold")
	using_2_button_t = Label(using,text="With this button you can choose which language to translate to",font="Franklin 13")
	using_input = Label(using,text="3.INPUT    --- ",font="Arial 14 bold")
	using_input_t = Label(using,text="You enter the text to be translated through the input section",font="Franklin 13")
	using_trans_button = Label(using,text="4.TRANSLATE button    --- ",font="Arial 14 bold")
	using_trans_button_t = Label(using,text="With this button you can click to translate the text",font="Franklin 13")
	using_consol = Label(using,text="5.CONSOL    --- ",font="Arial 14 bold")
	using_consol_t = Label(using,text="This section is a text translation window",font="Franklin 13 ")
	using_1_button.place(x="30",y="100")
	using_1_button_t.place(x="430",y="105")
	using_2_button.place(x="30",y="140")
	using_2_button_t.place(x="390",y="145")
	using_input.place(x="30",y="180")
	using_input_t.place(x="180",y="185")
	using_trans_button.place(x="30",y="220")
	using_trans_button_t.place(x="290",y="225")
	using_consol.place(x="30",y="260")
	using_consol_t.place(x="205",y="265")

prog_menu = Menu(main_menu, tearoff=0)
about_menu = Menu(main_menu, tearoff=0)
help_menu = Menu(main_menu, tearoff=0)

prog_menu.add_command(label="Programmer",command=programmer)
prog_menu.add_command(label="Connect", command=tg_linkk)

about_menu.add_command(label="About program",command=about)
about_menu.add_command(label="Program fuction",command=prog_func)

help_menu.add_command(label="For questions",command=tg_linkk)
help_menu.add_command(label="Using program",command=use)

main_menu.add_cascade(label="Program",menu=prog_menu)
main_menu.add_cascade(label="About",menu=about_menu)
main_menu.add_cascade(label="Help",menu=help_menu)

lang_src = ["Uzbek","Russian","English","Arabic","German","Turkish","Italian","Spanish","French","Kazakh","Kyrgyz","Hindi","Japan","Korean"]
lang_srcc_v = StringVar()
lang_srcc_v.set("From which language")

lang_dest_v= StringVar()
lang_dest_v.set("To which language")

languages = ["Uz","En","Ru"]
languages_v = StringVar()
languages_v.set("Language")
def language_func(noargument):
	if languages_v.get()=="Uz":
		window.title("Tarjimon")
		prog_name.config(text="Tarjimon")
		prog_menu.add_cascade(label="Dastur")
		lang_srcc_v.set("Qaysi tildan")
		lang_dest_v.set("Qaysi tilga")
		result_btn.config(text="TARJIMA")
	elif languages_v.get()=="En":
		window.title("Translator")
		prog_name.config(text="Translator")
		lang_srcc_v.set("From which language")
		lang_dest_v.set("To which language")
		result_btn.config(text="TRANSLATE")
	elif languages_v.get()=="Ru":
		window.title("Переводчик")
		prog_name.config(text="Переводчик")
		lang_srcc_v.set("с какого языка")
		lang_dest_v.set("какой язык")
		result_btn.config(text="ПЕРЕВОД")

languages_choise = OptionMenu(
    window,
    languages_v,
    *languages,
    command=language_func
)
languages_choise.pack(anchor="ne",padx="50",pady="20")

prog_name = Label(text="TRANSLATOR",fg="blue",width="40",height="3",font="Stencil 40")
prog_name.pack(side=TOP)

get_var = StringVar()

def srcc_choicee(choice):
    choice = lang_srcc_v.get()
    if choice == "Uzbek":
    	srcc_logo.config(text="uz")
    elif choice == "Russian":
    	srcc_logo.config(text="ru")
    elif choice == "English":
    	srcc_logo.config(text="en")
    elif choice =="Arabic":
    	srcc_logo.config(text="ar")
    elif choice == "German":
    	srcc_logo.config(text="de")
    elif choice == "Spanish":
    	srcc_logo.config(text="es")
    elif choice == "Turkish":
    	srcc_logo.config(text="tr")
    elif choice == "Italian":
    	srcc_logo.config(text="it")
    elif choice == "French":
    	srcc_logo.config(text="fr")
    elif choice == "Kazakh":
    	srcc_logo.config(text="kk")
    elif choice == "Kyrgyz":
    	srcc_logo.config(text="ky")
    elif choice == "Hindi":
    	srcc_logo.config(text="hi")
    elif choice == "Japan":
    	srcc_logo.config(text="ja")
    elif choice == "Korean":
    	srcc_logo.config(text="ko")

srcc = OptionMenu(
    window,
    lang_srcc_v,
    *lang_src,
    command=srcc_choicee
)
srcc.place(x="350",y="260",width="200",height="60")

def dest_choicee(choice):
    choice = lang_dest_v.get()
    if choice == "Uzbek":
    	en_logo.config(text="uz")
    elif choice == "Russian":
    	en_logo.config(text="ru")
    elif choice == "English":
    	en_logo.config(text="en")
    elif choice == "Arabic":
    	en_logo.config(text="ar")
    elif choice == "German":
    	en_logo.config(text="de")
    elif choice == "Spanish":
    	en_logo.config(text="es")
    elif choice == "Turkish":
    	en_logo.config(text="tr")
    elif choice == "Italian":
    	en_logo.config(text="it")
    elif choice == "French":
    	en_logo.config(text="fr")
    elif choice == "Kazakh":
    	en_logo.config(text="kk")
    elif choice == "Kyrgyz":
    	en_logo.config(text="ky")
    elif choice == "Hindi":
    	en_logo.config(text="hi")
    elif choice == "Japan":
    	en_logo.config(text="ja")
    elif choice == "Korean":
    	en_logo.config(text="ko")

destt = OptionMenu(
    window,
    lang_dest_v,
    *lang_src,
    command=dest_choicee
)

destt.place(x="950",y="260",width="200",height="60")
#translator = Translator()
#result_word = (translator.translate(get_var.get(), src="uz", dest="ru")).text

words = Entry(font="Berlin 20",textvariable=get_var)
words.place(x="50",y="400",width="1440",height="50")

en_logo = Label(text="",font="Haettenschweiler 20")
en_logo.place(x="25",y="610",width="20")
srcc_logo = Label(text="",font="Haettenschweiler 20")
srcc_logo.place(x="25",y="410",width="20")

def translate_get():
	translator = Translator()
	result_word = (translator.translate(get_var.get(), src=srcc_logo["text"], dest=en_logo["text"])).text
	result_consol_en.config(text=result_word)

result_consol_en = Label(bg="white",font="Berlin 15")
result_consol_en.place(x="50",y="600",width="1440",height="50")

#goto_label = Label(f"From {srcc_logo["text"]} to {en_logo["text"]}")
#goto_label.place(x='550', y="200",width="200",height="60")

result_btn = Button(text="TRANSLATE",bg="ivory",font="Algerian 20",command=translate_get)
result_btn.place(x="600",y="500",width="350",height="75")

window.mainloop()
#ru_logo = Label(text="RU",font="Haettenschweiler 20")
#ru_logo.place(x="25",y="560",width="20")
#result_consol_ru = Label(bg="white",font="Berlin 15")
#result_consol_ru.place(x="50",y="550",width="1440",height="50")


import torch
import torch.nn as nn
import torch.nn.functional as F
from utils.masking import TriangularCausalMask, ProbMask, Tri_sliding

class moving_avg(nn.Module):
    """
    Moving average block to highlight the trend of time series
    """
    def __init__(self, kernel_size, stride):
        super(moving_avg, self).__init__()
        self.kernel_size = kernel_size
        self.avg = nn.AvgPool1d(kernel_size=kernel_size, stride=stride, padding=0)

    def forward(self, x):
        # padding on the both ends of time series
        front = x[:, 0:1, :].repeat(1, (self.kernel_size - 1) // 2, 1)
        end = x[:, -1:, :].repeat(1, (self.kernel_size) // 2, 1)
        x = torch.cat([front, x, end], dim=1)
        x = self.avg(x.permute(0, 2, 1))
        x = x.permute(0, 2, 1)
        return x

class series_decomp(nn.Module):
    """
    Series decomposition block
    """
    def __init__(self, kernel_size):
        super(series_decomp, self).__init__()
        self.moving_avg = moving_avg(kernel_size, stride=1)

    def forward(self, x):
        trend = self.moving_avg(x)
        seasonality = x - trend
        return seasonality, trend

class ConvLayer(nn.Module):
    def __init__(self, c_in):
        super(ConvLayer, self).__init__()
        padding = 1 if torch.__version__>='1.5.0' else 2
        self.downConv = nn.Conv1d(in_channels=c_in,
                                  out_channels=c_in,
                                  kernel_size=3,
                                  padding=padding,
                                  padding_mode='circular')
        self.norm = nn.BatchNorm1d(c_in)
        self.activation = nn.ELU()
        self.maxPool = nn.MaxPool1d(kernel_size=3, stride=2, padding=1)

    def forward(self, x):
        x = self.downConv(x.permute(0, 2, 1))
        x = self.norm(x)
        x = self.activation(x)
        x = self.maxPool(x)
        x = x.transpose(1,2)
        return x

class EncoderLayer(nn.Module):
    def __init__(self, attn, attention, enc_lstm, step_len, d_model, d_ff=None, dropout=0.05, activation="relu"):
        super(EncoderLayer, self).__init__()
        d_ff = d_ff or 4*d_model
        self.attn = attn
        self.attention = attention
        self.step = step_len
        self.conv1 = nn.Conv1d(in_channels=d_model, out_channels=d_ff, kernel_size=1)
        self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_model, kernel_size=1)

        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.dropout = nn.Dropout(dropout)
        self.activation = F.relu if activation == "relu" else F.gelu

        self.lstm = nn.GRU(input_size=d_model, hidden_size=d_model, num_layers=enc_lstm)
        self.lstm1 = nn.GRU(input_size=d_model, hidden_size=d_model, num_layers=enc_lstm)
        self.decomp1 = series_decomp(step_len)
        self.decomp2 = series_decomp(step_len)

    def forward(self, x, attn_mask=None):
        '''
        if self.attn == 'full':
            attn_mask = TriangularCausalMask(B, L, device=x.device)
        elif self.attn == 'long':
            attn_mask = Tri_sliding(B, L, H, device=x.device).mask
        else:
            attn_mask = TriangularCausalMask(B, L, device=x.device)
        '''
        new_x = self.attention(
            x, x, x, attn_mask
        )
        y1, hidden = self.lstm(x.permute(1, 0, 2).to(torch.float32))
        y1 = y1.permute(1, 0, 2)
        y1 = self.dropout(torch.softmax(y1, dim=-1)*x) + x
        x1 = self.dropout(new_x + y1)

        x, trend1 = self.decomp1(x1)
        y = self.norm1(x + self.dropout(new_x))
        y = self.dropout(self.activation(self.conv1(y.transpose(-1,1))))
        y = self.dropout(self.conv2(y).transpose(-1,1))
        res, trend2 = self.decomp2(x + y)
        trend = trend1 + trend2
        y1, _ = self.lstm1(trend.permute(1, 0, 2))
        y1 = y1.permute(1, 0, 2)
        res = (res + y1)/2
        return res, hidden

class Encoder(nn.Module):
    def __init__(self, attn_layers, conv_layers=None, norm_layer=None):
        super(Encoder, self).__init__()
        self.attn_layers = nn.ModuleList(attn_layers)
        self.conv_layers = nn.ModuleList(conv_layers) if conv_layers is not None else None
        self.norm = norm_layer

    def forward(self, x, attn_mask=None):
        # x [B, L, D]
        attns = []
        if self.conv_layers is not None:
            for attn_layer, conv_layer in zip(self.attn_layers, self.conv_layers):
                x, hidden = attn_layer(x, attn_mask=attn_mask)
                x = conv_layer(x)
            x, hidden = self.attn_layers[-1](x,  attn_mask=attn_mask)
        else:
            for attn_layer in self.attn_layers:
                x, hidden = attn_layer(x, attn_mask=attn_mask)
        if self.norm is not None:
            x = self.norm(x)
        return x, hidden