# Tkinter gui window

##############################
# IMPORTS
##############################

from tkinter import *
import os
from PIL import ImageTk, Image
from multiprocessing.managers import BaseManager
import types
import sys
import threading
import webbrowser

##############################
# Global Variables
##############################

ipcQueueItems = []
storagePath = os.path.join(os.getenv('LOCALAPPDATA'), 'hll-companion')
settingsPath = os.path.join(storagePath, 'settings.txt')
scalesPositionsPath = os.path.join(storagePath, 'sliders.txt')
windowOnTop = 0

##############################
# INITIALIZE WINDOW
##############################

def initGui():
    ##############################
    # DATA MANIPULATION
    ##############################

    def getPath(filename):
        return os.path.join(os.path.realpath(os.path.dirname(__file__)), filename)

    # Declare data storage class
    class ParsedObj:
            def __init__(self, option, value):
                self.option = option
                self.value = value

    # Retrieve data from game ini and store in levelsData
    def getData(levelsData):
        levelsData.clear()
        # Read ini file and assign to list
        f = open(os.path.expanduser('~') + '\\AppData\\Local\\HLL\\Saved\\Config\\WindowsNoEditor\\GameUserSettings.ini')
        lines = f.readlines()

        # Function for parsing read data
        def parseData(lines, levelsData):
            for i in range(len(lines)):
                parsed = lines[i].rsplit("=")

                if parsed[0] == "ProximityVoiceVolume" or parsed[0] == "UnitVoiceVolume" or parsed[0] == "LeadershipVoiceVolume":
                    levelsData.append(ParsedObj(parsed[0], parsed[1]))
            return levelsData
        levelsData = parseData(lines, levelsData)
        return levelsData
    levelsData = []
    levelsData = getData(levelsData)

    # Set up Local Storage
    def createSettingsFile():
        print('Creating Settings file')
        settingsFile = open(settingsPath, 'w')
        settingsFile.write('[resolution:{x:1920,y:1080}][stayOnTop:{value:0}]')

    def createSlidersFile():
        print('Creatings sliders.txt...')
        slidersFile = open(scalesPositionsPath, 'w')
        slidersFile.write('{ProximityVoiceVolume:{high:70,low:30}}{UnitVoiceVolume:{high:70,low:30}}{LeadershipVoiceVolume:{high:70,low:30}}')

    def initLocal():
        # If no folder, create folder
        if os.path.exists(storagePath):
            print('Storage present')
        else:
            print('Storage not found, creating...')
            os.mkdir(storagePath)

        # # If no settings file, create settings file
        if os.path.isfile(settingsPath):
            print('Settings file found')
        else:
            print('Settings file not found')
            createSettingsFile()

        # # if no scalesPositions file, create scalesPosition file
        if os.path.isfile(scalesPositionsPath):
            print('sliders.txt found')
        else:
            print('sliders.txt not found')
            createSlidersFile()
    initLocal()

    def parseSettingsString(settingsString):
        resultObj = types.SimpleNamespace()

        # Remove first bracket
        settingsString = settingsString[1:]
        # Remove last bracket
        settingsString = settingsString[:-1]

        # Split objects
        objectsStrings = settingsString.split('][')

        for obj in objectsStrings:
            newObj = obj
            # Check if first character is a bracket and remove
            if newObj[1] == '[':
                newObj = obj[1:]
            if newObj[-1] == ']':
                newObj = obj[:-1]

            # Split category name and assign to result
            catObj = types.SimpleNamespace()
            catName = newObj.split(':{')[0]
            setattr(catObj, catName, types.SimpleNamespace())

            # Remove last curly brace of value pairs
            valuePairs = newObj.split(':{')[1]
            if valuePairs[-1] == '}':
                valuePairs = valuePairs[:-1]

            # Split into individual pairs
            indvPairs = valuePairs.split(',')

            # Split into key value pairs
            for pair in indvPairs:
                keyValueList = pair.split(':')
                # Assign attribute to category
                setattr(catObj, keyValueList[0], keyValueList[1])
                setattr(resultObj, catName, catObj)
        return resultObj

    def parseScaleValuesString(scaleValuesString):

        resultObj = types.SimpleNamespace()

        # Remove first character
        scaleValuesString = scaleValuesString[1:]
        # Remove last character
        scaleValuesString = scaleValuesString[:-1]

        elements = scaleValuesString.split('}{')
        for element in elements:
            splitElement = element.split(':{')
            name = splitElement[0]

            # Set attributes with names
            setattr(resultObj, name, types.SimpleNamespace())

            # Parse values
            # remove last character
            splitElement[1] = splitElement[1][:-1]
            # split
            valuePair = splitElement[1].split(',')
            # Assign values to new object, assign new object to result object
            setattr(vars(resultObj)[name], 'high', valuePair[0].split(':')[1])
            setattr(vars(resultObj)[name], 'low', valuePair[1].split(':')[1])
        return resultObj

    ###############################
    # RENDER PROCESS
    ###############################

    # Render a window and display data

    def render():

        ##############################
        # Event Handlers
        ##############################

        # Reset ipcQueueItems
        def resetQueueItems():
            global ipcQueueItems
            ipcQueueItems = []

        # Add to ipcQueueItems
        def updateQueue(newItem):
            global ipcQueueItems

            # Add item
            ipcQueueItems.append(newItem)

            # Send to multiprocess queue
            manager = BaseManager(address=('localhost', 50000), authkey=b'blahkey')
            manager.connect()

            currentQueue = manager.getIpcQueue()

            if not currentQueue.empty():
                currentQueue.get()

            currentQueue.put(newItem)

            # Reset Queue
            resetQueueItems()

        # Serialize scales values
        def serializeScalesValues(scales):

            scalesValuesString = ''
            for scale in scales:
                # Start Item
                scalesValuesString += '{'
                # name
                scalesValuesString += scale.option
                # Start object
                scalesValuesString += ':{'
                # High value
                scalesValuesString += 'high:' + str(scale.highScale.get()) + ','
                # Low value
                scalesValuesString += 'low:' + str(scale.lowScale.get())
                # End object
                scalesValuesString += '}'
                # Close item
                scalesValuesString += '}'
            return scalesValuesString

        # Update Scales Values
        def updateScalesValues(scales):
            scalesValuesString = serializeScalesValues(scales)
            file = open(scalesPositionsPath, 'w')
            file.write(scalesValuesString)
            updateQueue(scalesValuesString)

        def handleUpdateClick(levelsData, frames):
            #  Refresh levels data
            levelsData = getData(levelsData)

            # Update height of meters
            def updateMeter(levelsData, frames):
                i = 0
                for frame in frames:
                    # Set meter height
                    meterHeight = round(float(levelsData[i].value) * 100)

                    # Set color of meter according to meterHeight
                    if meterHeight > 75:
                        meterColor = 'green'
                    elif meterHeight < 76 and meterHeight > 50:
                        meterColor = 'yellow'
                    elif meterHeight < 51 and meterHeight > 25:
                        meterColor = 'orange'
                    elif meterHeight < 26:
                        meterColor = 'red'

                    if meterHeight == 0:
                        meterHeight = 100
                        meterColor = 'gray20'

                    # Send Options
                    frame.config(bg=meterColor)
                    frame.config(height=meterHeight)

                    i += 1
            updateMeter(levelsData, frames)

        ###############################
        # Set up window
        ###############################
        root = Tk()
        root.geometry('400x330')
        root.title('HLL Companion')
        root.configure(background='gray30')
        root.resizable(False, False)
        root.wm_iconbitmap(getPath("assets\\tank.ico"))

        # Global variable for settings menu
        savedResolution = StringVar();

        # Get Settings from settings txt and parse to object
        def getSettingsObj():
            settingsFile = open(settingsPath, 'r')
            return parseSettingsString(settingsFile.read())

        # Check if window should be on top and update global variable
        def checkIfTop(displayOnTop=False):

            if displayOnTop == False:
                savedSettings = getSettingsObj()
                global windowOnTop
                windowOnTop = int(savedSettings.stayOnTop.value)
            elif displayOnTop == True:
                windowOnTop = 1

        # Set the log message
        def setLogMessage(message, mode='write'):
            manager = BaseManager(address=('localhost', 50000), authkey=b'blahkey')
            manager.connect()
            currentQueue = manager.getLogMessage()
            currentQueue.put(message + '\\n' + mode)

        # Update log from ipc
        def updateLogMessage(log):

            def startLogUpdateThread(log):
                manager = BaseManager(address=('localhost', 50000), authkey=b'blahkey')
                manager.connect()
                currentQueue = manager.getLogMessage()

                if currentQueue.empty() == False:
                    queueString = currentQueue.get()
                    receivedMessage = queueString.split('\\n')[0]
                    receivedMode = queueString.split('\\n')[1]
                    if receivedMode == 'write':
                        message = receivedMessage
                    elif receivedMode == 'append':
                        message = log.cget("text") + receivedMessage
                    else:
                        message = ''
                    log.config(text=message)

            newThread = threading.Thread(target=lambda: startLogUpdateThread(log), daemon=True)
            newThread.start()

        # Set up update function
        def update(levelsData, frames, log):
            handleUpdateClick(levelsData, frames)
            updateLogMessage(log)

            # Stay on top?
            if windowOnTop == 1:
                root.attributes('-topmost', True)
            else:
                root.attributes('-topmost', False)

            root.after(500, lambda: update(levelsData, frames, log))

        # Render meters frame
        metersFrame = Frame(root, bg='gray10', relief='ridge', bd=2)
        metersFrame.pack()
        metersFrame.place(bordermode=INSIDE, anchor='nw', height=120, width=380, x=10, y=10)

        # Render meters
        def renderMeters(levelsData):
            frames = []
            i = 0
            for dataObj in levelsData:
                # Determine height of meter according to levels
                meterHeight = round(float(dataObj.value) * 100)

                # Set color of meter according to meterHeight
                if meterHeight > 75:
                    meterColor = 'green'
                elif meterHeight < 76 and meterHeight > 50:
                    meterColor = 'yellow'
                elif meterHeight < 51 and meterHeight > 25:
                    meterColor = 'orange'
                elif meterHeight < 26:
                    meterColor = 'red'

                # Create meters
                frame = Frame(metersFrame, bg=meterColor, height=meterHeight)
                frame.pack()
                frame.place(bordermode=OUTSIDE, anchor='sw', width=40, x=70 + (i * 100), y=115)
                frames.append(frame)
                i += 1
            return frames
        frames = renderMeters(levelsData)

        # Render Labels
        def renderLabels(levelsData):
            i = 0
            for dateObj in levelsData:
                label = Label(root, relief='ridge', text=dateObj.option.split('Voice')[0], padx=5, pady=3)
                label.pack()
                label.place(bordermode=OUTSIDE, anchor='center', x=100 + (i * 100), y=150)
                i += 1
        renderLabels(levelsData)

        # Render Scales
        def renderScales(levelsData):
            scalesFile = open(scalesPositionsPath, 'r')
            scalesValues = parseScaleValuesString(scalesFile.read())

            scales = []
            i = 0
            for dateObj in levelsData:

                # Get starting values from local storage file
                if dateObj.option == 'LeadershipVoiceVolume':
                    highValue = scalesValues.LeadershipVoiceVolume.high
                    lowValue = scalesValues.LeadershipVoiceVolume.low
                elif dateObj.option == 'UnitVoiceVolume':
                    highValue = scalesValues.UnitVoiceVolume.high
                    lowValue = scalesValues.UnitVoiceVolume.low
                elif dateObj.option == 'ProximityVoiceVolume':
                    highValue = scalesValues.ProximityVoiceVolume.high
                    lowValue = scalesValues.ProximityVoiceVolume.low

                # High Sliders
                dateObj.highScale = Scale(root, from_=0, to=100, orient=HORIZONTAL, length=75, label='      High')
                dateObj.highScale.bind("<ButtonRelease-1>", lambda event : updateScalesValues(scales))
                dateObj.highScale.pack()
                dateObj.highScale.set(highValue)
                dateObj.highScale.place(anchor='center', x=100 + (i * 100), y=195)

                # Low Sliders
                dateObj.lowScale = Scale(root, from_=0, to=100, orient=HORIZONTAL, length=75, label='      Low')
                dateObj.lowScale.bind("<ButtonRelease-1>", lambda event : updateScalesValues(scales))
                dateObj.lowScale.pack()
                dateObj.lowScale.set(lowValue)
                dateObj.lowScale.place(anchor='center', x=100 + (i * 100), y=255)

                scales.append(dateObj)

                i += 1
            return scales
        scales = renderScales(levelsData)
        # On app mount update
        updateScalesValues(scales)

        ###################################################
        # SETTINGS MODAL
        ###################################################

        def startSettingsModal():

            # Local Storage
            savedSettings = getSettingsObj()

            savedHeight = StringVar()
            savedHeight.set(savedSettings.resolution.y)

            savedWidth = StringVar()
            savedWidth.set(savedSettings.resolution.x)

            # Create frame and overlay
            settingsFrame = Frame(root, background='gray50')
            settingsFrame.pack()
            settingsFrame.place(height=330, width=400)

            # Resolution Settings
            resFrame = Frame(settingsFrame, relief='ridge')
            resFrame.pack()
            resFrame.place(anchor='nw', width=150, height=75, x=20, y=20)

            # Resolution label
            resNameLbl = Label(resFrame, text='Resolution')
            resNameLbl.pack(side=TOP)

            # Resolution dropdown
            print('Saved Setting: ', savedSettings.resolution.x)
            if savedSettings.resolution.y == '1440':
                savedResolution.set("1440p");
            else:
                savedResolution.set("1080p");

            resRadio1080p = Radiobutton(resFrame, text="1080p", variable=savedResolution, value="1080p");
            resRadio1080p.pack();
            resRadio1080p.place(anchor='center', x=75, y=30);

            resRadio1440p = Radiobutton(resFrame, text="1440p", variable=savedResolution, value="1440p");
            resRadio1440p.pack();
            resRadio1440p.place(anchor='center', x=75, y=50);

            # Stay on top
            stayTopFrame = Frame(settingsFrame, relief='ridge')
            stayTopFrame.pack()
            stayTopFrame.place(anchor='ne', width=150, height=75, x=380, y=20)

            stayTopLabel = Label(stayTopFrame, text='Stay On Top')
            stayTopLabel.pack()
            stayTopLabel.place(anchor='nw', x=5, y=5)

            stayTop = IntVar()
            stayTop.set(int(savedSettings.stayOnTop.value))
            stayTopCheck = Checkbutton(stayTopFrame, variable=stayTop, onvalue=1, offvalue=0 )
            stayTopCheck.pack()
            stayTopCheck.place(anchor='ne', x=145, y=5)

            def handleOKSettingsModal(settingsFrame):

                # Get resolution settings
                if savedResolution.get() == '1440p':
                    widthSetting = '2560'
                    heightSetting = '1440'
                else:
                    widthSetting = '1920'
                    heightSetting = '1080'

                stringToWrite = '['

                # Serialize resolution settings
                stringToWrite += 'resolution:{'
                # Width
                stringToWrite += 'x:' + widthSetting
                # New Item
                stringToWrite += ','
                # Height
                stringToWrite += 'y:' + heightSetting + '}'

                # Close String
                stringToWrite += ']'

                # # Serialize stay on top setting
                stringToWrite += '[stayOnTop:{value:' + str(stayTop.get()) + '}]'

                # Write to file
                settingsFile = open(settingsPath, 'w')
                settingsFile.write(stringToWrite)
                settingsFile.close()

                checkIfTop(bool(stayTop.get()))

                # Remove Gui
                settingsFrame.destroy()

            # Render Ok button
            okBtn = Button(settingsFrame, text='OK', command=lambda: handleOKSettingsModal(settingsFrame))
            okBtn.pack()
            okBtn.place(anchor='center', width=75, height=25, x=150, y=300)

            # Update log
            setLogMessage('Settings Saved')

            def handleCancelSettingsModal(settingsFrame):
                settingsFrame.destroy()
                setLogMessage('Changes to Settings Discarded')

            # Render cancel button
            cancelBtn = Button(settingsFrame, text='Cancel', command=lambda: handleCancelSettingsModal(settingsFrame))
            cancelBtn.pack()
            cancelBtn.place(anchor='center', width=75, height=25, x=250, y=300)

        # Render settings Button
        def renderSettingsBtn():

            img = Image.open(getPath("assets\\gear.png"))
            img.resize((50, 50), Image.ANTIALIAS)
            finalImg = ImageTk.PhotoImage(img)
            settingsBtn = Button(root, image=finalImg, command=startSettingsModal)
            settingsBtn.pack()
            settingsBtn.image = finalImg
            settingsBtn.place(anchor='center', x=380, y=310)
        renderSettingsBtn()

        ######################################################
        # INFO MODAL
        ######################################################

        def startInfoModal():
            # Create frame and overlay
            infoFrame = Frame(root, background='gray50')
            infoFrame.pack()
            infoFrame.place(height=330, width=400)

            # Event handler for OK Button
            def handleOKInfoModal(infoFrame):
                infoFrame.destroy()

            # Render Ok button
            okBtn = Button(infoFrame, text='OK', command=lambda: handleOKInfoModal(infoFrame))
            okBtn.pack()
            okBtn.place(anchor='center', width=75, height=25, x=200, y=310)

            # Render Hotkeys Frame
            hotFrame = Frame(infoFrame)
            hotFrame.pack()
            hotFrame.place(anchor='nw', width=360, height=160, x=20, y=10)

            # Hotkey Title Label
            hotTitleLbl = Label(hotFrame, text='Hotkeys\nAction triggers after Right Alt is released\nRelease all other keys while triggering hotkey')
            hotTitleLbl.pack(side=TOP)

            # Proximity hotkeys frame
            proxFrame = Frame(hotFrame, bd=2, relief='ridge')
            proxFrame.pack()
            proxFrame.place(width=120, height=90, x=0, y=60, anchor='nw')

            proxTitle = Label(proxFrame, text='Proximity', anchor='center')
            proxTitle.pack(side=TOP)

            proxActionsContent = ' High:\nLow:\n Mute:'
            proxActions = Label(proxFrame, anchor='nw', text=proxActionsContent)
            proxActions.pack()
            proxActions.place(width=55, height=60, anchor='nw', y=20, x=0)

            proxKeysContent = ' RAlt + p\nRAlt + l\nRAlt + ,'
            proxKeys = Label(proxFrame, anchor='nw', text=proxKeysContent)
            proxKeys.pack()
            proxKeys.place(width=55, height=60, anchor='nw', y=20, x=60)

            # Unit hotkeys frame
            unitFrame = Frame(hotFrame, bd=2, relief='ridge')
            unitFrame.pack()
            unitFrame.place(width=119, height=90, x=120, y=60, anchor='nw')

            unitTitle = Label(unitFrame, text='Unit', anchor='center')
            unitTitle.pack(side=TOP)

            unitActionsContent = ' High:\nLow:\n Mute:'
            unitActions = Label(unitFrame, anchor='nw', text=unitActionsContent)
            unitActions.pack()
            unitActions.place(width=55, height=60, anchor='nw', y=20, x=0)

            unitKeysContent = 'RAlt + [\nRAlt + ;\nRAlt + .'
            unitKeys = Label(unitFrame, anchor='nw', text=unitKeysContent)
            unitKeys.pack()
            unitKeys.place(width=55, height=60, anchor='nw', y=20, x=60)

            # Leadership hotkeys frame
            leadershipFrame = Frame(hotFrame, bd=2, relief='ridge')
            leadershipFrame.pack()
            leadershipFrame.place(width=120, height=90, x=239, y=60, anchor='nw')

            leadershipTitle = Label(leadershipFrame, text='Leadership', anchor='center')
            leadershipTitle.pack(side=TOP)

            leadershipActionsContent = ' High:\nLow:\n Mute:'
            leadershipActions = Label(leadershipFrame, anchor='nw', text=leadershipActionsContent)
            leadershipActions.pack()
            leadershipActions.place(width=55, height=60, anchor='nw', y=20, x=0)

            leadershipKeysContent = 'RAlt + ]\nRAlt + \'\nRAlt + /'
            leadershipKeys = Label(leadershipFrame, anchor='nw', text=leadershipKeysContent)
            leadershipKeys.pack()
            leadershipKeys.place(width=55, height=60, anchor='nw', y=20, x=60)

            # Buy me a coffee frame

            coffeeFrame = Frame(infoFrame)
            coffeeFrame.pack()
            coffeeFrame.place(anchor='nw', width=360, height=110, x=20, y=175)

            coffeeMessage = 'Buy Me a Beer?\nHas this app improved your gaming experience? \nAre you pulling off headshots at 400m because you\'re\n no longer distracted by all those PESKY callouts?\n We\'re glad you like the app!\nPlease consider buying us a beer for our hard work.'

            coffeeMessageFrame = Label(coffeeFrame, text=coffeeMessage, pady=0)
            coffeeMessageFrame.pack()
            coffeeMessageFrame.place(width=300, height=90, anchor='n', x=180, y=2)

            def openBeerLink():
                url = 'https://www.buymeacoffee.com/rooseveltcat'
                webbrowser.open_new(url)
            # Render beer Button
            img = Image.open(getPath("assets\\beer.png"))
            img.resize((50, 50), Image.ANTIALIAS)
            finalImg = ImageTk.PhotoImage(img)
            beerBtn = Button(coffeeFrame,  image=finalImg,command=openBeerLink)
            beerBtn.pack()
            beerBtn.image = finalImg
            beerBtn.place(anchor='se', width=35, height=35, x=355, y=105)

        # Render info Button
        def renderInfoBtn():

            img = Image.open(getPath("assets\\info.png"))
            img.resize((50, 50), Image.ANTIALIAS)
            finalImg = ImageTk.PhotoImage(img)
            infoBtn = Button(root, image=finalImg, command=startInfoModal)
            infoBtn.pack()
            infoBtn.image = finalImg
            infoBtn.place(anchor='center', x=380, y=270)
        renderInfoBtn()
        ######################################################

        # Log Label
        def renderLog():
            # Initial Log Message
            settingsObj = getSettingsObj()
            message = 'Resolution at ' + settingsObj.resolution.x + ' x ' + settingsObj.resolution.y + '.  Click button to change.  →'

            # Render
            log = actionsLog = Label(root, text=message, fg='white', bg='black', anchor='center', justify=LEFT, relief='ridge')
            actionsLog.pack()
            actionsLog.place(bordermode=INSIDE, width=300, height=25, x=200, y=310, anchor='center')
            return log
        log = renderLog()

        # call update function
        checkIfTop()
        root.after(500, lambda: update(levelsData, frames, log))
        root.mainloop()

    render()


