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

version="0.3.5"

# Plugins/Billy/__init__.py
#
# This file is a plugin for EventGhost.
# Copyright © 2005-2020 EventGhost Project <http://www.eventghost.net/>
#
# EventGhost is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 2 of the License, or (at your option)
# any later version.
#
# EventGhost is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with EventGhost. If not, see <http://www.gnu.org/licenses/>.

eg.RegisterPlugin(
    name = "Billy Player",
    author = "Pako",
    version = version,
    kind = "program",
    guid = "{12CD9AEB-691F-4EBB-B1F5-10A5FF776429}",
    description = (
        'Adds actions to control the Billy audio player. \n\n
'
        '
ATTENTION !
Properly works only for beta version 1.04b of Bi'
        'lly !'
        '
The plugin will work with older versions of Billy only in limited '
        'mode!
'
    ),
    createMacrosOnAdd = True,
    url = "http://www.eventghost.net/forum/viewtopic.php?t=537",
    icon = (
        "R0lGODlhEAAQAPcAAAQCBMz+tPz+/AAAABkEFSEAAAAAAAAAAGECDR4AAAAAAAAAAAAADQ"
        "AAABUAAAAAAA0AyAAAHgAAEAAAagAAXQIABAAAhQAAAwAAFwMAAAAAAAAAAIgBAeIAABIA"
        "AAAAAOkaGeUAAIEAAHwAAAAAEQAAAAEAAAAAAFYA0QAAOQAAJQAAW5AVhOEAABIAAAAAAH"
        "MViAAAFgAAKAAAW7ANFeIAABIAAAAAABgNTe4AAJAAAHwAAHDIlQUeOZEQJXxqW/9dYP8E"
        "QP+FOP8DAG0X/gUAEZEAHnwAAIUBUOcAQIEAOHwAAAAZ2wAAGhUAJQAAW1gR/AMA8gAAEg"
        "AAAHABEIUA9xkARQAAAIgHhEIAABUAAAAAAAAI/gAAEQAAHgAAAH4JhAAAAAAAAMAAAAAi"
        "AAAcAAABAACSAP8ATf8AAP8Awf8AAP+IBP/jAP8SAP8AAADQ4gA8BAAlAABbAABIcQBB1Q"
        "A4NgAAfgBNAAAAABUAAAAAAMDBYOIAnhIAgAAAfNJI+ObkVIESFnwAAIhGAELQABUmAABb"
        "AEpIB+NBAIE4AHwAAMAFAHYAAFAAAAAAAIj+AEIRUAEeFgAAAGtQAABAAAA4AAAAAPyJAO"
        "FaABIAAAAAAADYAADjAAASAAAAAPiFAPcrABKDAAB8ABgAaO4AnpAAgHwAfHAA/wUA/5EA"
        "/3wA//8AYP8Anv8AgP8AfG0pIAW3AJGSAHx8AEr4IPRUAIAWAHwAAAA0SABk6xWDEgB8AA"
        "D//wD//wD//wD//4gAAEIAABUAAAAAAAC8BAHj5QASEgAAAAA0vgBkOwCDTAB8AFf45PT3"
        "5IASEnwAAOgYd+PuEBKQTwB8AIgAGEK35RWSEgB8ABH/NAD/ZAD/gwD/fAT4qABU5QAWEg"
        "AAAAM03gBk/wCD/wB8fwAAiADl5QASEgAAAADn+ABkVACDFgB8AASINABkZACDgwB8fAMB"
        "+AAAVAAAFgAAAAAxiQAAWgAAAAAAAAAAAAAAAAAAAAAAAAoA6QAAzgAARwAAACH5BAEAAA"
        "IALAAAAAAQABAABwhEAAUIHEiwoMGDBgEoXMhQIUEAASJKnAjg4cSLASoOhIhRokaBHDtm"
        "tChy5MaSJkGi/CggZEeWLjHCXPmwoU2EOHMeDAgAOw=="
    ),
)

import os
from shutil import copyfile
from win32gui import GetWindowText, MessageBox
from threading import Thread
from time import sleep
from win32api import ShellExecute,GetSystemMetrics

FindBilly = eg.WindowMatcher(
    u'Billy.exe',
    u'{*}Billy{*}',
    u'TAppBilly',
    None,
    None,
    1,
    True,
    0.0,
    0
)

#===============================================================================

class MyDirBrowseButton(eg.DirBrowseButton):
    def GetTextCtrl(self):          #  now I can make build-in textCtrl non-editable !!!
        return self.textControl     #

class Text:
  #  filemask = "Billy.exe|Billy.exe|All-Files (*.*)|*.*"
    label1 = "Path to Billy.exe:"
    label2 = "Path to Start_Billy_Events.exe and Stop_Billy_Events.exe:"
    text0="Couldn't find file Stop_Billy_Events.exe !"
    text1 = "Couldn't find Billy window !"
    text2 = "Couldn't find file %s !"
    lbl_start_stop = 'Activate/deactivate event sender by actions "Run or restore/Exit"'
    browseTitle = "Selected folder:"
    toolTipFolder = "Press button and browse to select folder ..."
    boxTitle = 'Folder "%s" is incorrect'
    boxMessage1 = 'Missing file %s !'
    boxMessage2 = 'Missing file %s or %s !'
#===============================================================================

class Billy(eg.PluginClass):

    text=Text
    BillyPath = None
    path2 = None
    menuDlg = None
    play = True
    force = False
    fav_path = ""

    def Execute(self, exe, path):
        try:
            ShellExecute(
                0,
                None,
                exe,
                None,
                path,
                1
            )
        except:
            self.PrintError(self.text.text2 % exe)

    def PlayFavFromMenu(self):
        dir = self.BillyPath+'\\Favorites'
        dirpath = self.fav_path
        template = dir+'\\%s'

        files = os.listdir(dirpath)
        tmpList = []
        for item in files:
            if item[-4:].lower() in ('.txt', '.m3u', '.pls'):
                tmpList.append(item)
        tmpList.sort()

        if os.path.isfile(template % '!!!!!!!!') :
            os.remove(template % '!!!!!!!!')

        if self.menuDlg is not None:
            sel=self.menuDlg.GetSizer().GetChildren()[0].GetWindow().\
                GetSelection()

        else:
            pass
        keys = u'{Ctrl+%s}' % chr(sel+49)
        self.menuDlg.Close()  #

        #Status "playnig/paused" OR "stopped" ???
        hwnds = FindBilly()
        if len(hwnds) != 0:
            strBillyTitle = GetWindowText(hwnds[0])
            if strBillyTitle[-8:] == ' - Billy':
                playing = True
            else:
                playing = False

            if self.force:
                eg.SendKeys(hwnds[0], '{0}{0}', True)    #Stop current playing track

            if sel < 9 and dirpath == dir:  # 0 ... 8
                eg.SendKeys(hwnds[0], keys, False)
            else:
                copyfile(dirpath+'\\'+tmpList[sel], template % '!!!!!!!!.txt')
                eg.SendKeys(hwnds[0], u'{Ctrl+1}', True) #Load Favorite 1 = Selected Playlist
                os.remove(template % '!!!!!!!!.txt')     #Delete temporary file !!!!!!!!.txt

            if (self.force and playing) or (self.play and not playing):
                sleep(0.5)
                eg.SendKeys(hwnds[0], u'{Space}', True)  #Play track from new playlist
        else:
            self.PrintError(self.text.text1)

    def __init__(self):
        text=Text
        self.AddActionsFromList(ACTIONS)

    def __start__(self, BillyPath=None, path2 = None):
        self.BillyPath = BillyPath
        self.path2 = path2

    def Configure(self, BillyPath=None, path2 = None):
        panel = eg.ConfigPanel(self)
        label1Text = wx.StaticText(panel, -1, self.text.label1)
        label2Text = wx.StaticText(panel, -1, self.text.label2)
        filepathCtrl = MyDirBrowseButton(
            panel,
            size=(410,-1),
            toolTip = self.text.toolTipFolder,
            dialogTitle = self.text.browseTitle,
            buttonText = eg.text.General.browse
        )

        filepathCtrl.GetTextCtrl().SetEditable(False)
        checkBoxCtrl = wx.CheckBox(panel, label="  "+self.text.lbl_start_stop)
        if BillyPath is None:
            BillyPath = eg.folderPath.ProgramFiles+'\\Billy'
            filepathCtrl.SetValue("")
        else:
            filepathCtrl.SetValue(BillyPath)
        filepathCtrl.startDirectory = BillyPath
        if path2:
            checkBoxCtrl.SetValue(True)
            startDir = path2
        else:
        #    checkBoxCtrl.SetValue(False)
            startDir = BillyPath
        startStopPathCtrl = MyDirBrowseButton(
            panel,
            size=(410,-1),

            toolTip = self.text.toolTipFolder,
            dialogTitle = self.text.browseTitle,
            startDirectory=startDir,
            buttonText=eg.text.General.browse
        )
        startStopPathCtrl.GetTextCtrl().SetEditable(False)
        startStopPathCtrl.SetValue(startDir)
        sizerAdd = panel.sizer.Add
        sizerAdd(label1Text, 0, wx.TOP,15)
        sizerAdd(filepathCtrl,0,wx.TOP,3)
        sizerAdd(checkBoxCtrl,0,wx.TOP,30)
        sizerAdd(label2Text,0,wx.TOP,15)
        sizerAdd(startStopPathCtrl,0,wx.TOP,3)
        def OnCheckBox(event = None):
            flag = checkBoxCtrl.GetValue()
            if not flag:
                startStopPathCtrl.SetValue("")
                if event:
                    event.Skip()
            else:
                if event:
                    startStopPathCtrl.OnBrowse()
                    if startStopPathCtrl.GetValue() =="":
                        flag = False
            checkBoxCtrl.SetValue(flag)
            label2Text.Enable(flag)
            startStopPathCtrl.Enable(flag)
        checkBoxCtrl.Bind(wx.EVT_CHECKBOX, OnCheckBox)
        OnCheckBox()

        def OnPathChange(event = None):
            path = filepathCtrl.GetValue()
            path2 = startStopPathCtrl.GetValue()
            flag0 = os.path.exists(path+"\\Billy.exe")
            if path2 != "":
                flag1 = os.path.exists(path2+"\\Start_Billy_Events.exe")
                flag2 = os.path.exists(path2+"\\Stop_Billy_Events.exe")
                flag = flag0 and flag1 and flag2
            else:
                flag = flag0
            panel.dialog.buttonRow.okButton.Enable(flag)
            panel.isDirty = True
            panel.dialog.buttonRow.applyButton.Enable(flag)
            if event and not flag0:
                MessageBox(
                    panel.GetHandle(),
                    self.text.boxMessage1 % 'Billy.exe',
                    self.text.boxTitle % path,
                        0
                    )
            if path != "":
                filepathCtrl.startDirectory = path
        filepathCtrl.Bind(wx.EVT_TEXT,OnPathChange)
        OnPathChange()

        def OnPath2Change(event = None):
            path = filepathCtrl.GetValue()
            path2 = startStopPathCtrl.GetValue()
            flag0 = os.path.exists(path+"\\Billy.exe")
            if checkBoxCtrl.GetValue():
                flag1 = os.path.exists(path2+"\\Start_Billy_Events.exe")
                flag2 = os.path.exists(path2+"\\Stop_Billy_Events.exe")
                flag = flag1 and flag2
                if event and not flag:
                    MessageBox(
                        panel.GetHandle(),
                        self.text.boxMessage2 % (
                            'Start_Billy_Events.exe',
                            'Stop_Billy_Events.exe'
                        ),
                        self.text.boxTitle % path2,
                        0
                    )
                startStopPathCtrl.startDirectory = path2
            else:
                flag = True
            flg = flag and flag0
            panel.dialog.buttonRow.okButton.Enable(flg)
            panel.isDirty = True
            panel.dialog.buttonRow.applyButton.Enable(flg)
        startStopPathCtrl.Bind(wx.EVT_TEXT,OnPath2Change)
        OnPath2Change()

        while panel.Affirmed():
            if checkBoxCtrl.GetValue():
                startStopPath = startStopPathCtrl.GetValue()
            else:
                startStopPath =None
            panel.SetResult(filepathCtrl.GetValue(),
            startStopPath,
            )
#===============================================================================

class Run(eg.ActionClass):

    def __call__(self, start = True, startPath = ""):
        self.plugin.Execute('Billy.exe',self.plugin.BillyPath)
        if self.plugin.path2:
            self.plugin.Execute('Start_Billy_Events.exe',self.plugin.path2)
#===============================================================================

class Exit(eg.ActionClass):

    def __call__(self, stop = False):
        hwnds = FindBilly()
        if len(hwnds) != 0:
            eg.SendKeys(hwnds[0], self.value, True)
        else:
            self.PrintError(self.plugin.text.text1)
        if self.plugin.path2:
            self.plugin.Execute('Stop_Billy_Events.exe',self.plugin.path2)
#===============================================================================

class HotKeyAction(eg.ActionClass):
    def __call__(self):
        hwnds = FindBilly()
        if len(hwnds) != 0:
            eg.SendKeys(hwnds[0], self.value, True)
        else:
            self.PrintError(self.plugin.text.text1)
