import Server
import os
import socket
import threading
from tkinter import *
from tkinter import filedialog, messagebox

import customtkinter as ctk
from CTkListbox import *

import PIL.Image
import PIL.ImageTk
from Server import *

SIZE = 1024
FORMAT = "utf-8"
PORT = 4000

connFlag = [False, 0]

def serverLogWindow(frame, main_window, folderpath):
    # l=[f for f in os.listdir(folderpath) if os.path.isfile(os.path.join(folderpath, f))]
    l = []

    IP = socket.gethostbyname(socket.gethostname() + ".local")
    ADDR = (IP, PORT)

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(ADDR)
    sock.listen()

    devicesConnectedVar = StringVar()
    devicesConnectedVar.set(f"Devices connected:{connFlag[1]}")

    serverLogs = []
    serverLogsVar = Variable(value=str(serverLogs))

    serverLogs.append("[STARTING] Server is starting...")
    serverLogsVar.set(str(serverLogs))

    print("Waiting for connection...")
    print(f"Share this code: {IP}")

    def checkChanges(server, addr):
        l = []
        while True:
            new_l = [
                f
                for f in os.listdir(folderpath)
                if os.path.isfile(os.path.join(folderpath, f))
            ]
            if connFlag[0] == True or l != new_l:
                l = new_l
                msg = f"UPDATE%{str(new_l)}"
                # print(msg)
                server.send(convertToSIZE(msg))
                connFlag[0] = False

    def serverHandler():
        while True:
            conn, addr = sock.accept()

            if conn:
                serverConnected(conn, addr)

    def serverConnected(conn, addr):
        global server

        server = conn
        msg = "[NEW CLIENT] : HOST"
        # server.send(convertToSIZE(msg.encode(FORMAT)))
        server.send(msg.encode(FORMAT))

        serverLogs.append(f"[NEW CONNECTION]: {addr} Connected")
        serverLogsVar.set(str(serverLogs))

        clientThread = threading.Thread(target=clientHandlerHost, args=(server, addr))
        clientThread.start()

        connFlag[1] += 1
        devicesConnectedVar.set(f"Devices connected:{connFlag[1]}")

        # if connFlag[1] == 1:
        checkChangeThread = threading.Thread(target=checkChanges, args=(server, addr))
        checkChangeThread.start()

    def clientHandlerHost(server, addr):
        new_l = [
            f
            for f in os.listdir(folderpath)
            if os.path.isfile(os.path.join(folderpath, f))
        ]

        msg = f"UPDATE%{str(new_l)}"
        server.send(convertToSIZE(msg))

        while True:
            msg = server.recv(SIZE)
            if not msg:
                continue
            else:
                msg = removeExtraBytes(msg).decode(FORMAT)

                cmd, msg = msg.split("%")

                if cmd == "DOWNLOAD":
                    filename = msg

                    filepath = os.path.join(folderpath, filename)
                    packetCount = getPacketCount(filepath)

                    fileData = f'["{filename}", "{packetCount}"]'

                    msgSend = f"TAKE_DATA%{fileData}"
                    server.send(convertToSIZE(msgSend))

                    with open(filepath, "rb") as f:
                        while packetCount > 0:
                            data = f.read(SIZE)
                            server.send(data)
                            packetCount -= 1

                    serverLogs.append(f"[DOWNLOADED]: {filename} downloaded by {addr}")
                    serverLogsVar.set(str(serverLogs))

                elif cmd == "UPLOAD":
                    filename = msg
                    filepath = os.path.join(folderpath, filename).replace("\\", "/")

                    packetCountResponse = eval(
                        removeExtraBytes(server.recv(SIZE)).decode(FORMAT)
                    )

                    with open(filepath, "wb") as f:
                        while packetCountResponse > 0:
                            data = server.recv(SIZE)
                            f.write(data)
                            packetCountResponse -= 1

                    connFlag[0] = True

                    serverLogs.append(f"[UPLOADED]: {filename} uploaded by {addr}")
                    serverLogsVar.set(str(serverLogs))

                elif cmd == "DELETE":
                    filename = msg
                    filepath = os.path.join(folderpath, filename).replace("\\", "/")

                    os.remove(filepath)
                    connFlag[0] = True
                    serverLogs.append(f"[DELETED]: {filename} deleted by {addr}")
                    serverLogsVar.set(str(serverLogs))

    def shutDownServerButton():
        frame.destroy()
        main_window()

    serverThread = threading.Thread(target=serverHandler)
    serverThread.start()

    lb1 = ctk.CTkLabel(
        frame,
        text="SERVER LOGS",
        font=("Comic Sans MS bold", 20),
        padx=5,
        pady=5,
    )
    lb1.pack()

    lb2 = ctk.CTkLabel(
        frame,
        text=f"Share this code to join: {IP}",
        font=("Comic Sans MS bold", 18),
        padx=5,
        pady=5,
    )
    lb2.place(x=10, y=50)

    lb3 = ctk.CTkLabel(
        frame,
        textvariable=devicesConnectedVar,
        font=("Comic Sans MS bold", 18),
        padx=5,
        pady=5,
    )
    lb3.place(x=790, y=50)

    listbox1 = CTkListbox(frame, listvariable=serverLogsVar, height=400, width=950)
    listbox1.place(x=10, y=100)

    btn1 = ctk.CTkButton(frame, text="Shut Down Server", command=shutDownServerButton)
    btn1.place(x=450, y=550)


import requests
import re
import datetime
from dateutil import parser
import time
from PIL import Image, ImageDraw, ImageFont
import urllib.parse

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import os
import pickle
import codecs

HEADER = {'User-Agent': 'Live Match Results Ticker (beomulf@gmail.com)'}

S = requests.Session()

URL = "https://liquipedia.net/starcraft2/api.php"
HEADER = {'User-Agent': 'Live Match Results Ticker (beomulf@gmail.com)'}
TIMEZONES = {'CEST': '+02:00', 'EDT': '-04:00'}
RACELIBRARY = {'T': 'Terran', 'P': 'Protoss', 'Z': 'Zerg', 'R': 'Random'}

def build_ticker_DH_NA_groups(pageid, prepend=''):
    params = {
        'action': "parse",
        'pageid': pageid,
        'prop': 'wikitext',
        'section': 6,
        'format': "json"
    }
    """ Parse a section of a page, fetch its table data and save it to a CSV file
    """
    res = S.get(url=URL, params=params, headers=HEADER)
    data = res.json()
    wikitext = data['parse']['wikitext']['*']
    lines = wikitext.split('|-')
    matches = {}

    table = lines[0].split('{{HiddenSort')
    del table[0]
    for group in table:
        match_list = re.split('\|M[0-9]|<', group)
        group_name = group[1:8] + ' | '
        del match_list[0]
        player_names = re.split('\|p[0-9]=', group)
        del player_names[0]
        player_names_list = [x.split('|')[0].split('=') for x in player_names[0:8]]
        player_names_list = [x[0] for x in player_names_list]
        results_dict = dict.fromkeys(player_names_list)
        for key in player_names_list:
            results_dict[key] = {'Map Diff': 0, 'Map Wins': 0, 'Map Losses': 0, 'Match Wins': 0, 'Match Losses': 0}

        matches[group_name] = []
        for match in match_list:
            if 'opponent1' in match:
                if 'bestof=5' in match:
                    break
                subseries = match.split('    ')
                dateinfo = match.split('date=')[1].split('|')[0]
                date = dateinfo.split('{{')
                date = date[0] + re.sub('[a-z |{|}|\/]', '', date[1]).replace('\n', '')
                for zone, offset in TIMEZONES.items():
                    try:
                        date = date.replace(zone, offset)
                    except:
                        print('Invalid Timezone')

                date = parser.parse(date)
                currentTime = datetime.datetime.now(datetime.timezone.utc).astimezone()
                timeDiff = abs(currentTime-date)
                timeDiff = timeDiff.days * 24 + timeDiff.seconds // 3600
                manual_score_flag = False

                p1_score = 0
                p2_score = 0
                for line in subseries:
                    if 'opponent1' in line:
                        if re.search('\|1=', line):
                            p1 = line.split('|1=')[-1].split('|')[0].replace('}}\n', '')
                        else:
                            p1 = line.split('|')[2].replace('}}\n', '').split('p1=')[0]
                        if 'score' in line:
                            p1_score = line.split('score=')[1].split('}')[0]
                        else:
                            manual_score_flag = True
                    elif 'opponent2' in line:
                        if re.search('\|1=', line):
                            p2 = line.split('|1=')[-1].split('|')[0].replace('}}\n', '')
                        else:
                            p2 = line.split('|')[2].replace('}}\n', '').split('p1=')[0]
                        if 'score' in line:
                            p2_score = line.split('score=')[1].split('}')[0]
                        else:
                            manual_score_flag = True
                    if 'walkover=1' in line:
                        p1_score = 'W'
                        p2_score = 'L'
                    elif 'walkover=2' in line:
                        p1_score = 'L'
                        p2_score = 'W'
                    elif manual_score_flag and 'winner' in line:
                        winner_id = line.split('winner=')[1].split('}')[0].partition('|')
                        winner_id = winner_id[0]
                        if winner_id == '1':
                            p1_score += 1
                        elif winner_id == '2':
                            p2_score += 1

                if p1_score == '':
                    p1_score = '0'
                if p2_score == '':
                    p2_score = '0'
                if p1 not in results_dict:
                    results_dict[p1] = {'Map Diff': 0, 'Map Wins': 0, 'Map Losses': 0, 'Match Wins': 0,
                                         'Match Losses': 0}
                if p2 not in results_dict:
                    results_dict[p2] = {'Map Diff': 0, 'Map Wins': 0, 'Map Losses': 0, 'Match Wins': 0,
                                         'Match Losses': 0}
                results_dict[p1]['Map Wins'] += p1_score
                results_dict[p2]['Map Wins'] += p2_score
                results_dict[p1]['Map Losses'] += p2_score
                results_dict[p2]['Map Losses'] += p1_score
                results_dict[p1]['Map Diff'] += p1_score - p2_score
                results_dict[p2]['Map Diff'] += p2_score - p1_score
                if p1_score >= 2 or p2_score >= 2:
                    if p1_score > p2_score:
                        results_dict[p1]['Match Wins'] += 1
                        results_dict[p2]['Match Losses'] += 1
                    if p2_score > p1_score:
                        results_dict[p2]['Match Wins'] += 1
                        results_dict[p1]['Match Losses'] += 1

                if timeDiff < 10:
                    if p1 != '':
                        if p1 != 'BYE' and p2 != 'BYE':
                            matches[group_name].append(
                                ' ' + p1 + ' ' + str(p1_score) + '-' + str(p2_score) + ' ' + p2 + '    ')
                        elif p1 == 'BYE':
                            matches[group_name].append(' ' + p2 + ' (Bye) ')
                        elif p2 == 'BYE':
                            matches[group_name].append(' ' + p1 + ' (Bye) ')
                    if p1 == '':
                        p1 = 'TBD'
                    if p2 == '':
                        p2 = 'TBD'

        generate_group_standings_img(group_name, results_dict)

    matchlist = []
    for key in matches.keys():
        if matches[key] != []:
            if prepend != '':
                matchlist.append('  |  ' + prepend + '  |  ')

            matchlist.append(key + ''.join(matches[key]))

    matchstr = ''.join(matchlist)
    with open('results.txt', 'w') as output:
        output.write(matchstr)
    print('Populated Results')
    time.sleep(40)