import numpy as np
import time

debug = True

class LinUCB:
    def __init__(self, articles=None):
        self.alpha = 0.25
        self.r1 = 0.6
        self.r0 = -16
        self.d = 6  # dimension of user features
        self.Aa = {}  # Aa : collection of matrix to compute disjoint part for each article a, d*d
        self.AaI = {}  # AaI : store the inverse of all Aa matrix

        self.ba = {}  # ba : collection of vectors to compute disjoin part, d*1
        self.theta = {}

        self.a_max = 0

        self.x = None
        self.xT = None

        if articles is not None:
            self.articles = articles
        else:
            self.articles = []

    def init_article_if_absent(self, article):
        if article not in self.articles:
            self.articles.append(article)
            self.Aa[article] = np.identity(self.d)  # 创建单位矩阵
            self.ba[article] = np.zeros((self.d, 1))
            self.AaI[article] = np.identity(self.d)
            self.theta[article] = np.zeros((self.d, 1))

    def init_all_articles(self, articles):
        for article in articles:
            self.init_article_if_absent(article)

    def update(self, reward):
        if reward == 1.0:
            r = self.r1
        elif reward == 0.0:
            r = self.r0
        else:
            print(f"reward:{reward} is not valid")
            r = 0

        self.Aa[self.a_max] += np.dot(self.x, self.xT)
        self.ba[self.a_max] += r * self.x
        self.AaI[self.a_max] = np.linalg.inv(self.Aa[self.a_max])
        self.theta[self.a_max] = np.dot(self.AaI[self.a_max], self.ba[self.a_max])

    def recommend(self, user_features, articles=None):
        xaT = np.array([user_features])
        xa = np.transpose(xaT)  # d * 1

        if articles is None:
            articles = self.articles

        AaI_tmp = np.array([self.AaI[article] for article in articles]) # (n, d, d)
        theta_tmp = np.array([self.theta[article] for article in articles]) #(n, d, 1)
        if debug:
            exploit = np.dot(xaT, theta_tmp)
            explore = np.sqrt(np.dot(np.dot(xaT, AaI_tmp), xa))
            idx = np.argmax(exploit + self.alpha * explore)
        else:
            idx = np.argmax(np.dot(xaT, theta_tmp) + self.alpha * np.sqrt(np.dot(np.dot(xaT, AaI_tmp), xa)))
        art_max = articles[idx]

        self.x = xa
        self.xT = xaT
        self.a_max = art_max

        return self.a_max