#===============================================================================

# new since 0.3.3:
class GetPlayingFile(eg.ActionClass):

    def __call__(self):
        strBillyTitle = ""
        hwnds = FindBilly()
        if ( hwnds is not None ):
            strBillyTitle = GetWindowText(hwnds[0])
            strBillyTitle = strBillyTitle.replace(" - Billy", "")
        return strBillyTitle
#===============================================================================

class ShowMenu(eg.ActionClass):
    panel = None
    testFlag = False

    class text:
        menuPreview = 'On screen menu preview:'
        menuFont = 'Menu font:'
        txtColour = 'Text colour'
        background = 'Background colour'
        play_label = 'If Billy is stoped, after loading of playlist start play'
        force_label = 'If Billy is playing or paused, interrupt and immediately start new playlist'
        radioPath = 'Folder with playlists/favorites'
        standard = 'Standard (..\\Billy\\Favorites)'
        user = 'User defined'
        dir_err = "Couldn't find Favorites folder !"
        pathdir_err = "Couldn't find folder %s !"
#===============================================================================

    class MenuColourSelectButton(wx.BitmapButton):

        def __init__(
            self,
            id = -1,
            value=(255, 255, 255),
            name="ColourSelectButton",
            pos=wx.DefaultPosition,
            size=(40, wx.Button.GetDefaultSize()[1]),
            style=wx.BU_AUTODRAW,
            validator=wx.DefaultValidator,
        ):
            self.id = id
            self.value = value
            self.name = name
            wx.BitmapButton.__init__(
                self, panel, id, wx.NullBitmap, pos, size, style, validator,name
            )
            self.SetValue(value)
            self.Bind(wx.EVT_BUTTON, self.OnButton)

        def OnButton(self, event):
            colourData = wx.ColourData()
            colourData.SetChooseFull(True)
            colourData.SetColour(self.value)
            for n, colour in enumerate(eg.config.colourPickerCustomColours):
                colourData.SetCustomColour(n, colour)
            colourDlg = wx.ColourDialog(self.GetParent(), colourData)
            colourDlg.SetTitle(self.name)
            if colourDlg.ShowModal() == wx.ID_OK:
                colourData = colourDlg.GetColourData()
                colour=colourData.GetColour().Get()
                self.SetValue(colour)
                listBoxCtrl = event.GetEventObject().GetParent().GetSizer().\
                    GetChildren()[0].GetSizer().GetChildren()[0].GetSizer().\
                    GetChildren()[0].GetSizer().GetChildren()[1].GetWindow()
                btnId = event.GetId()
                if btnId == 1:
                    listBoxCtrl.SetBackgroundColour(colour)
                    listBoxCtrl.Refresh()
                else:
                    listBoxCtrl.SetForegroundColour(colour)
                    listBoxCtrl.Refresh()
                event.Skip()
            eg.config.colourPickerCustomColours = [
                colourData.GetCustomColour(n).Get() for n in range(16)
            ]
            colourDlg.Destroy()

        def GetValue(self):
            return self.value

        def SetValue(self, value):
            self.value = value
            w, h = self.GetSize()
            image = wx.EmptyImage(w-10, h-10)
            image.SetRGBRect((1, 1, w-12, h-12), *value)
            self.SetBitmapLabel(image.ConvertToBitmap())
#===============================================================================

    class MenuFontButton(wx.BitmapButton):

        def __init__(
            self,
            fontInfo = None,
            id=-1,
            pos=wx.DefaultPosition,
            size=(40, wx.Button.GetDefaultSize()[1]),
            style=wx.BU_AUTODRAW,
            validator=wx.DefaultValidator,
            name="MenuFontButton",
        ):
            self.window = panel
            self.fontInfo = fontInfo
            wx.BitmapButton.__init__(
                self,
                panel,
                id,
                wx.Bitmap("images/font.png"),
                pos,
                size,
                style,
                validator,
                name
            )
            self.Bind(wx.EVT_BUTTON, self.OnButton)

        def OnButton(self, event):
            data = wx.FontData()
            if self.fontInfo is not None:
                font = wx.FontFromNativeInfoString(self.fontInfo)
                data.SetInitialFont(font)
            else:
                data.SetInitialFont(
                    wx.SystemSettings_GetFont(wx.SYS_ANSI_VAR_FONT )
                )
            dlg = wx.FontDialog(self.window, data)
            if dlg.ShowModal() == wx.ID_OK:
                data = dlg.GetFontData()
                font = data.GetChosenFont()

                listBoxCtrl = event.GetEventObject().GetParent().GetSizer().\
                    GetChildren()[0].GetSizer().GetChildren()[0].GetSizer().\
                    GetChildren()[0].GetSizer().GetChildren()[1].GetWindow()
                for n in range(10,20):
                    font.SetPointSize(n)
                    listBoxCtrl.SetFont(font)
                    if listBoxCtrl.GetTextExtent('X')[1]>20:
                        break
                self.fontInfo = data.GetChosenFont().GetNativeFontInfo().\
                    ToString()
                event.Skip()
            dlg.Destroy()

        def GetValue(self):
            return self.fontInfo

        def SetValue(self, fontInfo):
            self.fontInfo = fontInfo

    def __call__(
        self,
        fore = (0, 0, 0),
        back = (255, 255, 255),
        fontInfo = None,
        play = True,
        force = False,
        folder = False,
        dirpath = ""

    ):

        if self.plugin.menuDlg is not None:
            return
        if dirpath == "":
            dirpath = self.plugin.BillyPath+'\\Favorites'
        if not os.path.exists(dirpath):
            self.PrintError(self.text.pathdir_err % dirpath)
            return

        self.plugin.play = play
        self.plugin.force = force
        self.plugin.fav_path = dirpath
        self.fore = fore
        self.back = back

        files = os.listdir(dirpath)
        choices = []
        for item in files:
            if item[-4:].lower() in ('.txt', '.m3u', '.pls'):

                choices.append(item[:-4])
        choices.sort()
        self.plugin.favList = choices #

        self.plugin.menuDlg = wx.Frame(
                None, -1, 'OS_Menu',
                style=wx.STAY_ON_TOP | wx.SIMPLE_BORDER
            )
        favChoiceCtrl=wx.ListBox(
            self.plugin.menuDlg,
            choices = choices,
            style=wx.LB_SINGLE|wx.LB_NEEDED_SB
        )

        if fontInfo is None:
            font = favChoiceCtrl.GetFont()
            font.SetPointSize(36)
            fontInfo = font.GetNativeFontInfoDesc()
        else:
            font = wx.FontFromNativeInfoString(fontInfo)
        favChoiceCtrl.SetFont(font)
        # menu height calculation:
        h=favChoiceCtrl.GetCharHeight()
        height0 = len(choices)*h+5
        height1 = h*((GetSystemMetrics (1)-20)/h)+5
        height = min(height0,height1)
        # menu width calculation:
        width_lst=[]
        for item in choices:
            width_lst.append(favChoiceCtrl.GetTextExtent(item+' ')[0])
        width = max(width_lst)+8
        if height < height0:
            width += 20 #for vertical scrollbar
        width = min((width,GetSystemMetrics (0)-50))
        self.plugin.menuDlg.SetSize((width+6,height+6))
        favChoiceCtrl.SetDimensions(2,2,width,height,wx.SIZE_AUTO)
        mainSizer =wx.BoxSizer(wx.VERTICAL)
        self.plugin.menuDlg.SetSizer(mainSizer)
        favChoiceCtrl.SetSelection(0)
        self.plugin.menuDlg.SetBackgroundColour((0,0,0))
        favChoiceCtrl.SetBackgroundColour(self.back)
        favChoiceCtrl.SetForegroundColour(self.fore)
        mainSizer.Add(favChoiceCtrl, 0, wx.EXPAND)

        def OnClose(evt):
            self.plugin.menuDlg = None
            self.testFlag = False
            evt.Skip()
        self.plugin.menuDlg.Bind(wx.EVT_CLOSE, OnClose)

        def On2Click(evt):
            if self.plugin.menuDlg is not None:
                self.plugin.PlayFavFromMenu()
                evt.StopPropagation()
        favChoiceCtrl.Bind(wx.EVT_LISTBOX_DCLICK, On2Click)

        self.plugin.menuDlg.Centre()
        if self.testFlag:
            pass
            cm=self.CloseMenu(self.plugin.menuDlg)
            cm.start()
        self.plugin.menuDlg.Show()
#===============================================================================

    class CloseMenu(Thread):

        def __init__(self,dlg):
            Thread.__init__(self)
            self.dlg = dlg

        def run(self):
            sleep(5)
            try:
                self.dlg.Close() #
            except:
                pass
#===============================================================================

    def GetLabel(
        self,
        fore,
        back,
        fontInfo,
        play,
        force,
        folder,
        dirpath
    ):
        return self.name+" "+dirpath

    def Configure(
        self,
        fore = (0, 0, 0),
        back = (255, 255, 255),
        fontInfo = None,
        play = True,
        force = False,
        folder = False,
        dirpath = ""
    ):

#        class MyDirBrowseButton(eg.DirBrowseButton):
#            def GetTextCtrl(self):          #  now I can make build-in textCtrl non-editable !!!
#                return self.textControl     #

        dir = self.plugin.BillyPath+'\\Favorites'
        if not os.path.exists(dir):
            self.PrintError(self.text.dir_err)
            return
#        files = os.listdir(dir)
        if not os.path.exists(dirpath):
            dirpath = dir
        files = os.listdir(dirpath)
        choices = []
        for item in files:
            if item[-4:].lower() in ('.txt', '.m3u', '.pls'):
                choices.append(item[:-4])
        choices.sort()
        self.plugin.favList = choices #

        self.fore = fore
        self.back = back
        self.oldSel=0

    #Controls
        global panel
        panel = eg.ConfigPanel(self)
        previewLbl=wx.StaticText(panel, -1, self.text.menuPreview)
        #Font button
        fontLbl=wx.StaticText(panel, -1, self.text.menuFont)
        fontButton = self.MenuFontButton(fontInfo)
        #Button Text Colour
        foreLbl=wx.StaticText(panel, -1, self.text.txtColour+':')
        foreColourButton = self.MenuColourSelectButton(
            0,
            fore,
            self.text.txtColour
        )
        #Button Background Colour
        backLbl=wx.StaticText(panel, -1, self.text.background+':')
        backColourButton = self.MenuColourSelectButton(
            1,
            back,
            self.text.background
        )
        w1 = panel.GetTextExtent(self.text.menuFont)[0]
        w2 = panel.GetTextExtent(self.text.txtColour+':')[0]
        w3 = panel.GetTextExtent(self.text.background+':')[0]
        w = max(w1,w2,w3)
        listBoxCtrl=wx.ListBox(
            panel,-1,
            size=wx.Size(400-w,130),
            style=wx.LB_SINGLE|wx.LB_NEEDED_SB
        )
        listBoxCtrl.SetBackgroundColour(self.back)
        listBoxCtrl.SetForegroundColour(self.fore)
        if fontInfo is None:
            font = listBoxCtrl.GetFont()
            font.SetPointSize(36)
            fontInfo = font.GetNativeFontInfoDesc()
        else:
            font = wx.FontFromNativeInfoString(fontInfo)
        for n in range(10,20):
            font.SetPointSize(n)
            listBoxCtrl.SetFont(font)
            if listBoxCtrl.GetTextExtent('X')[1]>20:
                break
        playCtrl = wx.CheckBox(panel, -1, '  '+self.text.play_label)
        playCtrl.SetValue(play)
        forceCtrl = wx.CheckBox(panel, -1, '  '+self.text.force_label)
        forceCtrl.SetValue(force)
        rb1 = panel.RadioButton(not folder, self.text.standard, style=wx.RB_GROUP)
        rb2 = panel.RadioButton(folder, self.text.user)
        dirpathCtrl = MyDirBrowseButton(
            panel,
            -1,
            size=(410,-1),
            toolTip = self.plugin.text.toolTipFolder,
            dialogTitle = self.plugin.text.browseTitle,
            startDirectory=dirpath,
            labelText="",
            buttonText=eg.text.General.browse,
        )
        dirpathCtrl.GetTextCtrl().SetEditable(False)
        dirpathCtrl.SetValue(dirpath)
        box = wx.StaticBox(panel,-1,self.text.radioPath)

    #Sizers
        mainSizer=wx.BoxSizer(wx.VERTICAL)
        topSizer = wx.BoxSizer(wx.HORIZONTAL)
        leftSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer = wx.BoxSizer(wx.VERTICAL)
        radioSizer = wx.BoxSizer(wx.HORIZONTAL)
        boxSizer = wx.StaticBoxSizer(box,wx.VERTICAL)

        panel.sizer.Add(mainSizer)
        mainSizer.Add(topSizer)
        topSizer.Add(leftSizer)
        topSizer.Add(rightSizer,0,wx.LEFT,20)
        leftSizer.Add(previewLbl)
        leftSizer.Add(listBoxCtrl,0,wx.TOP,5)
        rightSizer.Add(fontLbl,0,wx.TOP,0)
        rightSizer.Add(fontButton,0,wx.TOP,3)
        rightSizer.Add(foreLbl,0,wx.TOP,10)
        rightSizer.Add(foreColourButton,0,wx.TOP,3)
        rightSizer.Add(backLbl,0,wx.TOP,10)
        rightSizer.Add(backColourButton,0,wx.TOP,3)
        radioSizer.Add(rb1)
        radioSizer.Add(rb2, 0, wx.LEFT|wx.EXPAND,35)
        boxSizer.Add(radioSizer)
        boxSizer.Add(dirpathCtrl,0,wx.TOP,6)
        mainSizer.Add(boxSizer,0,wx.TOP,10)
        mainSizer.Add(playCtrl,0,wx.TOP,10)
        mainSizer.Add(forceCtrl,0,wx.TOP,8)

    #Events handling
        def OnRadioButton(event=None):
            flag = rb2.GetValue()
            dirpathCtrl.Enable(flag)
            if not flag:
                dirpathCtrl.SetValue(dir)
            if event:
                event.Skip()
        rb1.Bind(wx.EVT_RADIOBUTTON, OnRadioButton)
        rb2.Bind(wx.EVT_RADIOBUTTON, OnRadioButton)
        OnRadioButton()

        def OnPathChange(evt = None):
            dirpath = dirpathCtrl.GetValue()
            files = os.listdir(dirpath)
            choices = []
            for item in files:
                if item[-4:].lower() in ('.txt', '.m3u', '.pls'):
                    choices.append(item[:-4])
            choices.sort()
            self.plugin.favList = choices #
            self.plugin.fav_path = dirpath
            listBoxCtrl.Set(choices)
            listBoxCtrl.SetSelection(-1)
            if evt:
                evt.Skip()
        dirpathCtrl.Bind(wx.EVT_TEXT, OnPathChange)
        OnPathChange()

        def OnClick(evt):
            listBoxCtrl.SetSelection(-1)
            evt.StopPropagation()
        listBoxCtrl.Bind(wx.EVT_LISTBOX, OnClick)

        # re-assign the test button
        def OnButton(event):
            self.testFlag = True
            event.Skip()
        panel.dialog.buttonRow.testButton.Bind(wx.EVT_BUTTON, OnButton)

    #On close panel
        while panel.Affirmed():
            panel.SetResult(
            foreColourButton.GetValue(),
            backColourButton.GetValue(),
            fontButton.GetValue(),
            playCtrl.GetValue(),
            forceCtrl.GetValue(),
            rb2.GetValue(),
            dirpathCtrl.GetValue(),
        )