def build_ticker_ept_cups(pageid, prepend=''):
    # TODO: Generalize function to all events
    # TODO: convert match_list to dictionary so we can bump less useful results
    # TODO: add gui to plug in pageid
    # TODO: loop every 30s to reduce user overhead
    params = {
        'action': "parse",
        'pageid': pageid,
        'prop': 'wikitext',
        'format': "json",
        'Accept-Encoding': 'gzip'
    }

    """ Parse a section of a page, fetch its table data and save it to a CSV file
    """
    try:
        res = S.get(url=URL, params=params, headers=HEADER)
        data = res.json()
        wikitext = data['parse']['wikitext']['*']
        lines = wikitext.split('|-')
        matches = []
        rounds = {}

        table = lines[0].split('==Results==')
        del table[0]
        table = re.split('\|R[0-9]', table[0])
        prev_series = 100
        round_tracker = 0

        for series in table:
            if '{{bracket' not in series:
                if 'header' in series:
                    header = series.split('=')[1].split('({{')
                    rounds[str(header[0])] = header[1].split('|')[1].replace('}})\n', '').split('\n')[0]
                elif re.search('M[0-9]', series):
                    round_keys = list(rounds.keys())
                    subseries = series.split('    ')
                    series_num = int(subseries[0].split('M')[1].split('=')[0])
                    manual_score_flag = False
                    p1_score = 0
                    p2_score = 0
                    for line in subseries:
                        if 'opponent1' in line:
                            if re.search('\|1=', line):
                                p1 = line.split('|1=')[-1].split('|')[0].replace('}}\n', '')
                            else:
                                p1 = line.split('|')[2].replace('}}\n', '')
                            if 'score' in line:
                                p1_score = line.split('score=')[1].split('}')[0]
                            else:
                                manual_score_flag = True
                        elif 'opponent2' in line:
                            if re.search('\|1=', line):
                                p2 = line.split('|1=')[-1].split('|')[0].replace('}}\n', '')
                            else:
                                p2 = line.split('|')[2].replace('}}\n', '')
                            if 'score' in line:
                                p2_score = line.split('score=')[1].split('}')[0]
                            else:
                                manual_score_flag = True
                        if 'walkover=1' in line:
                            p1_score = 'W'
                            p2_score = 'L'
                        elif 'walkover=2' in line:
                            p1_score = 'L'
                            p2_score = 'W'
                        elif manual_score_flag and 'winner' in line:
                            winner_id = line.split('winner=')[1].split('}')[0].partition('|')
                            winner_id = winner_id[0]
                            if winner_id == '1':
                                p1_score += 1
                            elif winner_id == '2':
                                p2_score += 1
                    if series_num < prev_series and p1 != '':
                        key = str(round_keys[round_tracker])
                        matches.append('| ' + key + ' (BO ' + rounds[key] + ') :')
                        round_tracker += 1
                    if p1_score == '':
                        p1_score = '0'
                    if p2_score == '':
                        p2_score = '0'
                    if p1 == '' and p2 != '':
                        p1 = 'TBD'
                    if p2 == '' and p1 != '':
                        p2 = 'TBD'
                    if p1 != '':
                        if p1 != 'BYE' and p2 != 'BYE':
                            matches.append(' ' + p1 + ' ' + str(p1_score) + '-' + str(p2_score) + ' ' + p2 + '    ')
                        elif p1 == 'BYE':
                            matches.append(' ' + p2 + ' (Bye) ')
                        elif p2 == 'BYE':
                            matches.append(' ' + p1 + ' (Bye) ')

                    prev_series = series_num
        matchstr = ' '.join(matches)
        if 'Quarterfinals  (BO 3)' in matchstr:
            matchstr = matchstr[matchstr.index('| Quarterfinals  (BO 3)'):]
    except:
        print('Invalid ID')
        matchstr = ''
    if prepend != '':
        prepend = '  |  ' + prepend
    matchstr = prepend + matchstr

    while len(matchstr) < 100 and len(matchstr) != 0:
        matchstr += matchstr

    with codecs.open('results.txt', 'w', encoding="utf-8") as output:
        output.write(matchstr)
        print('Populated Results')

    time.sleep(40)

def build_ticker_DH_EU_groups(pageid, prepend=''):
    # TODO: Generalize function to all events
    # TODO: convert match_list to dictionary so we can bump less useful results
    # TODO: convert match_list to dictionary so we can bump less useful results
    # TODO: add gui to plug in pageid
    # TODO: loop every 30s to reduce user overhead
    params = {
        'action': "parse",
        'pageid': pageid,
        'prop': 'wikitext',
        'format': "json",
        'Accept-Encoding': 'gzip'
    }

    """ Parse a section of a page, fetch its table data and save it to a CSV file
    """
    res = S.get(url=URL, params=params, headers=HEADER)
    data = res.json()
    wikitext = data['parse']['wikitext']['*']
    lines = wikitext.split('|-')
    matches = []
    rounds = {}

    lines = lines[-1]
    lines = lines.split('Toggle group')[1]
    group_table = lines.split('{{:')
    new_groups = group_table[0].split('{{Matchlist')
    group_names = [x.split('}')[0] for x in new_groups[1:len(new_groups)]]

    prev_series = 100
    round_tracker = 0
    matches = {}
    for group in group_names:
        print(group)
        time.sleep(40)
        HEADER_GROUPS = {'User-Agent': f'Live Match Results Ticker {group} (beomulf@gmail.com)'}

        group_params = {
            'action': "parse",
            'page': group,
            'prop': 'wikitext',
            'format': "json",
            'Accept-Encoding': 'gzip'
        }
        res = S.get(url=URL, params=group_params, headers=HEADER_GROUPS)
        data = res.json()
        wikitext = data['parse']['wikitext']['*']
        lines = wikitext.split('|-')
        group_data = lines[-1]
        player_names = re.split('\|p[0-9]=', group_data)
        del player_names[0]
        # if 'bg' in group:
        #     player_names = re.split('\|p[0-9]=', group_data)
        player_names_list = [x.split('\n')[0].split('=') for x in player_names[0:8]]
        player_names_list = [x[0] for x in player_names_list]
        results_dict = dict.fromkeys(player_names_list)
        for key in player_names_list:
            results_dict[key] = {'Map Diff': 0, 'Map Wins': 0, 'Map Losses': 0, 'Match Wins': 0, 'Match Losses': 0}

        table = re.split('\|M[0-9]|<', group_data)
        for match in table:
            if '{{HiddenSort' in match:
                group_name = match.split('|')[1].split('}}')[0] + ' | '
                matches[group_name] = []
            elif 'header' not in match and 'opponent1' in match:
                if 'bestof=5' in match:
                    break
                date_info = match.split('|')
                date = [x for x in date_info if 'date' in x]
                date = date[0].split('=')[1].split('{{')
                date = date[0] + re.sub('[a-z |{|}|\/]', '', date[1]).replace('\n', '')
                date = date.replace('A', '')
                for zone, offset in TIMEZONES.items():
                    try:
                        date = date.replace(zone, offset)
                    except:
                        print('Invalid Timezone')

                date = parser.parse(date)
                currentTime = datetime.datetime.now(datetime.timezone.utc).astimezone()
                timeDiff = abs(currentTime - date)
                timeDiff = timeDiff.days * 24 + timeDiff.seconds // 3600

                subseries = match.split('    ')
                manual_score_flag = False
                p1_score = 0
                p2_score = 0

                for line in subseries:
                    if 'opponent1' in line:
                        if re.search('\|1=', line):
                            p1 = line.split('|1=')[-1].split('|')[0].replace('}}\n', '')
                        else:
                            p1 = line.split('|')[2].replace('}}\n', '').split('p1=')[1]
                        if 'score' in line:
                            p1_score = line.split('score=')[1].split('}')[0]
                        else:
                            manual_score_flag = True
                    elif 'opponent2' in line:
                        if re.search('\|1=', line):
                            p2 = line.split('|1=')[-1].split('|')[0].replace('}}\n', '')
                        else:
                            p2 = line.split('|')[2].replace('}}\n', '').split('p1=')[1]
                        if 'score' in line:
                            p2_score = line.split('score=')[1].split('}')[0]
                        else:
                            manual_score_flag = True
                    if 'walkover=1' in line:
                        p1_score = 'W'
                        p2_score = 'L'
                    elif 'walkover=2' in line:
                        p1_score = 'L'
                        p2_score = 'W'
                    elif manual_score_flag and 'winner' in line:
                        winner_id = line.split('winner=')[1].split('}')[0].partition('|')
                        winner_id = winner_id[0]
                        if winner_id == '1':
                            p1_score += 1
                        elif winner_id == '2':
                            p2_score += 1

                if p1_score == '':
                    p1_score = '0'
                if p2_score == '':
                    p2_score = '0'
                results_dict[p1]['Map Wins'] += p1_score
                results_dict[p2]['Map Wins'] += p2_score
                results_dict[p1]['Map Losses'] += p2_score
                results_dict[p2]['Map Losses'] += p1_score
                results_dict[p1]['Map Diff'] += p1_score-p2_score
                results_dict[p2]['Map Diff'] += p2_score-p1_score
                if p1_score >= 2 or p2_score >= 2:
                    if p1_score > p2_score:
                        results_dict[p1]['Match Wins'] += 1
                        results_dict[p2]['Match Losses'] += 1
                    if p2_score > p1_score:
                        results_dict[p2]['Match Wins'] += 1
                        results_dict[p1]['Match Losses'] += 1

                if timeDiff < 8:
                    if p1 != '':
                        if p1 != 'BYE' and p2 != 'BYE':
                            matches[group_name].append(' ' + p1 + ' ' + str(p1_score) + '-' + str(p2_score) + ' ' + p2 + '    ')
                        elif p1 == 'BYE':
                            matches[group_name].append(' ' + p2 + ' (Bye) ')
                        elif p2 == 'BYE':
                            matches[group_name].append(' ' + p1 + ' (Bye) ')
                    if p1 == '':
                        p1 = 'TBD'
                    if p2 == '':
                        p2 = 'TBD'

        generate_group_standings_img(group_name, results_dict)

    matchstr = ''
    for key in matches.keys():
        if matches[key] != []:
            matchstr += key + ''.join(matches[key])
    if prepend != '':
        matchstr = '  |  ' + prepend + '  |  ' + matchstr

    with open('results.txt', 'w') as output:
        output.write(matchstr)
    print('Populated Results')