# def policy_evaluator(T: int, recommend, stream, articles):
#     total_r = 0.0
#     for i in range(T):
#         features, a, r = stream.next()
#         while recommend(features) != a:
#             features, a, r = stream.next()
#         total_r += r
#     return total_r/T

def get_train_data(file_name):
    with open(file_name, 'r', encoding='utf8') as f:
        for line in f:
            sp = line.strip().split('\u0001')
            features = list(map(lambda s: float(s), sp[0].split(',')))
            arm = sp[1]
            r = float(sp[2])
            yield (features, arm, r)

if __name__ == '__main__':
    linUCB = LinUCB()

    total_r = 0.0
    T = 1000

    # log内容，一行：
    # feature1 feature2 ...feature6\tarticle_id\tclick_or_not
    # 0.1 0.3 0 1 0 0\t123456\t0
    data_generator = get_train_data('/Users/jiananliu/work/AISEALs/data/ee/train.txt')
    # arms = []
    # for features, a, r in data_generator:
    #     if a not in arms:
    #         arms.append(a)
    #         # print(len(arms))
    # print(set(arms))

    for i in range(T):
        r = None
        num_not_use = 0
        t1 = time.time()
        for features, a, r in data_generator:
            num_not_use += 1
            linUCB.init_article_if_absent(a)
            if linUCB.recommend(features) == a:
                break
        t2 = time.time()
        if r is not None:
            linUCB.update(r)
            total_r += r

        if i % 1 == 0:
            print(f'evaluate step:{i} mean reward:{total_r/T} arm set:{len(linUCB.articles)}, num not use:{num_not_use}, use ts:{(t2-t1)*1000}ms, avg:{(t2-t1)*1000/num_not_use}ms')


import os
import re
import json
from get_commands import Retrieve
from post_results import Deliver
from register_task import Task

def format_response(status_code, result, message, log, **kwargs):
    response = {'outcome': result}
    if message:
        response['message'] = message
    if kwargs:
        for k, v in kwargs.items():
            if v:
                response[k] = v
    if log:
        log['response'] = response
        print(log)
    return {'statusCode': status_code, 'body': json.dumps(response)}

def lambda_handler(event, context):
    region = re.search('arn:aws:lambda:([^:]+):.*', context.invoked_function_arn).group(1)
    deployment_name = os.environ['DEPLOYMENT_NAME']
    results_queue_expiration = int(os.environ['RESULTS_QUEUE_EXPIRATION'])
    enable_task_results_logging = os.environ['ENABLE_TASK_RESULTS_LOGGING']
    log = {'event': event}
    results = None
    detail = None

    user_id = event['requestContext']['authorizer']['user_id']
    data = json.loads(event['body'])
    try:
        command = data['command']
    except:
        return format_response(400, 'failed', 'invalid request', log)

    if command not in ['register_task', 'get_commands', 'post_results']:
        return format_response(400, 'failed', f'{command} is not a valid command', log)

    if 'detail' in data:
        detail = data['detail']

    if 'results' in data:
        results = data['results']

    if command == 'register_task':
        if not detail:
            return format_response(400, 'failed', 'missing detail', log)
        else:
            t = Task(region, deployment_name, user_id, detail, log)
            response = t.registration()
            return response

    if command == 'get_commands':
        if not detail:
            return format_response(400, 'failed', 'missing detail', log)
        else:
            r = Retrieve(region, deployment_name, user_id, detail, log)
            response = r.retrieve_commands()
            return response

    if command == 'post_results':
        if not results:
            return format_response(400, 'failed', 'missing results', log)
        else:
            d = Deliver(region, deployment_name, results_queue_expiration, enable_task_results_logging, user_id, results, log)
            response = d.deliver_result()
            return response


class AlgoRunAs:
    def __init__(self, travian_object):
        global gid_dict
        self.TRAVIAN = travian_object

    def _old_all_auto_by_min_resource(self):
        adventure_time = time.time()
        last_oid_dict = {}.fromkeys(self.TRAVIAN.village_newdid_list)
        pprint_two_dicts_not_empty(self.TRAVIAN.Village.resource_status, self.TRAVIAN.Village.building_status)
        while 1:
            try:
                for newdid in self.TRAVIAN.village_newdid_list:
                    self.TRAVIAN.goto(newdid)
                    if len(self.TRAVIAN.Village.resource_status["農場"]) == 15:  # 15 田
                        status_dict = self.TRAVIAN.Village.resource_status[gid_dict[str(4)]]
                        min_food_level = status_dict[min(status_dict, key=status_dict.get)]
                        brick_level = self.TRAVIAN.Village.resource_status["泥坑"]["16"]
                        wood_level = self.TRAVIAN.Village.resource_status["伐木場"]["3"]
                        steel_level = self.TRAVIAN.Village.resource_status["鐵礦場"]["4"]
                        if brick_level < min_food_level - 3:
                            oid = "16"
                            gid = "2"
                        elif wood_level < min_food_level - 3:
                            oid = "3"
                            gid = "1"
                        elif steel_level < min_food_level - 3:
                            oid = "4"
                            gid = "3"
                        else:
                            oid = min(status_dict, key=status_dict.get)
                            gid = "4"
                    else:
                        stock_list = self.TRAVIAN.Village.stock
                        if stock_list[4] < 15:
                            gid = "4"  # farm
                        else:
                            gid = stock_list.index(min(stock_list[0:4])) + 1
                        status_dict = self.TRAVIAN.Village.resource_status[gid_dict[str(gid)]]
                        oid = min(status_dict, key=status_dict.get)
                        if len(status_dict) > 1:
                            if oid == last_oid_dict[newdid]:
                                tmp_dict = dict(status_dict)
                                tmp_dict.pop(oid)
                                oid = min(tmp_dict, key=tmp_dict.get)
                    status = self.TRAVIAN.Village.upgrade(oid)
                    if status == "green":
                        upgrade_item = gid_dict[str(gid)]
                        logger(f"[UPGRADE] : [vid:{newdid}] - {upgrade_item}")
                        last_oid_dict[newdid] = oid
                    time.sleep(random.randint(3, 5))
                time.sleep(random.randint(30, 60))
                if time.time() > adventure_time + random.randint(3600, 4800):
                    self.TRAVIAN.Hero.go_adventure()
                    adventure_time = time.time()
                    time.sleep(random.randint(3, 5))

            except ConnectionError:
                logger("[Error] Connection Error occured.")
            except KeyboardInterrupt:
                logger("[Stop] by Keyboard Interruption.")
                exit(0)

    def _old_build_by_oid(self, build_oid_queue):
        while 1:
            try:
                while len(build_oid_queue) > 0:
                    oid = build_oid_queue[0]
                    status = self.TRAVIAN.Village.upgrade(oid)
                    if status == "green":
                        done_oid = build_oid_queue.pop(0)
                        logger(f"oid({done_oid}) is building.")
                        sec = random.randint(3, 5)
                        time.sleep(sec)
                    else:
                        sec = random.randint(150, 180)
                        logger(f"oid({oid}) skipped. Waiting {sec} seconds.")
                        time.sleep(sec)
                logger("build oid queue is empty now, exit...")
                exit(0)
            except ConnectionError:
                logger("[ERROR] Connection Error occurred!")
                time.sleep(random.randint(180, 200))
                self.TRAVIAN = Travian("ts2", username, password)

    def _old_build_by_gid(self, gid_queue):
        while len(gid_queue) > 0:
            last_gid = str(gid_queue[0])
            self.TRAVIAN.update_all_status()
            if int(last_gid) > 4:
                status_dict = self.TRAVIAN.Village.building_status[gid_dict[last_gid]]
                oid = min(status_dict, key=status_dict.get)
            else:
                status_dict = self.TRAVIAN.Village.resource_status[gid_dict[last_gid]]
                oid = min(status_dict, key=status_dict.get)
                if oid == self.TRAVIAN.Village.last_upgrade_oid:
                    tmp_dict = dict(status_dict)
                    tmp_dict.pop(oid)
                    oid = min(tmp_dict, key=tmp_dict.get)
            status = self.TRAVIAN.Village.upgrade(oid)
            if status == "green":
                logger(f"[UPGRADE] : {gid_dict[last_gid]}")
                time.sleep(random.randint(10, 20))
                gid_queue.pop(0)
            else:
                time.sleep(random.randint(160, 180))
        logger("build oid queue is empty now, exit...")
        exit(0)

    def _old_auto_run_by_min_resource(self):
        adventure_time = time.time()
        while 1:
            try:
                self.TRAVIAN.update_all_status()
                stock_list = self.TRAVIAN.Village.stock
                if stock_list[4] < 15:
                    gid = 4  # farm
                else:
                    gid = stock_list.index(min(stock_list[0:4])) + 1
                status_dict = self.TRAVIAN.Village.resource_status[gid_dict[str(gid)]]
                oid = min(status_dict, key=status_dict.get)
                if len(status_dict) > 1:
                    if oid == self.TRAVIAN.Village.last_upgrade_oid:
                        tmp_dict = dict(status_dict)
                        tmp_dict.pop(oid)
                        oid = min(tmp_dict, key=tmp_dict.get)
                status = self.TRAVIAN.Village.upgrade(oid)
                if status == "green":
                    time.sleep(random.randint(10, 20))
                else:
                    time.sleep(random.randint(160, 180))
                if time.time() > adventure_time + 1800:
                    self.TRAVIAN.Hero.go_adventure()
                    adventure_time = time.time()
            except ConnectionError:
                logger("[ERROR] Connection Error.")
                time.sleep(200)


# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QPushButton
from PyQt5.QtCore import pyqtSlot
import backend
import time
import threading
import os
import re
import subprocess
import SpotipyManager
import Excel

indexread = False
index = 0
startTime = 0
endTime = 0
song = ""
artist = ""

if os.name == "nt":
    import ctypes
    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("spotifylyrics.version1")

class Communicate(QtCore.QObject):
    signal = QtCore.pyqtSignal(str, str)

class Ui_Form(object):
    sync = False
    ontop = False
    open_spotify = False

    if os.name == "nt":
        settingsdir = os.getenv("APPDATA") + "\\SpotifyLyrics\\"
    else:
        settingsdir = os.path.expanduser("~") + "/.SpotifyLyrics/"
    def __init__(self):
        super().__init__()

        self.comm = Communicate()
        self.comm.signal.connect(self.change_lyrics)
        self.setupUi(Form)
        self.set_style()
        Excel.setupExcelFormatting()
        self.load_save_settings()
        if self.open_spotify:
            self.spotify()
        self.start_thread()

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(550, 610)
        Form.setMinimumSize(QtCore.QSize(350, 310))
        self.gridLayout_2 = QtWidgets.QGridLayout(Form)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_songname = QtWidgets.QLabel(Form)
        self.label_songname.setObjectName("label_songname")
        self.label_songname.setOpenExternalLinks(True)
        self.horizontalLayout_2.addWidget(self.label_songname, 0, QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.comboBox = QtWidgets.QComboBox(Form)
        self.comboBox.setGeometry(QtCore.QRect(160, 120, 69, 22))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox, 0, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.fontBox = QtWidgets.QSpinBox(Form)
        self.fontBox.setMinimum(1)
        self.fontBox.setProperty("value", 10)
        self.fontBox.setObjectName("fontBox")
        self.horizontalLayout_2.addWidget(self.fontBox, 0, QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.textBrowser = QtWidgets.QTextBrowser(Form)
        self.textBrowser.setObjectName("textBrowser")
        self.textBrowser.setAcceptRichText(True)
        self.textBrowser.setStyleSheet("font-size: %spt;" % self.fontBox.value() * 2)
        self.textBrowser.setFontPointSize(self.fontBox.value())
        self.verticalLayout_2.addWidget(self.textBrowser)
        self.gridLayout_2.addLayout(self.verticalLayout_2, 2, 0, 1, 1)
        #self.button = QtGui.QPushButton('Test', self)
        #self.button.clicked.connect(self.handleButton)
        self.retranslateUi(Form)
        self.fontBox.valueChanged.connect(self.update_fontsize)
        self.comboBox.currentIndexChanged.connect(self.optionschanged)

        self.button = QPushButton("&Erase all",Form)
        self.button.setToolTip('This is an example button')
        self.button.move(50,550)
        self.button.clicked.connect(Excel.eraseExcelData)

        QtCore.QMetaObject.connectSlotsByName(Form)
        Form.setTabOrder(self.textBrowser, self.comboBox)
        Form.setTabOrder(self.comboBox, self.fontBox)

    def load_save_settings(self, save=False):
        settingsfile = self.settingsdir + "settings.ini"
        if save is False:
            if os.path.exists(settingsfile):
                with open(settingsfile, 'r') as settings:
                    for line in settings.readlines():
                        lcline = line.lower()
                        if "syncedlyrics" in lcline:
                            if "true" in lcline:
                                self.sync = True
                            else:
                                self.sync = False
                        if "alwaysontop" in lcline:
                            if "true" in lcline:
                                self.ontop = True
                            else:
                                self.ontop = False
                        if "fontsize" in lcline:
                            set = line.split("=",1)[1].strip()
                            try:
                                self.fontBox.setValue(int(set))
                            except ValueError:
                                pass
                        if "openspotify" in lcline:
                            if "true" in lcline:
                                self.open_spotify = True
                            else:
                                self.open_spotify = False

            else:
                directory = os.path.dirname(settingsfile)
                if not os.path.exists(directory):
                    os.makedirs(directory)
                with open(settingsfile, 'w+') as settings:
                    settings.write("[settings]\nAlwaysOnTop=False\nFontSize=10\nOpenSpotify=False")
            if self.ontop is True:
                Form.setWindowFlags(Form.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
                self.comboBox.setItemText(2, ("Always on Top (on)"))
                Form.show()
            if self.open_spotify is True:
                self.comboBox.setItemText(4, ("Start spotify (on)"))
        else:
            with open(settingsfile, 'w+') as settings:
                settings.write("[settings]\n")
                if self.ontop is True:
                    settings.write("AlwaysOnTop=True\n")
                else:
                    settings.write("AlwaysOnTop=False\n")
                if self.open_spotify is True:
                    settings.write("OpenSpotify=True\n")
                else:
                    settings.write("AlwaysOnTop=False\n")
                settings.write("FontSize=%s" % str(self.fontBox.value()))

    def optionschanged(self):
        current_index = self.comboBox.currentIndex()
        if current_index == 1:
            if self.ontop is False:
                self.ontop = True
                Form.setWindowFlags(Form.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
                self.comboBox.setItemText(1, ("Always on Top (on)"))
                Form.show()
            else:
                self.ontop = False
                Form.setWindowFlags(Form.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
                self.comboBox.setItemText(1, ("Always on Top"))
                Form.show()
        elif current_index == 2:
            self.load_save_settings(save=True)
        elif current_index == 3:
            if self.open_spotify is True:
                self.open_spotify = False
                self.comboBox.setItemText(3, ("Open Spotify"))
            else:
                self.open_spotify = True
                self.comboBox.setItemText(3, ("Open Spotify (on)"))
        else:
            pass
        self.comboBox.setCurrentIndex(0)

    def set_style(self):
        if os.path.exists(self.settingsdir + "theme.ini"):
            themefile = self.settingsdir + "theme.ini"
        else:
            themefile = "theme.ini"
        if os.path.exists(themefile):
            with open(themefile, 'r') as theme:
                try:
                    for setting in theme.readlines():
                        lcsetting = setting.lower()
                        try:
                            set = setting.split("=",1)[1].strip()
                        except IndexError:
                            set = ""
                        if "windowopacity" in lcsetting:
                            Form.setWindowOpacity(float(set))
                        if "backgroundcolor" in lcsetting:
                            Form.setStyleSheet("background-color: %s" % set)
                        if "lyricsbackgroundcolor" in lcsetting:
                            style = self.textBrowser.styleSheet()
                            style = style + "background-color: %s;" % set
                            self.textBrowser.setStyleSheet(style)
                        if "lyricstextcolor" in lcsetting:
                            style = self.textBrowser.styleSheet()
                            style = style + "color: %s;" % set
                            self.textBrowser.setStyleSheet(style)
                        if "songnamecolor" in lcsetting:
                            style = self.label_songname.styleSheet()
                            style = style + "color: %s;" % set
                            self.label_songname.setStyleSheet(style)
                        if "fontboxbackgroundcolor" in lcsetting:
                            style = self.fontBox.styleSheet()
                            style = style + "background-color: %s;" % set
                            self.comboBox.setStyleSheet(style)
                            self.fontBox.setStyleSheet(style)
                        if "fontboxtextcolor" in lcsetting:
                            style = self.fontBox.styleSheet()
                            style = style + "color: %s;" % set
                            self.comboBox.setStyleSheet(style)
                            self.fontBox.setStyleSheet(style)
                        if "songnameunderline" in lcsetting:
                            if "true" in set.lower():
                                style = self.label_songname.styleSheet()
                                style = style + "text-decoration: underline;"
                                self.label_songname.setStyleSheet(style)
                except Exception:
                    pass
        else:
            self.label_songname.setStyleSheet("color: black; text-decoration: underline;")
            pass

    def resource_path(self, relative_path):
        try:
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")
        return os.path.join(base_path, relative_path)

    def update_fontsize(self):
        self.textBrowser.setFontPointSize(self.fontBox.value())
        style = self.textBrowser.styleSheet()
        style = style.replace('%s' % style[style.find("font"):style.find("pt;") + 3], '')
        style = style.replace('p ', '')
        self.textBrowser.setStyleSheet(style + "p font-size: %spt;" % self.fontBox.value() * 2)
        lyrics = self.textBrowser.toPlainText()
        self.textBrowser.setText(lyrics)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Spotify Lyrics - {}".format(backend.version())))
        Form.setWindowIcon(QtGui.QIcon(self.resource_path('icon.png')))
        self.textBrowser.setText(_translate("Form", "I don't think Spotify is open")) ##THIS Writes stuff
        self.fontBox.setToolTip(_translate("Form", "Font Size"))
        self.comboBox.setItemText(0, _translate("Form", "Options"))
        self.comboBox.setItemText(1, _translate("Form", "Always on Top"))
        self.comboBox.setItemText(2, _translate("Form", "Save Settings"))
        self.comboBox.setItemText(3, _translate("Form", "Open Spotify"))

    def newSong(self, songname):
        Excel.manageIndex(songname)

        Excel.writeNewSongToFile(songname)

    def lyrics_thread(self, comm):
        global song
        global artist
        oldsongname = ""
        style = self.label_songname.styleSheet()
        if style == "":
            color = "color: black"
        else:
            color = style
        while True:
            songname = backend.getwindowtitle()
            if oldsongname != songname and songname != "":
                print("Changed!")
                self.newSong(songname)
            oldsongname = songname

            print("Playing: " + song)

            song, artist = backend.getSongData(songname)

            comm.signal.emit(songname, "Playing song " + song + " by " + artist)
            if songname != "Spotify" and songname != "": #when you switch songs

                lyrics, url, timed = backend.getlyrics(songname)
                if url == "":
                    header = songname
                else:
                    header = '''%s''' % (color, url, songname)
            time.sleep(1)

    def start_thread(self):
        lyricsthread = threading.Thread(target=self.lyrics_thread, args=(self.comm,))
        lyricsthread.daemon = True
        lyricsthread.start()

    def change_lyrics(self, songname, lyrics):
        _translate = QtCore.QCoreApplication.translate
        self.label_songname.setText(_translate("Form", songname))
        self.textBrowser.setText(_translate("Form", lyrics))
        self.textBrowser.scrollToAnchor("#scrollHere")

    def spotify(self):
        if os.name == "nt":
            path = os.getenv("APPDATA") + '\Spotify\Spotify.exe'
            subprocess.Popen(path)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    Form.show()
    sys.exit(app.exec_())


class TNode:
    def __init__(self,val,w):
        self.val=val
        self.left=None
        self.right=None
        self.w=w

def dfsSum(curr,sum,len):
    global s
    global maxLen
    if sum==s:
        if curr.left!=None and curr.left.w==0:
            dfsSum(curr.left, sum, len + 1)
        elif curr.right!=None and curr.right.w==0:
            dfsSum(curr.right, sum, len + 1)
        else:
            if len > maxLen: maxLen = len
    elif sum<s:
        if curr.left: dfsSum(curr.left,curr.left.w+sum,len+1)
        if curr.right: dfsSum(curr.right, curr.right.w + sum, len + 1)

def dfs(root):
    dfsSum(root,root.w,1)
    if root.left: dfs(root.left)
    if root.right: dfs(root.right)

line=[int(x) for x in input().split()]
Nv=line[0]
rootIdx=line[1]
TNodesInfo=[[]]
for i in range(1,Nv+1):
    TNodesInfo.append([int(x) for x in input().split()])
TNodesMap={0:None}
for i in range(1,Nv+1):
    TNodesMap[TNodesInfo[i][0]]=TNode(TNodesInfo[i][0],TNodesInfo[i][3])
for i in range(1,Nv+1):
    curr=TNodesMap[TNodesInfo[i][0]]
    curr.left=TNodesMap[TNodesInfo[i][1]]
    curr.right=TNodesMap[TNodesInfo[i][2]]
root=TNodesMap[rootIdx]

s=int(input())
maxLen=0
dfs(root)
print(maxLen)


"""Calculates P values from a given variants file and baseline.

Takes in a varscan SNP file and a baseline file
and in turn calculates P-values for each variant.
"""
import logging
import os
import sys
import numpy as np
import pandas as pd
from scipy import stats
import vcf

log = logging.getLogger(__name__)

def build_parser(parser):
    parser.add_argument('sample_variants',
                        help='Variants file for a sample')
    parser.add_argument('error_baseline',
                        help='An error profile baseline file to analyze against')
    parser.add_argument('output_file',
                        help='Output file to write to')
    parser.add_argument('--full_output', action='store_true',
                        help="Output full merged data from error profile and variant file as csv")

def action(args):
    ''' Takes in arguments for sample_variants, error_baseline,
    output_file and calculates P-values for variants.'''
    sample_variants = args.sample_variants
    error_baseline = args.error_baseline
    output_file = args.output_file
    full_output = args.full_output

    # Check that required input files exist
    if not os.path.isfile(sample_variants):
        print("Sample variants file not found. Exiting.")
        sys.exit()
    if not os.path.isfile(error_baseline):
        print("Error baseline file not found. Exiting.")
        sys.exit()

    # build pandas dataframe for sample from VCF
    columns = ['position_base','chromosome','position','var_base','ref_base','var_freq_pct','var_freq_flt','var_pval']
    vcf_reader = vcf.Reader(open(sample_variants))
    row_list = []
    for record in vcf_reader:
        call_data = record.samples[0].data
        # Need following data: Chromosome, Position, Var Base, Ref Base, Var Freq
        row_dict = {}
        row_dict['chromosome'] = record.CHROM
        row_dict['position'] = record.POS
        if len(record.ALT) == 1:
            row_dict['var_base'] = record.ALT[0]
        else:
            # May need to support this for indels/large deletions in future versions
            print("Multiple variant bases...not supported - passing")
            continue
        row_dict['ref_base'] = record.REF
        row_dict['var_freq_pct'] = call_data.FREQ
        row_dict['var_freq_flt'] = percent_to_float(call_data.FREQ)
        row_dict['var_pval'] = call_data.PVAL
        row_dict['position_base'] = str(row_dict['chromosome']) + ':' + str(row_dict['position']) + ':' + str(row_dict['var_base'])
        row_list.append(row_dict)
    sample_df = pd.DataFrame(row_list, columns=columns)

    # create another dataframe from the error baseline
    dtype={'chrom':str,'position':int,'base':str,'mean':float,'std':float,'alpha':float,'beta':float}

    # Read error_baseline file in from csv file
    error_df = pd.read_csv(error_baseline, dtype=dtype)
    error_df['position_base'] = error_df.apply(get_error_position_base_key,axis=1)
    error_df.set_index('position_base')

    # do inner join with sample_df on the common key position_base (ie chrom:position:base)
    merged_df = sample_df.merge(error_df, on='position_base',how='inner')

    # uw_dec_p_value calculated using beta distribution parameters
    merged_df['uw_dec_p_value'] = merged_df.apply(calculate_p_value,axis=1)

    # used in full output only
    merged_df['pdf'] = merged_df.apply(calculate_pdf,axis=1)
    merged_df['cdf'] = merged_df.apply(calculate_cdf,axis=1)

    # drop rows with null results
    final_df = merged_df[merged_df['uw_dec_p_value'].isnull()==False]

    # Write output file
    if full_output:
        merged_df_to_full_output(final_df, output_file)
    else:
        merged_df_to_munge_ready_output(final_df, output_file)

def get_sample_position_base_key(row):
    ''' Creates a position key consisting of the chromosome, position, and base'''
    return str(row['Chrom']) + ":" + str(row['Position']) + ":" + str(row['Var'])

def get_error_position_base_key(row):
    ''' Creates a position key consisting of the chromosome, position, and base'''
    return str(row['chrom']) + ":" + str(row['position']) + ":" + str(row['base'])

def calculate_pdf(row):
    ''' Calculates the probability density function given beta values.'''
    if row['var_freq_flt'] and row['alpha'] and row['beta']:
        var_freq_flt = row['var_freq_flt']
        if var_freq_flt == 1.0:
            var_freq_flt = var_freq_flt - 0.0001 #0.9999
        return stats.beta.pdf(var_freq_flt, row['alpha'], row['beta'])
    else:
        return None

def calculate_cdf(row):
    ''' Calculates the cumulative density function given beta distribution parameters.'''
    if row['var_freq_flt'] and row['alpha'] and row['beta']:
        var_freq_flt = row['var_freq_flt']
        if var_freq_flt == 1.0:
            var_freq_flt = var_freq_flt - 0.0001 #0.9999
        return stats.beta.cdf(var_freq_flt, row['alpha'], row['beta'])
    else:
        return None

def calculate_p_value(row):
    """ Calculates the cdf and inverts it."""
    if row['var_freq_flt'] and row['alpha'] and row['beta']:
        var_freq_flt = row['var_freq_flt']
        if var_freq_flt == 1.0:
            var_freq_flt = var_freq_flt - 0.0001 #0.9999
        return (1 - stats.beta.cdf(var_freq_flt, row['alpha'], row['beta']))
    else:
        return None

def percent_to_float(val):
    '''turns a percentage to a float.'''
    return float(val.strip('%'))/100

def merged_df_to_full_output(merged_df, output_file):
    '''output full csv'''
    merged_df.to_csv(output_file)

def merged_df_to_munge_ready_output(merged_df, output_file):
    ''' Just need to output:
    generic\tp.value\tchr\tstart\tstop\tref_base\tvar_base\n
    '''
    out_f = open(output_file, 'w')
    # loop through dataframe, write row to file
    for index, row in merged_df.iterrows():
        line = "generic\t" + str(row['uw_dec_p_value']) + "\t" + str(row['chrom']) + "\t" + str(row['position_x']) + "\t" + str(row['position_x']) + "\t" + str(row['ref_base']) + "\t" + str(row['var_base']) + "\n"
        out_f.write(line)
    out_f.close()


import skimage.io as io
import numpy as np
import matplotlib.pyplot as plt
import skimage.util.noise as noise
import skimage.util as util
import scipy.ndimage as ndi
from numpy.fft import fftshift, fft2, ifft2, ifftshift
import skimage.exposure as ex

# Read the input image
img = io.imread('5.3.01.tiff')

# Add salt and pepper noise to the image
sp = noise.random_noise(img, mode='s&p', amount=0.3)

# Add periodic noise
r, c = img.shape
x, y = np.mgrid[0:r, 0:c].astype('float32')
p = np.sin(x / 3 + y / 3) + 1.0
gp = (2 * util.img_as_float(img) + p / 2) / 3

# Display images with salt and pepper noise and periodic noise
plt.subplot(1, 2, 1)
plt.title('Image with salt and pepper noise')
plt.imshow(sp, cmap='gray')
plt.subplot(1, 2, 2)
plt.title('Image with Periodic Noise')
plt.imshow(gp, cmap='gray')
plt.show()

# Apply median filtering to remove salt and pepper noise
img_med = ndi.median_filter(sp, 3)

# Apply the band-reject filter to the image with periodic noise
gf=fftshift(fft2(gp))
mg_spectrum=np.abs(gf)
temp= ex.rescale_intensity(abs(gf),out_range=(0,1))
gf2=util.img_as_ubyte(temp)
gf2[512,512]=0  #center of dft
i,j=np.where(gf2==gf2.max())
z=np.sqrt((x-512)**2+(y-512)**2)
k=1
d=np.sqrt(5832)
br=(z<np.floor(d-k))|(z>np.ceil(d+k))
gfr=gf*br
filtered_gp = np.real(ifft2(ifftshift(gfr)))

# Display the images with removed salt and pepper noise and periodic noise
plt.subplot(1, 2, 1)
plt.title('Removing salt and pepper noise')
plt.imshow(img_med, cmap='gray')
plt.subplot(1, 2, 2)
plt.title('Removing Periodic Noise')
plt.imshow(filtered_gp, cmap='gray')
plt.show()


# Example 1
import numpy as np

X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
y = np.array([1, 1, 2, 2])

from sklearn.svm import SVC

# clf = SVC(gamma='auto')

clf = SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
          decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',
          max_iter=-1, probability=False, random_state=None, shrinking=True,
          tol=0.001, verbose=False)  # 可以根据前面介绍的参数，做出相应改变观察结果变化

clf.fit(X, y)
print(clf.predict([[-0.8, -1]]))

print(clf.support_vectors_)
print(clf.dual_coef_, clf.coef_, clf.intercept_)


n=int(input())

lis=list(map(int,input().split(" ")))

lis=sorted(lis)

ans=0
for i in range(0,len(lis),2):
    ans=lis[i+1]-lis[i]+ans

print(ans)


import os

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import PyPDF2

class DataHandler(object):
    """
    Given data from different sources, DataConverter converts and reformats the data so
    that it can be used in training a neural network. The data can be saved as csv file or
    returned as a pandas DataFrame.

    File naming convention: Element/Compound_lower temperature_upper temperature_temperature increment
    The temperatures in the filenames are in K for all elements.

    Table 1:
    -----------------------------
    Data Source     | File format
    -----------------------------
    FactSage        | .txt
    """

    def __init__(self, source, input_file):
        """

        :param source: name string of the data source as listed in Table 1.
        :param input_file: absolute path of input file
        """
        super(DataHandler, self).__init__()

        # Specify error prompts
        self.errors = {'ERR_VIS_1': '*** ERR_VIS_1: Entered column name is not a valid column name *** ',
                       'ERR_SRC_1': '*** ERR_SRC_1: Entered source is not a valid source ***',
                       'ERR_SRC_2': '*** ERR_SRC_2: Entered file could not be opened ***',
                       'ERR_SVE_1': '*** ERR_SVE_1: Table could not be saved because input_file is None',
                       'ERR_SVE_2': '*** ERR_SVE_2: Table could not be saved because source is None'}

        self.input_file = input_file
        self.table = None
        self.source = None
        self.possible_sources = [None, 'FactSage', 'Barin', 'Dorog']
        self.set_source(source)
        self.id_figure = 1  # Used in specifying a new plot
        self.max_suffix = 1

        if self.source is not None and self.input_file is not None:
            self.load_table()

    def convert(self, set_table=True):
        """
        Loads and converts the table

        :param set_table: If set table is True, the converted table will be saved to self.table.
        If set_table is False, the converted table is returned as pandas DataFrame. This is because
        converting table might be necessary without wanting to change self.table
        :return:
        """

        def text_from_pdf(pdf_file, page_number):
            # creating a pdf file object
            pdf_file_obj = open(pdf_file, 'rb')

            # creating a pdf reader object
            pdf_reader = PyPDF2.PdfFileReader(pdf_file_obj)

            # creating a page object
            page_obj = pdf_reader.getPage(page_number)

            return page_obj.extractText()

        # Treat different sources differently
        if self.source == 'FactSage':
            # Extract the data and temporarily save every column in the txt file into a list
            first = True
            end_of_block = False
            header = 5
            table_dict = dict()
            save_data = []
            column_names = []

            phase_translation = {'Fe': {'S1': 'bcc', 'S2': 'fcc', 'L1': 'liquid', 'G1': 'gas'}}

            element = self.get_element_from_file()

            def table_to_dict():
                """
                Takes the column names and the extracted data and makes a dict of it (easy to convert
                into pd.DataFrame)
                :return:
                """
                for i, c in enumerate(column_names):
                    table_dict[c] = save_data[i]

            with open(self.input_file, 'r') as f:
                for i, line in enumerate(f):
                    #print(i, 'O', line)
                    if i < header:
                        continue

                    # FactSage tables are separated by a row of '_'. If such row occurs, save
                    # the data obtained priorly and reinitialize save_data.
                    if '_' in line:
                        # If the '_' row occurs the first time, there is nothing yet to save
                        if not first and not end_of_block:
                            table_to_dict()
                        elif first:
                            first = False

                        # The row of '_' marks the end and the beginning of a block. In between
                        # are the column names. To extract those, end_of_block marks which row
                        # of '_' was found (first or second).
                        end_of_block = not end_of_block
                    # If end_of_block is True, the line is in between two lines of '_'. Then,
                    # the column names can be extracted.
                    elif end_of_block:
                        # Get the column names
                        column_names = list(filter(lambda v: v != '', line.strip().split(' ')))
                        # Get the phase (first entry in column_names) and remove it
                        phase = column_names[0]
                        column_names.remove(phase)
                        # If there is a different name for the phase, translate it
                        if element in phase_translation:
                            phase = phase_translation[element][phase]
                        # Append _phase to every column name to make it unique (there might be other phases)
                        column_names = [c + '_' + phase for c in column_names]

                        # Reset save_data
                        save_data = []
                        for _ in range(len(column_names)):
                            save_data.append([])
                    # If an empty line is found, EOF is reached
                    elif line.isspace():
                        # If EOF is reached, table_dict is converted to a pandas DataFrame
                        table_to_dict()
                        table = pd.DataFrame(table_dict)
                        if set_table:
                            self.table = table
                        else:
                            return table
                    # Extract the numeric values
                    else:
                        # Get the values
                        values = list(filter(lambda v: v != '' and not v.isalpha(), line.strip().split(' ')))
                        for i_data in range(len(save_data)):
                            save_data[i_data].append(float(values[i_data]))

    def get_element_from_file(self):
        """
        Extracts the element from the filename. The element is always specified as the string after the first '_'
        in the filename
        :return: String of element abbreviation
        """

        return self.input_file.split('_')[1]

    def save_table(self, output_filename=None):
        """

        :param output_filename: Specifies where to save the table at. Is None by default, which indicates
        that the file should be saved in the standard location defined in code
        :return:
        """

        if output_filename is None:
            # Check if there is an input file specified and ask for one if not
            if self.input_file is None:
                print(self.errors['ERR_SVE_1'])
                self.input_file = input('Please enter absolute input file path: ')
            # Check if there is a source specified and ask for one if not
            if self.source is None:
                print(self.errors['ERR_SVE_2'])
                self.set_source(-1)

            directory = r"C:\Users\danie\Documents\Montanuni\Masterarbeit\4 Daten\Preprocessed" + "\\" \
                        + self.get_element_from_file()
            filename = os.path.basename(self.input_file).split('.')[0] + '.xlsx'
            self.table.to_excel(os.path.join(directory, filename), index=False)
        else:
            self.table.to_excel(output_filename, index=False)

    def get_x_y_data(self, x_col, y_col):
        """

        :param x_col: column name of x values
        :param y_col: column name of y values
        :return: x, y data as numpy arrays
        """

        self.load_table()

        # Extract the x and y data
        x = np.array(self.table[x_col])
        y = np.array(self.table[y_col])

        return x, y

    def get_column_names(self):
        self.load_table()

        cols = self.table.columns
        print(list(cols))

        return cols

    def set_input_file(self, new_input_file):
        # Check if file exists
        if os.path.isfile(new_input_file):
            self.input_file = new_input_file
        else:
            print(self.errors['ERR_SRC_2'])
            while not os.path.isfile(new_input_file):
                new_input_file = input('Enter file path: ')
            self.input_file = new_input_file

    def set_source(self, new_source):
        # Check if source is valid
        while new_source not in self.possible_sources:
            print(self.errors['ERR_SRC_1'])
            print('Source entered: ', new_source, ' Please select one of the following sources:')
            print(self.possible_sources)
            new_source = input('Enter source: ')
        self.source = new_source

    def show_table(self, n_cols=5):
        self.load_table()

        print(self.table.head(n_cols))

    def load_table(self):
        # If no table was opened yet, open the one specified
        if self.table is None:
            # If the input file is a .txt file from FactSage, it needs to be converted first
            filename, file_extension = os.path.splitext(self.input_file)
            if self.source == 'FactSage' and file_extension.lower() == '.txt':
                self.convert()
            elif file_extension.lower() == '.csv':
                self.table = pd.read_csv(self.input_file)
            elif file_extension.lower() == '.xlsx':
                self.table = pd.read_excel(self.input_file)

    def change_table(self, source, input_file):
        self.set_source(source)
        self.set_input_file(input_file)
        self.load_table()

    def plot_data(self, x_col, y_col, title=None, axis_labels=None):
        """
        Plots the data from the table
        :param x_col: Column name for the x-values
        :param y_col: Column name for the y-values
        :param title: Plot title
        :param axis_labels: Axis labels in the format (x_label, y_label)
        :return:
        """

        self.load_table()

        plt.figure(self.id_figure)
        self.id_figure += 1

        def check_column_name(col_name):
            new_col = col_name
            while col_name not in self.table.columns:
                print(self.errors['ERR_VIS_1'])
                print('Please enter valid column name! Valid columns:')
                self.get_column_names()
                new_col = input('Enter column name: ')

            return new_col

        # Check x_col
        x_col = check_column_name(x_col)

        # Check y_col(s) and plot the data
        if type(y_col) == list:
            for i, col in enumerate(y_col):
                y_col[i] = check_column_name(col)
                x, y = self.get_x_y_data(x_col, y_col[i])
                plt.scatter(x, y, s=1)
                plt.legend(y_col)
        else:
            y_col = check_column_name(y_col)
            x, y = self.get_x_y_data(x_col, y_col)
            plt.scatter(x, y, s=1)

        # Beautify the plot
        plt.grid(b=True)
        if title is not None:
            plt.title(title)
        else:
            plt.title(None)

        if axis_labels is not None:
            plt.xlabel(axis_labels[0])
            plt.ylabel(axis_labels[1])
        else:
            plt.xlabel(None)
            plt.ylabel(None)

    def plot_gibbs(self, temp_col_name=None):
        """
        Makes a full plot of all the Gibbs energies for all phases over the temperature
        :param temp_col_name: Specifies a column which includes temperature values
        :return:
        """

        self.plot_variable_over_temp('G(J)', plot_title='Gibbs energy vs temperature', temp_col_name=None)

    def plot_enthalpy(self, temp_col_name=None):
        """
        Makes a full plot of all the Enthalpies for all phases over the temperature
        :param temp_col_name: Specifies a column which includes temperature values
        :return:
        """

        self.plot_variable_over_temp('H(J)', plot_title='Enthalpy vs temperature', temp_col_name=None)

    def plot_heat_capacity(self, temp_col_name=None):
        """
        Makes a full plot of all the heat capacities for all phases over the temperature
        :param temp_col_name: Specifies a column which includes temperature values
        :return:
        """

        self.plot_variable_over_temp('Cp(J/K)', plot_title='Heat capacity vs temperature', temp_col_name=None)

    def plot_entropy(self, temp_col_name=None):
        """
        Makes a full plot of the Entropy for all phases over the temperature
        :param temp_col_name: Specifies a column which includes temperature values
        :return:
        """

        self.plot_variable_over_temp('S(J/K)', plot_title='Entropy vs temperature', temp_col_name=None)

    def plot_variable_over_temp(self, y_col_name: str, plot_title=None, temp_col_name=None):
        """
        Plots all columns where the name contains y_col_name (a thermodynamic variable like the
        Gibbs energy) over the temperature

        :param y_col_name: Specifies which columns shall be plotted. For example for plotting
        all Gibbs energy columns, col_name could be 'G(J)'
        :param plot_title: Specifies the title of the plot
        :param temp_col_name: Specifies a column which includes temperature values
        :return:
        """

        self.load_table()

        columns = self.table.columns

        # Find temperature column and all columns with Gibbs energies of different phases
        var_cols = []
        for col in columns:
            if 'T(K)' in col and temp_col_name is None:
                temp_col_name = col
            elif y_col_name in col:
                var_cols.append(col)

        # Don't plot, if no data is available
        if len(var_cols) == 0:
            print('No data available for ', y_col_name)
        else:
            self.plot_data(temp_col_name, var_cols, title=plot_title, axis_labels=('T(K)', y_col_name))

    def merge(self, other, keep_data_handler=True, keep_tables_unique=False):
        """

        :param keep_data_handler: If keep is True, the DataHandler from which merge was called will now
        be the merged DataHandler (it contains the merged DataFrame)
        :param other: DataHandler to merge with
        :param keep_tables_unique: If keep_tables_unique is False, columns with the same name but from different sources
        will be mixed into one column. If keep_tables_unique is True, the columns will be kept unique by adding suffixes
        to their column names (ascending index saved in self.max_suffix)
        :return: Merged DataHandler
        """

        if not keep_tables_unique:
            merged_table = self.table.append(other.table, ignore_index=True)
            merged_table = merged_table.sort_values(by=['T(K)_bcc'])
        else:
            left_table = self.table.add_suffix('_' + str(self.max_suffix))
            right_table = self.table.add_suffix('_' + str(self.max_suffix + 1))
            self.max_suffix += 2
            merged_table = left_table.append(right_table, ignore_index=True)

        if keep_data_handler:
            self.table = merged_table
            self.set_source(None)
            self.set_input_file(None)
        else:
            new_data_handler = DataHandler(None, None)
            new_data_handler.table = merged_table
            new_data_handler.max_suffix = self.max_suffix
            return new_data_handler


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding: utf-8
import sys
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# index_col=0  将第0列作为行索引
from sklearn.model_selection import cross_val_score

train_df = pd.read_csv('data/train.csv', index_col=0)
test_df = pd.read_csv('data/test.csv', index_col=0)
print(train_df.head())

prices = pd.DataFrame({'price': train_df['SalePrice'], 'log(price+1)': np.log1p(train_df['SalePrice'])})
prices.hist()  # 画图 看一下标签是否平滑
plt.show()

y_train = np.log1p(train_df.pop('SalePrice'))  # 将原来的标签删除 剩下log(price+1)列的数据

# y_train = train_df.pop('SalePrice')

all_df = pd.concat((train_df, test_df), axis=0)  # 将train_df, test_df合并
# 有些数据的取值只有四五，或者可数个。这类数据我们转为one_hot编码

# 发现MSSubClass值应该是分类值
print(all_df['MSSubClass'].dtypes)  # int64
all_df['MSSubClass'] = all_df['MSSubClass'].astype(str)
print(all_df['MSSubClass'].value_counts())

all_dummy_df = pd.get_dummies(all_df)
# 我们用均值填充
mean_cols = all_dummy_df.mean()
all_dummy_df = all_dummy_df.fillna(mean_cols)

# 再检查一下是否有缺失值
print(all_dummy_df.isnull().sum().sum())  # 0
#先找出数字型数据
numeric_cols = all_df.columns[all_df.dtypes != 'object']
print(numeric_cols)

# 对其标准化
numeric_col_mean = all_dummy_df.loc[:, numeric_cols].mean()
numeric_col_std = all_dummy_df.loc[:, numeric_cols].std()
all_dummy_df.loc[:, numeric_cols] = (all_dummy_df.loc[:, numeric_cols]-numeric_col_mean) / numeric_col_std

# 将合并的数据此时进行拆分  分为训练数据和测试数据
dummy_train_df = all_dummy_df.loc[train_df.index]
dummy_test_df = all_dummy_df.loc[test_df.index]

X_train = dummy_train_df.values
# X_test = dummy_test_df.values

from xgboost import XGBRegressor

clf = XGBRegressor(max_depth=5,n_estimators=100)
test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring='neg_mean_squared_error'))
print (np.mean(test_score))

# 用sklearn自带的cross validation方法来测试模型
# params = [1, 2, 3, 4, 5, 6]
# test_scores = []
# for param in params:
#     clf = XGBRegressor(max_depth=param)
#     test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring='neg_mean_squared_error'))
#     test_scores.append(np.mean(test_score))
# plt.plot(params, test_scores)
# plt.title("max_depth vs CV Error")
# plt.show()
# print(test_scores)
# print(test_scores.mean())
from tools import  DrawTools
clf.fit(X_train, y_train)
DrawTools.feature_importance(clf, dummy_train_df.columns)
plt.show()


# -*- coding: utf-8 -*-
"""
Created on Tue Dec 18 09:25:52 2018

@author: saras
"""

##Task 1#

x = 33
while x >=1:
        print(x, ': ', end='')
        x = x / 2
print(x)

##Task 2#

def triangular():
    n = int(input("choose a number? "))
    result = 0
    while n > 0:
        result = result + n
        n = n-1
    return result

print(triangular())

##Task 3#

mark = 1
while mark > 0:
    mark = int(input('Enter student mark '))
    if mark >=80:
        print("Top marks that's a first class!")
    elif mark >=60:
            print("Well done you passed!")
    else:
        print("Sorry that's a fail - you can retake in June")

i = 55
while i > 10:
    print (i)
    i = i * 0.8
    if i==35.2:
        break

##Task 4#
while True:
    name = input("Please enter name: ")
    if name == "done":
        break
    print ("Hello", name)

##Task 5#
from random import randint
def guess(counter,end_range):
    number = randint(1,end_range)
    print ("Welcome! Can you guess my secret number?")
    while counter >0:
        guess = int(input("What is your guess, choose a number between 1 and "+ str(end_range)+ ' : '))
        if guess==number:
            print ("Well done - your guess is correct! Goodbye")
            break
        elif guess >number:
            print ("Your guess is too high")
        elif guess <number:
            print ("Your guess is too low. ")

        counter =counter-1
        print ("Guesses you have left: "+ str(counter) + ' : ')
        #removed  #

    print ("END-OF-GAME: thanks for playing!")

guess(3,20)


"""
list of movies that goes into fresh_tomatoes.py file

"""

import media
import fresh_tomatoes

zootopia = media.Movie("Zootopia",
                        "http://t2.gstatic.com/images?q="
                        "tbn:ANd9GcQj1fU0-Idujcrs_MB2xEWbVEygeCkcjYUp4Z"
                        "-hSIPqgu0vFbQi",
                        "https://www.youtube.com/watch?v=WWFB-zrxn7o",
                        "March 4, 2016 (USA)",
                        "Byron Howard, Rich Moore")

storks = media.Movie("Storks",
                     "http://t3.gstatic.com/images?q="
                     "tbn:ANd9GcSQq_t91J3Rtb5v1gbnqGPF6BSDeFvtFcVmxU50"
                     "nuczt5KHWsP8",
                     "https://www.youtube.com/watch?v=Rqj8bz1sbk4",
                     "September 23, 2016 (USA)",
                     "Nicholas Stoller, Doug Sweetland")

life_of_pets = media.Movie("The Secret Life Of Pets",
                           "http://t2.gstatic.com/images?q="
                           "tbn:ANd9GcQmH4RygTa2ipQP54pc6pJMde8e0iBbwVO"
                           "7LW1h1RhpX4zDhef6",
                           "https://www.youtube.com/watch?v=MbjZPbiOsEg",
                           "July 28, 2016 (Germany)",
                           "Chris Renaud, Yarrow Cheney")

kubo = media.Movie("KUBO And The Two Strings",
                   "http://t2.gstatic.com/images?q="
                   "tbn:ANd9GcRQeUx8alN89H9qOSbfZY9sKwIOECZSYcz2LA3auB3"
                   "bldJI-hmE",
                   "https://www.youtube.com/watch?v=ykD2W8U6wH4",
                   "August 19, 2016 (USA)",
                   "Travis Knight")

ratatouille = media.Movie("Ratatouille",
                          "http://upload.wikimedia.org/wikipedia"
                          "/en/5/50/RatatouillePoster.jpg",
                          "https://www.youtube.com/watch?v=c3sBBRxDAqk",
                          "June 29, 2007 (USA)",
                          "Brad Bird, Jan Pinkava")

kungfu_panda_3 = media.Movie("Kung Fu Panda 3",
                             "http://t0.gstatic.com/images?q="
                             "tbn:ANd9GcTv8AULgHD6dyYlMkjvC2YITU41wECw"
                             "kPSGxHUyr9DXvct7vwY2",
                             "https://www.youtube.com/watch?v="
                             "ytuUAve6VW4&disable_polymer=true",
                             "January 29, 2016 (USA)",
                             "Jennifer Yuh Nelson, Alessandro Carloni")

minions = media.Movie("Minions",
                      "http://t2.gstatic.com/images?q="
                      "tbn:ANd9GcRbHFoQWQZLymKtwzfjVEvfNDOIdcWOL-tUFst"
                      "MC00m5OMf961D",
                      "https://www.youtube.com/watch?v=GGssZksONtY",
                      "July 10, 2015 (USA)",
                      "Pierre Coffin, Kyle Balda")

cinderella = media.Movie("Cinderella",
                         "http://t1.gstatic.com/images?q="
                         "tbn:ANd9GcRl6ZJu9B44N_YzggP0_QMKJvGrSGWGGHSf"
                         "7Jv6eGXhJQMGdxny",
                         "https://www.youtube.com/watch?v=2kajFKO0fBQ",
                         "March 13, 2015 (USA)",
                         "Kenneth Branagh")

good_dinosaur = media.Movie("The Good Dinosaur",
                            "http://t1.gstatic.com/images?q="
                            "tbn:ANd9GcRGAyjFdJJlz5XtNdDbO0fmwLswSdIZ"
                            "NTGMBdrVFi5nnss4AlHW",
                            "https://www.youtube.com/watch?v=q7LwbWH8nWo",
                            "November 25, 2015 (USA)",
                            "Peter Sohn")

angry_birds = media.Movie("The Angry Birds",
                           "http://t3.gstatic.com/images?q="
                           "tbn:ANd9GcTL4cM7wCCXjCEoxmzvs_vmiQtNqrpMQ80r"
                           "gdjABG2_N-IEE-tp",
                           "https://www.youtube.com/watch?v=I-QSKuRa0to",
                           "May 11, 2016 (Trinidad and Tobago)",
                           "Clay Kaytis, Fergal Reilly")

spongebob = media.Movie("The Spongebob",
                        "http://t0.gstatic.com/images?q="
                        "tbn:ANd9GcRSqIWmY8hI_csJFC9twZFOduvUtJBVRT1-y4"
                        "OgxzllJLoIMPjV",
                        "https://www.youtube.com/watch?v=n6BSuhCvJXI",
                        "January 28, 2015 (Belgium)",
                        "Paul Tibbitt, Mike Mitchell")

finding_dori = media.Movie("Finding Dori",
                           "http://t1.gstatic.com/images?q="
                           "tbn:ANd9GcTPxyoxzLf33_chM3uqooaT3tiyEBbQmq"
                           "Jb0Ndbvpt6qfQ4ybIk",
		           "https://www.youtube.com/watch?v=agtOeNjC_3U",
                           "June 17, 2016 (USA)",
                           "Andrew Stanton, Angus MacLane, Jose Luis Angulo")

# movie instances added to movies list
movies = [zootopia,storks,life_of_pets,kubo,ratatouille,kungfu_panda_3,
          minions,cinderella,good_dinosaur,angry_birds,spongebob,
          finding_dori]

# calling the open_movies_page function in fresh_tomatoes module
fresh_tomatoes.open_movies_page(movies)


n = eval(input())
bookings = []
for i in range(n):
    bookings.append(list(map(int,input().split(','))))
bookings.sort(key=lambda x:x[0])
n = int(input())
answer = [0]*n
for i in bookings:
    for j in range(i[0],i[1]+1):
        answer[j-1] = answer[j-1] + i[2]
print(answer)


def gen_rand_pts(min_x, min_y, delta_x, delta_y, y_cell, x_cell, rand_num):
    ''' Inputs: latitude min, latitude max, longitude min, longitude max, number of x and y cells, number of random points
    Actions: First, it creates random points within the boundaries of a single cell. Then, it translates these random points
    to each cell.
    Outputs: a list of arrays of random points per cell '''
    #generate random points of a single cell
    rand_x_grid = np.random.uniform(min_x, min_x + delta_x, rand_num)
    rand_y_grid = np.random.uniform(min_y, min_y + delta_y, rand_num)
    old_grid_pts = np.array(list(zip(rand_x_grid, rand_y_grid)))

    list_of_pts = []
    new_grid_pts = np.copy(old_grid_pts)

    for y_tick in range(y_cell):
        for x_tick in range(x_cell):
            new_grid_pts[:, 0] =  old_grid_pts[:, 0] + delta_x * x_tick #shift horizontally
            list_of_pts.append(np.copy(new_grid_pts))
        new_grid_pts[:, 1] += delta_y #shift vertically
    return list_of_pts

#Testing the function above
x = [ -71.20197, -70.96679]
y = [42.291441, 42.420578]
x_cell = 50
y_cell = 50
num_pts = 100
delta_x = abs(x[1] - x[0]) * 1. / x_cell
delta_y = abs(y[1] - y[0]) * 1. / y_cell

rand_pts = gen_rand_pts(x[0], y[0], delta_x, delta_y, x_cell, y_cell, num_pts)

np.save('correct_randpts', np.array(rand_pts))


import time
import sys
import os
import math
import numpy as np
from scipy.optimize import NonlinearConstraint, minimize
from sklearn.preprocessing import PolynomialFeatures
import pickle
from collections import deque

N = 4
LAMBDA = 0.5
ALPHA = 0.1
BETA = 0.1
THETA =  2.1 * 10**-3
deltaT = 1

# Hyperparameters
GAMMA = 1

def f(b):
    return math.exp(-LAMBDA*b)

def VQ(theta, r):
    return 1 - np.exp(-theta*r)

class QOEOptimization:
    def __init__(self, abrList, Tp, windowLength=3):
        self.w = [500 for _ in range(4*Tp)]
        self.abrList = abrList
        self.initMLModels()
        self.Tp = Tp
        self.windowLength = windowLength

    def initMLModels(self):
        self.abrModels = {}
        for abr in self.abrList:
            if abr not in self.abrModels:
                with open("./Data/Models/{}.pickle".format(abr), "rb") as mf:
                    self.abrModels[abr] = pickle.load(mf)

    def playerABR(self, x, prev_bw, b, prev_r, abr):
        poly = PolynomialFeatures(degree=3)
        X = [x] + [pbw*1000 for pbw in prev_bw] + b + [prev_r]
        X = np.array(X).reshape(1, -1)
        x_poly = poly.fit_transform(X)

        y_pred = self.abrModels[abr].predict(x_poly)

        return max(y_pred, 0)

    def ABR(self, bw_list, buf_list, r, abr):
        poly = PolynomialFeatures(degree=3)
        X = list(bw_list) + list(buf_list) + [r]
        X = np.array(X).reshape(1, -1)
        x_poly = poly.fit_transform(X)

        y_pred = self.abrModels[abr].predict(x_poly)

        return min(max(y_pred[0], 0), 1000000)

    def QoE(self, bw_list, buf_list, prev_r, abr):
        return VQ(THETA, self.ABR(bw_list, buf_list, prev_r, abr)) - BETA * f(buf_list[0]) - abs(ALPHA*(VQ(THETA, self.ABR(bw_list, buf_list, prev_r, abr)) - VQ(THETA, prev_r)))

    def pairwiseSum(self, QoEs):
        pairwiseError = 0
        for i in QoEs:
            for j in QoEs:
                pairwiseError += abs(i-j)
        return pairwiseError

    def tpSumGen(self, t):
        def tpSum(x):
            x_vals = [x[self.Tp*n+t] for n in range(N)]
            return sum(x_vals)
        return tpSum

    # Should return pairwise sum
    def costFunction(self, x, inputs):
        # Build bandwidths deque
        bandwidths = {k: deque(maxlen=self.windowLength) for k in range(1, 5)}
        for k in range(1, 5):
            for bw in inputs[k]["bandwidth"]:
                bandwidths[k].append(bw*1000)

        # Build bitrates dict
        bitrates = {k: inputs[k]["bitrate"] for k in range(1, 5)}

        # Build buffer deque
        buffers = {k: deque(maxlen=self.windowLength) for k in range(1, 5)}
        for k in range(1, 5):
            for buf in inputs[k]["buffer"]:
                buffers[k].append(buf)

        # Calculate pairwise sum for prediction window
        totalPairwiseSum = 0
        totalSocialWelfare = 0
        for t in range(self.Tp):
            QoEs = []
            for n in range(N):
                QoEs.append(self.QoE(
                    bandwidths[n+1],
                    buffers[n+1],
                    bitrates[n+1],
                    self.abrList[n]))

                # Update inputs for next timestamp
                next_abr_for_buf = self.ABR(bandwidths[n+1], buffers[n+1], bitrates[n+1], self.abrList[n])
                if next_abr_for_buf != 0:
                    new_buf = buffers[n+1][0] + (bandwidths[n+1][0] / next_abr_for_buf) * deltaT
                else:
                    new_buf = max(0, buffers[n+1][0] - deltaT)
                # print("next aBR: ", next_abr_for_buf)
                # print("New buf: ", new_buf, buffers[n+1][0])
                # print("New bw: ", x[N*n+t])
                buffers[n+1].appendleft(new_buf)
                bandwidths[n+1].appendleft(x[self.Tp*n + t])
                bitrates[n+1] = self.ABR(bandwidths[n+1], buffers[n+1], bitrates[n+1], self.abrList[n])

            totalPairwiseSum += self.pairwiseSum(QoEs)
            totalSocialWelfare += sum(QoEs)

        totalSocialWelfare = -totalSocialWelfare / (N * self.Tp)
        return GAMMA*totalSocialWelfare + (1 - GAMMA)*totalPairwiseSum

    def runOneIteration(self, inputs):
        for k in ["W", 1, 2, 3, 4]:
            if k not in inputs:
                print("{} not in inputs".format(k))
                return []

        for i in range(1, 5):
            for k in ["bandwidth", "bitrate", "buffer"]:
                if k not in inputs[i]:
                    print("{} not in inputs[{}]".format(k, i))
                    return []
            if inputs[i]["bitrate"] < 0:
                inputs[i]["bitrate"] = 0
            inputs[i]["buffer"] = [max(buf, 0) for buf in inputs[i]["buffer"]]

        # Constraints
        nlc1 = [NonlinearConstraint(self.tpSumGen(t), int(inputs["W"][t]*1000), int(inputs["W"][t]*1000)) for t in range(self.Tp)]
        bounds = [(0, None) for _ in range(N*self.Tp)]

        # Objective Function
        sol = minimize(self.costFunction, self.w, args=(inputs), method='SLSQP', bounds=bounds, constraints=nlc1)

        self.w = [int(solx) for solx in sol.x]
        print("Optimizedzz: ", [self.w[self.Tp*n] for n in range(N)])
        print()

        return [self.w[self.Tp*n]/1000 for n in range(N)][::-1]

if __name__ == "__main__":
    qoe = QOEOptimization(["YouTube", "YouTube", "mpc", "mpc"], 3)
    inputs = {
        "W": [0.94457142, 1.11073432, 0.72179543],
        1: {
            "bandwidth": [0.1, 0.1, 0.1],
            "bitrate": 3000,
            "buffer": [4, 5, 6]
        },
        2: {
            "bandwidth": [0.1, 0.1, 0.1],
            "bitrate": 3000,
            "buffer": [4, 5, 6]
        },
        3: {
            "bandwidth": [0.5, 0.5, 0.5],
            "bitrate": 300,
            "buffer": [4, 5, 6]
        },
        4: {
            "bandwidth": [0.5, 0.5, 0.5],
            "bitrate": 300,
            "buffer": [4, 5, 6]
        }
    }
    print(qoe.runOneIteration(inputs))


from ..models import Rzeczy, Category
from .serializers import FindsSerializer, CategorySerializer, UserSerializer
from django.shortcuts import redirect
from rest_framework.decorators import api_view
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView

class FindList(APIView):
    def get(self, request):
        finds = Rzeczy.objects.all()
        serializer = FindsSerializer(finds, many=True)
        return Response(serializer.data)

class FindDetail(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'znajdki_detail.html'

    def get(self, request, pk):
        find = Rzeczy.objects.get(pk=pk)
        serializer = FindsSerializer(find)
        return Response(serializer.data)

    def put(self, request, pk):

        find = Rzeczy.objects.get(pk=pk)
        serializer = FindsSerializer(find, data=request.data)
        if not serializer.is_valid():
            return Response({'serializer': serializer})
        serializer.save()
        return redirect('rest-framework:finds_detail', pk=pk)

@api_view(['GET'])
def api_overview(request):
    api_urls = {
        'List': 'list/',
        'Detail': 'list/<int:pk>/',
    }
    return Response(api_urls)


"""
@file   image_embeddings.py
@author Nianchen Deng, Shanghai AI Lab
@brief  Learnable image embeddings
"""

__all__ = [
    'ImageEmbeddings'
]

import torch
import torch.nn as nn
from nr3d_lib.config import ConfigDict

from nr3d_lib.utils import torch_dtype
from nr3d_lib.fmt import log

from app.resources import Scene, SceneNode
from app.models.base import AssetAssignment, AssetModelMixin

class ImageEmbeddings(AssetModelMixin, nn.ModuleDict):
    assigned_to = AssetAssignment.SCENE
    def __init__(
        self,
        dims: int,
        ego_node_id: str=None, ego_class_name: str="Camera",
        weight_init: str="normal", weight_init_std: float=1.0,
        dtype=torch.float, device=torch.device('cuda')) -> None:
        super().__init__()

        self.dims = dims
        self.ego_node_id = ego_node_id
        self.ego_class_name = ego_class_name
        self.weight_init = weight_init
        self.weight_init_std = weight_init_std
        self.dtype = torch_dtype(dtype)
        self.device = device

    def populate(self, scene: Scene = None, obj: SceneNode = None, config: ConfigDict = None,
                 dtype=torch.float, device=torch.device('cuda'), **kwargs):
        self.scene = scene
        if self.ego_node_id is not None:
            ego_node_list = [self.scene.all_nodes[self.ego_node_id]]
        elif self.ego_class_name is not None:
            ego_node_list = self.scene.all_nodes_by_class_name[self.ego_class_name]
        else:
            raise RuntimeError(
                f"Invalid combination of arguments ego_node_id={self.ego_node_id}, "
                f"ego_class_name={self.ego_class_name}")

        self.exposures = nn.ModuleDict()
        n_frames = len(self.scene)
        for ego_node in ego_node_list:
            embedding_weight = torch.empty(n_frames, self.dims, dtype=self.dtype)
            if self.weight_init == "uniform":
                embedding_weight.uniform_(-self.weight_init_std, self.weight_init_std)
            elif self.weight_init == "normal":
                embedding_weight.normal_(0., self.weight_init_std)
            elif self.weight_init == "zero":
                embedding_weight.zero_()
            else:
                raise ValueError("Unknown weight initial method")
            self[ego_node.id] = nn.Embedding(n_frames, self.dims, dtype=self.dtype, _weight=embedding_weight, device=self.device)
        log.info(f"{self.scene.id} create image embeddings for {[node.id for node in ego_node_list]}")

    @classmethod
    def compute_model_id(cls, scene: Scene = None, obj: SceneNode = None, class_name: str = None) -> str:
        return f"{cls.__name__}#{scene.id}"


import sys
from util import *

def parse(line):
    return ints(line.strip())

xs = list(map(parse, sys.stdin))

g = Grid(xs)

seen = set()
asts = []
for p, v in g.points():
    if p in seen:
        continue
    seen.add(p)

    def search(p, ast):
        for n, nv in g.orthogonal(p):
            if n in ast:
                continue

            if nv:
                ast.add(n)
                search(n, ast)

    if v:
        ast = set([p])
        search(p, ast)

        seen.update(ast)

        asts.append(sum(g[pp] for pp in ast))

print(int(sum(asts) / len(asts)))


import json
from unittest import TestCase

from service import DataManager

class DataManagerTest(TestCase):

    def setUp(self):
        self.data = DataManager()

    def test_insert_record(self):
        result = self.data.update_record(1,
                                         first_name="Test",
                                         last_name="Test",
                                         company="Test",
                                         phone_1="Test"
                                         )
        self.assertTrue(result)

        expected_data = {
            "last_name": "Test",
            "first_name": "Test",
            "middle_name": "Иванович",
            "company": "Test",
            "phone_1": "Test",
            "phone_2": "+79129998877"
        }

        with open("data.json", "r") as fp:
            data = json.load(fp)

        self.assertEqual(expected_data, data[0])