#===============================================================================

class MoveCursor(eg.ActionClass):

    def __call__(self):
        if self.plugin.menuDlg is not None:
            max=len(self.plugin.favList)
            if max > 0:
                sel=self.plugin.menuDlg.GetSizer().GetChildren()[0].\
                    GetWindow().GetSelection()
                if sel == eval(self.value[0]):
                    sel = eval(self.value[1])
                self.plugin.menuDlg.GetSizer().GetChildren()[0].GetWindow().\
                    SetSelection(sel+self.value[2])
#===============================================================================

class OK_Btn(eg.ActionClass):

    def __call__(self):
        if self.plugin.menuDlg is not None:
            self.plugin.PlayFavFromMenu()
#===============================================================================

class Cancel_Btn(eg.ActionClass):

    def __call__(self):
        if self.plugin.menuDlg is not None:
            self.plugin.menuDlg.Close()
#===============================================================================

ACTIONS = (
    (Run,"Run","Run or Restore","Run Billy with its default settings or restore window.", None),
    (Exit,"ExitBilly","Exit Billy","Exit Billy.",u'{Esc}'),
    ( eg.ActionGroup, 'Main', 'Main', 'Adds actions to main control Billy',(
        (HotKeyAction,"Play","Play","Play selected file.",u'{Enter}'),
        (HotKeyAction,"Pause","Pause","Pause.",u'{0}'),
        (HotKeyAction,"PausePlay","Pause/Play","Pause/Play.",u'{Space}'),
        (HotKeyAction,"Stop","Stop","Stop.",'{0}{0}'),
        (HotKeyAction,"Next","Next","Next.",u'{Tab}'),
        (HotKeyAction,"Previous","Previous","Previous.",u'{Shift+Tab}'),
        (HotKeyAction,"ToStart","Jump to start","Jump to start of playing file.",u'{Backspace}'),
        #(HotKeyAction,"SeekLeft","Seek Left","Seek in track left.",u'{Left}'),
        #(HotKeyAction,"SeekRight","Seek Right","Seek in track Right.",u'{Right}'),
        #(HotKeyAction,"SeekLeftBig","Seek Left Big","Seek 60s in track left.",u'{Ctrl+Left}'),
        #(HotKeyAction,"SeekRightBig","Seek Right Big","Seek 60s in track Right.",u'{Ctrl+Right}'),
        #(HotKeyAction,"VolumeUp","Volume Up","Volume Up.",u'{Add}'),
        #(HotKeyAction,"VolumeDown","Volume Down","Volume Down.",u'{Subtract}'),
        )),
    ( eg.ActionGroup, 'Playlist', 'Playlist', 'Adds actions to control of playlist Billy',(
        (HotKeyAction,"TogglePlayMode","Toggle play mode","Toggle play mode.",u'{F9}'),
        (HotKeyAction,"ToggleViewMode","Toggle view mode","Toggle layout list all.",u'{F8}'),
        (HotKeyAction,"OpenFolder","Open Folder","Open a dir with music files.",u'{F4}'),
        (HotKeyAction,"AddFolder","Add Folder","Add a dir with music files.",u'{F3}'),
        (HotKeyAction,"AddFile","Add File(s)","Add File(s).",u'{Ctrl+L}'),
        (HotKeyAction,"AddURL","Add Internet radio stream","Add Internet radio stream.",u'{Ctrl+R}'),
        (HotKeyAction,"OpenPlaylist","Open Playlist","Load Billy Playlist.",u'{Ctrl+O}'),
        (HotKeyAction,"SavePlaylist","Save Playlist","Save Playlist.",u'{Ctrl+S}'),
        #(HotKeyAction,"MoveItemsUp","Move Items Up","Move Items Up.",u'{Ctrl+Up}'),
        #(HotKeyAction,"MoveItemsDown","Move Items Down","Move Items Down.",u'{Ctrl+Down}'),
        #(HotKeyAction,"SelectAll","Select All","Select All.",u'{Ctrl+A}'),
        (HotKeyAction,"Remove","Remove file from list","Remove file from list.",u'{Del}'),
        (HotKeyAction,"Delete","Delete file to recycle bin","Delete file to recycle bin.",u'{Shift+Del}'),
        (HotKeyAction,"ClearList","Clear list","Clear list.",u'{Ctrl+N}'),
        (HotKeyAction,"CheckNewFiles","Check for new files","Check for new files.",u'{F5}'),
        #(HotKeyAction,"SelectPlayingItem","Select playing item","Select playing item.",u';'),
        (HotKeyAction,"Queue","Queue","Add selected file to Queue.",u'{Ins}'),
        (HotKeyAction,"CropQueued","Crop selected or queued items","Crop selected or queued items.",u'{Ctrl+Del}'),
        (HotKeyAction,"ClearHistory","Clear shuffle/queue history","Clear shuffle/queue history.",u'{Shift+Ctrl+C}'),
        #(HotKeyAction,"RemoveMissing","Remove missing files from list","Remove missing files from list.",u'{Alt+Del}'),
        (HotKeyAction,"CutEntry","Cut playlist entry","Cut playlist entry.",u'{Ctrl+X}'),
        (HotKeyAction,"CopyEntry","Copy playlist entry","Copy playlist entry.",u'{Ctrl+C}'),
        (HotKeyAction,"PasteEntry","Paste playlist entry","Paste playlist entry.",u'{Ctrl+V}'),
        (HotKeyAction,"EditEntry","Edit playlist entry","Edit playlist entry.",u'{Shift+F2}'),
        )),
    ( eg.ActionGroup, 'Extras', 'Extras', 'Adds extra actions to control Billy',(
        (HotKeyAction,"Properties","Properties","Properties or multiple filename renamer (on multiple selection).",u'{F2}'),
        (HotKeyAction,"Explore","Explore","Open Explorer in file folder.",u'{Ctrl+E}'),
        (HotKeyAction,"Find","Find","Find file in active list.",u'{Ctrl+F}'),
        (HotKeyAction,"Record","Record Internet Radio","Record.",u'{Multiply}'),
        #(HotKeyAction,"Restore","Restore","Maximize, Restore.",u'{F12}'),
        (HotKeyAction,"Minimize","Minimize to Tray","Minimize to tray.",u'{F11}'),
        #(HotKeyAction,"SoftMute","Soft Mute","Soft mute (30% of volume).",u'{Pause}'),
        #(HotKeyAction,"ExploreApplPath","Explore Billy Directory","Explore from Billy Directory.",u'{Alt+Ctrl+E}'),
        (HotKeyAction,"ResetMixer","Reset Windows Mixer","Reset Windows Mixer.",u'{Ctrl+Space}'),
        #(HotKeyAction,"PlayingLength","Playing Length","Calculate total playlist time.",u'{Ctrl+Alt+T}'),
        #(HotKeyAction,"SleepTimer","Sleep Timer","Sleep Timer.",u'{Alt+T}'),
        (HotKeyAction,"Settings","Settings","Settings menu Billy.",u'{F6}'),
        (GetPlayingFile,"GetPlayingFile","Get Currently Playing File","Gets the name of currently playing file.", None),
        )),
    ( eg.ActionGroup, 'Favorites', 'Favorites', 'Adds actions to control Favorites of Billy',(
        (HotKeyAction,"AddPlistToFav","Add playlist to favorites","Add playlist to favorites.",u'{Ctrl+D}'),
        (HotKeyAction,"OrganizeFav","Organize favorites","Organize favorites.",u'{Ctrl+B}'),
        (HotKeyAction,"LoadFav1","Load Favorite 1","Load Favorite playlist 1.",u'{Ctrl+1}'),
        (HotKeyAction,"LoadFav2","Load Favorite 2","Load Favorite playlist 2.",u'{Ctrl+2}'),
        (HotKeyAction,"LoadFav3","Load Favorite 3","Load Favorite playlist 3.",u'{Ctrl+3}'),
        (HotKeyAction,"LoadFav4","Load Favorite 4","Load Favorite playlist 4.",u'{Ctrl+4}'),
        (HotKeyAction,"LoadFav5","Load Favorite 5","Load Favorite playlist 5.",u'{Ctrl+5}'),
        (HotKeyAction,"LoadFav6","Load Favorite 6","Load Favorite playlist 6.",u'{Ctrl+6}'),
        (HotKeyAction,"LoadFav7","Load Favorite 7","Load Favorite playlist 7.",u'{Ctrl+7}'),
        (HotKeyAction,"LoadFav8","Load Favorite 8","Load Favorite playlist 8.",u'{Ctrl+8}'),
        (HotKeyAction,"LoadFav9","Load Favorite 9","Load Favorite playlist 9.",u'{Ctrl+9}'),
        (eg.ActionGroup, 'Menu', 'Menu', 'Menu',(
            (ShowMenu, 'ShowMenu', 'Show menu', 'Show on screen menu.', None),
            (MoveCursor, 'MoveDown', 'Cursor down', 'Cursor down.', ('max-1', '-1', 1)),
            (MoveCursor, 'MoveUp', 'Cursor up', 'Cursor up.', ('0', 'max', -1)),
            (OK_Btn, 'OK_Btn', 'OK', 'OK button pressed.', None),
            (Cancel_Btn, 'Cancel_Btn', 'Cancel', 'Cancel button pressed.', None),
        )),
    )),
)
#===============================================================================


""""
Purpose: Display IP information to OLED on "Adafruit Radio+OLED bonnet"
Organization: San Diego Wildlife Association: Conservation Technology Lab (CTL)
Author: Trent Moca
Date: 11/10/22
"""

# Import Python System Libraries
import signal
import subprocess

# Import Blinka Libraries
import busio
from digitalio import DigitalInOut
import board
# Import the SSD1306 module.
import adafruit_ssd1306

def configDisplay():
    # Create the I2C interface.
    i2c = busio.I2C(board.SCL, board.SDA)

    # 128x32 OLED Display
    reset_pin = DigitalInOut(board.D4)
    display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, reset=reset_pin)
    # Clear the display
    display.fill(0)
    display.show()
    return display

display = configDisplay()

# returns hostname, first ip, and second ip
def getHostData():  # derived from scrubcam "little_readout.py"
    cmd = "hostname"
    hostname = subprocess.check_output(cmd, shell=True).decode("utf-8")
    cmd = "hostname -I | cut -d' ' -f1"
    ip1 = subprocess.check_output(cmd, shell=True).decode("utf-8")
    cmd = "hostname -I | cut -d' ' -f2"
    ip2 = subprocess.check_output(cmd, shell=True).decode("utf-8")
    return hostname, ip1, ip2

def getIP1():
    host, i1, i2 = getHostData()
    return i1

def getHost():
    host, i1, i2 = getHostData()
    return host