def build_kob_ticker(mainstream_group='', offstream_group=''):
    SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
    SPREADSHEET_ID = '1TX2a7CHmrJaaNvytF_iVUGPAD9ALnRhIJXrVjJelTDk'
    creds = None

    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                '../KoB_Toolsuite/credentials.json', SCOPES) # here enter the name of your downloaded JSON file
            creds = flow.run_local_server(port=8080)
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('sheets', 'v4', credentials=creds)

    # Call the Sheets API
    sheet = service.spreadsheets()
    result_input = sheet.get(spreadsheetId=SPREADSHEET_ID).execute()
    values_input = result_input.get('values', [])
    sheets = result_input.get('sheets', '')
    sheet_names = [x.get("properties", {}).get("title") for x in sheets]
    if mainstream_group == '':
        return sheet_names

def generate_group_standings_img(group_name, results_dict):
    img = Image.new('RGBA', (1920, 1080), color=(0, 0, 0, 0))
    img2 = Image.new('RGBA', (1920, 1080), color=(0, 0, 0, 0))
    fnt = ImageFont.truetype('Roboto-Bold.ttf', size=30)
    d = ImageDraw.Draw(img)
    d2 = ImageDraw.Draw(img2)

    ordered_results = sorted(results_dict, key=lambda x: (results_dict[x]['Match Wins'] - results_dict[x]['Match Losses'],
                                                          results_dict[x]['Map Diff'],
                                                          results_dict[x]['Map Wins']))
    # Player Names
    d.text((1260, 370), ordered_results[7], font=fnt, fill=(255, 255, 255))
    d.text((1260, 415), ordered_results[6], font=fnt, fill=(255, 255, 255))
    d.text((1260, 457), ordered_results[5], font=fnt, fill=(255, 255, 255))
    d.text((1260, 501), ordered_results[4], font=fnt, fill=(255, 255, 255))
    d.text((1260, 545), ordered_results[3], font=fnt, fill=(255, 255, 255))
    d.text((1260, 590), ordered_results[2], font=fnt, fill=(255, 255, 255))
    d.text((1260, 635), ordered_results[1], font=fnt, fill=(255, 255, 255))
    d.text((1260, 675), ordered_results[0], font=fnt, fill=(255, 255, 255))

    # Match Score
    d.text((1620, 375),
           str(results_dict[ordered_results[7]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[7]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 420),
           str(results_dict[ordered_results[6]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[6]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 464),
           str(results_dict[ordered_results[5]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[5]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 509),
           str(results_dict[ordered_results[4]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[4]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 553),
           str(results_dict[ordered_results[3]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[3]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 597),
           str(results_dict[ordered_results[2]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[2]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 640),
           str(results_dict[ordered_results[1]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[1]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1620, 683),
           str(results_dict[ordered_results[0]]['Match Wins']) + ' - ' + str(
               results_dict[ordered_results[0]]['Match Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')

    # Map Scores
    d.text((1820, 375),
           str(results_dict[ordered_results[7]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[7]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 420),
           str(results_dict[ordered_results[6]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[6]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 464),
           str(results_dict[ordered_results[5]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[5]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 509),
           str(results_dict[ordered_results[4]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[4]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 553),
           str(results_dict[ordered_results[3]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[3]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 597),
           str(results_dict[ordered_results[2]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[2]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 640),
           str(results_dict[ordered_results[1]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[1]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')
    d.text((1820, 683),
           str(results_dict[ordered_results[0]]['Map Wins']) + ' - ' + str(
               results_dict[ordered_results[0]]['Map Losses']),
           font=fnt, fill=(255, 255, 255), anchor='mt')

    img.save(group_name.split('|')[0].replace(' ', '') + '.png')

    fullscreen_start = 300
    score_start = 640
    maps_start = 815
    # Player Names
    name_vert_start = 730
    num_vert_start = 735
    counter = 0
    for result in ordered_results:
        d2.text((fullscreen_start, name_vert_start-counter*50), result, font=fnt, fill=(255, 255, 255))
        d2.text((score_start, num_vert_start-counter*50),
                str(results_dict[result]['Match Wins']) + ' - ' + str(results_dict[result]['Match Losses']),
                font=fnt,
                fill=(255, 255, 255),
                anchor='mt')
        d2.text((maps_start, num_vert_start-counter*50),
                str(results_dict[result]['Map Wins']) + ' - ' + str(results_dict[result]['Map Losses']),
                font=fnt,
                fill=(255, 255, 255),
                anchor='mt')
        counter += 1

    img2.save(group_name.split('|')[0].replace(' ', '') + '_FullScreen.png')


from collections import Counter
class Solution:
    def longestPalindrome(self, s: str) -> int:
        counter = Counter(s)
        ans = 0
        odd = False

        for k,v in counter.items():
            ans += v // 2 * 2
            if v % 2:
                odd = True
        if odd: ans += 1

        return ans


import os
import streamlit as st
import openai
from dotenv import load_dotenv

def load_guidelines(filepath):
    with open(filepath, 'r', encoding='utf-8') as f:
        return f.read()

def save_guidelines(filepath, content):
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(content)

load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
# print(api_key)
openai.api_key = api_key

def chat_with_model(prompt, guidelines):
    messages = [
        {"role": "system", "content": guidelines},
        {"role": "user", "content": prompt},
        {"role": "assistant", "content": ""}
    ]
    response = openai.ChatCompletion.create(
        model="gpt-4",
        max_tokens=1536,
        messages=messages,
        temperature=0,
        stream=True
    )
    return response['choices'][0]['message']['content']

# Load Guidelines from a file
guidelines_path = "system.txt"  # Replace with your file path
guidelines = load_guidelines(guidelines_path)

# Streamlit App
st.title("OpenAI Chat Assistant for Text Improvement")

with st.expander("Guidelines ein-/ausblenden"):
    guidelines = st.text_area("Content Guidelines:", guidelines)
    if st.button("Speichern"):
        save_guidelines(guidelines_path, guidelines)

# st.write("Bitte geben Sie Ihr Textbeispiel ein.")

user_input = st.text_area("Bitte geben Sie Ihr Textbeispiel ein.")

if user_input:
    assistant_reply = chat_with_model(user_input, guidelines)
    st.write(f"Assistant: {assistant_reply}")


from typing import Any, Dict, Optional

import httpx

from ...client import Client
from ...models.wallet_module_response import WalletModuleResponse
from ...types import UNSET, Response

def _get_kwargs(
    *,
    client: Client,
    did: str,
) -> Dict[str, Any]:
    url = "{}/wallet/did/local/rotate-keypair".format(client.base_url)

    headers: Dict[str, str] = client.get_headers()
    cookies: Dict[str, Any] = client.get_cookies()

    params: Dict[str, Any] = {}
    params["did"] = did

    params = {k: v for k, v in params.items() if v is not UNSET and v is not None}

    return {
        "method": "patch",
        "url": url,
        "headers": headers,
        "cookies": cookies,
        "timeout": client.get_timeout(),
        "params": params,
    }

def _parse_response(*, response: httpx.Response) -> Optional[WalletModuleResponse]:
    if response.status_code == 200:
        response_200 = WalletModuleResponse.from_dict(response.json())

        return response_200
    return None

def _build_response(*, response: httpx.Response) -> Response[WalletModuleResponse]:
    return Response(
        status_code=response.status_code,
        content=response.content,
        headers=response.headers,
        parsed=_parse_response(response=response),
    )

def sync_detailed(
    *,
    client: Client,
    did: str,
) -> Response[WalletModuleResponse]:
    """Rotate keypair for a DID not posted to the ledger

    Args:
        did (str):

    Returns:
        Response[WalletModuleResponse]
    """

    kwargs = _get_kwargs(
        client=client,
        did=did,
    )

    response = httpx.request(
        verify=client.verify_ssl,
        **kwargs,
    )

    return _build_response(response=response)

def sync(
    *,
    client: Client,
    did: str,
) -> Optional[WalletModuleResponse]:
    """Rotate keypair for a DID not posted to the ledger

    Args:
        did (str):

    Returns:
        Response[WalletModuleResponse]
    """

    return sync_detailed(
        client=client,
        did=did,
    ).parsed

async def asyncio_detailed(
    *,
    client: Client,
    did: str,
) -> Response[WalletModuleResponse]:
    """Rotate keypair for a DID not posted to the ledger

    Args:
        did (str):

    Returns:
        Response[WalletModuleResponse]
    """

    kwargs = _get_kwargs(
        client=client,
        did=did,
    )

    async with httpx.AsyncClient(verify=client.verify_ssl) as _client:
        response = await _client.request(**kwargs)

    return _build_response(response=response)

async def asyncio(
    *,
    client: Client,
    did: str,
) -> Optional[WalletModuleResponse]:
    """Rotate keypair for a DID not posted to the ledger

    Args:
        did (str):

    Returns:
        Response[WalletModuleResponse]
    """

    return (
        await asyncio_detailed(
            client=client,
            did=did,
        )
    ).parsed


from model import db_connection
from helper import id_generator,paginated_results
from flask import Flask, request

class Contacts:
    def __init__(self):
        self.db=db_connection.Database()

    def record_exists(self,field,data):
        count = self.db.get_doc_count("contacts",field,data)
        if count:
            return True
        return False

    def generate_id(self):
        id = id_generator.ran_gen()
        while True:
            if self.record_exists("contact_id",id):
                id = id_generator.ran_gen()
            else:
                return id

    def create_contact(self,input):
        output ={"status": "" , "message" : ""}
        try:
            name=input['name']
            email=input['email']
            user=input['user']

            if self.record_exists("email",email):
                output["status"] = "error"
                output["message"] = "Email Exists"

            else:
                data_to_insert = {}
                data_to_insert['contact_id'] = self.generate_id()
                data_to_insert['name'] = name
                data_to_insert['email'] = email

                self.db.insert_one_data("contacts",data_to_insert)
                self.db.insert_one_to_array("users","user",user,"contacts",data_to_insert['contact_id'])
                output["status"] = "success"

        except:
            output["status"] = "success"

        return output

    def remove_contact(self,input):
        output ={"status": "" , "message" : ""}
        try:
            user=input['user']
            contact_id=input['contact_id']
            self.db.delete_one_from_array("users","user",user,"contacts",contact_id)
            output["status"] = "success"
        except :
            output["status"] = "error"

        return output

    def list_contact(self,input):
        output ={"status": "" , "message" : ""}

        try:
            try:
                page = int(request.args.get("page"))
            except:
                page = 1

            try:
                limit = int(request.args.get("limit"))
            except:
                limit = 10

            user=input['user']
            query={"user":user}
            contact_ids = self.db.get_values("users",query,["contacts"],["_id"])[0]['contacts']

            query={"contact_id":{"$in":contact_ids}}
            contacts = self.db.get_values("contacts",query,["contact_id","name","email"],["_id"])

            output["results"]= paginated_results.paginated_results(contacts,page,limit)
            output["status"] = "success"
        except:
            output["status"] = "error"

        return output

    def search_contact(self,input):
        output ={"status": "" , "message" : ""}

        try:
            search_string = input['search_string']
            output["results"] = self.db.search("contacts",search_string)
            output["status"] = "success"
        except:
            output["status"] = "error"

        return output

    def update_contact(self,input):
        output ={"status": "" , "message" : ""}

        try:
            fields_to_update = input['fields_to_update']
            contact_id = input['contact_id']

            new_fields = {}
            for field in fields_to_update:
                new_fields[field] = input[field]
            self.db.update_one("contacts","contact_id",contact_id,new_fields)
            output["status"] = "success"
        except:
            output["status"] = "error"

        return  output

    def add_contacts(self,input):
        output ={"status": "" , "message" : ""}

        try:
            contact_ids = input['contact_ids']
            user=input['user']
            self.db.insert_many_to_array("users","user",user,"contacts",contact_ids)
            output["status"] = "success"
        except :
            output["status"] = "error"

        return output


import os
import sys

import numpy as np
import pytest
from numpy.random import rand

sys.path.append(os.path.join(os.path.dirname(__file__), "../.."))
module = __import__("Models", fromlist=["GPR"])

class TestGPR:
    @pytest.mark.skip
    def test_getPredictValue(self, x):
        ...

    @pytest.mark.skip
    def test_getPredictDistribution(self, x):
        ...

    @pytest.mark.parametrize(
        ("dim", "obj", "num"),
        [(3, 2, 10), (5, 3, 10), (10, 10, 10), (5, 5, 20), (10, 10, 50)],
    )
    def test_getPredictDistributionAll_random(self, dim, obj, num):

        x = np.array([[rand() for _ in range(dim)] for __ in range(num)])
        y = np.array([rand() for _ in range(num)])

        model = module.GPR.GPR(x, y)

        p = np.array([[rand() for _ in range(dim)] for __ in range(num)])
        mvL = model.getPredictDistributionAll(p)

        for t, mv in zip(p, mvL):
            m, v = model.getPredictDistribution(t)
            assert np.abs(m - mv[0]) < 1e-5
            assert np.abs(v - mv[1]) < 1e-5

    @pytest.mark.parametrize(
        ("dim", "obj", "num"),
        [(3, 2, 10), (5, 3, 10), (10, 10, 10), (5, 5, 20), (10, 10, 50)],
    )
    def test_getPredictValueAll_random(self, dim, obj, num):

        x = np.array([[rand() for _ in range(dim)] for __ in range(num)])
        y = np.array([rand() for _ in range(num)])

        model = module.GPR.GPR(x, y)

        p = np.array([[rand() for _ in range(dim)] for __ in range(num)])
        vL = model.getPredictValueAll(p)

        for t, v in zip(p, vL):
            v2 = model.getPredictValue(t)
            assert np.abs(v - v2) < 1e-5


# this is question 2 of the backend asigment given by CHAABI in which we are given extensiontype and some test
#that are to beb conducted to determine those types

def printfile(extensiontype, test):
    #we are seprating  the values so that we can create pairs of the them to add to ref_dic
    temp = [num.split(",") for num in extensiontype.split(";")]
    #here the ref_dic is created using the same temp array we build together
    ref_dic = {num[0]: num[1] for num in temp}
    #an empty dictionary as output which will be returned
    op = {}
    #we are iterating over each test case to cover them
    for n in test:
        if "." in n:
            #here we are seprating those to get the exact tracker
            extension = n.split(".")[-1]
            #here we are fetching if it exist in the dictionary otherwise will return unknown
            file_type = ref_dic.get(extension, "unknown")
        else:
            file_type = "unknown"
        #here we are matching the file_type with itself
        op[n] = file_type
    #op is returned
    return op

inputextension = "xls,spreadsheet;xlsx,spreadsheet;jpg,image"
test = ["abc.jpg", "xyz.xls", "text.csv", "123"]
#final_res stores the dictionary that we are going to ptibt after calling the fuction(not necessary)
final_res = printfile(inputextension, test)
print(final_res)#simple print statement


from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect,JsonResponse
from .forms import NameForm
from .models import NameFormModel
import json, os, requests
from datetime import datetime
# Create your views here.
database = []
def moviemanagerView(request):
    if request.method == 'POST':
        form = NameForm(request.POST)
        #year_model = Year(request.POST)
        if form.is_valid():
            #Not initializing db here, instead storing cleaned data for manipulation
            cleanForm = form.cleaned_data
            print(cleanForm)
            print(type(cleanForm))
            #obj = NameFormModel.objects.create(**form.cleaned_data)
            movies_json = JsonResponse(cleanForm, safe = False)
            #Always have to futz with dates for one reason or another. This prevents the db from having datetime() instead of your actual date.
            cleanForm["date_watched_field"] = cleanForm["date_watched_field"].strftime("%m/%d/%Y")
            #Check to see if your db already exists, if it doesn't you need to do some more work. If it does you can just continue
            if os.path.exists('moviedatabase.json'):
                with open('moviedatabase.json') as outfile:
                    data = json.load(outfile)
            if not os.path.exists('moviedatabase.json'):
                data = []
            data.append(cleanForm)
            with open('moviedatabase.json','w') as outfile:
                json.dump(data,outfile)
            # This is just to show a response to the user. You can render another form here instead of the default form. This is your chance to return a templated list instead but this should get you on the right road.
            return HttpResponse(str(data))
            #return render (request, 'form.html',{'form':form})
    else:
        form = NameForm()
    return render (request, 'form.html',{'form':form})

def moviemanager(request):
    if request.method == 'POST':
        form = NameForm(request.POST)
        if form.is_valid():
            form = NameForm()
            #return redirect('home:home')
            return render (request, 'form.html',{'form':form})
    else:
        form = NameForm()
    return render (request, 'form.html',{'form':form})

def about_page(request):
    page_tile = "About title"
    return render(request, "about.html",{"title":page_tile})

def contact_page(request):
    contact_title = "Contact title"
    return render(request, "contact.html",{"title":contact_title})


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

from odoo import models, fields, api
from odoo.exceptions import UserError
from odoo.fields import first

class sale_order_product_pack(models.Model):
    _inherit = "sale.order"

    @api.onchange("order_line")
    def check_pack_line_unlink(self):
        origin_line_ids = self._origin.order_line.ids
        line_ids = self.order_line.ids
        removed_line_ids = list(set(origin_line_ids) - set(line_ids))
        removed_line = self.env["sale.order.line"].browse(removed_line_ids)
        if removed_line.filtered(
            lambda x: x.pack_parent_line_id
            and not x.pack_parent_line_id.product_id.pack_modifiable
        ):
            pass

class sale_order_line_product_pack(models.Model):
    _inherit = "sale.order.line"

    is_pack_outside = fields.Boolean('帳票出力外', default=False)

    def expand_pack_line(self, write=False):
        self.ensure_one()
        vals_list = []
        if self.product_id.pack_ok and self.pack_type == "detailed":
            for subline in self.product_id.product_tmpl_id.mapped('pack_line_ids'):
                vals = subline.get_sale_order_line_vals(self, self.order_id)
                if write:
                    existing_subline = first(
                        self.pack_child_line_ids.filtered(
                            lambda child: child.product_id == subline.product_id
                        )
                    )
                    # if subline already exists we update, if not we create
                    if existing_subline:
                        if self.do_no_expand_pack_lines:
                            vals.pop("product_uom_qty", None)
                            vals.pop("discount", None)
                        existing_subline.write(vals)
                    elif not self.do_no_expand_pack_lines:
                        vals_list.append(vals)
                else:
                    vals_list.append(vals)
            if vals_list:
                self.create(vals_list)

class product_pack(models.Model):
    _inherit = "product.pack.line"

    def get_sale_order_line_vals(self, line, order):
        self.ensure_one()
        quantity = self.quantity * line.product_uom_qty
        line_vals = {
            "order_id": order.id,
            "sequence": line.sequence,
            "product_id": self.product_id.id or False,
            "pack_parent_line_id": line.id,
            "pack_depth": line.pack_depth + 1,
            "company_id": order.company_id.id,
            "pack_modifiable": line.product_id.pack_modifiable,
            "is_pack_outside": True
        }
        sol = line.new(line_vals)
        sol.product_id_change()
        sol.product_uom_qty = quantity
        sol.product_uom_change()
        sol._onchange_discount()
        vals = sol._convert_to_write(sol._cache)
        pack_price_types = {"totalized", "ignored"}
        sale_discount = 0.0
        if line.product_id.pack_component_price == "detailed":
            sale_discount = 100.0 - (
                (100.0 - sol.discount) * (100.0 - self.sale_discount) / 100.0
            )
        elif (
            line.product_id.pack_type == "detailed"
            and line.product_id.pack_component_price in pack_price_types
        ):
            vals["price_unit"] = 0.0
        vals.update(
            {
                "discount": sale_discount,
                "name": "{}{}".format("> " * (line.pack_depth + 1), sol.name),
            }
        )
        return vals

class product_template_product_pack(models.Model):
    _inherit = 'product.template'

    def write(self, vals):
        _vals = vals.copy()
        list_vals = []
        child_products = []
        child_product = self.env['product.product'].search(
            [('product_tmpl_id', '=', self.id)])
        for product in child_product:
            child_products.append(product.id)
        if vals.get("pack_line_ids", False):
            for val in vals.get("pack_line_ids", False):
                if not val[0] == 4:  # CREATE
                    list_vals.append(val)
                if val[0] == 2:  # DELETE
                    pack_line_product_id = self.env['product.pack.line'].search(
                        [('id', '=', val[1])]).product_id.id
                    pack_line = self.env['product.pack.line'].search(
                        [('parent_product_id', 'in', child_products), ('product_id', '=', pack_line_product_id)])
                    if pack_line:
                        for pack in pack_line:
                            if [2, pack.id, False] not in list_vals:
                                list_vals.append([2, pack.id, False])
                if val[0] == 1:  # UPDATE
                    pack_line_product_id = self.env['product.pack.line'].search(
                        [('id', '=', val[1])]).product_id.id
                    pack_line = self.env['product.pack.line'].search(
                        [('parent_product_id', 'in', child_products), ('product_id', '=', pack_line_product_id)])
                    if pack_line:
                        for pack in pack_line:
                            if [1, pack.id, val[2]] not in list_vals:
                                list_vals.append([1, pack.id, val[2]])
        self.product_variant_ids.write({"pack_line_ids": list_vals})
        if 'pack_line_ids' in vals:
            _vals.pop("pack_line_ids")
        return super().write(_vals)


people1 = [1, 2, 3, 4, 5]
people2 = [2, 1, 2, 3, 2, 4, 2, 5]
people3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]

def solution(answers):
    cnt1, cnt2, cnt3 = 0, 0, 0
    answer = [1]
    cnt_lst = []
    for i in range(len(answers)):
        if answers[i] == people1[i % len(people1)]:
            cnt1 += 1
        cnt_lst.append(cnt1)
    # answer.append(1)

    # for i in range(len(answers)):
        if answers[i] == people2[i % len(people2)]:
            cnt2 += 1

        if answers[i] == people3[i % len(people3)]:
            cnt3 += 1

    if cnt2 == cnt_lst[-1]:
        answer.append(2)
    elif cnt2 > cnt_lst[-1]:
        answer.clear()
        answer.append(2)
        cnt_lst.append(cnt2)

    # for i in range(len(answers)):
    #     if answers[i] == people3[i % len(people3)]:
    #         cnt3 += 1
    if cnt3 == cnt_lst[-1]:
        answer.append(3)
    elif cnt3 > cnt_lst[-1]:
        answer.clear()
        answer.append(3)
        cnt_lst.append(cnt3)

    return answer

print(solution([1,2,3,4,5]))
print(solution([1,3,2,4,2]))


#SNAKE MENU
import pygame
import time

ANSI_HOME_CURSOR = u"\u001B[0;0H\u001B[2"
RESET_COLOR = u"\u001B[0m\u001B[2D"

def snake_print(position):
  snake = ["                     ____", "                    / . .\ ", "                    \   ---<", "   _________________/ /", "  \__________________/"]
  print(ANSI_HOME_CURSOR)
  print(RESET_COLOR)
  sp = " " * position
  for line in snake:
    print("\033[1;33;93m" + sp +  line)
  print(RESET_COLOR)

def snake():

  start = 0
  end = 50
  step = 2

  for position in range(start, end, step):
    snake_print(position)
    time.sleep(0.3)

#main menu
def main():
  snake()
  print(" ")
  print("SNAKE REMAKE!")
  print(" ")
  print("1: Tutorial")
  print("2: Play")
  print("0: Exit")

  try:
    answer = int(input("SELECT A NUMBER: "))
    if answer >= 4:
      print("INVALID NUMBER:", answer)
      return

    while answer < 4:
      if answer == 1:
        print("Tutorial: Control the snake using your arrow keys. Eat the fruit, and avoid moving off the screen or bumping into yourself. Get the as many fruits as you can!")
        answer = int(input("SELECT A NUMBER TO CONTINUE: "))
      elif answer == 2:
        print(" ")
        print("E: Easy")
        print("M: Medium")
        print("H: Hard")
        leveltype = input("SELECT A LEVEL: ")
        setlevel(leveltype)
        return
      elif answer == 0:
        return
      else:
        print("INVALID NUMBER: {answer}")
        return
  except ValueError:
    print("NOT A NUMBER")

def easy():
  import easy
  pygame.init()
def medium():
  import medium
  pygame.init()
def hard():
  import hard
  pygame.init()

def setlevel(leveltype):
  if leveltype == "E":
    print("Welcome to Easy Mode!")
    easy()
  elif leveltype == "M":
    print("Welcome to Medium Mode!")
    medium()
  elif leveltype == "H":
    print("Welcome to Hard Mode!")
    hard()
  else:
    print("INVALID INPUT:", leveltype)

main()


# https://en.wikipedia.org/wiki/LU_decomposition
# https://www.quantstart.com/articles/LU-Decomposition-in-Python-and-NumPy

def scal(arg1, arg2):
    assert len(arg1) == len(arg2)
    return sum(map(lambda i, j: i * j, arg1, arg2))

def mat_prod(arg1, arg2):
    assert len(arg1[0]) == len(arg2[0])
    return list(map(lambda x, y: list(map(scal, x, y)), list(map(lambda x: [x] * len(arg2), arg1)), [arg2] * len(arg2)))

def identity_mat(arg):
    iden_mat = [[0] * len(arg) for i in range(len(arg))]
    print(iden_mat)
    for i in range(len(iden_mat)):
        iden_mat[i][i] = 1
    return iden_mat

def lu_decomposition(arg):
    P = identity_mat(arg)
    PA = mat_prod(P, arg)
    L = [[0] * len(arg) for i in range(len(arg))]
    U = [[0] * len(arg) for i in range(len(arg))]
    for j in range(len(arg)):
        L[j][j] = 1
        for i in range(j + 1):
            s1 = sum(U[k][j] * L[i][k] for k in range(i))
            U[i][j] = PA[i][j] - s1
        for i in range(j, len(arg)):
            s2 = sum(U[k][j] * L[i][k] for k in range(j))
            L[i][j] = (PA[i][j] - s2) / U[j][j]

    return (L, U)

def det(arg1):
    l, u = lu_decomposition(arg1)
    p1, p2 = 1, 1
    for i in range(len(l)):
       p1 *= l[i][i]
    for i in range(len(u)):
        p2 *= u[i][i]
    return p1 * p2

A = [[15, 3, -16, 2], [3, -84, 1, -100], [14, 1, 400, -1], [2, 63, -1, -6]]
print(det(A))

import numpy as np

print(np.linalg.det(A))

Basics/Homeworks/Homework_6/Exercise_2_fast determinant (LU decomposition).py


from django.core.mail import EmailMessage

TITLE = [
    ('Mr', 'Mr'),
    ('Mrs', 'Mrs'),
    ('Ms', 'Ms'),
    ('Dr', 'Dr'),
]

EXPERTISE = [
    ('UI/UX Design', 'UI/UX Design'),
    ('Product Design', 'Product Design'),
    ('AI Design', 'AI Design'),
]

MENTORSHIP_AREAS = [
    ('Career Advice', 'Career Advice'),
    ('Portfolio Review', 'Portfolio Review'),
    ('Interview Techniques', 'Interview Techniques'),
]

USER_TYPE = [('mentor', 'mentor'), ('member', 'member')]

MENTOR_STATUS = [('n/a', 'not applicable'), ('pending', 'pending'),
                 ('approved', 'approved'), ('denied', 'denied')]

class Util:

    @staticmethod
    def send_email(data):
        email = EmailMessage(
            subject=data['email_subject'],
            body=data['email_body'],
            to=(data['to_email'],))
        email.send()


"""A modified BFS algorithm for the Android Bubble Sort Puzzle Solver."""

from collections import deque

from solver.trie import Trie
from solver.state import is_solved_state
from solver.state import count_finished_tubes
from solver.state import get_next_states

class QuantizedDoubleEndedPriorityQueue:
    """A Quantized version of the deque data structure."""

    def __init__(self):
        """Create a QuantizedDoubleEndedPriorityQueue."""
        self.d = {}
        self.count = 0

    def add(self, rank, state, moves):
        """Add a state to QuantizedDoubleEndedPriorityQueue."""
        if rank not in self.d:
            self.d[rank] = deque()
        self.d[rank].append((state, moves))
        self.count += 1

    def get(self):
        """Return the next state to be checked."""
        rank = max(self.d.keys())

        ret = self.d[rank].popleft()

        if len(self.d[rank]) == 0:
            del self.d[rank]

        self.count -= 1
        return ret

def bfs(initial_state):
    """Run the modified BFS algorithm."""
    states = QuantizedDoubleEndedPriorityQueue()

    rank = count_finished_tubes(initial_state)
    states.add(rank, initial_state, [])

    visited_states = Trie()

    while states.count > 0:
        # print("#" * (len(states) // 100))
        # print("#" * (len(visited_state_strings) // 10))

        state, moves = states.get()

        # print("")
        # print("")
        # print(f"BFS state is: {state}")

        if visited_states.contains(state):
            continue

        if is_solved_state(state):
            return moves

        visited_states.add(state)

        for next_state, next_moves in get_next_states(state, moves):
            if visited_states.contains(next_state):
                continue

            rank = count_finished_tubes(next_state)
            states.add(rank, next_state, next_moves)


""" Livestock Animal Pens """

#Django
from django.db import models

ORIENTATION_CHOICES = (
    ('Norte','Norte'),
    ('Sur','Sur'),
    ('Este','Este'),
    ('Oeste','Oeste')
)

class LivestockAnimalPens(models.Model):
    """ Modelo de Corrales de animales
    de la produccion ganadera """

    production_livestock = models.ForeignKey(
        "producer.ProductionLivestock",
        related_name="livestock_animal_pens",
        on_delete=models.CASCADE
        )
    orientation = models.CharField(max_length=20, blank=True, null=True)
    building_material = models.CharField(max_length=50, blank=True, null=True)
    roof_material = models.CharField(max_length=30, blank=True, null=True)
    foor_material = models.CharField(max_length=30, blank=True, null=True)
    surface = models.FloatField(default=0)
    num_animals = models.PositiveIntegerField(default=0)
    lat = models.FloatField(default=0)
    lng = models.FloatField(default=0)


from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
import os
import time

fig = plt.figure()
plt.ion()
ax = fig.add_subplot(111, projection='3d')
ax.grid(False)

for root, folder, files in os.walk("./results/features"):
    for file in sorted(files):
        if ".npy" not in file:
            continue

        p = np.load(os.path.join("./results/features",file))
        p = np.reshape(p, (13,3))
        ax.clear()
        ax.grid(False)
        ax.set_xlim([-1, 1])
        ax.set_ylim([-1, 1])
        ax.set_zlim([-1, 1])

        ax.scatter(p[:,0],p[:,1],p[:,2])
        plt.draw()
        plt.pause(1)
        plt.show()


__author__ = 'piyush'

k = int(input())

x = []
for i in range(k):
    x.append(int(input()))

def prime(a):
    sum = []
    for num in range(2,a+1):
        if all(num%i!=0 for i in range(2,num)):
            sum.append(num)
    return sum

def lcm_upto(N):
  total = 1
  for p in prime(N):
    x=1
    while x*p <= N:
      x=x*p
    total = total * x
  return total

for i in range(k):
    print(lcm_upto(x[i]))


"""empty message

Revision ID: d21d3839c096
Revises: 0c6b29c57638
Create Date: 2020-01-08 12:54:10.048577

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'd21d3839c096'
down_revision = '0c6b29c57638'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('word_classification',
    sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
    sa.Column('word_classification', sa.String(length=4), nullable=False),
    sa.Column('word', sa.String(length=1024), nullable=False),
    sa.Column('last_name_used', sa.String(length=1024), nullable=True),
    sa.Column('last_prep_name', sa.String(length=1024), nullable=True),
    sa.Column('frequency', sa.BIGINT(), nullable=True),
    sa.Column('approved_by', sa.Integer(), nullable=True),
    sa.Column('approved_dt', sa.DateTime(timezone=True), nullable=True),
    sa.Column('start_dt', sa.DateTime(timezone=True), nullable=True),
    sa.Column('end_dt', sa.DateTime(timezone=True), nullable=True),
    sa.Column('last_updated_by', sa.Integer(), nullable=True),
    sa.Column('last_update_dt', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['approved_by'], ['users.id'], ),
    sa.ForeignKeyConstraint(['last_updated_by'], ['users.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_word_classification_word'), 'word_classification', ['word'], unique=False)
    op.create_index(op.f('ix_word_classification_word_classification'), 'word_classification', ['word_classification'], unique=False)
   # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_word_classification_word_classification'), table_name='word_classification')
    op.drop_index(op.f('ix_word_classification_word'), table_name='word_classification')
    op.drop_table('word_classification')
    # ### end Alembic commands ###


#!/usr/bin/env python3
import ev3dev.ev3 as ev3
from time import sleep
btn = ev3.Button()
gy = ev3.GyroSensor()
#Gyro can be reset with changing between modes :) (WTF!)
gy.mode = 'GYRO-ANG'
gy.mode = 'GYRO-RATE'
gy.mode='GYRO-ANG'
while not btn.any():
    print("Gyro loop")
    angle = gy.value()
    print(str(angle))
    sleep(0.1)


a=float(input("please enter a: "))
b=float(input("please enter b: "))
c=float(input("please enter c: "))
print(f"P={a}(x^2)+{b}x+{c}")
if a==0:
    if b==0:
        if c==0:
            print("p=0")
        else:
            print(f"P={c}")
    elif b==1:
        if c==0:
            print(f"P=x")
        else:
            print(f"P=x+{c}")
    else:
        if c==0:
            print(f"P={b}x")
        else:
            print(f"{b}x+{c}")
elif a==1:
    if b==0:
        if c==0:
            print("p=x^2")
        else:
            print(f"P=x^2+{c}")
    elif b==1:
        if c==0:
            print(f"p=x^2+x")
        else:
            print(f"P=x^2+x+{c}")
    else:
        print(f"x^2+{b}x+{c}")
else:
    if b==0:
        if c==0:
            print(f"p={a}x^2")
        else:
            print(f"P={a}x^2+{c}")
    elif b==1:
        if c==0:
            print(f"p={a}^2+x")
        else:
            print(f"P={a}x^2+x+{c}")
    else:
        print(f"P={a}x^2+{b}x+{c}")
#حل معادله
if a==0:
    if b==0:
        if c==0:
            print("The equation has infinite answers.")
        else:
            print("The equation doesn't have an answer.")
    else:
        if c==0:
            print("The equation has an answer:",0)
        else:
            print("The equation only has one answer: ",-c/b)
else:
    delta = b ** 2 - 4 * a * c
    print("delta=", delta)
    if delta < 0:
        print("The equation doesn't have an answer.")
    elif delta == 0:
        print("The equation only has one answer: ")
        x = (-b) / (2 * a)
        print(x)
    else:
        print("The equation has two answers: ")
        x1 = (-b + (delta) ** (0.5)) / 2 * a
        x2 = (-b - (delta) ** (0.5)) / 2 * a
        print(x1,x2)


# -*- coding: UTF-8 -*-
import sys
import os

folderPath = sys.path[0]
suiteName = os.path.realpath(sys.argv[0]).replace(folderPath, "")[1:-3]
batPath = folderPath + "/" + suiteName + ".bat"
outputFile = open(batPath, "w")
outputFile.truncate()

list = os.listdir(sys.path[0])
outputFile.write("python ")
# outputFile.write("py.test ")
g = os.walk(folderPath)

fileName = None
folderName = None

for path, d, filelist in g:
    for filePath in filelist:
        if filePath.endswith(".py") and filePath.startswith("test_") and not filePath.__contains__(
                "__init__") and not filePath.__contains__("Suite"):
            outputFile.write(os.path.join(path, filePath).replace(os.getcwd(), "..").replace("\\", "/") + " ")

outputFile.write("--html=../report.html ")
outputFile.close()


from dnn_app_utils_v3 import *
import numpy as np

# this script reads from h5 and output them to npy files
dir = "datasets/"
train_x_orig, train_y, test_x_orig, test_y, classes = load_data()
np.save(dir+"train_x_orig", train_x_orig)
np.save(dir+"train_y", train_y)
np.save(dir+"test_x_orig", test_x_orig)
np.save(dir+"test_y", test_y)
np.save(dir+"classes", classes)


import cv2
import numpy as np
import keras

emnist_labels = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]

def letters_extract(image_file: str, out_size=28):
    img = cv2.imread(image_file)
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
    img_erode = cv2.erode(thresh, np.ones((3, 3), np.uint8), iterations=1)
    contours, hierarchy = cv2.findContours(img_erode, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    output = img.copy()
    letters = []
    for idx, contour in enumerate(contours):
        (x, y, w, h) = cv2.boundingRect(contour)
        if hierarchy[0][idx][3] == 0:
            cv2.rectangle(output, (x, y), (x + w, y + h), (70, 0, 0), 1)
            letter_crop = gray[y:y + h, x:x + w]
            size_max = max(w, h)
            letter_square = 255 * np.ones(shape=[size_max, size_max], dtype=np.uint8)
            if w > h:
                y_pos = size_max//2 - h//2
                letter_square[y_pos:y_pos + h, 0:w] = letter_crop
            elif w < h:
                x_pos = size_max//2 - w//2
                letter_square[0:h, x_pos:x_pos + w] = letter_crop
            else:
                letter_square = letter_crop

            letters.append((x, w, cv2.resize(letter_square, (out_size, out_size), interpolation=cv2.INTER_AREA)))

    letters.sort(key=lambda x: x[0], reverse=False)

    return letters

def emnist_predict_img(model, img):
    img_arr = np.expand_dims(img, axis=0)
    img_arr = 1 - img_arr/255.0
    img_arr[0] = np.rot90(img_arr[0], 3)
    img_arr[0] = np.fliplr(img_arr[0])
    img_arr = img_arr.reshape((1, 28, 28, 1))
    predict_x=model.predict([img_arr])
    result=np.argmax(predict_x,axis=1)
    return chr(emnist_labels[result[0]])

def img_to_str(model, image_file: str):
    letters = letters_extract(image_file)
    s_out = ""
    for i in range(len(letters)):
        dn = letters[i+1][0] - letters[i][0] - letters[i][1] if i < len(letters) - 1 else 0
        s_out += emnist_predict_img(model, letters[i][2])
        if (dn > letters[i][1]/4):
            s_out += ' '
    return s_out

image_file = (r'D:\gzip\gzip\3.png')
model = keras.models.load_model('D:\gzip\gzip\Demnist_letters1.h5')
s_out = img_to_str(model, image_file)
print(s_out)

Распознование текста дополнительно/main.py


import os, yaml, logging, re
# external imports
import torch
from joeynmt.helpers import load_config
from subword_nmt import apply_bpe
from subword_nmt import apply_bpe
from sacremoses import MosesTokenizer, MosesDetokenizer
from joeynmt.helpers import load_config, get_latest_checkpoint, \
    load_checkpoint
from joeynmt.vocabulary import build_vocab
from joeynmt.model import build_model
from joeynmt.prediction import validate_on_data
from urllib.request import urlopen
from io import BytesIO
from zipfile import ZipFile

# internal imports
from core.utils import load_line_as_data

class MasakhaneModelLoader():
    """User Defined Class to manage the download of machine trasnlation models"""
    def __init__(self, available_models_file):
        # model directory to store the modeks
        self._model_dir_prefix = os.environ.get('MODEL',
                                                "./models/joeynmt/")
        self._src_language = ''
        #load availiable models into memory
        self.models = self.load_available_models(available_models_file)

    def load_available_models(self, available_models_file):
        """Load a dictonary with available models to download"""
        models = {}
        with open(available_models_file, 'r') as ofile:
            # iterate over file entries
            for i, line in enumerate(ofile):
                entries = line.strip().split("\t")
                # extract headers
                if i == 0:
                    header_keys = [h.__str__() for h in entries]
                    continue

                # build available model dictionary from the headers & entries:
                # https://www.geeksforgeeks.org/python-dictionary-comprehension/
                model = {key:value for key,value in zip(header_keys, entries)}
                # don't add incomplete models
                if model['complete'] != 'yes':
                    continue

                models[f"{model['src_language']}-{model['tgt_language']}-{model['domain']}"] = model

        print('Found {} Masakhane models.'.format(len(models)))

        return models

    def download_model(self, src_language, tgt_language, domain):
        """ Download model for given trg language. """
        model_dir = f"{self._model_dir_prefix}{src_language}-{tgt_language}-{domain}"

        if not os.path.exists(model_dir):
            os.system(f'mkdir -p {model_dir}')

        model_files = self.models[f"{src_language}-{tgt_language}-{domain}"]

        # Check if files exist
        ckpt_path = os.path.join(model_dir, 'model.ckpt')
        src_vocab_path = os.path.join(model_dir, 'src_vocab.txt')
        trg_vocab_path = os.path.join(model_dir, 'trg_vocab.txt')
        config_path = os.path.join(model_dir, 'config_orig.yaml')
        src_bpe_path = os.path.join(model_dir, 'src.bpe.model')
        trg_bpe_path = os.path.join(model_dir, 'trg.bpe.model')

        if not os.path.exists in [ckpt_path, src_vocab_path, trg_vocab_path, config_path, src_bpe_path, trg_bpe_path]:
            URL = "https://zenodo.org/record/7636723/files/" + \
                src_language + "-" + tgt_language
            if domain == "":
                URL += "-baseline.zip?download=1"
            else:
                URL += "-" + domain + "-baseline.zip?download=1"

            http_response = urlopen(URL)
            zipfile = ZipFile(BytesIO(http_response.read()))
            zipfile.extractall(path=model_dir)

        # Rename config file to config_orig.yaml.
        os.rename(os.path.join(model_dir, 'config.yaml'), config_path)

        # Adjust config.
        config = load_config(config_path)
        new_config_file = os.path.join(model_dir, 'config.yaml')
        config = self._update_config(config, src_vocab_path, trg_vocab_path,
                                     model_dir, ckpt_path)
        with open(new_config_file, 'w') as cfile:
            yaml.dump(config, cfile)

        print('Downloaded model for {}-{}.'.format(src_language, tgt_language))

    def load_model(self, src_language, tgt_language, domain, bpe_src_code=None, tokenize=None):
        """ Load model for given trg language. """
        model_dir = f"{self._model_dir_prefix}{src_language}-{tgt_language}-{domain}"

        ckpt_path = os.path.join(model_dir, 'model.ckpt')
        src_vocab_path = os.path.join(model_dir, 'src_vocab.txt')
        trg_vocab_path = os.path.join(model_dir, 'trg_vocab.txt')
        config_path = os.path.join(model_dir, 'config_orig.yaml')

        # Adjust config.
        config = load_config(config_path)
        new_config_file = os.path.join(model_dir, 'config.yaml')
        config = self._update_config(config, src_vocab_path, trg_vocab_path,
                                     model_dir, ckpt_path)
        with open(new_config_file, 'w') as cfile:
            yaml.dump(config, cfile)

        print('Loaded model for {}-{}.'.format(src_language, tgt_language))

        conf = {}

        logger = logging.getLogger(__name__)
        conf["logger"] = logger
        # load the Joey configuration
        cfg = load_config(new_config_file)
        # load the checkpoint
        if "load_model" in cfg['training'].keys():
            ckpt = cfg['training']["load_model"]
        else:
            ckpt = get_latest_checkpoint(model_dir)
            if ckpt is None:
                raise FileNotFoundError("No checkpoint found in directory {}."
                                        .format(model_dir))

        # prediction parameters from config
        conf["use_cuda"] = cfg["training"].get(
            "use_cuda", False) if torch.cuda.is_available() else False

        conf["level"] = cfg["data"]["level"]
        conf["max_output_length"] = cfg["training"].get(
            "max_output_length", None)
        conf["lowercase"] = cfg["data"].get("lowercase", False)

        # load the vocabularies
        src_vocab_file = cfg["training"]["model_dir"] + "/src_vocab.txt"
        trg_vocab_file = cfg["training"]["model_dir"] + "/trg_vocab.txt"

        conf["src_vocab"] = build_vocab(field="src", vocab_file=src_vocab_file,
                                        dataset=None, max_size=-1, min_freq=0)
        conf["trg_vocab"] = build_vocab(field="trg", vocab_file=trg_vocab_file,
                                        dataset=None, max_size=-1, min_freq=0)

        # whether to use beam search for decoding, 0: greedy decoding
        if "testing" in cfg.keys():
            conf["beam_size"] = cfg["testing"].get("beam_size", 0)
            conf["beam_alpha"] = cfg["testing"].get("alpha", -1)
        else:
            conf["beam_size"] = 1
            conf["beam_alpha"] = -1

        # pre-processing
        if tokenize is not None:
            src_tokenizer = MosesTokenizer(lang=cfg["data"]["src"])
            trg_tokenizer = MosesDetokenizer(lang=cfg["data"]["trg"])
            # tokenize input
            def tokenizer(x): return src_tokenizer.tokenize(x, return_str=True)
            def detokenizer(x): return trg_tokenizer.detokenize(
                x.split(), return_str=True)
        else:
            def tokenizer(x): return x
            def detokenizer(x): return x

        if bpe_src_code is not None and level == "bpe":
            # load bpe merge file
            merge_file = open(bpe_src_code, "r")
            bpe = apply_bpe.BPE(codes=merge_file)
            def segmenter(x): return bpe.process_line(x.strip())
        elif conf["level"] == "char":
            # split to chars
            def segmenter(x): return list(x.strip())
        else:
            def segmenter(x): return x.strip()

        conf["preprocess"] = [tokenizer, segmenter]
        conf["postprocess"] = [detokenizer]
        # build model and load parameters into it
        model_checkpoint = load_checkpoint(ckpt, conf["use_cuda"])
        model = build_model(
            cfg["model"], src_vocab=conf["src_vocab"], trg_vocab=conf["trg_vocab"])
        model.load_state_dict(model_checkpoint["model_state"])
        if conf["use_cuda"]:
            model.cuda()
        conf["model"] = model
        print("Joey NMT model loaded successfully.")

        return conf

    def _update_config(self, config, new_src_vocab_path, new_trg_vocab_path,
                       new_model_dir, new_ckpt_path):
        """Overwrite the settings in the given config."""
        config['data']['src_vocab'] = new_src_vocab_path
        if config['model'].get('tied_embeddings', False):
            config['data']['trg_vocab'] = new_src_vocab_path
        else:
            config['data']['trg_vocab'] = new_trg_vocab_path
        config['training']['model_dir'] = new_model_dir
        config['training']['load_model'] = new_ckpt_path
        return config

    def _is_lowercase(self, src_vocab_path):
        # Infer whether the model is built on lowercased data.
        lowercase = True
        with open(src_vocab_path, 'r') as ofile:
            for line in ofile:
                if line != line.lower():
                    lowercase = False
                    break
        return lowercase

# Doesn't look like these functions are ever called...

    def _download_gdrive_file(self, file_id, destination):
        """Download a file from Google Drive and store in local file."""
        download_link = 'https://drive.google.com/uc?id={}'.format(file_id)
        os.system(f'gdown -q -O {destination} {download_link}')

    def _download_github_file(self, github_raw_path, destination):
        """Download a file from GitHub."""
        os.system(f'wget -q -O {destination} {github_raw_path}')

    def _download(self, url, destination):
        """Download file from Github or Googledrive."""
        try:
            if 'drive.google.com' in url:
                if url.startswith('https://drive.google.com/file'):
                    file_id = url.split("/")[-1]
                elif url.startswith('https://drive.google.com/open?'):
                    file_id = url.split('id=')[-1]
                self._download_gdrive_file(file_id, destination)
            else:
                self._download_github_file(url, destination)
        except:
            print("Download failed, didn't recognize url {}.".format(url))


from typing import Any, Dict, List, Type, TypeVar, Union

import attr

from ..models.share_credential import ShareCredential
from ..types import UNSET, Unset

T = TypeVar("T", bound="ModifyRepositoryProfileRequest")

@attr.s(auto_attribs=True)
class ModifyRepositoryProfileRequest:
    """Model having repository details

    Attributes:
        profile_name (Union[Unset, str]): name of the repository profile
        description (Union[Unset, str]):
        share_path (Union[Unset, str]): Provide the share path of catalog
        modified_by (Union[Unset, str]): Provide the modifiedby user
        share_credential (Union[Unset, ShareCredential]): Share credential details
    """

    profile_name: Union[Unset, str] = UNSET
    description: Union[Unset, str] = UNSET
    share_path: Union[Unset, str] = UNSET
    modified_by: Union[Unset, str] = UNSET
    share_credential: Union[Unset, ShareCredential] = UNSET
    additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        profile_name = self.profile_name
        description = self.description
        share_path = self.share_path
        modified_by = self.modified_by
        share_credential: Union[Unset, Dict[str, Any]] = UNSET
        if not isinstance(self.share_credential, Unset):
            share_credential = self.share_credential.to_dict()

        field_dict: Dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if profile_name is not UNSET:
            field_dict["profileName"] = profile_name
        if description is not UNSET:
            field_dict["description"] = description
        if share_path is not UNSET:
            field_dict["sharePath"] = share_path
        if modified_by is not UNSET:
            field_dict["modifiedBy"] = modified_by
        if share_credential is not UNSET:
            field_dict["shareCredential"] = share_credential

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        profile_name = d.pop("profileName", UNSET)

        description = d.pop("description", UNSET)

        share_path = d.pop("sharePath", UNSET)

        modified_by = d.pop("modifiedBy", UNSET)

        _share_credential = d.pop("shareCredential", UNSET)
        share_credential: Union[Unset, ShareCredential]
        if isinstance(_share_credential, Unset):
            share_credential = UNSET
        else:
            share_credential = ShareCredential.from_dict(_share_credential)

        modify_repository_profile_request = cls(
            profile_name=profile_name,
            description=description,
            share_path=share_path,
            modified_by=modified_by,
            share_credential=share_credential,
        )

        modify_repository_profile_request.additional_properties = d
        return modify_repository_profile_request

    @property
    def additional_keys(self) -> List[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties


#!usr/bin/python

import math

def fuel_needed(mass):
    fuel = math.floor(mass/3) - 2
    if fuel <= 0:
       return 0
    fuel_for_fuel = fuel_needed(fuel)
    if fuel_for_fuel <= 0:
      return fuel
    return fuel + fuel_for_fuel

answer = 0

with open('input.txt') as f:
    for line in f.readlines():
        answer += fuel_needed(int(line.strip('\n')))

print('%s\n' % (answer, ))


from jinja2 import Template
f = open('weather.log', 'r')
w = f.readlines()
f.close()

weather = []
for i in w:
    weather.append(i[:25].strip().split())

#print(weather)
html = open('weth.txt').read()
template = Template(html)
render = template.render(weather = weather)

f = open('weather.html', 'w')
f.write(render)
f.close()


"""
[最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/)
转换为最长子序列且序列中 0 的个数 <= K
"""

def longestOnes(A, K):
    N = len(A)
    res = 0
    left, right = 0, 0
    zeros = 0
    while right < N:
        if A[right] == 0:
            zeros += 1
        while zeros > K:
            if A[left] == 0:
                zeros -= 1
            left += 1
        res = max(res, right - left + 1)
        right += 1
    return res


import os
import sys

import numpy as np
import pytest
from numpy.random import normal

sys.path.append(os.path.join(os.path.dirname(__file__), "../.."))
module = __import__("Acquisition", fromlist=["EI"])

class TestEI:
    @pytest.mark.parametrize(
        ("mean", "var", "base"),
        [(0.0, 1.0, 0.5), (0.8, 0.1, 0.3), (0.1, 1.3, 0.7), (0.4, 0.1, 0.3),],
    )
    def test_f(self, mean, var, base) -> float:
        # 厳密解
        AF = module.EI.EI()
        ei = AF.f(mean, var, base)

        # 近似解(モンテカルロ積分)
        sum = 0.0
        size = 100000
        for x in normal(mean, var, size):
            sum += np.max([base - x, 0.0])
        sum /= size
        print(sum, ei)

        # 差分
        dif = np.abs(sum - ei)
        assert dif < 0.1


import hashlib
import time
import utils
import asyncpg
import asyncpg.exceptions as asyncpg_exc
from config import logger
from aiohttp import web
from db_wrapper import DbWrapper

router = web.RouteTableDef()

@router.post('/sign_in')
async def sign_in(request: web.Request):
    body = await request.json()
    email: str = body.get('email')
    password: str = body.get('password')
    hash = hashlib.sha256(password.encode('UTF-8')).hexdigest()
    user_data = await DbWrapper().get_user_data_by_email(email)
    if not user_data:
        return web.json_response(utils.generate_response(0, 'No account with such email'), status=403)

    if not hash == user_data['hash']:
        return web.json_response(utils.generate_response(0, 'Incorrect password'), status=403)

    # TODO send token
    response = utils.generate_response(1, 'Authorization_successful')
    token = await DbWrapper().get_token( user_data['user_id'])
    response['data'].update({'token': token['tkn'], 'timestamp': token['timestamp'], 'lifetime': token['lifetime']})
    return web.json_response(response, status=200)

@router.post('/sign_up')
async def sign_up(request: web.Request):
    body = await request.json()

    firstname: str = body.get('firstname')
    lastname: str = body.get('lastname')
    mail: str = body.get('email')
    password: str = body.get('password')
    pw_hash = hashlib.sha256(password.encode('utf-8')).hexdigest()
    try:
        user_by_email = await DbWrapper().get_user_data_by_email(mail)
        if user_by_email:
            return web.json_response(utils.generate_response(0, 'Account already exists'))

        user_insert_result = await DbWrapper().insert_user(firstname=firstname, lastname=lastname, email=mail, password_hash=pw_hash, timestamp=int(time.time()))
        # this is here because sometimes it's possible for two identical requests happening at the same time
        # causing an error due to none being inserted, as insert_user returns none because in another instance of this
        # handler being run it has already been added
        if user_insert_result:
            token = utils.generate_token()
            await DbWrapper().insert_token(user_insert_result, token, int(time.time()), 0)
            return web.json_response(utils.generate_response(1, 'Account created successfully'))
        else:
            return web.json_response(utils.generate_response(0, 'Account already exists'))

    except Exception as e:
        logger.warning(f'[Route Handlers] {e}, lineno:{e.__traceback__.tb_lineno}')
        # this will send a 500 response code
        raise

@router.get('/sessions')
async def all_sessions(request: web.Request):
    result = await DbWrapper().get_all_sessions()
    response = utils.generate_response(1, 'Session list returned')
    response['data'].update({'sessions':[]})
    for session in result:
        specializations = await DbWrapper().get_instructor_specs(session['instructor_id'])
        response['data']['sessions'].append({
            'session_id': session['session_id'],
            'session_start': session['session_start'],
            'session_place': session['session_place'],
            'session_name': session['session_name'],
            'capacity': session['capacity'],
            'signed_up': session['signed_up'],
            'firstname': session['firstname'],
            'lastname': session['lastname'],
            'specialization': [record['spec_name'] for record in specializations]
        })

    return web.json_response(response, status=200)

@router.post('/sign_up_for_session')
async def sign_for_session(request:web.Request):
    body = await request.json()
    session_id = body.get('session_id')
    uid = request.headers.get('X-User-Id')

    try:
        await DbWrapper().sign_up_for_session(user_id=uid, session_id=session_id)
    except asyncpg_exc.UniqueViolationError as e:
        return web.json_response(utils.generate_response(0, 'Double signup attempt'), status=400)
    except Exception as e:
        return web.json_response(utils.generate_response(0, f'Something went wrong. {e}'), status=500)

    return web.json_response(utils.generate_response(1, 'Success'), status=200)

@router.post('/unsign_from_session')
async def unsign_for_session(request: web.Request):

    body = await request.json()
    session_id = int(body.get('session_id'))
    uid = request.headers['X-User-Id']

    await DbWrapper().unsign_from_session(session_id = session_id, user_id=uid)

    return web.Response(status=200)

@router.get('/instructors')
async def get_instructors(request: web.Request):
    result = await DbWrapper().get_instructors()
    response = utils.generate_response(1, 'Instructor list returned')
    response['data'].update({'instructors': []})
    for instructor in result:
        response['data']['instructors'].append({
            'firstname': instructor['firstname'],
            'lastname': instructor['lastname'],
            'info': instructor['info'],
            'spec': instructor['spec_name']
        })

    return web.json_response(response, status=200)

@router.post('/sessions_by_uid')
async def get_sessions_by_uid(request: web.Request):
    body = await request.json()
    uid = int(request.headers['X-User-Id'])
    result = await DbWrapper().get_sessions_by_user(uid)
    response = utils.generate_response(1, 'Session list returned')
    response['data'].update({'sessions': []})
    for session in result:
        specializations = await DbWrapper().get_instructor_specs(session['instructor_id'])
        response['data']['sessions'].append({
            'session_id': session['session_id'],
            'session_start': session['session_start'],
            'session_place': session['session_place'],
            'session_name': session['session_name'],
            'capacity': session['capacity'],
            'signed_up': session['signed_up'],
            'firstname': session['firstname'],
            'lastname': session['lastname'],
            'specialization': [record['spec_name'] for record in specializations]
        })

    return web.json_response(response, status=200)

@router.get('/get_notifications_by_uid')
async def get_notifications_by_uid(request: web.Request):
    uid = request.headers['X-User-Id']
    notifications = await DbWrapper().get_notifications_by_user_id(uid)
    data = []
    for notification in notifications:
        new_notification = {
            'notification_id': notification['notification_id'],
            'text': notification['text']
        }
        data.append(notification_data)
    response = generate_response(1, 'Success')
    response['data'] = data
    return web.json_response(data, status=200)

@router.delete('/delete_notification_link')
async def soft_delete_notification_link(request: web.Request):
    body = await request.json()
    user_id = request.headers['user_id']
    notification_id = body['notification_id']
    try:
        await DbWrapper().unbind_notification(int(user_id), int(notification_id))
    except Exception as e:
        logger.exception('Exception during delete_notification_link:')
        response = utils.generate_response(0, 'Failed to delete notification link')
        return web.Response(response, status=500)

    return web.Response(response, status=200)

@router.get('/ping')
async def ping(request: web.Request):
    return web.Response(body='pong')


__author__ = 'James DeVincentis <james.d@hexhost.net>'

import os
import multiprocessing
import time

import schedule
import setproctitle

import cif

class Feeder(multiprocessing.Process):
    def __init__(self):
        multiprocessing.Process.__init__(self)
        self.backend = None
        self.logging = cif.logging.getLogger('FEEDER')
        self.logging.info("Loading Feeds")
        self.load_feeds()

    def load_feeds(self):
        schedule.clear()
        feeds = {}
        self.logging.debug("Getting List of Feeds")
        files = os.listdir(cif.options.feed_directory)
        feed_files = []
        for file in files:
            if file.endswith(".yml"):
                self.logging.debug("Found Feed File: {0}".format(file))
                feed_files.append(os.path.join(cif.options.feed_directory, file))

        feed_files.sort()
        for feed_file in feed_files:
            self.logging.info("Loading Feed File: {0}".format(feed_file))
            feeds[feed_file] = cif.feeder.Feed(feed_file)
            self.logging.info("Scheduling Feed File: {0}".format(feed_file))
            if 'feeds' not in feeds[feed_file].feed_config:
                self.logging.info("{0} does not contain feeds key".format(feed_file))
                continue
            for feed_name in feeds[feed_file].feed_config['feeds'].keys():
                if "interval" in feeds[feed_file].feed_config['feeds'][feed_name]:
                    if feeds[feed_file].feed_config['feeds'][feed_name]['interval'] == "hourly":
                        self.logging.info(repr(schedule.every().hour.at("00:00").do(feeds[feed_file].process, feed_name)))
                    elif feeds[feed_file].feed_config['feeds'][feed_name]['interval'] == "daily":
                        self.logging.info(repr(schedule.every().day.at("00:00").do(feeds[feed_file].process, feed_name)))
                    elif feeds[feed_file].feed_config['feeds'][feed_name]['interval'] == "weekly":
                        self.logging.info(repr(schedule.every().day.at("00:00").do(feeds[feed_file].process, feed_name)))
                else:
                    self.logging.info(repr(schedule.every(1).minute.do(feeds[feed_file].process, feed_name)))

    def run(self):
        try:
            setproctitle.setproctitle('[CIF-SERVER] - Feeder')
        except:
            pass
        while True:
            try:
                schedule.run_pending()
                time.sleep(1)
            except Exception as e:
                self.logging.error("Schedule dead, restarting")
                continue