def displayInternetData():
    spacing = int(display.height/2)

    display.fill(0)
    ip1 = getIP1()
    hostname = getHost()
    host_text = "Host: " + hostname
    display.text(host_text, 0, 0, 1)
    ip1_text = 'IP1: ' + getIP1()
    display.text(ip1_text, 0, spacing, 1)
    display.show()
    return ip1

def refreshInterrupt(signum, _):
    display.fill(0)
    display.show()
    displayInternetData()

if __name__ == '__main__':
    signal.signal(signal.SIGALRM, refreshInterrupt)
    signal.setitimer(signal.ITIMER_REAL, 3, 3)

    display = configDisplay()

    displayInternetData()
    while(True):
        True


import jsonschema
import requests

from tests.conftest import base_url, register_new_valid_user, register_new_invalid_user
from utils import load_schema

def test_successful_registration():
    schema = load_schema('register_user.json')

    response = requests.post(
        url=f'{base_url}/register',
        json=register_new_valid_user,
    )

    jsonschema.validate(response.json(), schema)
    assert (
        response.status_code == 200
    ), f"Status code {response.status_code} is incorrect"

def test_unsuccessful_registration():
    response = requests.post(url=f'{base_url}/register', json=register_new_invalid_user)

    assert (
        response.status_code == 400
    ), f"Status code {response.status_code} is incorrect"
    assert (
        response.json()['error'] == 'Missing password'
    ), f"Error message {response.json()['error']} is incorrect"


class Solution:
    # @param A : array of ints
    # @return nested array of arrays
    def permute(self, A):
        def permute_helper(subarray, placeholder, uniques):
            if len(placeholder) == len(A):
                uniques.append(placeholder)
                return uniques

            for idx in range(len(subarray)):
                # B/c we're breaking SA down, eventually 0 and -1 will match
                if len(subarray) > 1 and subarray[idx] == subarray[idx - 1]:
                    # If our eval isn't top level, cont
                    if not idx == 0:
                        continue
                local_placeholder = placeholder + [subarray[idx]]
                local_subarray = subarray[:idx] + subarray[idx + 1:]
                permute_helper(local_subarray, local_placeholder, uniques)

            return uniques

        # Main
        # Edge Case(s)
        if len(A) == 1: return [A]

        A.sort()
        return permute_helper(A, [], [])

A = [1, 1, 2]
print(Solution().permute(A))


def prime_factors(n):
    if type(n) != int:
        raise TypeError("argument must be of type 'int'")
    if n < 2:
        return []
    factors = []
    while n % 2 == 0:
        n //= 2
        factors.append(2)
    i = 3
    limit = int(n**0.5 + 1)
    while i <= limit:
        if n % i == 0:
            n //= i
            limit = int(n**0.5 + 1)
            factors.append(i)
            continue
        i += 2
    if n != 1:
        factors.append(int(n))
    return factors

num = 600851475143
print(primefactor(num)[-1])


from typing import List

class LogItem():
    def __init__(
        self,
        date: str,
        workout_type: str,
        title: str,
        tod: str,
        route: str,
        distance_str: str,
        time: str,
        shoes: str,
        warmup_cooldown_str: str,
        temperature: str,
        conditions: str,
        wind: str,
        sleep: str
    ):
        self.date = date
        self.type = workout_type
        self.tod = tod
        self.time = time
        self.route = route
        self.shoes = shoes
        self.distance = self.convert_to_miles(distance_str) if distance_str != "" else 0
        self.warmup_cooldown = self.convert_to_miles(warmup_cooldown_str) if warmup_cooldown_str != "" else 0
        self.temperature = temperature
        self.conditions = conditions
        self.wind = wind
        self.sleep = sleep

    def convert_to_miles(self, distance_str: str) -> float:
        if "miles" in distance_str:
            return self.distance_miles(distance_str)
        elif "kilometers" in distance_str:
            return self.distance_km(distance_str)
        elif "meters" in distance_str:
            return self.distance_meters(distance_str)
        elif "yards" in distance_str:
            return self.distance_yards(distance_str)
        elif distance_str.find(" ") == -1:
            return float(distance_str)
        else:
            raise ValueError("distance_str not of miles, kilometers, meters or yards.")

    def distance_miles(self, distance_str: str) -> float:
        return float(distance_str.replace(" miles", ""))

    def distance_km(self, distance_str: str) -> float:
        kms = float(distance_str.replace(" kilometers", ""))
        return kms * 0.62137119 # 1km = 0.62137119 mile

    def distance_meters(self, distance_str: str) -> float:
        kms = float(distance_str.replace(" meters", ""))/1000
        return kms * 0.62137119 # 1km = 0.62137119 mile

    def distance_yards(self, distance_str: str) -> float:
        yards = float(distance_str.replace(" yards", ""))
        return yards / 1760

class LogEntry():
    def __init__(self, items: List[LogItem]):
        self.items = items

    def add_log(self, item: LogItem) -> None:
        self.items.append(item)


# numbers=[i.strip() for i in open('../../DANE/przyklad.txt').readlines()]
numbers=[i.strip() for i in open('../../DANE/liczby.txt').readlines()]

def is_prime(n):
    for i in range(2, n):
        if n%i==0:
            return False
    return True

primes_with_prime_reflections=[i for i in numbers if is_prime(int(i)) and is_prime(int(i[::-1]))]
for n in primes_with_prime_reflections:
    print(n, end='\n')


text = input('input text: ')
vowels = {'а', 'я', 'о', 'у', 'ю', 'е', 'є', 'и', 'і', 'ї'}
text = text.replace('.', '')
letters = set()
words = text.split()
for word in words:
    for i in word:
        if i in vowels:
            letters.add(i)
print(letters)
finalvow = set()
for i in letters:
    result = True
    for w in words:
        result = i in w
        if not result:
            break
    if result:
        finalvow.add(i)
print(sorted(finalvow))


import numpy
import rospy
from std_msgs.msg import Float64
from TDLambda import *

class GTDLambda(TDLambda):
    def __init__(self, featureVectorLength, alpha):
        TDLambda.__init__(self, featureVectorLength, alpha)
        self.hWeights = numpy.zeros(featureVectorLength)
        self.priorObservation = -1 #Used only for debugging

    def rho(self):
        #TO be overwritten based on the target policy
        return 1

    def learn(self, lastState, action, newState, observation):

        print("")
        print("!!!!! LEARN  !!!!!!!")
        print("For " + str(self.priorObservation) + " to " + str(observation))
        pred = self.prediction(lastState)
        print("--- Prediction before learning: " + str(pred))
        print("alpha: " + str(self.alpha))
        #print("lastState: " )
        #print(lastState)
        print("action")
        print(action)
        #print("NewState")
        #print(newState)
        print("Observation:" + str(observation))
        #print("Weights before:")
        #print(self.weights)
        zNext = self.cumulant(newState, observation)
        print("Cumulant: " + str(zNext))
        gammaNext = self.gamma(newState, observation)
        print("gammaNext: " + str(gammaNext))
        lam = self.lam(newState, observation)
        print("gammaLast: " + str(self.gammaLast))

        print("lambda: " + str(lam))
        #print("Eligibility before:")
        #print(self.eligibilityTrace)
        rho = self.rho(action)
        print("rho: " + str(rho))
        self.eligibilityTrace = rho * (self.gammaLast * lam * self.eligibilityTrace + lastState)
        #print("Eligibility trace after:")
        #print(self.eligibilityTrace)
        tdError = zNext + gammaNext * numpy.inner(newState, self.weights) - numpy.inner(lastState, self.weights)

        print("tdError: " + str(tdError))

        #print("hWeights before:")
        #print(self.hWeights)

        self.hWeights = self.hWeights + self.alpha * 0.1 * (tdError * self.eligibilityTrace - (numpy.inner(self.hWeights, lastState)) * lastState)

        #print("hWeights after:")
        #print(self.hWeights)

        #print("Weights before:")
        #print(self.weights)

        self.weights = self.weights + self.alpha * (tdError * self.eligibilityTrace - gammaNext * (1-lam)  * (numpy.inner(self.eligibilityTrace, self.hWeights) * newState))

        #print("wEights after: ")
        #print(self.weights)
        pred = self.prediction(lastState)
        print("Prediction after learning: " + str(pred))

        self.gammaLast = gammaNext
        if (self.priorObservation > -1):
            pubPrediction = rospy.Publisher('horde_verifier/GTDpredictedValue', Float64, queue_size=10)
            pubPrediction.publish(pred)
            pubObs = rospy.Publisher('horde_verifier/NormalizedEncoderPosition', Float64, queue_size=10)
            normalizedObs = 3.0 * (self.priorObservation['encoder'] - 510.0) / (1023.0-510.0)
            pubObs.publish(normalizedObs )

        self.priorObservation = observation


import Models.genetic as genetic
from Models.FlappyNet.flappy_net import FlappyNet
from Games.FlappyDot.world import World
import torch
import matplotlib.pyplot as plt

def main():
    flaps = [FlappyNet() for _ in range(50)]
    avg_fits = []

    for gen in range(50):
        print("-------------{}-------------".format(gen))
        for net in flaps:
            train_loop(net)

        fits = [x.fitness for x in flaps]
        print(sorted(fits, reverse=True))
        avg_fit = sum(fits) / len(fits)
        print(avg_fit)
        avg_fits.append(avg_fit)

        new_models = genetic.elite_evolve(flaps, 46, 4, 10, 1, FlappyNet)
        sorted(flaps, key=lambda x: x.fitness)
        if (gen + 1) % 10 == 0:
            torch.save(flaps[-1].state_dict(), 'flap{}.pth.tar'.format(gen))
        # print(len(new_models))
        flaps = new_models

    xs = [i for i in range(len(avg_fits))]
    plt.scatter(xs, avg_fits)

def train_loop(net):
    game = World(net.move)
    fit = game.game_loop()
    net.fitness = fit

if __name__ == "__main__":
    main()


import os
import subprocess
import sys

sys.path.append('hooks/')

import multisite

from charmhelpers.core.hookenv import (
    action_fail,
    config,
    action_set,
)
from utils import (
    pause_unit_helper,
    resume_unit_helper,
    register_configs,
)

def pause(args):
    """Pause the Ceilometer services.
    @raises Exception should the service fail to stop.
    """
    pause_unit_helper(register_configs())

def resume(args):
    """Resume the Ceilometer services.
    @raises Exception should the service fail to start."""
    resume_unit_helper(register_configs())

def promote(args):
    """Promote zone associated with local RGW units to master/default"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not promoting')
        return
    try:
        multisite.modify_zone(zone,
                              default=True, master=True)
        multisite.update_period()
        action_set(
            values={'message': 'zone:{} promoted to '
                    'master/default'.format(zone)}
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable to promote zone:{} '
                    'to master: {}'.format(zone, cpe.output))

def readonly(args):
    """Mark zone associated with local RGW units as read only"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not marking read only')
        return
    try:
        multisite.modify_zone(zone, readonly=True)
        multisite.update_period()
        action_set(
            values={
                'message': 'zone:{} marked as read only'.format(zone)
            }
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable mark zone:{} '
                    'as read only: {}'.format(zone, cpe.output))

def readwrite(args):
    """Mark zone associated with local RGW units as read write"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not marking read write')
        return
    try:
        multisite.modify_zone(zone, readonly=False)
        multisite.update_period()
        action_set(
            values={
                'message': 'zone:{} marked as read write'.format(zone)
            }
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable mark zone:{} '
                    'as read write: {}'.format(zone, cpe.output))

def tidydefaults(args):
    """Delete default zone and zonegroup metadata"""
    zone = config('zone')
    if not zone:
        action_fail('No zone configuration set, not deleting defaults')
        return
    try:
        multisite.tidy_defaults()
        action_set(
            values={
                'message': 'default zone and zonegroup deleted'
            }
        )
    except subprocess.CalledProcessError as cpe:
        action_fail('Unable delete default zone and zonegroup'
                    ': {} - {}'.format(zone, cpe.output))

# A dictionary of all the defined actions to callables (which take
# parsed arguments).
ACTIONS = {
    "pause": pause,
    "resume": resume,
    "promote": promote,
    "readonly": readonly,
    "readwrite": readwrite,
    "tidydefaults": tidydefaults,
}

def main(args):
    action_name = os.path.basename(args[0])
    try:
        action = ACTIONS[action_name]
    except KeyError:
        return "Action %s undefined" % action_name
    else:
        try:
            action(args)
        except Exception as e:
            action_fail(str(e))

if __name__ == "__main__":
    sys.exit(main(sys.argv))


import asyncio
import locale
import os
from asyncio import shield
from datetime import datetime
from data.config import BASE_DIR
import pandas as pd
import pymorphy2
from docx.shared import Mm
from docxtpl import DocxTemplate, InlineImage
from openpyxl import load_workbook
from openpyxl_image_loader import SheetImageLoader
from met import convert_docx_to_pdf

async def get_image(img: str):
    wb = load_workbook(os.path.join(BASE_DIR, 'excel', 'Регистрация.xlsx'))
    sheet = wb['Регистрация']
    image_loader = SheetImageLoader(sheet)
    image = image_loader.get(img)
    image.save(os.path.join(BASE_DIR, 'excel', f'{img}.png'))

async def get_info(x: dict, image: str):
    locale.setlocale(locale.LC_ALL, 'ru_RU')
    doc = DocxTemplate(os.path.join(BASE_DIR, 'data', 'Reshenie_edinstvennogo_uchreditelja.docx'))
    morph = pymorphy2.MorphAnalyzer()
    e = ''
    for word in x.get('ФИО').split(" "):
        e += str("".join(morph.parse(word)[0].inflect({'gent'}).word.title()) + " ")
    context = {
        "Image": InlineImage(doc, os.path.join(BASE_DIR, 'excel', f"V{2 + int(image)}.png"), width=Mm(40)),
        "НАЗВАНИЕ": x.get("Фирма").strip(),
        "ЮР_ГОР": x.get("Юр. Адрес"),
        "ДАТА": datetime.today().strftime("%d %B %Y года."),
        "ФИО": x.get("ФИО"),
        "НОМЕР_УСТАВА": x.get("НОМЕР.УСТАВА"),
        "ИНН": x.get("ИНН"),
        "СУММ_ПРО": x.get("Уст.Кап")
    }

    doc.render(context)
    doc.save(os.path.join(BASE_DIR, 'excel', f'{x.get("Фирма").strip()}.docx'))
    return f'{x.get("Фирма").strip()}.docx'

async def get_image_xlsx():
    print('Получаем фото подписи')
    excel = pd.read_excel(os.path.join(BASE_DIR, 'excel', 'Регистрация.xlsx'), sheet_name='Регистрация').to_dict(
        'index')
    for i in range(len(excel)):
        await shield(get_image(f'V{2 + int(i)}'))
    print('Подписи получены')

async def write_docx():
    print('Записываем данные')
    await asyncio.sleep(3)
    excel = pd.read_excel(os.path.join(BASE_DIR, 'excel', 'Регистрация.xlsx'), sheet_name='Регистрация').to_dict(
        'index')
    for i in range(len(excel)):
        file = await get_info(excel[i], image=str(i))
        print(file)
        await convert_docx_to_pdf.to_tiff(file)

async def main():
    await asyncio.gather(
        asyncio.create_task(get_image_xlsx()),
        asyncio.create_task(write_docx()),
    )

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


import difflib
from operations import OPERATIONS

def parse_input(user_input):
    command = user_input
    data = ''
    for key in OPERATIONS:
        if user_input.strip().lower().startswith(key):
            command = key
            data = user_input[len(command):]
            break
    if data:
        return callback(command)(data.lstrip())
    try:
        return callback(command)()
    except KeyError:
        return find_command(command)

def callback(command):
    return OPERATIONS[command]

def find_command(wrong_command):
    similar_commands = difflib.get_close_matches(wrong_command, OPERATIONS.keys(), n=5, cutoff=0.4)
    if similar_commands:
        return f'{wrong_command} is not found, maybe you mean these: {", ".join(similar_commands)}'
    else:
        return 'Wrong command'


x = 0
inplist = []
while x < 5:
    y = int(input("input a number 1-5 : "))
    if (y > 0) and (y < 6):
        inplist.append(y)
        x = x + 1
    else:
        print("number not 1-5, try again")
print(inplist)
sum = 0
z = 0
while (z < len(inplist)):
    sum = sum + inplist[z]
    z = z + 1
print("sum of numbers is: " + str(sum))


import nltk
import urllib.request
from bs4 import BeautifulSoup
from nltk.corpus import stopwords
import matplotlib.pylab as plt

# Webscrape and frequency analyze the lastest Health News
# Install nltk: $ pip install --user -U nltk
# To load modules open Python shell and enter >>> import nltk >>> nltk.download()

response = urllib.request.urlopen('https://www.healthline.com/health-news')
html = response.read()
#print(html)
soup = BeautifulSoup(html, 'html5lib')
text = soup.get_text(strip = True)
print(text)
# tokenize words
tokens  =  [t for t in text.split()]
print(tokens)

# remove stop words (am, at, the, for) and count frequency
sr = stopwords.words('english')
chars = ["{", "=", "-", "}", "+", "_", "--", ">", "<", "<=", ">=", "—", "var"]
conjunctions = ["but", "But", "and", "or", "nor", "because", "although", "since", "unless", "while", "where"]
conjugations =  ["Is", "is", "Am", "am", "Are", "are", "Was", "was", "Were", "were", "Being", "being", "Been", "been"]
clean_tokens = tokens[:]
for token in tokens:
	if token in sr:
		clean_tokens.remove(token)
# calculate frequency
freq = nltk.FreqDist(clean_tokens)
wordFreqDic = {}
freqDic5 = {}
freqDic10 = {}
freqDic25 = {}
freqDic50 = {}
freqDic100 = {}

# function to remove special characters and conjunnctions
def removeWord(wordList, wordDic):
	for word in wordList:
		if word in wordDic:
			del wordDic[word]

# bucket dictionaries by increasing word frequency
for key,val in freq.items():
	if val >= 5:
		#print(key)
		freqDic5.update({key: val})
		removeWord(chars, freqDic5)
		removeWord(conjunctions, freqDic5)
		removeWord(conjugations, freqDic5)
	elif val >= 10:
		#print(key)
		freqDic10.update({key: val})
		for char in chars:
			if char in chars:
				del freqDic10[char]
	elif val >= 25:
		#print(key)
		freqDic25.update({key: val})
		for char in chars:
			if char in chars:
				del freqDic25[char]
	elif val >= 50:
		#print(key)
		freqDic50.update({key: val})
		for char in chars:
			if char in chars:
				del freqDic50[char]
	elif val >= 100:
		#print(key)
		freqDic100.update({key: val})
		for char in chars:
			if char in chars:
				del freq100[char]
	else:
		pass
	wordFreqDic.update({key: val})
	#print(str(key) + ":" + str(val))

totalDicLen = len(wordFreqDic)
print("Word Occurrences: " + str(totalDicLen))
# bucket out words by increasing  number of occurrences
freqDic5Len = len(freqDic5)
if freqDic5Len > 0:
	over5 = freqDic5Len/totalDicLen
	print("###############")
	print(">= 5 Word Occurrences:")
	print(str(freqDic5Len)+ " words occuring 5 or more times, or " + str(round((100*over5),2)) + "% of the total")
	print(" ")
	print(freqDic5)
	print("---------------------")
freqDic10Len = len(freqDic10)
if freqDic10Len > 0:
	over10 = freqDic10Len/totalDicLen
	print("###############")
	print(">= 10 Word Occurrences:")
	print(str(freqDic10Len)+ " words occuring 10 or more times, or " + str(round((100*over10),2)) + "% of the total")
	print(" ")
	print(freqDic10)
	print("---------------------")
freqDic25Len = len(freqDic25)
if freqDic25Len > 0:
	over25 = freqDic25Len/totalDicLen
	print("###############")
	print(">= 25 Word Occurrences:")
	print(str(freqDic25Len)+ " words occuring 5 or more times, or " + str(round((100*over25),2)) + "% of the total")
	print(" ")
	print(freqDic5)
	print("---------------------")
freqDic50Len = len(freqDic50)
if freqDic50Len > 0:
	over50 = freqDic50Len/totalDicLen
	print("###############")
	print(">= 50 Word Occurrences:")
	print(str(freqDic50Len)+ " words occuring 5 or more times, or " + str(round((100*over50),2)) + "% of the total")
	print(" ")
	print(freqDic50)
	print("---------------------")
freqDic100Len = len(freqDic100)
if freqDic100Len > 0:
	over100 = freqDic100Len/totalDicLen
	print("###############")
	print(">= 100 Word Occurrences:")
	print(str(freqDic100Len)+ " words occuring 5 or more times, or " + str(round((100*over100),2)) + "% of the total")
	print(" ")
	print(freqDic100)
	print("---------------------")
if freqDic5Len == 0 and freqDic10Len == 0 and freqDic25Len == 0 and freqDic50Len == 0 and freqDic100Len == 0:
	print("###############")
	print(" >= 1 Word Occurences: ")
	print(wordFreqDic)
	print("---------------------")

######PLOTS###########
# plot function
def plotWords(wordDic):
	plt.plot(*zip(*sorted(wordDic.items())))
	plt.show()

if freqDic5Len != 0:
	plotWords(freqDic5)
if freqDic10Len != 0:
	plotWords(freqDic10)
if freqDic25Len != 0:
	plotWords(freqDic25)
if freqDic50Len != 0:
	plotWords(freqDic50)
if freqDic100Len != 0:
	plotWords(freqDic100)


import sqlite3
import pandas as pd
import numpy as np
import colorcet as cc
from bokeh.plotting import figure, output_file, show

# Constants
sqlite_file = "FPA_FOD_20170508.sqlite"

latMax = 50.0  # 50 Degrees North
latMin = 25.0  # 25 Degrees North
latRange = latMax-latMin

lonMax = -60.0  # 60 Degrees West
lonMin = -130.0 # 130 Degrees West
lonRange = lonMax-lonMin

width = 1400
height = 800

latBucketNum = int(latRange*10.0)
lonBucketNum = int(lonRange*10.0)

# Create buckets for the data
scaledLatBuckets = [[0.0 for j in range(lonBucketNum)] for i in range(latBucketNum)]
scaledLotBuckets = [[0.0 for j in range(lonBucketNum)] for i in range(latBucketNum)]
sizeSumBuckets = [[0.0 for j in range(lonBucketNum)] for i in range(latBucketNum)]
countBuckets = [[0 for j in range(lonBucketNum)] for i in range(latBucketNum)]
latBuckets = [[0.0 for j in range(lonBucketNum)] for i in range(latBucketNum)]
lotBuckets = [[0.0 for j in range(lonBucketNum)] for i in range(latBucketNum)]

# Load wildfire data in to the data array.
conn = sqlite3.connect(sqlite_file)
cur = conn.cursor()
cur.execute('SELECT LATITUDE, LONGITUDE, FIRE_SIZE FROM fires')
data = cur.fetchall()
conn.close()

# Put all the data into buckets
for entries in data:
    lat = entries[0]
    lon = entries[1]
    size = entries[2]
    if lat >= latMin and lat <= latMax and lon >= lonMin and lon <= lonMax:
        i = int((lat-latMin)/latRange * (latBucketNum-1))
        j = int((lon-lonMin)/lonRange * (lonBucketNum-1))
        scaledLatBuckets[i][j] += size*lat
        scaledLotBuckets[i][j] += size*lon
        sizeSumBuckets[i][j] += size
        countBuckets[i][j] += 1

# Get maximum size of fire average for the buckets
maxSize = 0.0
for i in range(latBucketNum):
    for j in range(lonBucketNum):
        count = countBuckets[i][j]
        if count > 0:
            size = sizeSumBuckets[i][j]
            maxSize = max(maxSize, size)
            latBuckets[i][j] = scaledLatBuckets[i][j]/size
            lotBuckets[i][j] = scaledLotBuckets[i][j]/size

# Get data out of buckets and prepare to plot it.
latResults = []
lonResults = []
colorResults = []
for i in range(latBucketNum):
    for j in range(lonBucketNum):
        size = sizeSumBuckets[i][j]
        if size > 0.0:
            lat = latBuckets[i][j]
            lon = lotBuckets[i][j]
            value = pow(size/maxSize, 0.5)
            color = cc.fire[int(value * (len(cc.fire)-1))]

            latResults.append(lat)
            lonResults.append(lon)
            colorResults.append(color)

# Plot
output_file("plot.html", title="fire maximum size", mode="cdn")

TOOLS = "crosshair,pan,wheel_zoom,box_zoom,reset,box_select,lasso_select"
p = figure(tools=TOOLS, x_range=(lonMin, lonMax), y_range=(latMin, latMax),
           width=width, height=height, background_fill_color="#000000")
p.grid.grid_line_color = None
p.circle(lonResults, latResults, radius=0.1, fill_color=colorResults, line_color=None)

show(p)


from multiprocessing import context
from typing import Any, Dict
from django.views.generic import TemplateView
from django.shortcuts import render
from .forms import VueloForms, PasajeroForms, TripulacionForms
from entrega_intermedia.mvt.models import Vuelo, Pasajero, Tripulacion

class Vueloview(TemplateView):

   template_name = 'forms/formulario_vuelo.html'

   def get(self, request):
      context = {
         'form' : VueloForms()
      }
      return render(request, self.template_name, context)

   def post(self, request):

      response = VueloForms(request.POST)

      print(response)

      if response.is_valid:
         obj_response = response.cleaned_data

         obj_vuelo = Vuelo(
                        airline = obj_response.get('airline'),
                        number = obj_response.get('number')
                           )
         obj_vuelo.save()

         context = {
            'form' : VueloForms()
            }
      return render(request ,self.template_name, context)

class Pasajeroview(TemplateView):

   template_name = 'forms/formulario_pasajero.html'

   def get(self, request):
      context = {
            'form' : PasajeroForms()
      }
      return render(request, self.template_name, context)

   def post(self, request):

      response = PasajeroForms(request.POST)

      print(response)

      if response.is_valid:

         obj_response = response.cleaned_data

         obj_pasajero = Pasajero(
                        name = obj_response.get('name'),
                        lastname = obj_response.get('lastname'),
                        email = obj_response.get('email')
                           )
         obj_pasajero.save()

         context = {
            'form' : PasajeroForms()
         }

      return render(request ,self.template_name, context)

class Tripulacionview(TemplateView):

   template_name = 'forms/formulario_tripulacion.html'

   def get(self, request):
      context = {
         'form' : TripulacionForms()
      }
      return render(request, self.template_name, context)

   def post(self, request):
      response = TripulacionForms(request.POST)

      print(response)

      if response.is_valid:

         obj_response = response.cleaned_data

         obj_curso = Tripulacion(
                                 name = obj_response.get('name'),
                                 lastname = obj_response.get('lastname'),
                                 worked = obj_response.get('worked')
                                 )
         obj_curso.save()

         context = {
            'form' : TripulacionForms()
         }

      return render(request ,self.template_name, context)

class SearchPasajero(TemplateView):

   template_name = 'forms/search_pasajero.html'

   def post(self, request):

      context = {
         "elements" : Pasajero.objects.filter(
               name__icontains=request.POST.get('name')
               )
      }

      return render(request, self.template_name, context)

class SearchVuelo(TemplateView):

   template_name = 'forms/search_vuelo.html'

   def post(self, request):

      context = {
         "elements" : Vuelo.objects.filter(
               number__icontains=request.POST.get('number')
               )
      }

      return render(request, self.template_name, context)

class SearchTripulacion(TemplateView):

   template_name = 'forms/search_tripulacion.html'

   def post(self, request):

      context = {
         "elements" : Tripulacion.objects.filter(
               worked__icontains=request.POST.get('worked')
               )
      }

      return render(request, self.template_name, context)


import os
import sys
import argparse
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
import tensorflow as tf

from common_utils import input_pipeline, console
from models import network

def validate(filenames, num_classes, ckpt_dir="./"):
    """Performs validation run on a tfrecord dataset files. =
    Also calculates accuracy using multiple patches from an image.

    Args:
        filenames: Tfrecord filenames.
        num_classes: Number of classes in the softmax classification layer.
        ckpt_dir: Location where the checkpoints are stored.
    """
    use_inception = False
    use_large = True

    pt = console.ProgressTracker()
    sess = tf.Session()

    iterator = input_pipeline.make_image_patches(filenames, use_large=use_large)
    images, labels = iterator.get_next()

    """
        Network model
    """
    if use_inception:
        logits, _ = network.build_net(images, num_classes, is_training=False)
    else:
        logits, _ = network.build_nasnet(images, num_classes, is_training=False, use_large=use_large)

    """
        Results
    """
    with tf.name_scope('results'):
        labels = tf.expand_dims(labels, 0)
        correct_prediction = tf.equal(tf.cast(labels, tf.int64), tf.argmax(logits[:1], 1))

        accuracy = tf.reduce_sum(tf.cast(correct_prediction, tf.float32), name='accuracy')
        in_top_5 = tf.reduce_sum(tf.cast(tf.nn.in_top_k(logits[:1], labels, k=5), tf.float32),
                                 name='top_5_predictions')
        in_top_10 = tf.reduce_sum(tf.cast(tf.nn.in_top_k(logits[:1], labels, k=10), tf.float32),
                                  name='top_10_predictions')

        logits = tf.expand_dims(tf.reduce_mean(tf.nn.softmax(logits), axis=0), 0)
        correct_prediction = tf.equal(tf.cast(labels, tf.int64), tf.argmax(logits, 1))

        accuracy_averaged = tf.reduce_sum(tf.cast(correct_prediction, tf.float32), name='accuracy_averaged')
        in_top_5_averaged = tf.reduce_sum(tf.cast(tf.nn.in_top_k(logits, labels, k=5), tf.float32),
                                          name='top_5_predictions_averaged')
        in_top_10_averaged = tf.reduce_sum(tf.cast(tf.nn.in_top_k(logits, labels, k=10), tf.float32),
                                           name='top_10_predictions_averaged')

    sess.run(tf.global_variables_initializer())

    """
        Savers
    """
    pt.info(">> Restoring trained model.")
    saver = tf.train.Saver()
    if os.path.isdir(ckpt_dir):
        saver.restore(sess, tf.train.latest_checkpoint(ckpt_dir))
    else:
        saver.restore(sess, ckpt_dir)

    """
        Validation
    """
    pt.info(">> Validating...")

    top_acc = {
        "top_1": 0,
        "top_5": 0,
        "top_10": 0,
        "top_1_avg": 0,
        "top_5_avg": 0,
        "top_10_avg": 0
    }
    examples = 0
    while True:
        try:
            top1, top5, top10, top1_avg, top5_avg, top10_avg = sess.run([
                accuracy, in_top_5, in_top_10, accuracy_averaged, in_top_5_averaged, in_top_10_averaged
            ])
            top_acc["top_1"] += top1
            top_acc["top_5"] += top5
            top_acc["top_10"] += top10
            top_acc["top_1_avg"] += top1_avg
            top_acc["top_5_avg"] += top5_avg
            top_acc["top_10_avg"] += top10_avg
            examples += 1

            results = "Results: " + ", ".join([
                "{:8} {:.4f}%".format(name, val / examples * 100) for name, val in top_acc.items()
            ])
            pt.progress_info("Images evaluated:{:6d} | {}", [examples, results])
        except tf.errors.OutOfRangeError:
            pt.info(">> Validation completed.")
            break

    results = ["{:8} {:.4f}%".format(name, val / examples * 100) for name, val in top_acc.items()]
    pt.info("Results: " + ", ".join(results))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--val', type=str, required=True)
    parser.add_argument('--ckpt_dir', type=str, required=True,
                        help='Directory of the checkpoints.')
    args = parser.parse_args()

    if len(sys.argv) == 1:
        parser.print_help()
        exit(1)

    val = [os.path.join(args.val, name) for name in os.listdir(args.val) if name[-9:] == ".tfrecord"]

    validate(val, num_classes=1243, ckpt_dir=args.ckpt_dir)


import json

import pytest
from fastapi.testclient import TestClient

from api import app

@pytest.fixture(scope='session')
def client():
    return TestClient(app)

@pytest.fixture(scope='session')
def store_json():
    file = open('stores.json')
    yield json.load(file)
    file.close()

def test_home(client):
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {
        "author": "Ahmed Al-Jawahiry",
    }

def test_stores_api_with_no_page(client, store_json):
    response = client.get("/stores/")
    assert response.status_code == 200
    assert response.json()['data'] == store_json[0:3]

def test_stores_api_with_page(client, store_json):
    response = client.get("/stores/?page=4")
    assert response.status_code == 200
    assert response.json()['data'] == store_json[9:12]

def test_can_search(client, store_json):
    response = client.get("/stores/?search=st_alb")
    assert response.status_code == 200

    response_json = response.json()
    assert response_json['data'] == [{"name": "St_Albans", "postcode": "AL1 2RJ"}]
    assert response_json['total'] == 1
    assert not response_json['next']


import unittest
from math import cos
from teachcompute.ext_test_case import ExtTestCase, measure_time

class TestMeasureTime(ExtTestCase):
    def test_measure_time(self):
        res = measure_time(lambda: cos(5))
        self.assertIsInstance(res, dict)
        self.assertIn("average", res)

if __name__ == "__main__":
    unittest.main(verbosity=2)


import contextlib
import shutil
import unittest
from pathlib import Path

import kalasiris.sweetened as isis
from .utils import (
    resource_check as rc,
    real_files as run_real_files,
    real_files_reason as run_real_files_reason
)

# Hardcoding this, but I sure would like a better solution.
HiRISE_img = Path("test-resources") / "PSP_010502_2090_RED5_0.img"
img = HiRISE_img

@unittest.skipUnless(run_real_files, run_real_files_reason)
class TestResources(unittest.TestCase):
    """Establishes that the test image exists."""

    def test_resources(self):
        (truth, test) = rc(img)
        self.assertEqual(truth, test)

@unittest.skipUnless(run_real_files, run_real_files_reason)
class Test_hi2isis_filesystem(unittest.TestCase):
    def setUp(self):
        self.img = img

    def tearDown(self):
        with contextlib.suppress(FileNotFoundError):
            Path("print.prt").unlink()

    def test_hi2isis_with_to(self):
        tocube = Path("test_sweetened_hi2isis.cub")
        isis.hi2isis(self.img, to=tocube)
        self.assertTrue(tocube.is_file())
        tocube.unlink()

    def test_hi2isis_without_to(self):
        sweet_img = self.img.with_name("sweet.img")
        shutil.copy(self.img, sweet_img)
        tocube = sweet_img.with_suffix(".cub")
        isis.hi2isis(sweet_img)
        self.assertTrue(tocube.is_file())
        tocube.unlink()
        sweet_img.unlink()

@unittest.skipUnless(run_real_files, run_real_files_reason)
class Test_getkey(unittest.TestCase):
    def setUp(self):
        self.cub = Path("test_sweetened_getkey.cub")
        isis.hi2isis(HiRISE_img, to=self.cub)

    def tearDown(self):
        self.cub.unlink()
        with contextlib.suppress(FileNotFoundError):
            Path("print.prt").unlink()

    def test_getkey_k(self):
        truth = "HIRISE"
        key = isis.getkey(self.cub, "Instrument", "InstrumentId")
        self.assertEqual(truth, key)


# Importando modulos

import matplotlib.pyplot as plt
import pandas as pd
from scipy.io import arff
from sklearn import preprocessing
from sklearn.cluster import KMeans
from mpl_toolkits.mplot3d import Axes3D

# Cargando la base de datos

def load_data(nombres):
    data = '../data/seismic-bumps.arff'
    input_data, input_meta = arff.loadarff(data)
    df = pd.DataFrame(input_data)
    df.columns = nombres
    return df

# Rescribiendo las etiquetas

nombres = ['seismic',
'seismoacoustic',
'shift',
'genergy',
'gpuls',
'gdenergy',
'gdpuls',
'ghazard',
'nbumps',
'nbumps2',
'nbumps3',
'nbumps4',
'nbumps5',
'nbumps6',
'nbumps7',
'nbumps89',
'energy',
'maxenergy',
'clase']

# Cargando las nuevas equitas, e imprimiendolas
df = load_data(nombres)
df.describe()

def preprocess_features(df, cols):
    """transform categorical features"""
    le = preprocessing.LabelEncoder()
    for clmn in cols:
        df[clmn] = le.fit_transform(df[clmn])

    return df

cat_cols = ['seismic', 'seismoacoustic', 'shift', 'ghazard', 'clase']
df = preprocess_features(df, cat_cols)
for clmn in cat_cols:
    print(df[clmn].unique)

X = df.iloc[:, 0:17].values
y = df.iloc[:, 18].values

# Estandarizando los datos a una distribucion normal
df_standardized = preprocessing.scale(df)
df_standardized = pd.DataFrame(df_standardized)

# Encontrando el numero de cluster apropiados
plt.figure(figsize=(10, 8))
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(df_standardized)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.title('Metodo de Elbow')
plt.xlabel('Numero de cluster')
plt.ylabel('WCSS')
plt.show()

# Ajustando los datos mediante el algoritmo K-Means
kmeans = KMeans(n_clusters = 3, init = 'k-means++', random_state = 42)
y_kmeans = kmeans.fit_predict(df_standardized)

# Inicia el cluster en numero 1 en lugar de 0
y_kmeans1=y_kmeans
y_kmeans1=y_kmeans+1

# Nuevo dataframe llamado cluster
cluster = pd.DataFrame(y_kmeans1)

# Adicionando cluster a al conjunto de datos df
df['cluster'] = cluster

# Valor medio de los clusters
kmeans_mean_cluster = pd.DataFrame(round(df.groupby('cluster').mean(),1))
print('kmeans_mean_cluster: ', kmeans_mean_cluster)

kmeans = KMeans(n_clusters=3).fit(X)
centroids = kmeans.cluster_centers_

# Prediciendo los clusters
labels = kmeans.predict(X)
# Obteniendo los centros de los clusters
C = kmeans.cluster_centers_

# Graficando los clusters obtenidos
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(X[:, 0], X[:, 1], X[:, 2])
ax.scatter(C[:, 0], C[:, 1], C[:, 2])
plt.show()


import re
import sqlite3 as sqlite
import json

def roman2arabic(roman):
    digit = {"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}
    arabic = 0
    for d in range(len(roman)):
        try:
            if digit[roman[d]]<digit[roman[d+1]]:
                arabic-=digit[roman[d]]
            else:
                arabic+=digit[roman[d]]
        except IndexError:
            arabic+=digit[roman[d]]
    return arabic

def fa(string, st):
    numchar = 0
    finaut = {}
    finaut[(0,'<')]=1 #begining
    finaut[(1,'i')]=2 #inside id-tag
    finaut[(2,'d')]=3 #inside id-tag
    finaut[(3,'=')]=4 #inside id-tag
    finaut[(4,'1')]=5 #id-num
    finaut[(4,'2')]=5 #id-num
    finaut[(4,'3')]=5 #id-num
    finaut[(4,'4')]=5 #id-num
    finaut[(4,'5')]=5 #id-num
    finaut[(4,'6')]=5 #id-num
    finaut[(4,'7')]=5 #id-num
    finaut[(4,'8')]=5 #id-num
    finaut[(4,'9')]=5 #id-num
    finaut[(5,'1')]=5 #id-num
    finaut[(5,'2')]=5 #id-num
    finaut[(5,'3')]=5 #id-num
    finaut[(5,'4')]=5 #id-num
    finaut[(5,'5')]=5 #id-num
    finaut[(5,'6')]=5 #id-num
    finaut[(5,'7')]=5 #id-num
    finaut[(5,'8')]=5 #id-num
    finaut[(5,'9')]=5 #id-num
    finaut[(5,'0')]=5 #id-num
    finaut[(5,'>')]=6 #id-tag fin
    finaut[(6,'<')]=7 #bold-tag
    finaut[(7,'b')]=8 #bold-tag
    finaut[(8,'>')]=9 #bold-tag fin
    ident = ''
    ident_final = ''
    for i in string:
        numchar+=1
        if (st, i) in finaut:
            st = finaut[(st,i)]
            if st == 5:
                ident+=i
            if st == 6:
                ident_final = ident
                ident = ''
            if st == 9:
                return [ident_final,st,numchar]

def wordfa(string,numchar):
    st = 9
    bigletters = 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮѢ'
    faw = {}
    numchar1 = numchar
    faw[(9, '<')] = 10
    faw[(10, '/')] = 11
    faw[(11, 'b')] = 12
    faw[(12, '>')] = 13
    word = ''
    for i in string[numchar:]:
        numchar1+=1
        if (st,i) not in faw:
            word+=i
        else:
            st = faw[(st,i)]
            if st == 13:
                return([word,st,numchar1])
def wordfa1(string,numchar):
    bigletters = 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮѢ,. '
    st = 0
    numchar1 = numchar
    faw = {}
    faw[(0,',')]=0
    faw[(0,' ')]=0
    faw[(0,'<')]=0
    faw[(0,'/')]=14
    faw[(14,'i')]=15
    faw[(15,'>')]=0
    faw[(0,'и')]=1
    faw[(1,'л')]=13
    faw[(13,'и')]=1
    faw[(0,'ч')]=10
    faw[(10,'а')]=11
    faw[(11,'щ')]=12
    faw[(12,'е')]=1
    faw[(1,' ')]=1
    faw[(1,'<')]=2
    faw[(2,'b')]=3
    faw[(3,'>')]=4
    faw[(5,'<')]=6
    faw[(6,'/')]=7
    faw[(7,'b')]=8
    faw[(8,'>')]=9
    fw = ''
    for i in string[numchar:]:
        numchar1+=1
        if (st,i) not in faw and st != 4 and st !=5:
            return(None)
        if (st,i) in faw:
            st = faw[(st,i)]
        if st == 5:
            fw+=i
        if st == 4:
            st = 5
        if st == 9:
            return([fw,numchar1])

def gram(string,numchar):
    st = 13
    numchar1 = numchar
    dic = {}
    dic[(13,'и')]=13
    dic[(13,'/')]=13
    dic[(13,'i')]=13
    dic[(13,'>')]=13
    dic[(13,'<')]=13
    dic[(13,',')]=13
    dic[(13,' ')]=13
    dic[(13,'.')]=13
    dic[(13,'с')]=44
    dic[(44,'м')]=48
    dic[(13,'<')]=15
    dic[(15,'i')]=16
    dic[(16,'>')]=17
    dic[(17,' ')]=17
    dic[(17,'м')]=18
    dic[(18,'н')]=44
    dic[(17,'с')]=18
    dic[(17,'ж')]=18
    dic[(17,'п')]=21
    dic[(18,'е')]=22
    dic[(22,'с')]=23
    dic[(23,'т')]=24
    dic[(17,'п')]=21
    dic[(21,'р')]=22
    dic[(22,'е')]=35
    dic[(35,'д')]=36
    dic[(36,'л')]=37
    dic[(37,'о')]=38
    dic[(38,'г')]=39
    dic[(22,'и')]=23
    dic[(23,'л')]=24
    dic[(23,'ч')]=43
    dic[(17,'н')]=25
    dic[(25,'а')]=26
    dic[(26,'р')]=27
    dic[(27,'е')]=28
    dic[(28,'ч')]=29
    dic[(18,'о')]=30
    dic[(30,'ю')]=31
    dic[(31,'з')]=32
    dic[(17,'ч')]=33
    dic[(33,'а')]=34
    dic[(34,'с')]=35
    dic[(35,'т')]=36
    dic[(36,'и')]=37
    dic[(37,'ц')]=38
    dic[(38,'а')]=39
    dic[(33,'и')]=40
    dic[(40,'с')]=41
    dic[(41,'л')]=42
    dic[(18,'<')]=19
    dic[(24,'<')]=19
    dic[(29,'<')]=19
    dic[(32,'<')]=19
    dic[(39,'<')]=19
    dic[(42,'<')]=19
    dic[(43,'<')]=19
    dic[(44,'<')]=19
    dic[(19,'/')]=19
    dic[(19,'i')]=19
    dic[(19,'>')]=19
    dic[(18,'.')]=20
    dic[(19,'.')]=20
    dic[(24,'.')]=20
    dic[(29,'.')]=20
    dic[(32,'.')]=20
    dic[(39,'.')]=20
    dic[(39,' ')]=39
    dic[(42,'.')]=20
    dic[(43,'.')]=20
    dic[(44,'.')]=20
    word =''
    for i in string[numchar:]:
        if (st,i) in dic:
            st = dic[(st,i)]
            if st <= 44:
                numchar1+=1
            if st == 18 or st >= 21 and st <=44:
                word+=i
            if st == 20:
                if word == '':
                    return(['глаг',numchar1])
                else:
                    return([word,numchar1])
            if st ==48:
                return(None)
        else:
            return(['глаг',numchar1])

def meanings(string,numchar):
    meanings = string[numchar:].split('

')
    return(meanings)

def links(string,numchar):
    st = 0
    d = re.search('( )?см\.( )?.+?',string[numchar:])
    if d is not None:
        return([d.group(0),numchar])

def examplesdev(string):
    string = re.sub('(<)(/)?[pib]>','',string)
    string = re.sub('([XVI1642357890]+? (в(в)?|г(г)?)\.( ~ [1642357890XVI]+? (г(г)?|в(в)?)\.)?)','\\1@',string)
    arr = string.split('@')
    return(arr)

def finfu(string):
    finalstring = ''
    finarr = []
    numchar = 0
    ident = fa(string,numchar)
    finarr.append(ident)
    if ident is not None:
        numchar = ident[2]
    word1 = wordfa(string, numchar)
    finarr.append(word1)
    if word1 is not None:
        numchar = word1[2]
    gram1 = gram(string,numchar)
    finarr.append(gram1)
    if gram1 is not None:
        numchar = gram1[1]
    word2 = wordfa1(string,numchar)
    finarr.append(word2)
    if word2 is not None:
        numchar = word2[1]
    gram2 = gram(string,numchar)
    finarr.append(gram2)
    if gram2 is not None:
        numchar = gram2[1]
    link = links(string,numchar)
    finarr.append(link)
    if link is not None:
        numchar = link[1]
    for i in finarr:
        if i is not None:
            finalstring+=i[0]+'\t'
        else:
            finalstring+='NULL\t'
    if ident is None:
        ident = 'NULL'
    else:
        ident = ident[0]
    if word1 is None:
        word1 = 'NULL'
    else:
        word1 = word1[0]
    if gram1 is None:
        gram1 = 'NULL'
    else:
        gram1 = gram1[0]
    if word2 is None:
        word2 = 'NULL'
        gram2 = None
    else:
        word2 = word2[0]
    if gram2 is None or gram2 == 'глаг':
        gram2 = 'NULL'
    else:
        gram2 = gram2[0]
    if link is None:
        link = 'NULL'
    else:
        link = re.sub('(( )?см\.( )?|)','',link[0])

    meanings1 = meanings(string,numchar)
    meaningID = 1
    full = ''
    for i in meanings1:
        meaningID+=1
        d = re.search('<?i?>?.*?(\))?((\.)?( )?.*?)?(( )?(\()?( )?( )?(\()?( )?в знач( )?(\.)?( )?( )?(\.)?( )?[1234567890]( ?)(;|\.)?( )?(\))?)?((\.)?( )?[^ ]+?\))?((\\.)?( )?[1234567890](\.|;)?)?(( )?(\()?( )?ср\\. [^ ]+?( )?(\\.)?( )?[^ ]+( )?([^ ])?(( )?в этом знач(\.)?)?(( )?(‘)?(‘)?\w+?(’)?(‘)?)?(\))?)?(( )?\w+?( \w+?)?(\w+?)?(\.)?)?',i)
        #d = re.search('<?i?>?.*?((\.)?( )?.*?)?(( )?(\()?( )?( )?(\()?( )?в знач( )?(\.)?( )?( )?(\.)?( )?[1234567890]( ?)(;|\.)?( )?(\))?)?(( )?[^ ]+?\))?((\\.)?( )?[1234567890](\.|;)?)?(( )?ср\\. [^ ]+?\\. [^ ]+?\))?',i) . stwierdzić się ‘осуществиться’)
        if d is not None:
            me = re.sub('<(/)?[IiBb]>', '', d.group(0))
            query1 = "INSERT INTO Meanings VALUES(NULL, '" + me+"', " + ident+")"
            me1 = re.sub('(<)?(/)?i>', '', me)
            me1 = re.sub('&SUP&', ' ', me1)
            me1 = re.sub('&sup&', ' ', me1)
            full += '%&'+me1+'&'
            cursor.execute(query1)
            query2 = "SELECT Id FROM Meanings WHERE rowid=last_insert_rowid();"
            cursor.execute(query2)
            t = cursor.fetchall()
            meaningid = t[0][0]
            arrex = examplesdev(i[len(d.group(0)):len(i)])
            for x in arrex:
                x = re.sub("(\'|\")",'',x)
                #query3 = "INSERT INTO Examples VALUES(NULL, '" + x + "', " + str(meaningid)+")"
                #cursor.execute(query3)
                dat_source = re.search('(([ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ][ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNMйцукенгшщзхъфывапролджэячсмитьбю\.])*?(((№\s|(\.|,)(\s)?)[1234&567890йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm\.,]{1,7}(\.|,|\.,)?\s|№\s)*?[ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбюQWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm\.,]{2,}(\s[VXI,]+?)?\s[1234567890\.]+?)?(\s)?)(([XVI1642357890]+?((\s)?(~|–)(\s)?))?[XVI1642357890]+?\s(в(в)?|г(г)?)\.((\s)?(~|–)(\s)?[1642357890XVI]+?\s(г(г)?|в(в)?)\.)?|[XVI1642357890]+?(\s)?((в(в)?|г(г)?)\.)?(\s)?(~|–)(\s)?[1642357890XVI]+?(г(г)?|в(в)?)\.)',x)
                #if dat_source is not None:
                    #print(dat_source.group(0))
                dat = re.search('(([XVI1642357890]+?((\s)?(~|–)(\s)?))?[XVI1642357890]+?\s(в(в)?|г(г)?)\.((\s)?(~|–)(\s)?[1642357890XVI]+?\s(г(г)?|в(в)?)\.)?|[XVI1642357890]+?(\s)?((в(в)?|г(г)?)\.)?(\s)?(~|–)(\s)?[1642357890XVI]+?(г(г)?|в(в)?)\.)',x)
                if dat_source is not None:
                    ds = dat_source.group(1)
                    ds = re.sub('^(\s)?(\.|,)(\s)?','',ds)
                    ds = re.sub('^\s','',ds)
                    if len(ds) > 0:
                        if ds not in arr_sou:
                            arr_sou.append(ds)
                        fi.write(ds+'\n')
                        ds = re.sub('', '', ds)
                    date = dat.group(0)
                    date = re.sub('г', '', date)
                    date = re.sub('в', '', date)
                    date = re.sub('\s', '', date)
                    date = re.sub('\.', '', date)
                    datea = date.split('~')
                    if len(datea) == 1:
                        datea.append(datea[0])
                    dateaa = []
                    for i in datea:
                        i = i.split('–')
                        if len(i) == 1:
                            i.append(i[0])
                        for e in i:
                            dateaa.append(e)
                    if 'X' in dateaa[0] or 'V' in dateaa[0] or 'I' in dateaa[0]:
                        dateaa[0] = str(roman2arabic(dateaa[0]))
                    if 'X' in dateaa[1] or 'V' in dateaa[1] or 'I' in dateaa[1]:
                        dateaa[1] = str(roman2arabic(dateaa[1]))
                    if 'X' in dateaa[2] or 'V' in dateaa[2] or 'I' in dateaa[2]:
                        dateaa[2] = str(roman2arabic(dateaa[2]))
                    if 'X' in dateaa[3] or 'V' in dateaa[3] or 'I' in dateaa[3]:
                        dateaa[3] = str(roman2arabic(dateaa[3]))

                    da = dateaa[0] + ", " + dateaa[1] + ", " + dateaa[2] + ", " + dateaa[3]
                    if ds in list_s:
                        query3 = "INSERT INTO Examples VALUES(NULL, '" + x + "', '" + str(list_s[ds]) + "', " + da + ", " + str(meaningid)+")"
                    else:
                        query3 = "INSERT INTO Examples VALUES(NULL, '" + x + "', '" + '' + "', " + da + ", " + str(meaningid)+")"

                    cursor.execute(query3)
                else:
                    if dat is not None:
                        query3 = "INSERT INTO Examples VALUES(NULL, '" + x + "', '" + 'NULL' + "', " + da + ", " + str(meaningid)+")"

                        cursor.execute(query3)
                    else:
                        query3 = "INSERT INTO Examples VALUES(NULL, '" + x + "', '" + 'NULL' + "', " + "NULL, NULL, NULL, NULL" + ", " + str(meaningid)+")"

                        cursor.execute(query3)
                x = re.sub('&SUP&', ' ', x)
                x = re.sub('&sup&', ' ', x)
                x = re.sub('(<)?(/)?i>', '',x)
                full += x
    word1 = re.sub('&SUP&', ' ', word1)
    word2 = re.sub('&SUP&', ' ', word2)
    word1 = re.sub('&sup&', ' ', word1)
    word2 = re.sub('&sup&', ' ', word2)
    word1 = re.sub(',', '', word1)
    word2 = re.sub(',', '', word2)
    word1 = re.sub('^\s', '',word1)
    word1 = re.sub('\s$', '',word1)
    word1 = re.sub('\.', '',word1)
    word2 = re.sub('^\s', '',word2)
    word2 = re.sub('\s$', '',word2)
    word2 = re.sub('\.', '',word2)
    query = "INSERT INTO Words VALUES(" + ident + ", '" + word1 + "', '" + gram1 + "', '" + word2 + "', '" + gram2 + "', '" + link + "', '"+ full + "')"
    cursor.execute(query)
    return(finalstring)

connection = sqlite.connect('RusDict.db')
cursor = connection.cursor()
cursor.execute('''
CREATE TABLE Words(
Id INTEGER,
Word1 TEXT,
Gram1 TEXT,
Word2 TEXT,
Gram2 TEXT,
Link TEXT,
Full TEXT
);
''')

cursor.execute('''
CREATE TABLE Meanings(
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Def TEXT,
IDword INTEGER
);
''')

cursor.execute('''
CREATE TABLE Examples(
Id INTEGER PRIMARY KEY AUTOINCREMENT,
example TEXT,
source TEXT,
date1 INTEGER,
date2 INTEGER,
date3 INTEGER,
date4 INTEGER,
meaningID TEXT
);
''')
file1 = open('test2.json','r',encoding='utf-8')
j = ''
for i in file1:
    j+=i
list_s = json.loads(j)
arr_sou = []
#print(gram(' ж. Ласк.',0))
fi = open('test.txt', 'w', encoding='utf-8')
file = open('fi.html', 'r', encoding='utf-8')
word = ''
val=0
f = open('res.csv', 'w', encoding='utf-8')
for i in file:
    if i is not None and len(i)>1 and fa(i,0) is not None:
        i = i[0:len(i)-1]
        finfu(i)
        #f.write(finfu(i)[:len(finfu(i))]+'\n')
#    if i is not None and len(i)>1 and fa(i,0) is not None:
#        f.write(str(fa(i, 0)[0])+' | '+str(wordfa(i,fa(i,0)[2])[0])+' | '+str(gram(i,wordfa(i,fa(i,0)[2])[2])[0])+'\n')
f.close()
file.close()
fi.close()
connection.commit()
count = 1
arr_sou_id = []
for i in arr_sou:
    arr_sou_id.append({i: count})
    count += 1
file2 = open('1.json','w',encoding='utf-8')
kf = json.dumps(arr_sou_id, ensure_ascii=False, indent = 2)
file2.write(kf)
file1.close()


from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from starlette.responses import JSONResponse

from api.dependency.db import get_db
from api.dependency.security import get_current_active_superuser
from request.category import CreateCategory, ListCategory
from response.category import CategoryList, CategoryItem
from service import category as service

router = APIRouter()

@router.get("/", response_model=CategoryList)
def list(
        request: ListCategory = Depends(),
        db: Session = Depends(get_db),
        current_user=Depends(get_current_active_superuser),
):
    count, categories = service.list(db, request=request)
    return CategoryList.from_model(count, categories)

@router.get("/{id}", response_model=CategoryItem)
def get(
        id: int,
        db: Session = Depends(get_db),
        current_user=Depends(get_current_active_superuser),
):
    category = service.get(db, id=id)
    if not category:
        return JSONResponse(status_code=404, content={"message": "The category not found"})
    return CategoryItem.from_model(category)

@router.post("/", response_model=CategoryItem)
def post(
        request: CreateCategory,
        db: Session = Depends(get_db),
        current_user=Depends(get_current_active_superuser),
):
    if service.get_by_name(db, name=request.name):
        return JSONResponse(status_code=400, content={"message": "The category is already exists"})
    return CategoryItem.from_model(service.post(db, request=request))


import pandas as pd
import scipy
import torch
import operator
import numpy as np
import random
from statistics import median

NEWS_ARTICLES_JSON = "huffpost_dataset.json"

def get_df():
    news = pd.read_json(NEWS_ARTICLES_JSON, lines=True)
    news = clean_df(news)
    return news

def clean_df(df):
    df = df[df['date'] >= pd.Timestamp(2012, 1, 1)]
    df = df[df['headline'].apply(lambda x: len(x.split()) > 5)]
    df = df[df['short_description'].apply(lambda x: len(x.split()) > 1)]
    df.sort_values('headline', inplace=True, ascending=False)
    duplicated_articles_series = df.duplicated('headline', keep=False)
    df = df[~duplicated_articles_series]
    df.index = range(df.shape[0])
    return df

# def get_recommendations(queries, query_embeddings, all_corpus_embeddings, prev_liked, prev_rec, closest_n):
#     # get cosine similarities for all articles
#     all_results = []
#     all_results_unexp = []
#     for query, query_embedding in zip(queries, query_embeddings):
#         distances = scipy.spatial.distance.cdist(torch.reshape(query_embedding, (1, query_embedding.shape[0])),
#                                                  all_corpus_embeddings,
#                                                  "cosine")[0]
#
#         results = zip(range(len(distances)), distances)
#         all_results.extend(results)
#         results = zip(range(len(distances)), distances)
#         all_results_unexp.append(sorted(results, key=lambda x: x[0]))
#
#     # remove articles that have been previously liked or recommended from the corpus
#     rem_elem = []
#     for index, elem in enumerate(all_results):
#         if elem[0] in prev_rec or elem[0] in prev_liked:
#             rem_elem.append(elem)
#
#     filtered_rec_list = [elem for elem in all_results if elem not in rem_elem]
#
#     unexpected_indices = get_unexpected_recs(all_results_unexp, len(queries))
#
#     # sort from highest to lowest cosine similarity
#     filtered_rec_list = sorted(filtered_rec_list, key=lambda x: x[1])
#
#     return filtered_rec_list, unexpected_indices

def get_recommendations(queries, query_embeddings, all_corpus_embeddings, prev_liked, prev_rec, closest_n, SERENDIPITY):
    # get cosine similarities for all articles
    all_results = []
    unexpected_indices = []
    for query, query_embedding in zip(queries, query_embeddings):
        distances = scipy.spatial.distance.cdist(torch.reshape(query_embedding, (1, query_embedding.shape[0])),
                                                 all_corpus_embeddings,
                                                 "cosine")[0]

        results = zip(range(len(distances)), distances)
        # sort from highest to lowest cosine similarity
        all_results.append(sorted(results, key=lambda x: x[1]))

    # create new corpus with articles that have not been previously liked or recommended
    remaining_articles = []
    for each_query_result in all_results:
        not_recommended_articles = []
        for art_no, cos_sim in each_query_result:
            if art_no not in prev_rec and art_no not in prev_liked:
                not_recommended_articles.append((art_no, cos_sim))
        remaining_articles.append(not_recommended_articles)

    if SERENDIPITY:
        unexpected_indices = get_unexpected_recs(remaining_articles, closest_n)

    return remaining_articles, unexpected_indices

def remove_liked_articles(new_recs, already_liked):
    s1 = set(new_recs)
    s2 = set(already_liked)
    if len(already_liked) != 1:
        new_recs = list(s1.difference(s2))
    return new_recs

def get_unexpected_recs(cosine_sim_list, n_liked_items):
    sorted_articles = []

    for each_query_result in cosine_sim_list:
        each_query_result = sorted(each_query_result, key=lambda x: x[0])
        sorted_articles.append(each_query_result)

    item_item_mat = []
    # create item-item matrix
    for row in sorted_articles:
        item_item_mat.append([sim[1] for sim in row])

    # calcuate unexpectedness of each article
    unexpectedness = 1 - (np.sum(item_item_mat, axis=0) / n_liked_items)
    median_unexp = median(unexpectedness)

    # get 2 recommendations that lie closest to the median
    m1 = unexpectedness[unexpectedness > median_unexp].min()
    m2 = unexpectedness[unexpectedness < median_unexp].max()
    m1_idx = np.where(unexpectedness == m1)
    m2_idx = np.where(unexpectedness == m2)

    unexpected_indices = [m1_idx[0][0], m2_idx[0][0]]
    unexpected_indices_act = [sorted_articles[0][unexpected_indices[0]][0], sorted_articles[0][unexpected_indices[1]][0]]

    return unexpected_indices_act

def get_rec_df(df, artNo_vs_sim):
    for k, v in artNo_vs_sim.items():
        artNo_vs_sim[k] = float(v)

        sorted_d = dict(sorted(artNo_vs_sim.items(), key=operator.itemgetter(1), reverse=True))
        for key in sorted(artNo_vs_sim.items(), key=operator.itemgetter(1), reverse=True)[:10]:
            print(df.loc[key, :])

def get_combined_articles(queries, df, previously_liked_news):
    # combine desc and headline and store index of previously liked articles
    combined_articles = []
    for i in range(len(queries)):
        article_number = df.index[(df['short_description'] == queries[i])].tolist()
        previously_liked_news.append(article_number[0])
        heads = df.at[article_number[0], 'headline']
        combined_articles.append((heads + " " + queries[i]))

    return combined_articles

# def get_final_rec_indices(filtered_rec_list, closest_n, unexp_list, query_categories, df):
#     rec_indices = []
#     cos_sim = []
#
#     # aggressively recommend articles from the same category
#     for i in range(len(filtered_rec_list)):
#         count = 0
#         for idx, distance in filtered_rec_list[i][0]:
#             if df.at[idx, 'category'] in query_categories:
#                 rec_indices.append(idx)
#                 cos_sim.append(1 - distance)
#                 count += 1
#             if count == closest_n:
#                 break
#
#     for i in range(len(unexp_list)):
#         rec_indices.append(unexp_list[i])
#         cos_sim.append(0)
#
#     return rec_indices, cos_sim

def get_final_rec_indices(filtered_rec_list, closest_n, unexp_list, query_categories, SERENDIPITY, df):
    rec_indices = []
    cos_sim = []

    # aggressively recommend articles from the same category
    for each_query_result in filtered_rec_list:
        count = 0
        for idx, distance in each_query_result:
            if df.at[idx, 'category'] in query_categories:
                rec_indices.append(idx)
                cos_sim.append(1 - distance)
                count += 1
            if count == closest_n:
                break

    # if SERENDIPITY:
    #     random.shuffle(rec_indices)
    #     rec_indices = rec_indices[:8]
    #     rec_indices.extend(unexp_list)
    #     return rec_indices, cos_sim[:10]  # COS_SIM IS NOT SHUFFLED!!!!!!!!!!!!!!!!!!!!!
    # else:
    #     random.shuffle(rec_indices)
    #     return rec_indices[:10], cos_sim[:10]  # COS_SIM IS NOT SHUFFLED!!!!!!!!!!!!!!!!!!!!!

    rec_np = np.array(rec_indices)
    sim_np = np.array(cos_sim)
    p = np.random.permutation(len(rec_np))
    rec_np = rec_np[p].tolist()
    sim_np = sim_np[p].tolist()

    if SERENDIPITY:
        rec_np = rec_np[:8]
        sim_np = sim_np[:8]
        rec_np.extend(unexp_list)
        sim_np.extend([0, 0])
        return rec_np, sim_np
    else:
        return rec_np[:10], sim_np[:10]


import xml.sax.handler

class EmpHandler(xml.sax.handler.ContentHandler):
    def __init__(self):
        self.inDepartment = False
        self.inFirstName = False

    def startElement(self, name, attributes):
        if name == 'department':
            self.inDepartment = True
        elif name == 'firstName':
            self.inFirstName = True

    def characters(self, data):
        if self.inDepartment:
            print(data)
        elif self.inFirstName:
            print(data)

    def endElement(self, name):
        if name == 'department':
            self.inDepartment = False
        elif name == 'firstName':
            self.inFirstName = False

import xml.sax

parser = xml.sax.make_parser()

handler = EmpHandler()

parser.setContentHandler(handler)

parser.parse('sample.xml')