import os
import json
import calendar
import http.client
import urllib.request
from pathlib import Path
from bs4 import BeautifulSoup
# from newsapi import NewsApiClient
import xml.etree.ElementTree as ET
from datetime import datetime, date
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

people = dict()
theDate = ""
gameID = ""
cTime = 0
name = ""
modified = ""
teams = {
    "Cleveland Cavaliers": ["http://content.sportslogos.net/logos/6/222/full/ige5q46x2v9c8hw80jhi4f85h.png", "https://ssl.gstatic.com/onebox/media/sports/logos/NAlGkmv45l1L-3NhwVhDPg_48x48.png"],
    "Detroit Pistons": ["http://content.sportslogos.net/logos/6/223/full/2164_detroit_pistons-primary-2018.png", "https://ssl.gstatic.com/onebox/media/sports/logos/qvWE2FgBX0MCqFfciFBDiw_48x48.png"],
    "Indiana Pacers": ["http://content.sportslogos.net/logos/6/224/full/gdm7egmgv3tsspc6f1gym7cwz.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/andumiE_wrpDpXvUgqCGYQ_48x48.png"],
    "Orlando Magic": ["http://content.sportslogos.net/logos/6/217/full/h2k5cbia6m8e1dbdcfxfgre84.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/p69oiJ4LDsvCJUDQ3wR9PQ_48x48.png"],
    "Miami Heat": ["http://content.sportslogos.net/logos/6/214/full/93lzfcfcnq125eh7etyxpuhfp.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/0nQXN6OF7wnLY3hJz8lZJQ_48x48.png"],
    "Brooklyn Nets": ["http://content.sportslogos.net/logos/6/3786/full/930_brooklyn-nets-partial-2013.png", "https://ssl.gstatic.com/onebox/media/sports/logos/iishUmO7vbJBE7iK2CZCdw_48x48.png"],
    "Philadelphia 76ers": ["http://content.sportslogos.net/logos/6/218/full/7034_philadelphia_76ers-primary-2016.png", "https://ssl.gstatic.com/onebox/media/sports/logos/US6KILZue2D5766trEf0Mg_48x48.png"],
    "Golden State Warriors": ["http://content.sportslogos.net/logos/6/235/full/5gzur7f6x09cv61jt16smhopl.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/XD2v321N_-vk7paF53TkAg_48x48.png"],
    "Dallas Mavericks": ["http://content.sportslogos.net/logos/6/228/full/5118_dallas_mavericks-alternate-2018.png", "https://ssl.gstatic.com/onebox/media/sports/logos/xxxlj9RpmAKJ9P9phstWCQ_48x48.png"],
    "Memphis Grizzlies": ["http://content.sportslogos.net/logos/6/231/full/7277_memphis_grizzlies-alternate-2019.png", "https://ssl.gstatic.com/onebox/media/sports/logos/3ho45P8yNw-WmQ2m4A4TIA_48x48.png"],
    "San Antonio Spurs": ["http://content.sportslogos.net/logos/6/233/full/828.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/FKwMB_85FlZ_7PTt1f7hjQ_48x48.png"],
    "Oklahoma City Thunder": ["http://content.sportslogos.net/logos/6/2687/full/qdx55wdx4akljqkvzi1s3e6t3.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/b4bJ9zKFBDykdSIGUrbWdw_48x48.png"],
    "Utah Jazz": ["http://content.sportslogos.net/logos/6/234/full/txe1ybetuoye8pirnrhqalh04.png", "https://ssl.gstatic.com/onebox/media/sports/logos/SP_dsmXEKFVZH5N1DQpZ4A_48x48.png"],
    "Milwaukee Bucks": ["http://content.sportslogos.net/logos/6/225/full/3864_milwaukee_bucks-alternate-2016.png", "https://ssl.gstatic.com/onebox/media/sports/logos/Wd6xIEIXpfqg9EZC6PAepQ_48x48.png"],
    "Phoenix Suns": ["http://content.sportslogos.net/logos/6/238/full/3834_phoenix_suns-partial-2014.png", "https://ssl.gstatic.com/onebox/media/sports/logos/pRr87i24KHWH0UuAc5EamQ_48x48.png"],
    "Los Angeles Lakers": ["http://content.sportslogos.net/logos/6/237/full/uig7aiht8jnpl1szbi57zzlsh.png", "https://ssl.gstatic.com/onebox/media/sports/logos/4ndR-n-gall7_h3f7NYcpQ_48x48.png"],
    "Denver Nuggets": ["http://content.sportslogos.net/logos/6/229/full/8954_denver_nuggets-alternate-2019.png", "https://ssl.gstatic.com/onebox/media/sports/logos/9wPFTOxV_zP1KmRRggJNqQ_48x48.png"],
    "New Orleans Pelicans": ["http://content.sportslogos.net/logos/6/4962/full/2681_new_orleans_pelicans-primary-2014.png", "https://ssl.gstatic.com/onebox/media/sports/logos/JCQO978-AWbg00TQUNPUVg_48x48.png"],
    "Sacramento Kings": ["http://content.sportslogos.net/logos/6/240/full/4043_sacramento_kings-primary-2017.png", "https://ssl.gstatic.com/onebox/media/sports/logos/wkCDHakxEThLGoZ4Ven48Q_48x48.png"],
    "Los Angeles Clippers": ["http://content.sportslogos.net/logos/6/236/full/1038_los_angeles_clippers-secondary-2016.png", "https://ssl.gstatic.com/onebox/media/sports/logos/F36nQLCQ2FND3za-Eteeqg_48x48.png"],
    "Chicago Bulls": ["http://content.sportslogos.net/logos/6/221/full/zdrycpc7mh5teihl10gko8sgf.png", "https://ssl.gstatic.com/onebox/media/sports/logos/ofjScRGiytT__Flak2j4dg_48x48.png"],
    "Portland Trail Blazers": ["http://content.sportslogos.net/logos/6/239/full/826.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/_bgagBCd6ieOIt3INWRN_w_48x48.png"],
    "Boston Celtics": ["http://content.sportslogos.net/logos/6/213/full/slhg02hbef3j1ov4lsnwyol5o.png", "https://ssl.gstatic.com/onebox/media/sports/logos/GDJBo7eEF8EO5-kDHVpdqw_48x48.png"],
    "Minnesota Timberwolves": ["http://content.sportslogos.net/logos/6/232/full/9669_minnesota_timberwolves-primary-2018.png", "https://ssl.gstatic.com/onebox/media/sports/logos/JzePt6Fp_HJMNEz-1B99yw_48x48.png"],
    "Atlanta Hawks": ["http://content.sportslogos.net/logos/6/220/full/8452_atlanta_hawks-alternate-2016.png", "https://ssl.gstatic.com/onebox/media/sports/logos/pm5l5mtY1elOQAl9ZEcm2A_48x48.png"],
    "Washington Wizards": ["http://content.sportslogos.net/logos/6/219/full/3g5wchibh2ltoh617fcpgmfio.png", "https://ssl.gstatic.com/onebox/media/sports/logos/NBkMJapxft4V5kvufec4Jg_48x48.png"],
    "Houston Rockets": ["http://content.sportslogos.net/logos/6/230/full/etpzlhc48xgh58agjuln2khsl.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/zhO6MIB1UzZmtXLHkJQBmg_48x48.png"],
    "Charlotte Hornets": ["http://content.sportslogos.net/logos/6/5120/full/1926_charlotte__hornets_-primary-2015.png", "https://ssl.gstatic.com/onebox/media/sports/logos/ToeKy5-TrHAnTCl-qhuuHQ_48x48.png"],
    "Toronto Raptors": ["http://content.sportslogos.net/logos/6/227/full/4578_toronto_raptors-primary-2016.png", "https://ssl.gstatic.com/onebox/media/sports/logos/745IgW4NSvnRxg-W9oczmQ_48x48.png"],
    "New York Knicks": ["http://content.sportslogos.net/logos/6/216/full/2nn48xofg0hms8k326cqdmuis.gif", "https://ssl.gstatic.com/onebox/media/sports/logos/-rf7eY39l_0V7J4ekakuKA_48x48.png"]
}
teamMapping = {
    '1610612749': "Milwaukee Bucks",
    '1610612761': "Toronto Raptors",
    '1610612754': "Indiana Pacers",
    '1610612755': "Philadelphia 76ers",
    '1610612738': "Boston Celtics",
    '1610612765': "Detroit Pistons",
    '1610612751': "Brooklyn Nets",
    '1610612766': "Charlotte Hornets",
    '1610612748': "Miami Heat",
    '1610612753': "Orlando Magic",
    '1610612764': "Washington Wizards",
    '1610612737': "Atlanta Hawks",
    '1610612741': "Chicago Bulls",
    '1610612739': "Cleveland Cavaliers",
    '1610612752': "New York Knicks",
    '1610612744': "Golden State Warriors",
    '1610612743': "Denver Nuggets",
    '1610612745': "Houston Rockets",
    '1610612760': "Oklahoma City Thunder",
    '1610612757': "Portland Trail Blazers",
    '1610612762': "Utah Jazz",
    '1610612746': "Los Angeles Clippers",
    '1610612759': "San Antonio Spurs",
    '1610612758': "Sacramento Kings",
    '1610612750': "Minnesota Timberwolves",
    '1610612747': "Los Angeles Lakers",
    '1610612740': "New Orleans Pelicans",
    '1610612742': "Dallas Mavericks",
    '1610612763': "Memphis Grizzlies",
    '1610612756': "Phoenix Suns"
}

def getTime(time):
    day = list(str(time))
    day = day[0:19]
    del day[10]
    day.insert(10, "T")
    day = ''.join(day)
    day += "+00:00"
    currentTime = datetime.fromisoformat(day).timestamp()
    return currentTime

def openStore(currentTime):
    upcoming = []
    file = open("static/database/store.txt", "r")
    N = int(file.readline().strip("\n"))
    for i in range(N):
        info = []
        gameTime = float(file.readline().strip("\n"))
        if gameTime > currentTime:
            info.append(gameTime)
            file.readline()
            d1 = str(date.fromtimestamp(gameTime))
            d2 = str(date.fromtimestamp(currentTime))
            n1 = int(d1[0:4]) * 365 + int(d1[5:7]) * 30 + int(d1[8:10])
            n2 = int(d2[0:4]) * 365 + int(d2[5:7]) * 30 + int(d2[8:10])
            if n1 == n2:
                info.append("Today")
            elif n1 - n2 == 1:
                info.append("Tomorrow")
            else:
                dayMapping = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5: "Sat", 6: "Sun"}
                dayOfWeek = dayMapping[date(int(d1[0:4]), int(d1[5:7]), int(d1[8:10])).weekday()]
                string = dayOfWeek + ", " + str(int(d1[5:7])) + "/" + str(int(d1[8:10]))
                info.append(string)
            for j in range(5):
                info.append(file.readline().strip("\n"))
            upcoming.append(info)
        else:
            for i in range(6):
                file.readline()
    file.close()
    return upcoming

def openDate():
    file = open("static/database/date.txt", "r")
    a = file.readline().strip("\n")
    b = file.readline().strip("\n")
    c = file.readline().strip("\n")
    file.close()
    return a, b, c

def writeXML(year, month, day):
    if year % 400 == 0:
        leap_year = True
    elif year % 100 == 0:
        leap_year = False
    elif year % 4 == 0:
        leap_year = True
    else:
        leap_year = False
    if month in (1, 3, 5, 7, 8, 10, 12):
        month_length = 31
    elif month == 2:
        if leap_year:
            month_length = 29
        else:
            month_length = 28
    else:
        month_length = 30
    if day < month_length:
        day += 1
    else:
        day = 1
        if month == 12:
            month = 1
            year += 1
        else:
            month += 1
    conn = http.client.HTTPSConnection("api.sportradar.us")
    with open("credentials.txt", "r") as f:
        f.readline()
        nba_api_key = f.readline().strip("\n")

    conn.request("GET", "/nba/trial/v5/en/games/" + str(year) + "/" + str(month) + "/" + str(day) + "/schedule.xml?api_key=" + nba_api_key)
    res = conn.getresponse()
    data = res.read()
    text = data.decode("utf-8")
    file = open("static/xml/upcoming_" + str(year) + "_" + str(month) + "_" + str(day) + ".xml", "w")
    file.write(text)
    file.close()
    return str(year), str(month), str(day)

def deleteXML(year, month, day):
    value = 365 * year + 30 * month + day
    files = os.listdir("static/xml/")
    for i in files:
        s = i.split("_")
        y = int(s[1])
        m = int(s[2])
        d = int(s[3][:-4])
        newValue = 365 * y + 30 * m + d
        if newValue < value:
            os.remove("static/xml/" + i)

def changeStore(upcoming):
    file = open("static/database/store.txt", "w")
    file.write(str(len(upcoming)) + "\n")
    for i in range(len(upcoming)):
        for j in upcoming[i]:
            file.write(str(j) + "\n")
    file.close()
    return ''

def changeDate(currentTime):
    num = str(date.fromtimestamp(currentTime))
    a = str(int(num[0:4]))
    b = str(int(num[5:7]))
    c = str(int(num[8:10]))
    file = open("static/database/date.txt", "w")
    file.write(a + "\n")
    file.write(b + "\n")
    file.write(c + "\n")
    file.close()
    return ''

def updateUpcoming(upcoming, currentTime, offset, a, b, c):
    overlap = False
    count = 0
    while len(upcoming) < 6:
        count += 1
        if count >= 21:
            upcoming = "Season Over"
            break
        a, b, c = writeXML(int(a), int(b), int(c))
        deleteXML(int(a), int(b), int(c))
        tree = ET.parse("static/xml/upcoming_" + a + "_" + b + "_" + c + ".xml")
        info = []
        dates = []
        for elem in tree.iter():
            if elem.tag == "{http://feed.elasticstats.com/schema/basketball/schedule-v5.0.xsd}game":
                if elem.attrib["status"] == "closed":
                    pass

                time = elem.attrib["scheduled"].strip("Z")
                gameTime = datetime.fromisoformat(time).timestamp() - offset
                d1 = str(date.fromtimestamp(gameTime))
                d2 = str(date.fromtimestamp(currentTime))
                if gameTime > currentTime:
                    info.append(gameTime)
                    n1 = int(d1[0:4]) * 365 + int(d1[5:7]) * 30 + int(d1[8:10])
                    n2 = int(d2[0:4]) * 365 + int(d2[5:7]) * 30 + int(d2[8:10])
                    if n1 == n2:
                        info.append("Today")
                    elif n1 - n2 == 1:
                        info.append("Tomorrow")
                    else:
                        dayMapping = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5: "Sat", 6: "Sun"}
                        dayOfWeek = dayMapping[date(int(d1[0:4]), int(d1[5:7]), int(d1[8:10])).weekday()]
                        string = dayOfWeek + ", " + str(int(d1[5:7])) + "/" + str(int(d1[8:10]))
                        info.append(string)
                    h = int(time[11:13]) - offset // 3600
                    m = time[14:16]
                    if h < 0:
                        h += 24
                    if h == 0:
                        h += 12
                        info.append(str(h) + ":" + m + " AM")
                        continue
                    if h > 12:
                        h -= 12
                        info.append(str(h) + ":" + m + " PM")
                    elif h == 12:
                        info.append(str(h) + ":" + m + " PM")
                    else:
                        info.append(str(h) + ":" + m + " AM")
                else:
                    overlap = True
            elif elem.tag == "{http://feed.elasticstats.com/schema/basketball/schedule-v5.0.xsd}home" or elem.tag == "{http://feed.elasticstats.com/schema/basketball/schedule-v5.0.xsd}away":
                if overlap == False:
                    info.append(elem.attrib["name"])
                    info.append(teams[elem.attrib["name"]][0])
            elif elem.tag == "{http://feed.elasticstats.com/schema/basketball/schedule-v5.0.xsd}broadcasts":
                if overlap == False:
                    if info not in upcoming:
                        upcoming.append(info)
                info = []
                overlap = False
    changeStore(upcoming)
    changeDate(currentTime)
    return upcoming

def getStandings():
    standings = []
    with urllib.request.urlopen("http://data.nba.net/prod/v1/current/standings_conference.json") as url:
        data = json.loads(url.read().decode())
        east = data['league']['standard']['conference']['east']
        west = data['league']['standard']['conference']['west']
        for i in east:
            teamName = teamMapping[i['teamId']]
            logo = teams[teamName][1]
            win = i['win']
            loss = i['loss']
            winPct = i['winPct']
            gamesBehind = str(float(i['gamesBehind']))
            if gamesBehind == "0.0":
                gamesBehind = "-"
            conference = i['confWin'] + "-" + i['confLoss']
            home = i['homeWin'] + "-" + i['homeLoss']
            away = i['awayWin'] + "-" + i['awayLoss']
            lastTen = i['lastTenWin'] + "-" + i['lastTenLoss']
            if i['isWinStreak']:
                streak = "W" + i['streak']
            else:
                streak = "L" + i['streak']
            standings.append([logo, teamName, win, loss, winPct, gamesBehind, conference, home, away, lastTen, streak])
        for i in west:
            teamName = teamMapping[i['teamId']]
            logo = teams[teamName][1]
            win = i['win']
            loss = i['loss']
            winPct = i['winPct']
            gamesBehind = i['gamesBehind']
            if gamesBehind == "0":
                gamesBehind = "-"
            conference = i['confWin'] + "-" + i['confLoss']
            home = i['homeWin'] + "-" + i['homeLoss']
            away = i['awayWin'] + "-" + i['awayLoss']
            lastTen = i['lastTenWin'] + "-" + i['lastTenLoss']
            if i['isWinStreak']:
                streak = "W" + i['streak']
            else:
                streak = "L" + i['streak']
            standings.append([logo, teamName, win, loss, winPct, gamesBehind, conference, home, away, lastTen, streak])
    return standings

def getPlayers():
    global people
    players = dict()
    javascript = []
    file = open("static/database/players.txt", "r")
    year = int(file.readline().strip("\n"))
    n = int(file.readline().strip("\n"))
    for i in range(n):
        key = file.readline().strip("\n")
        value = file.readline().strip("\n")
        season = file.readline().strip("\n")
        players[key] = [value, season]
        javascript.append(key)
    file.close()

    temp = year
    while True:
        try:
            with urllib.request.urlopen("http://data.nba.net/prod/v1/" + str(year) + "/players.json") as url:
                data = json.loads(url.read().decode())
                for i in data['league']['standard']:
                    key = i['firstName'] + " " + i['lastName']
                    value = i['personId']
                    season = year
                    if key not in javascript:
                        javascript.append(key)
                    players[key] = [value, season]
            year += 1
        except urllib.error.HTTPError:
            if temp != year:
                file = open("static/database/players.txt", "w")
                file.write(str(year) + "\n")
                file.write(str(len(players)) + "\n")
                for i in players:
                    file.write(i + "\n")
                    file.write(players[i][0] + "\n")
                    file.write(str(players[i][1]) + "\n")
                file.close()
            break
    people = players
    return players, javascript

def getStats(playerID, year):
    stats = []
    try:
        with urllib.request.urlopen("http://data.nba.net/prod/v1/" + year + "/players/" + playerID + "_profile.json") as url:
            data = json.loads(url.read().decode())
            for i in data['league']['standard']['stats']['regularSeason']['season']:
                for j in i['teams']:
                    team = teamMapping[j['teamId']]
                    logo = teams[team][1]
                    try:
                        points = float(j['ppg'])
                    except:
                        points = -1
                    try:
                        rebounds = float(j['rpg'])
                    except:
                        rebounds = -1
                    try:
                        assists = float(j['apg'])
                    except:
                        assists = -1
                    try:
                        minutes = float(j['mpg'])
                    except:
                        minutes = -1
                    try:
                        steals = float(j['spg'])
                    except:
                        steals = -1
                    try:
                        turnovers = float(j['topg'])
                    except:
                        turnovers = -1
                    try:
                        blocks = float(j['bpg'])
                    except:
                        blocks = -1
                    try:
                        totAssists = int(j['assists'])
                    except:
                        totAssists = -1
                    try:
                        totBlocks = int(j['blocks'])
                    except:
                        totBlocks = -1
                    try:
                        totSteals = int(j['steals'])
                    except:
                        totSteals = -1
                    try:
                        totTurnovers = int(j['turnovers'])
                    except:
                        totTurnovers = -1
                    try:
                        totReb = int(j['totReb'])
                    except:
                        totReb = -1
                    try:
                        fieldGoalsMade = int(j['fgm'])
                    except:
                        fieldGoalsMade = -1
                    try:
                        fieldGoalsAttempted = int(j['fga'])
                    except:
                        fieldGoalsAttempted = -1
                    try:
                        fieldGoalPercent = float(j['fgp'])
                    except:
                        fieldGoalPercent = -1
                    try:
                        threePointsMade = int(j['tpm'])
                    except:
                        threePointsMade = -1
                    try:
                        threePointsAttempted = int(j['tpa'])
                    except:
                        threePointsAttempted = -1
                    try:
                        threePointPercent = float(j['tpp'])
                    except:
                        threePointPercent = -1
                    try:
                        freeThrowsMade = int(j['ftm'])
                    except:
                        freeThrowsMade = -1
                    try:
                        freeThrowsAttempted = int(j['fta'])
                    except:
                        freeThrowsAttempted = -1
                    try:
                        freeThrowPercent = float(j['ftp'])
                    except:
                        freeThrowPercent = -1
                    try:
                        personalFouls = int(j['pFouls'])
                    except:
                        personalFouls = -1
                    try:
                        totPoints = int(j['points'])
                    except:
                        totPoints = -1
                    try:
                        gamesPlayed = int(j['gamesPlayed'])
                    except:
                        gamesPlayed = -1
                    try:
                        gamesStarted = int(j['gamesStarted'])
                    except:
                        gamesStarted = -1
                    try:
                        totMinutes = int(j['min'])
                    except:
                        totMinutes = -1
                    try:
                        doubleDoubles = int(j['dd2'])
                    except:
                        doubleDoubles = -1
                    try:
                        tripleDoubles = int(j['td3'])
                    except:
                        tripleDoubles = -1
                    stats.append([i['seasonYear'], logo, team, totMinutes, minutes, totPoints, points,
                    totAssists, assists, totReb, rebounds, totBlocks, blocks, totSteals, steals,
                    totTurnovers, turnovers, threePointsMade, threePointsAttempted, threePointPercent,
                    fieldGoalsMade, fieldGoalsAttempted, fieldGoalPercent, freeThrowsMade,
                    freeThrowsAttempted, freeThrowPercent, personalFouls, gamesPlayed, gamesStarted,
                    doubleDoubles, tripleDoubles])

            try:
                career = data['league']['standard']['stats']['careerSummary']
                logo = ""
                team = ""
                points = float(career['ppg'])
                rebounds = float(career['rpg'])
                assists = float(career['apg'])
                minutes = float(career['mpg'])
                steals = float(career['spg'])
                blocks = float(career['bpg'])
                totAssists = int(career['assists'])
                totBlocks = int(career['blocks'])
                totSteals = int(career['steals'])
                totTurnovers = int(career['turnovers'])
                totReb = int(career['totReb'])
                fieldGoalsMade = int(career['fgm'])
                fieldGoalsAttempted = int(career['fga'])
                fieldGoalPercent = float(career['fgp'])
                threePointsMade = int(career['tpm'])
                threePointsAttempted = int(career['tpa'])
                threePointPercent = float(career['tpp'])
                freeThrowsMade = int(career['ftm'])
                freeThrowsAttempted = int(career['fta'])
                freeThrowPercent = float(career['ftp'])
                personalFouls = int(career['pFouls'])
                totPoints = int(career['points'])
                gamesPlayed = int(career['gamesPlayed'])
                gamesStarted = int(career['gamesStarted'])
                totMinutes = int(career['min'])
                doubleDoubles = int(career['dd2'])
                tripleDoubles = int(career['td3'])

                stats.append(["Career", logo, team, totMinutes, minutes, totPoints, points,
                totAssists, assists, totReb, rebounds, totBlocks, blocks, totSteals, steals,
                totTurnovers, "None", threePointsMade, threePointsAttempted, threePointPercent,
                fieldGoalsMade, fieldGoalsAttempted, fieldGoalPercent, freeThrowsMade,
                freeThrowsAttempted, freeThrowPercent, personalFouls, gamesPlayed, gamesStarted,
                doubleDoubles, tripleDoubles])
            except:
                stats.append(["Career", -1, -1, -1])

        background = []
        n = name.split(" ")
        with urllib.request.urlopen("https://www.nba.com/players/" + n[0].lower() + "/" + n[1].lower() + "/" + playerID) as url:
            data = url.read().decode()
            parsed = BeautifulSoup(data, features='lxml')
            try:
                jersey = parsed.body.find('span', attrs={'class':'nba-player-header__jersey-number'}).text
            except AttributeError:
                jersey = "None"
            try:
                position = parsed.body.find('span', attrs={'class':'nba-player-header__position'}).text
            except AttributeError:
                position = "None"
            try:
                height = parsed.body.findAll('p', attrs={'class':'nba-player-vitals__top-info-imperial'})
            except AttributeError:
                height = "None"

            try:
                children1 = height[0].findChildren("span", recursive=False)
                height1 = children1[0].text + " " + children1[1].text
            except:
                height1 = "None"
            try:
                children2 = height[1].findChildren("span", recursive=False)
                weight1 = children2[0].text
            except:
                weight1 = "None"

            try:
                info = parsed.body.findAll('span', attrs={'class':'nba-player-vitals__bottom-info'})
                born = info[0].text.strip()
                age = info[1].text.strip()
                from1 = info[2].text.strip()
                debut = info[3].text.strip()
                years = info[4].text.strip()
            except:
                info = "None"
                born = "None"
                age = "None"
                from1 = "None"
                debut = "None"
                years = "None"
            image = "https://ak-static.cms.nba.com/wp-content/uploads/headshots/nba/latest/260x190/" + playerID + ".png"
            background = [jersey, position, height1, weight1, born, age, from1, debut, years, image]

        stats.append(background)
    except urllib.error.HTTPError:
        return "Error"
    return stats

def getPreviewArticles(upcoming):
    preview = []
    articleInfo = []
    for i in range(6):
        d = str(date.fromtimestamp(upcoming[i][0])).replace("-", "")
        teams = [upcoming[i][3], upcoming[i][5]]
        with urllib.request.urlopen("http://data.nba.net/prod/v2/" + d + "/scoreboard.json") as url:
            data = json.loads(url.read().decode())
            for i in data['games']:
                game = i['gameId']
                t1 = teamMapping[i['vTeam']['teamId']]
                t2 = teamMapping[i['hTeam']['teamId']]
                if t1 in teams and t2 in teams:
                    try:
                        with urllib.request.urlopen("http://data.nba.net/prod/v1/" + d + "/" + game + "_preview_article.json") as url:
                            data2 = json.loads(url.read().decode())
                            title = data2['title']
                            copyright = data2['copyright']
                            info = [title, copyright]
                            for i in data2['paragraphs']:
                                info.append(i['paragraph'])
                        articleInfo.append(info)
                    except urllib.error.HTTPError:
                        articleInfo.append("Error")

    return articleInfo

def getNews(date1, date2):
    # newsapi = NewsApiClient(api_key='[KEY]')
    # top_headlines = newsapi.get_top_headlines(q='nba',
    #                                         category='sports',
    #                                         language='en',
    #                                         country='us')
    # all_articles = newsapi.get_everything(q='nba',
    #                                     sources='espn,bleacher-report',
    #                                     domains='espn.com,bleacherreport.com,nba.com',
    #                                     from_param=date1,
    #                                     to=date2,
    #                                     language='en',
    #                                     sort_by='relevancy')

    # seen = []
    # data = []
    # articles1 = top_headlines['articles']
    # articles2 = all_articles['articles']
    # data.append(len(articles1))
    # for i in articles1:
    #     source = i['source']['name']
    #     author = i['author']
    #     title = i['title']
    #     url = i['url']
    #     image = i['urlToImage']
    #     time = i['publishedAt']
    #     content = i['content']
    #     if source == 'Espn.com' or source == 'Nba.com' or source == 'Bleacher Report':
    #         if title not in seen:
    #             seen.append(title)
    #             by = ""
    #             if author is None:
    #                 by = source
    #             elif author == "NBA.com":
    #                 author = "Official release"
    #                 by = author + " from " + source
    #             else:
    #                 by = author + " from " + source
    #             if content is None:
    #                 content = "No content"
    #             if image is None:
    #                 image = "https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwin0ffp8v3gAhUcoYMKHaydCjYQjRx6BAgBEAU&url=https%3A%2F%2Fwww.apple.com%2Fshop%2Frefurbished%2Fclearance&psig=AOvVaw1B-rVuUmLBsRLXeO_bHC2o&ust=1552524562379261"

    #             mapping = {"01":"January", "02":"February", "03":"March", "04":"April", "05":"May",
    #             "06":"June", "07": "July", "08": "August","09": "September", "10": "October",
    #             "11":"November", "12":"December"}
    #             time = mapping[time[5:7]] + " " + str(int(time[8:10])) + ", " + time[0:4]
    #             content = content.replace('\xa0', ' -')
    #             data.append([title, by, time, content, image, url])

    # for i in articles2:
    #     source = i['source']['name']
    #     author = i['author']
    #     title = i['title']
    #     url = i['url']
    #     image = i['urlToImage']
    #     time = i['publishedAt']
    #     content = i['content']
    #     if title not in seen:
    #         seen.append(title)
    #         by = ""
    #         if author is None:
    #             by = source
    #         elif author == "NBA.com":
    #             author = "Official release"
    #             by = author + " from " + source
    #         else:
    #             by = author + " from " + source
    #         if content is None:
    #             content = "No content"
    #         if image is None:
    #             image = "https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwin0ffp8v3gAhUcoYMKHaydCjYQjRx6BAgBEAU&url=https%3A%2F%2Fwww.apple.com%2Fshop%2Frefurbished%2Fclearance&psig=AOvVaw1B-rVuUmLBsRLXeO_bHC2o&ust=1552524562379261"

    #         mapping = {"01":"January", "02":"February", "03":"March", "04":"April", "05":"May",
    #         "06":"June", "07": "July", "08": "August","09": "September", "10": "October",
    #         "11":"November", "12":"December"}
    #         time = mapping[time[5:7]] + " " + str(int(time[8:10])) + ", " + time[0:4]
    #         content = content.replace('\xa0', '  -')
    #         data.append([title, by, time, content, image, url])
    # return data
    return ""

def updateRecent(time):
    global theDate
    userTime = getTime(time[1])
    day = 0
    recent = []
    while len(recent) < 6:
        d = str(date.fromtimestamp(userTime - 86400 * day)).replace("-", "")
        theDate = d
        with urllib.request.urlopen("http://data.nba.net/prod/v1/" + d + "/scoreboard.json") as url:
            data = json.loads(url.read().decode())
            for i in data['games']:
                if i['statusNum'] == 3:
                    gameID = i['gameId']
                    team1 = teamMapping[i['vTeam']['teamId']]
                    logo1 = teams[team1][0]
                    record1 = "(" + i['vTeam']['win'] + " - " + i['vTeam']['loss'] + ")"
                    score1 = i['vTeam']['score']
                    team2 = teamMapping[i['hTeam']['teamId']]
                    logo2 = teams[team2][0]
                    record2 = "(" + i['hTeam']['win'] + " - " + i['hTeam']['loss'] + ")"
                    score2 = i['hTeam']['score']
                    recent.append([team1, logo1, record1, score1, team2, logo2, record2, score2, gameID, d])
        day += 1
    return recent

@app.route("/")
def output():
    return render_template("/index.html")

@app.route("/update", methods = ["POST"])
def update():
    global cTime
    info = request.get_json()
    offset = int(info[0])
    currentTime = getTime(info[1])
    cTime = currentTime
    upcoming = openStore(currentTime)
    a, b, c = openDate()
    upcoming = updateUpcoming(upcoming, currentTime, offset, a, b, c)
    if upcoming == "Season Over":
        return jsonify(upcoming)
    else:
        preview = getPreviewArticles(upcoming)
        upcoming.append(preview)
        return jsonify(upcoming)

@app.route("/updateAutocomplete", methods = ["POST"])
def updateAutocomplete():
    players, javascript = getPlayers()
    return jsonify(javascript)

@app.route('/gameID', methods = ["POST"])
def game_id():
    global gameID
    global theDate
    inputs = request.get_json()
    if type(inputs) == list:
        gameID = inputs[0]
        theDate = inputs[1]
    else:
        gameID = inputs
    if type(gameID) == list:
        gameID = gameID[0]
    return ''

@app.route('/gameUpdate', methods = ["POST"])
def gameUpdate():
    recap = []
    try:
        with urllib.request.urlopen("http://data.nba.net/prod/v1/" + theDate + "/" + gameID + "_recap_article.json") as url:
            data = json.loads(url.read().decode())
            title = data['title']
            copyright = data['copyright']
            info = [title, copyright]
            for i in data['paragraphs']:
                recap.append(i['paragraph'])
    except urllib.error.HTTPError:
        recap == ["Error"]

    info = []
    try:
        with urllib.request.urlopen("http://data.nba.net/prod/v1/" + theDate + "/" + gameID + "_boxscore.json") as url:
            data = json.loads(url.read().decode())

            both = []
            arena = data['basicGameData']['arena']['name']
            city = data['basicGameData']['arena']['city']
            abbrv = data['basicGameData']['arena']['stateAbbr']
            try:
                startTime = data['basicGameData']['startTimeEastern']
            except:
                startTime = ""
            startDate = data['basicGameData']['startDateEastern']

            days = {0: "Monday, ", 1: "Tuesday, ", 2: "Wednesday, ", 3: "Thursday, ",
            4: "Friday, ", 5: "Saturday, ", 6: "Sunday, "}
            months = {1:"January ", 2:"February ", 3:"March ", 4:"April ", 5:"May ",
            6:"June", 7: "July ", 8: "August ", 9: "September ", 10: "October ",
            11:"November ", 12:"December "}
            year = int(startDate[0:4])
            month = int(startDate[4:6])
            day = int(startDate[6:8])
            when = days[calendar.weekday(year, month, day)] + months[month] + str(day) + ", " + str(year) + " • " + startTime
            where = arena + " • " + city + ", " + abbrv
            text = data['basicGameData']['nugget']['text']
            attendance = data['basicGameData']['attendance']
            duration = int(data['basicGameData']['gameDuration']['hours']) * 60 + int(data['basicGameData']['gameDuration']['minutes'])

            t1 = []
            t2 = []
            team1 = teamMapping[data['basicGameData']['vTeam']['teamId']]
            logo1 = teams[team1][0]
            miniLogo1 = teams[team1][1]
            triCode1 = data['basicGameData']['vTeam']['triCode']
            record1 = "(" + data['basicGameData']['vTeam']['win'] + " - " + data['basicGameData']['vTeam']['loss'] + ")"
            score1 = data['basicGameData']['vTeam']['score']
            quarters1 = []
            for i in data['basicGameData']['vTeam']['linescore']:
                quarters1.append(i['score'])

            team2 = teamMapping[data['basicGameData']['hTeam']['teamId']]
            logo2 = teams[team2][0]
            miniLogo2 = teams[team2][1]
            triCode2 = data['basicGameData']['hTeam']['triCode']
            record2 = "(" + data['basicGameData']['hTeam']['win'] + " - " + data['basicGameData']['hTeam']['loss'] + ")"
            score2 = data['basicGameData']['hTeam']['score']
            quarters2 = []
            for i in data['basicGameData']['hTeam']['linescore']:
                quarters2.append(i['score'])

            timesTied = data['stats']['timesTied']
            leadChanges = data['stats']['leadChanges']
            both = [when, where, text, attendance, duration, timesTied, leadChanges]

            fastBreakPoints1 = data['stats']['vTeam']['fastBreakPoints']
            pointsInPaint1 = data['stats']['vTeam']['pointsInPaint']
            biggestLead1 = data['stats']['vTeam']['biggestLead']
            secondChancePoints1 = data['stats']['vTeam']['secondChancePoints']
            pointsOffTurnovers1 = data['stats']['vTeam']['pointsOffTurnovers']
            longestRun1 = data['stats']['vTeam']['longestRun']
            totalPoints1 = data['stats']['vTeam']['totals']['points']
            fieldGoalsMade1 = data['stats']['vTeam']['totals']['fgm']
            fieldGoalsAttempted1 = data['stats']['vTeam']['totals']['fga']
            fieldGoalPercentage1 = data['stats']['vTeam']['totals']['fgp']
            freeThrowsMade1 = data['stats']['vTeam']['totals']['ftm']
            freeThrowsAttempted1 = data['stats']['vTeam']['totals']['fta']
            freeThrowPercentage1 = data['stats']['vTeam']['totals']['ftp']
            threePointsMade1 = data['stats']['vTeam']['totals']['tpm']
            threePointsAttempted1 = data['stats']['vTeam']['totals']['tpa']
            threePointPercentage1 = data['stats']['vTeam']['totals']['tpp']
            offensiveRebounds1 = data['stats']['vTeam']['totals']['offReb']
            defensiveRebounds1 = data['stats']['vTeam']['totals']['defReb']
            totalRebounds1 = data['stats']['vTeam']['totals']['totReb']
            assists1 = data['stats']['vTeam']['totals']['assists']
            steals1 = data['stats']['vTeam']['totals']['steals']
            turnovers1 = data['stats']['vTeam']['totals']['turnovers']
            blocks1 = data['stats']['vTeam']['totals']['blocks']
            minutes1 = data['stats']['vTeam']['totals']['min']
            personalFouls1 = data['stats']['vTeam']['totals']['pFouls']
            pointsLeader1 = data['stats']['vTeam']['leaders']['points']['value']
            assistsLeader1 = data['stats']['vTeam']['leaders']['assists']['value']
            reboundsLeader1 = data['stats']['vTeam']['leaders']['rebounds']['value']
            t1 = [team1, logo1, miniLogo1, triCode1, record1, score1, quarters1, fastBreakPoints1, pointsInPaint1,
            biggestLead1, secondChancePoints1, pointsOffTurnovers1, longestRun1, totalPoints1,
            fieldGoalsMade1, fieldGoalsAttempted1, fieldGoalPercentage1, freeThrowsMade1,
            freeThrowsAttempted1, freeThrowPercentage1, threePointsMade1, threePointsAttempted1,
            threePointPercentage1, minutes1, offensiveRebounds1, defensiveRebounds1, totalRebounds1,
            assists1, steals1, turnovers1, blocks1, personalFouls1, pointsLeader1, assistsLeader1,
            reboundsLeader1]

            fastBreakPoints2 = data['stats']['hTeam']['fastBreakPoints']
            pointsInPaint2 = data['stats']['hTeam']['pointsInPaint']
            biggestLead2 = data['stats']['hTeam']['biggestLead']
            secondChancePoints2 = data['stats']['hTeam']['secondChancePoints']
            pointsOffTurnovers2 = data['stats']['hTeam']['pointsOffTurnovers']
            longestRun2 = data['stats']['hTeam']['longestRun']
            totalPoints2 = data['stats']['hTeam']['totals']['points']
            fieldGoalsMade2 = data['stats']['hTeam']['totals']['fgm']
            fieldGoalsAttempted2 = data['stats']['hTeam']['totals']['fga']
            fieldGoalPercentage2 = data['stats']['hTeam']['totals']['fgp']
            freeThrowsMade2 = data['stats']['hTeam']['totals']['ftm']
            freeThrowsAttempted2 = data['stats']['hTeam']['totals']['fta']
            freeThrowPercentage2 = data['stats']['hTeam']['totals']['ftp']
            threePointsMade2 = data['stats']['hTeam']['totals']['tpm']
            threePointsAttempted2 = data['stats']['hTeam']['totals']['tpa']
            threePointPercentage2 = data['stats']['hTeam']['totals']['tpp']
            offensiveRebounds2 = data['stats']['hTeam']['totals']['offReb']
            defensiveRebounds2 = data['stats']['hTeam']['totals']['defReb']
            totalRebounds2 = data['stats']['hTeam']['totals']['totReb']
            assists2 = data['stats']['hTeam']['totals']['assists']
            steals2 = data['stats']['hTeam']['totals']['steals']
            turnovers2 = data['stats']['hTeam']['totals']['turnovers']
            blocks2 = data['stats']['hTeam']['totals']['blocks']
            minutes2 = data['stats']['vTeam']['totals']['min']
            personalFouls2 = data['stats']['hTeam']['totals']['pFouls']
            pointsLeader2 = data['stats']['hTeam']['leaders']['points']['value']
            assistsLeader2 = data['stats']['hTeam']['leaders']['assists']['value']
            reboundsLeader2 = data['stats']['hTeam']['leaders']['rebounds']['value']
            t2 = [team2, logo2, miniLogo2, triCode2, record2, score2, quarters2, fastBreakPoints2, pointsInPaint2,
            biggestLead2, secondChancePoints2, pointsOffTurnovers2, longestRun2, totalPoints2,
            fieldGoalsMade2, fieldGoalsAttempted2, fieldGoalPercentage2, freeThrowsMade2,
            freeThrowsAttempted2, freeThrowPercentage2, threePointsMade2, threePointsAttempted2,
            threePointPercentage2, minutes2, offensiveRebounds2, defensiveRebounds2, totalRebounds2,
            assists2, steals2, turnovers2, blocks2, personalFouls2, pointsLeader2, assistsLeader2,
            reboundsLeader2]

            players1 = []
            players2 = []
            for i in data['stats']['activePlayers']:
                playerName = ""
                for j in people:
                    if people[j][0] == i['personId']:
                        playerName = j
                playerPoints = i['points']
                playerPosition = i['pos']
                playerMinutes = i['min']
                playerFieldGoalsMade = i['fgm']
                playerFieldGoalsAttempted = i['fga']
                playerFieldGoalPercentage = i['fgp']
                playerFreeThrowsMade = i['ftm']
                playerFreeThrowsAttempted = i['fta']
                playerFreeThrowPercentage = i['ftp']
                playerThreePointsMade = i['tpm']
                playerThreePointsAttempted = i['tpa']
                playerThreePointPercentage = i['tpp']
                playerOffensiveRebounds = i['offReb']
                playerDefensiveRebounds = i['defReb']
                playerTotalRebounds = i['totReb']
                playerAssists = i['assists']
                playerSteals = i['steals']
                playerTurnovers = i['turnovers']
                playerBlocks = i['blocks']
                playerPersonalFouls = i['pFouls']

                if i['teamId'] == data['basicGameData']['vTeam']['teamId']:
                    players1.append([playerName, playerPoints, playerPosition, playerMinutes,
                    playerFieldGoalsMade, playerFieldGoalsAttempted, playerFieldGoalPercentage,
                    playerFreeThrowsMade, playerFreeThrowsAttempted, playerFreeThrowPercentage,
                    playerThreePointsMade, playerThreePointsAttempted, playerThreePointPercentage,
                    playerOffensiveRebounds, playerDefensiveRebounds, playerTotalRebounds,
                    playerAssists, playerSteals, playerTurnovers, playerBlocks, playerPersonalFouls])
                else:
                    players2.append([playerName, playerPoints, playerPosition, playerMinutes,
                    playerFieldGoalsMade, playerFieldGoalsAttempted, playerFieldGoalPercentage,
                    playerFreeThrowsMade, playerFreeThrowsAttempted, playerFreeThrowPercentage,
                    playerThreePointsMade, playerThreePointsAttempted, playerThreePointPercentage,
                    playerOffensiveRebounds, playerDefensiveRebounds, playerTotalRebounds,
                    playerAssists, playerSteals, playerTurnovers, playerBlocks, playerPersonalFouls])

            t1.append(players1)
            t2.append(players2)
            info = [both, t1, t2, recap]

    except urllib.error.HTTPError:
        info = "NO DATA"
    return jsonify(info)

@app.route('/scores/<gameID>/')
def gameInfo(gameID):
    return render_template("gameInfo.html")

@app.route('/recent', methods = ["POST"])
def recent():
    time = request.get_json()
    recent = updateRecent(time)
    return jsonify(recent)

@app.route("/gameDate", methods = ["POST"])
def gameDate():
    global theDate
    date = request.get_json()
    theDate = date
    info = []
    try:
        with urllib.request.urlopen("http://data.nba.net/prod/v1/" + date + "/scoreboard.json") as url:
            data = json.loads(url.read().decode())
            if data['numGames'] == 0:
                info = "NO GAMES"
            else:
                for i in data['games']:
                    if i['statusNum'] == 3:
                        gameID = i['gameId']
                        team1 = teamMapping[i['vTeam']['teamId']]
                        logo1 = teams[team1][0]
                        record1 = "(" + i['vTeam']['win'] + " - " + i['vTeam']['loss'] + ")"
                        score1 = i['vTeam']['score']
                        team2 = teamMapping[i['hTeam']['teamId']]
                        logo2 = teams[team2][0]
                        record2 = "(" + i['hTeam']['win'] + " - " + i['hTeam']['loss'] + ")"
                        score2 = i['hTeam']['score']
                        info.append([team1, logo1, record1, score1, team2, logo2, record2, score2, gameID])
    except:
        info = "NO GAMES"
    if len(info) == 0:
        info = "NO GAMES"
    return jsonify(info)

@app.route("/scores/")
def scores():
    return render_template("/scores.html")

@app.route("/results", methods = ["POST"])
def results():
    standings = getStandings()
    return jsonify(standings)

@app.route("/standings/")
def standings():
    return render_template("/standings.html")

@app.route("/updateNews", methods = ["POST"])
def updateNews():
    d2 = str(date.fromtimestamp(cTime))
    d1 = str(date.fromtimestamp(cTime - 604800))
    news = getNews(d1, d2)
    return jsonify(news)

@app.route("/news/")
def news():
    return render_template("/news.html")

@app.route("/playerInfo", methods = ["POST"])
def playerInfo():
    players, javascript = getPlayers()
    playerID = players[name][0]
    playerYear = players[name][1]
    stats = getStats(playerID, playerYear)
    if stats != "Error":
        stats.append(name)
    return jsonify(stats)

@app.route("/playerName", methods = ["POST"])
def playerName():
    global name
    global modified
    name = request.get_json()
    modified = name
    modified = modified.replace(" ", "-")
    return ''

@app.route("/players/<modified>/")
def players(modified):
    return render_template("players.html")

if __name__ == '__main__':
    app.run("0.0.0.0")


"""
https://codeforces.com/problemset/problem/1538/G
Bài này 2100 điểm là bài cuối của Div 3
bài yêu cầu tìm max(n1+n2) biết
a*n1+b*n2=x (*1)
a*n2+b*n1=y (*2)
n1>=0
n2>=0
"""
n = int(input())
for _ in range(n):
    x,y,a,b = [int(i) for i in input().split()]
    if (a==b):
        print(min(x//a,y//a))
    else:    # print(min((x+y)//(a+b), x//min(a,b), y//min(a,b)))
        n2 = (y*a-x*b)//(a**2-b**2)
        n1 = (x*a-y*b)//(a**2-b**2)
        if (n2<0): # n2>=0
            print(min(x//a,y//b))
        elif (n1<0): #n1>=0
            print(min(x//b,y//a))
        else:
            ans1 = min((x-a*n1)//b, (y-b*n1)//a) + n1 # min bởi vì là số nguyên ->hàm min làm tròn n2
            ans2 = min((y-a*n2)//b, (x-b*n2)//a) + n2 # hàm min làm tròn n1. Ví dụ n1 với phương trình (*1) là 3 (*2) là 2.5 -> lấy 2 vì max nhất là 2.5
            print(max(ans1,ans2))


#!/usr/bin/env python
# coding: utf-8

# In[1]:

import pygame
from pygame.locals import *

pygame.init()

# In[2]:

#Screen Dimensions
screen_width = 600
screen_height = 600

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Breakout')

#Define Font
font = pygame.font.SysFont('Constantia', 30)

#define colors
background = (234, 218, 184)

#Blocks
brick_red = (242, 85, 96)
brick_green = (86, 174, 87)
brick_blue = (69, 177, 232)

#Paddle Colors
paddle_col = (142, 135, 123)
paddle_outline = (100, 100, 100)

text_color = (78, 81, 139)

#Define game variables
cols = 6
rows = 6
clock = pygame.time.Clock()
fps = 60
live_ball = False
game_over = 0

# In[3]:

#Print Text

def draw_text(text, font, text_color, x, y):
    img = font.render(text, True, text_color)
    screen.blit(img, (x, y))

# In[4]:

#Brick Class

class Brick():

    def __init__(self):
        self.width = screen_width // cols
        self.height = 50

    def create_brick(self):
        self.bricks = []

        #Create emply list
        brick_individual = []
        for row in range(rows):
            brick_row = []

            for col in range(cols):
                brick_x = col * self.width
                brick_y = row * self.height
                rect = pygame.Rect(brick_x, brick_y, self.width, self.height)

                if row < 2:
                    strength = 3
                elif row < 4:
                    strength = 2
                elif row < 6:
                    strength = 1

                brick_individual = [rect, strength]
                brick_row.append(brick_individual)

            self.bricks.append(brick_row)

    def draw_wall(self):

        for row in self.bricks:

            for brick in row:
                if brick[1] == 3:
                    brick_color = brick_blue
                elif brick[1] == 2:
                    brick_color = brick_green
                elif brick[1] == 1:
                    brick_color = brick_red

                pygame.draw.rect(screen, brick_color, brick[0])
                pygame.draw.rect(screen, background, (brick[0]), 2)

# In[5]:

#Paddle Class

class Paddle():
    def __init__(self):
        self.reset()

    def move(self):
        self.direction = 0

        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.x -= self.speed
            self.direction = -1

        if key[pygame.K_RIGHT] and self.rect.right < screen_width:
            self.rect.x += self.speed
            self.direction = 1

    def draw(self):
        pygame.draw.rect(screen, paddle_col, self.rect)
        pygame.draw.rect(screen, paddle_outline, self.rect, 3)

    def reset(self):
        self.height = 20
        self.width = int(screen_width / cols)
        self.x = int((screen_width / 2) - (self.width / 2))
        self.y = screen_height - (self.height * 2)
        self.speed = 10
        self.rect = Rect(self.x, self.y, self.width, self.height)
        self.direction = 0

# In[6]:

#Ball Class

class game_ball():
    def __init__(self, x, y):
        self.reset(x, y)

    def draw(self):
        pygame.draw.circle(screen, paddle_col,
                           (self.rect.x + self.ball_radius,
                            self.rect.y + self.ball_radius),
                            self.ball_radius)
        pygame.draw.circle(screen, paddle_outline,
                           (self.rect.x + self.ball_radius,
                            self.rect.y + self.ball_radius),
                            self.ball_radius, 3)

    def move(self):

        collision_threshold = 5

        wall_destroyed = 1

        row_count = 0
        for row in wall.bricks:

            item_count = 0
            for item in row:
                if self.rect.colliderect(item[0]):
                    if abs(self.rect.bottom - item[0].top) < collision_threshold and self.speed_y > 0:
                        self.speed_y *= -1
                    if abs(self.rect.top - item[0].bottom) < collision_threshold and self.speed_y < 0:
                        self.speed_y *= -1
                    if abs(self.rect.right- item[0].left) < collision_threshold and self.speed_x > 0:
                        self.speed_x *= -1
                    if abs(self.rect.left - item[0].right) < collision_threshold and self.speed_x < 0:
                        self.speed_x *= -1

                    if wall.bricks[row_count][item_count][1] > 1:
                        wall.bricks[row_count][item_count][1] -= 1
                    else:
                        wall.bricks[row_count][item_count][0] = (0, 0, 0, 0)

                if wall.bricks[row_count][item_count][0] != (0, 0, 0, 0):
                    wall_destroyed = 0

                item_count += 1
            row_count += 1

        if wall_destroyed == 1:
            self.game_over = 1

        if self.rect.left < 0 or self.rect.right > screen_width:
            self.speed_x *= -1

        if self.rect.top < 0:
            self.speed_y *= -1
        if self.rect.bottom > screen_height:
            self.game_over = -1

        if self.rect.colliderect(player_paddle):
            if abs(self.rect.bottom - player_paddle.rect.top) < collision_threshold and self.speed_y > 0:
                self.speed_y *= -1
                self.speed_x += player_paddle.direction
                if self.speed_x > self.speed_max:
                    self.speed_x = self.speed_max
                elif self.speed_x < 0 and self.speed_x < -self.speed_max:
                    self.speed_x = -self.speed_max
            else:
                self.speed_x *= -1

        self.rect.x += self.speed_x
        self.rect.y += self.speed_y

        return self.game_over

    def reset(self, x, y):
        self.ball_radius = 10
        self.x = x - self.ball_radius
        self.y = y
        self.rect = Rect(self.x, self.y, self.ball_radius*2, self.ball_radius*2)
        self.speed_x = 4
        self.speed_y = -4
        self.speed_max = 5
        self.game_over = 0

# In[7]:

#Create Wall
wall = Brick()
wall.create_brick()

#Create Paddle
player_paddle = Paddle()

#Create Ball
ball = game_ball(player_paddle.x + (player_paddle.width // 2),
                 player_paddle.y - player_paddle.height)

# In[8]:

run = True

while run:

    clock.tick(fps)

    screen.fill(background)

    wall.draw_wall()
    player_paddle.draw()
    ball.draw()

    if live_ball:
        player_paddle.move()
        game_over = ball.move()
        if game_over != 0:
            live_ball = False

    if not live_ball:
        if game_over == 0:
            draw_text('CLICK ANYWHERE TO START', font, text_color, 100, screen_height // 2 + 100)
        if game_over == 1:
            draw_text('YOU WON!', font, text_color, 240, screen_height // 2 + 50)
            draw_text('CLICK ANYWHERE TO START', font, text_color, 100, screen_height // 2 + 100)
        if game_over == -1:
            draw_text('YOU LOST!', font, text_color, 240, screen_height // 2 + 50)
            draw_text('CLICK ANYWHERE TO START', font, text_color, 100, screen_height // 2 + 100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.MOUSEBUTTONDOWN and live_ball == False:
            live_ball = True
            ball.reset(player_paddle.x + (player_paddle.width // 2),
                       player_paddle.y - player_paddle.height)
            player_paddle.reset()
            wall.create_brick()

    pygame.display.update()

pygame.quit()


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

from openerp import models, fields, api
import logging
from datetime import datetime, timedelta, date
import requests

_logger = logging.getLogger(__name__)

URL_OPERATIONS = 'https://api.mobbex.com/p/entity/operations'

class ExtendsResCompany(models.Model):
	_name = 'res.company'
	_inherit = 'res.company'

	mobbex_id = fields.Many2one('financiera.mobbex.config', 'Configuracion Mobbex')

	@api.one
	def mobbex_update_aprobados(self):
		if self.mobbex_id:
			headers = {
				'x-api-key': self.mobbex_id.api_key,
				'x-access-token': self.mobbex_id.access_token,
			}
			from_day = datetime.now() - timedelta(days=self.mobbex_id.days_check_update_aprobados)
			created = datetime.now()
			page = 0
			while (from_day < created):
				params = {
					'page': page,
					'limit': 50,
					'status': 200,
				}
				r = requests.get(URL_OPERATIONS, params=params, headers=headers)
				print("r", r)
				print("r.status_code", r.status_code)
				response = r.json()
				print("response", response)
				if 'result' in response and response['result'] == True and 'data' in response:
					print('result')
					data = response['data']
					if 'docs' in data:
						print('docs')
						docs = data['docs']
						for doc in docs:
							if 'reference' in doc:
								created = datetime.strptime(doc['created'].split('T')[0], "%Y-%m-%d")
								_id = doc['reference'].split('_')[0]
								if doc['context']['value'] == 'plugin.value.subscriptions:exec':
									cuota_id = self.env['financiera.prestamo.cuota'].sudo().browse(int(_id))
									if cuota_id.state == 'activa':
										cuota_id.mobbex_read_execution_aprobado(doc)
										_logger.info('Mobbex: nuevo debito procesado.')
								elif doc['context']['value'] == 'plugin.value.payment_order:web':
									orden_pago_id = self.env['financiera.mobbex.orden.pago'].sudo().browse(int(_id))
									if orden_pago_id.state != 'cobrada':
										orden_pago_id.mobbex_orden_pago_read_execution_aprobado(doc)
										_logger.info('Mobbex: nueva orden de pago procesada.')
							else:
								_logger.warning('Mobbex: No existe reference de cuota.')
							if from_day >= created:
								break
						if len(docs) <= 1:
							break
					else:
						break
				else:
					break
				page += 1


class Stack:
    def __init__(self):
        self.st = []

    def isempty(self):
        return self.st == []

    def push(self,element):
        self.st.append(element)

    def pop(self):
        if self.isempty():
            return -1
        else:
            return self.st.pop()

    def peep(self):
        n = len(self.st)
        if n == 0:
            return -1
        else:
            return self.st[n-1]

    def search(self,element):
        if self.isempty():
            return -1
        else:
            try:
                n = self.st.index(element)
                return len(self.st)-n
            except ValueError:
                return -2

    def display(self):
        return self.st

def main():
    s = Stack()
    choice = 0
    while choice < 5:
        print('STACK OPERATIONS')
        print('1. Push Element')
        print('2. Pop Element')
        print('3. Peep Element')
        print('4. Search Element')
        print('5. Exit')
        choice = int(input('Enter Your Choice: '))
        if choice == 1:
            element = int(input('Enter element: '))
            s.push(element)
        elif choice == 2:
            element = s.pop()
            if element == -1:
                print("The Stack is Empty...")
            else:
                print("Popped Element= ",element)
        elif choice == 3:
            element = s.peep()
            if element == -1:
                print("The Stack is Empty...")
            else:
                print("Top Most Element = ",element)
        elif choice == 4:
            element = int(input("Enter element: "))
            pos = s.search(element)
            if pos == -1:
                print("The Stack is Empty...")
            elif pos == -2:
                print("Element not found in the stack")
            else:
                print("Element found at position: ",pos)
        else:
            break
    print("Stack = ", s.display())

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
import sys
import genericIO
import SepVector
import Hypercube
import pyOperator as pyOp
import Elastic_iso_float_prop
import numpy as np
import time

#Dask-related modules
import pyDaskOperator as DaskOp

if __name__ == '__main__':

  #Getting parameter object
  parObject = genericIO.io(params=sys.argv)

  # Checking if Dask was requested
  client, nWrks = Elastic_iso_float_prop.create_client(parObject)

  # Initialize operator
  modelFloat, dataFloat, elasticParamFloat, parObject1, sourcesSignalsVector, sourcesVectorCenterGrid, sourcesVectorXGrid, sourcesVectorZGrid, sourcesVectorXZGrid, recVectorCenterGrid, recVectorXGrid, recVectorZGrid, recVectorXZGrid, modelFloatLocal = Elastic_iso_float_prop.BornOpInitFloat(
      sys.argv, client)

  if (client):
    #Instantiating Dask Operator
    BornOp_args = [
        (modelFloat.vecDask[iwrk], dataFloat.vecDask[iwrk],
         elasticParamFloat[iwrk], parObject1[iwrk], sourcesSignalsVector[iwrk],
         sourcesVectorCenterGrid[iwrk], sourcesVectorXGrid[iwrk],
         sourcesVectorZGrid[iwrk], sourcesVectorXZGrid[iwrk],
         recVectorCenterGrid[iwrk], recVectorXGrid[iwrk], recVectorZGrid[iwrk],
         recVectorXZGrid[iwrk]) for iwrk in range(nWrks)
    ]
    BornElasticOp = DaskOp.DaskOperator(
        client, Elastic_iso_float_prop.BornElasticShotsGpu, BornOp_args,
        [1] * nWrks)
    #Adding spreading operator and concatenating with Born operator (using modelFloatLocal)
    Sprd = DaskOp.DaskSpreadOp(client, modelFloatLocal, [1] * nWrks)
    BornElasticOp = pyOp.ChainOperator(Sprd, BornElasticOp)
  else:
    # Construct nonlinear operator object
    BornElasticOp = Elastic_iso_float_prop.BornElasticShotsGpu(
        modelFloat, dataFloat, elasticParamFloat, parObject1,
        sourcesSignalsVector, sourcesVectorCenterGrid, sourcesVectorXGrid,
        sourcesVectorZGrid, sourcesVectorXZGrid, recVectorCenterGrid,
        recVectorXGrid, recVectorZGrid, recVectorXZGrid)

  #Testing dot-product test of the operator
  if (parObject.getInt("dpTest", 0) == 1):
    BornElasticOp.dotTest(True)
    quit()

  # Forward
  if (parObject.getInt("adj", 0) == 0):

    print(
        "----------------------------------------------------------------------"
    )
    print(
        "------------------ Running Python Born Elastic forward ---------------"
    )
    print(
        "----------------------------------------------------------------------\n"
    )

    # Check that model was provided
    modelFile = parObject.getString("model", "noModelFile")
    if (modelFile == "noModelFile"):
      raise IOError("**** ERROR: User did not provide model file ****\n")
    dataFile = parObject.getString("data", "noDataFile")
    if (dataFile == "noDataFile"):
      raise IOError("**** ERROR: User did not provide data file name ****\n")

    #Reading model
    modelFloat = genericIO.defaultIO.getVector(modelFile)

    # Apply forward
    BornElasticOp.forward(False, modelFloat, dataFloat)

    # Write data
    dataFloat.writeVec(dataFile)

  # Adjoint
  else:
    print(
        "----------------------------------------------------------------------"
    )
    print(
        "------------------ Running Python Born Elastic adjoint ---------------"
    )
    print(
        "----------------------------------------------------------------------\n"
    )

    # Check that model was provided
    modelFile = parObject.getString("model", "noModelFile")
    if (modelFile == "noModelFile"):
      raise IOError("**** ERROR: User did not provide model file ****\n")
    dataFile = parObject.getString("data", "noDataFile")
    if (dataFile == "noDataFile"):
      raise IOError("**** ERROR: User did not provide data file name ****\n")

    #Reading model
    dataFloat = genericIO.defaultIO.getVector(dataFile, ndims=4)
    if (client):
      #Chunking the data and spreading them across workers if dask was requested
      dataFloat = Elastic_iso_float_prop.chunkData(dataFloat,
                                                   BornElasticOp.getRange())

    # Apply forward
    BornElasticOp.adjoint(False, modelFloatLocal, dataFloat)

    # Write data
    modelFloatLocal.writeVec(modelFile)

  print("-------------------------------------------------------------------")
  print("--------------------------- All done ------------------------------")
  print("-------------------------------------------------------------------\n")


# coding=utf-8

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo.settings')
import gensim
import jieba
import torch
import xlrd
import pandas as pd
import configparser
from similarity.tools import root_path
from rest_framework.response import Response
from similarity.tools import model_dir, data_dir
from similarity.word2vec_similarity_catalog import find_data, word_avg
from similarity.word2vec_similarity_catalog import device, model, delete_ndarray, \
    bert_sim, executor, tensor_module, model_path
from similarity.database_get import db

model_data_path = os.path.join(data_dir, '01人口源表.xlsx')
# 处理完后的目录表路径
exec_data_path = os.path.join(data_dir, 'model_data.csv')
model_data = []
model_data_number = 7500
model_data_vector_department = []
model_data_vector_table = []
model_data_vector_item = []
model_data_tensor_department = None
model_data_tensor_table = None
model_data_tensor_item = None
# 数据表机构名tensor的保存路径
data_department_tensor_path = os.path.join(data_dir, 'data_department.pt')
# 数据表表名tensor的保存路径
data_table_tensor_path = os.path.join(data_dir, 'data_table.pt')
# 数据表字段tensor的保存路径
data_item_tensor_path = os.path.join(data_dir, 'data_item.pt')
bert_data = {}
query_data = {}
percent = [0.4, 0.1, 0, 0.3, 0]

keyword = 'common_data'
read_ini = configparser.ConfigParser()
read_ini.read(os.path.join(root_path,'config.ini'), encoding='utf-8')

data_col = [int(x) for x in read_ini.get(keyword, 'data_col').split(',')]
table_name = read_ini.get(keyword, 'table_name')
business_type = 'model_data'

def init_model_vector_data(request):
    global process
    global model_data_path
    global model_data
    global model_data_number
    global model_data_vector_department
    global model_data_vector_table
    global model_data_vector_item
    global model_data_tensor_department
    global model_data_tensor_table
    global model_data_tensor_item

    parameter = request.data
    # # 目录表路径
    # model_data_path = parameter['filePath']
    # if not os.path.exists(model_data_path):
    #     return Response({"code": 404, "msg": "数据表路径不存在", "data": ""})
    process = 0
    # 重新加载模型
    model = gensim.models.KeyedVectors.load_word2vec_format(model_path, binary=True)
    process = 0.5
    # 重新缓存向量
    model_data = []
    model_data_vector_department = []
    model_data_vector_table = []
    model_data_vector_item = []
    # prepare_model_data(path=model_data_path)
    prepare_model_data()
    process = 0.75
    model_data_number = len(model_data)
    for i in range(len(model_data)):
        process = 0.75 + i / (model_data_number * 4)
        data = model_data[i]
        item = data.split(' ')
        segment2_1 = jieba.lcut(item[0], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        model_data_vector_department.append(s2)

        segment2_1 = jieba.lcut(item[1], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        model_data_vector_table.append(s2)

        segment2_1 = jieba.lcut(item[3], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        model_data_vector_item.append(s2)
    model_data_tensor_department = torch.Tensor(model_data_vector_department).to(device)
    model_data_tensor_table = torch.Tensor(model_data_vector_table).to(device)
    model_data_tensor_item = torch.Tensor(model_data_vector_item).to(device)

    # torch.save(model_data_tensor_department, data_department_tensor_path)
    # torch.save(model_data_tensor_table, data_table_tensor_path)
    # torch.save(model_data_tensor_item, data_item_tensor_path)

    bert_data.clear()
    query_data.clear()
    return Response({"code": 200, "msg": "词模型初始化完成；词向量缓存完成！", "data": ""})

def prepare_model_data():
    global model_data
    global table_name
    # # 打开excel
    # wb = xlrd.open_workbook(path)
    # # 按工作簿定位工作表
    # sh = wb.sheet_by_name('业务层表结构分析')
    # row_number = sh.nrows
    # for i in range(1, row_number):
    #     model_data.append(sh.cell(i, 0).value + ' ' + sh.cell(i, 1).value + ' ' + sh.cell(i, 2).value)
    # # print(model_data)

    # re = db.get_colum_by_num(data_col, table_name)
    # for i in re:
    #     while (None in i):
    #         i[i.index(None)] = '*'
    #     model_data.append(' '.join(i))
    #
    #
    # data_df = pd.DataFrame(model_data)
    # data_df.to_csv(exec_data_path, encoding='utf-8_sig', index=False)

    re = db.get_data_by_type_v2(data_col, business_type, table_name)
    for i in re:
        model_data.append(' '.join([i[0].replace('-', ' '), i[1], i[2]]))

    # print('model_data：' + str(len(model_data)))
    # for i in range(len(model_data)):
    #     print(model_data[i])

def increment_business_model_data(request):
    global model_data_vector_department
    global model_data_vector_table
    global model_data_vector_item
    global model_data_tensor_department
    global model_data_tensor_table
    global model_data_tensor_item
    global model_data
    parameter = request.data
    full_data = parameter['data']
    for single_data in full_data:
        match_str = single_data['matchStr']
        original_code = single_data['originalCode']
        original_data = single_data['originalData']

        if len(match_str.split('-')) != 5:
            return Response({"code": 200, "msg": "新增数据失败，有效数据字段不等于5", "data": ""})

        tmp = ' '.join(match_str.split('-'))
        tmp += (' ' + original_code + ' ' + original_data)
        model_data.append(tmp)

        # print('增加后：')
        # print('model_data：' + str(len(model_data)))
        # for i in range(len(model_data)):
        #     print(model_data[i])

        item = match_str.split('-')

        segment2_1 = jieba.lcut(item[0], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        model_data_vector_department.append(s2)

        segment2_1 = jieba.lcut(item[1], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        model_data_vector_table.append(s2)

        segment2_1 = jieba.lcut(item[3], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        model_data_vector_item.append(s2)
    model_data_tensor_department = torch.Tensor(model_data_vector_department).to(device)
    model_data_tensor_table = torch.Tensor(model_data_vector_table).to(device)
    model_data_tensor_item = torch.Tensor(model_data_vector_item).to(device)
    bert_data.clear()
    query_data.clear()
    return Response({"code": 200, "msg": "新增数据成功！", "data": ""})

def delete_business_model_data(request):
    global model_data_tensor_department
    global model_data_tensor_table
    global model_data_tensor_item
    global model_data_vector_department
    global model_data_vector_table
    global model_data_vector_item
    global model_data
    parameter = request.data
    full_data = parameter['data']
    for single_data in full_data:
        match_str = single_data['matchStr']
        original_code = single_data['originalCode']
        original_data = single_data['originalData']
        # 加入缓存中
        # tmp = original_data['departmentName'] + ' ' + original_data['catalogName'] + ' ' + \
        #       original_data['infoItemName'] + ' ' + original_data['departmentID'] + ' ' + original_data['catalogID']

        tmp = ' '.join(match_str.split('-'))
        tmp += (' ' + original_code + ' ' + original_data)
        # print('待删除数据：')
        # print(tmp)

        # 在目录列表中删除数据
        try:
            model_data.remove(tmp)
        except:
            return Response({"code": 200, "msg": "无该数据！", "data": ""})

        # print('删除后：')
        # print('model_data：' + str(len(model_data)))
        # for i in range(len(model_data)):
        #     print(model_data[i])

        item = match_str.split('-')

        segment2_1 = jieba.lcut(item[0], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        delete_ndarray(model_data_vector_department, s2)

        segment2_1 = jieba.lcut(item[1], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        delete_ndarray(model_data_vector_table, s2)

        segment2_1 = jieba.lcut(item[3], cut_all=True, HMM=True)
        s2 = word_avg(model, segment2_1)
        delete_ndarray(model_data_vector_item, s2)
    model_data_tensor_department = torch.Tensor(model_data_vector_department).to(device)
    model_data_tensor_table = torch.Tensor(model_data_vector_table).to(device)
    model_data_tensor_item = torch.Tensor(model_data_vector_item).to(device)
    bert_data.clear()
    query_data.clear()
    return Response({"code": 200, "msg": "删除数据成功！", "data": ""})

def model2data_recommend(request):
    global model_data
    global percent
    parameter = request.data
    full_data = parameter['data']
    k = parameter['k']
    if k > len(model_data):
        k = len(model_data)
    weight_percent = parameter['percent']
    if len(weight_percent.split(',')) != 5:
        return Response({"code": 404, "msg": "权重配置错误！", "data": ''})
    percent = [float(x) for x in weight_percent.split(',')]
    # load_data_data()
    if len(model_data) == 0:
        return Response({"code": 404, "msg": "数据为空！", "data": ''})
    # 顺序是部门-模型名称-模型描述-属性名称-属性描述
    source_data = []
    for i in range(len(full_data)):
        source_data.append(full_data[i]['matchStr'].replace('-', ' '))
    result = []

    for i in range(len(source_data)):
        res = {}
        data = source_data[i]
        query_id = full_data[i]['id']
        # 字符串匹配
        str_tmp = string_matching(demand_data=data, k=k)
        if len(str_tmp) >= k:
            sim_value = [1] * len(str_tmp)
            result.append(save_result(str_tmp, res, query_id, sim_value))
            continue

        # 查看查询缓存
        if data in query_data.keys():
            tmp = query_data.get(data)
            if len(tmp) == 2 * k:
                sim_value = tmp[int(len(tmp) / 2):]
                tmp = tmp[0: int(len(tmp) / 2)]
                result.append(save_result(tmp, res, query_id, sim_value))
                continue

        # 查看BERT缓存
        tmp = find_data(demand_data=data, k=k)
        if len(tmp) != 0:
            sim_value = tmp[int(len(tmp) / 2):]
            tmp = tmp[0: int(len(tmp) / 2)]
            result.append(save_result(tmp, res, query_id, sim_value))
            continue

        # 缓存清理FIFO
        if len(bert_data.keys()) >= 10000:
            bert_data.clear()
        if len(query_data.keys()) >= 10000:
            query_data.clear()

        # 词向量匹配
        tmp, sim_value = vector_matching(demand_data=data, k=k)

        # print('原来的str_tmp')
        # for index in range(len(str_tmp)):
        #     print(str_tmp[index])
        #
        # print('原来的tmp：')
        # for index in range(len(tmp)):
        #     print(tmp[index] + ' : ' + str(sim_value[index]))

        oringi_len = len(str_tmp)
        str_tmp += tmp
        str_sim_value = ([1] * oringi_len) + sim_value

        # print()
        # print('增加后的长度：' + str(len(str_tmp)))
        # print('增长后的情况：')
        # for index in range(len(str_tmp)):
        #     print(str_tmp[index] + ' : ' + str(str_sim_value[index]))

        for index in range(oringi_len):
            while str_tmp[index] in str_tmp[oringi_len:]:
                for tmp_index in range(oringi_len, len(str_tmp)):
                    if str_tmp[tmp_index] == str_tmp[index]:
                        str_tmp.pop(tmp_index)
                        str_sim_value.pop(tmp_index)
                        break

        # 保证增加后的数据不超过k个
        if len(str_tmp) > k:
            str_tmp = str_tmp[:k]

        # print()
        # print('删除后的情况：')
        # for tmp_index in range(len(str_tmp)):
        #     print(str_tmp[tmp_index] + ' : ' + str(str_sim_value[tmp_index]))

        # result.append(save_result(tmp, res, query_id, sim_value))
        result.append(save_result(str_tmp, res, query_id, str_sim_value))
        query_data[data] = tmp + sim_value

        # 缓存中不存在, 后台线程缓存
        executor.submit(save_data, data, k)

    return Response({"code": 200, "msg": "查询成功！", "data": result})

def string_matching(demand_data, k):
    # res = []
    # for data in model_data:
    #     tmp_data = data.split(' ')
    #     tmp_demand_data = demand_data.split(' ')
    #     if tmp_demand_data[0] + ' ' + tmp_demand_data[1] + ' ' + tmp_demand_data[3] == data:
    #         res.append(data)
    #         if len(res) == k:
    #             break
    # return res

    res = []
    # print('data_len：' + str(len(model_data)))
    #
    # for i in range(len(model_data)):
    #     print(model_data[i])

    for data in model_data:
        tmp_match_str = demand_data.split(' ')
        match_str = tmp_match_str[0] + ' ' + tmp_match_str[1] + ' ' + tmp_match_str[3]

        tmp_database_str = data.split(' ')
        tmp_str = tmp_database_str[0] + ' ' + tmp_database_str[1] + ' ' + tmp_database_str[3]

        if match_str == tmp_str:
            # print(111111111)
            res.append(data)
            if len(res) == k:
                break
    return res

def vector_matching(demand_data, k):
    # 字符串没有匹配项，则会进行向量相似度匹配，筛选前k个
    # sim_words = {}
    item = demand_data.split(' ')

    # 输入的模型表的字段名
    segment1_1 = jieba.lcut(item[3], cut_all=True, HMM=True)
    s1 = [word_avg(model, segment1_1)]
    x = torch.Tensor(s1).to(device)
    # final_value = tensor_module(torch.load(data_item_tensor_path), x) * percent[3]
    final_value = tensor_module(model_data_tensor_item, x) * percent[3]

    # 输入的模型表的部门
    if item[0] != '':
        segment1_1 = jieba.lcut(item[0], cut_all=True, HMM=True)
        s1 = [word_avg(model, segment1_1)]
        x = torch.Tensor(s1).to(device)
        # final_value += tensor_module(torch.load(data_department_tensor_path), x) * percent[0]
        final_value += tensor_module(model_data_tensor_department, x) * percent[0]

    # 输入的模型表的部门
    if item[1] != '':
        segment1_1 = jieba.lcut(item[1], cut_all=True, HMM=True)
        s1 = [word_avg(model, segment1_1)]
        x = torch.Tensor(s1).to(device)
        final_value += tensor_module(model_data_tensor_table, x) * percent[1]

    # # 材料描述、材料类型
    # if item[1] != '':
    #     segment1_1 = jieba.lcut(item[1], cut_all=True, HMM=True)
    #     s1 = [word_avg(model, segment1_1)]
    #     x = torch.Tensor(s1).to(device)
    #     final_value += tensor_module(catalogue_data_tensor_catalog, x) * percent[1]

    # 输出排序并输出top-k的输出
    value, index = torch.topk(final_value, k, dim=0, largest=True, sorted=True)
    sim_index = index.numpy().tolist()
    sim_value = value.numpy().tolist()
    res = []
    res_sim_value = []
    for i in sim_index:
        res.append(model_data[i[0]])
    # print('计算出的匹配值：')
    for i in sim_value:
        # print(i[0])
        if i[0] > 1:
            i[0] = 1.0
        res_sim_value.append(i[0])
    return res, res_sim_value

def load_data_data():
    global model_data
    data_df = pd.read_csv(exec_data_path, encoding='utf-8')
    model_data = [str(x[0]) for x in data_df.values]

def save_data(demand_data, k):
    sim_words = {}

    # item1(输入): 部门-模型名称-模型描述-属性名称-属性描述
    # item2(加入内存的数据格式): 机构名-数据表名-数据表字段名
    item1 = demand_data.split(' ')
    for data in model_data:
        sim = 0
        item2 = data.split(' ')
        # 部门名与机构名
        sim += bert_sim.predict(item1[0], item2[0])[0][1] * percent[0]
        # 模型表名与数据表名
        sim += bert_sim.predict(item1[1], item2[1])[0][1] * percent[1]
        # 模型属性名与数据字段
        sim += bert_sim.predict(item1[3], item2[3])[0][1] * percent[3]

        if len(sim_words) < k:
            sim_words[data] = sim
        else:
            min_sim = min(sim_words.values())
            if sim > min_sim:
                for key in list(sim_words.keys()):
                    if sim_words.get(key) == min_sim:
                        # 替换
                        del sim_words[key]
                        sim_words[data] = sim
                        break
    res = []
    sim_words = sorted(sim_words.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
    for sim_word in sim_words:
        res.append(sim_word[0])
    for sim_word in sim_words:
        if sim_word[1] > 1:
            sim_word[1] = 1.0
        res.append(sim_word[1])
    bert_data[demand_data] = res

def save_result(temp, res, query_id, sim_value):
    # single_res = []
    # for i in range(len(temp)):
    #     d = temp[i]
    #     tmp = d.split(' ')
    #     single_res.append({'originalCode': 'model2data', 'originalData': {'instituteName':tmp[0],
    #                                                                       'tableName':tmp[1],
    #                                                                       'itemName':tmp[2]},
    #                        'similarity': sim_value[i]})
    # res['key'] = query_id
    # res['result'] = single_res
    # return res

    single_res = []
    for i in range(len(temp)):
        d = temp[i]
        tmp = d.split(' ')

        single_res.append({'str': ' '.join(tmp[:5]),
                           'originalCode': tmp[5],
                           'originalData': tmp[6],
                           'similarity': sim_value[i]})

    res['key'] = query_id
    res['result'] = single_res
    return res


import json
from utils.db_utils import RabbitConn, init_db, init_rabbit
from services import logger_service, classifier_service, eval_service, experiment_service, model_service, orthanc_service, study_service
from services import messaging_service
import json
import traceback

def on_classifier_result(ch, method, properties, body):
    print(f'received classifier result {body}')
    message = json.loads(body)
    orthanc_id = message['id']
    result = message['output']
    classifier_service.save_classification(orthanc_id, result)

    messaging_service.send_notification(f'Study {orthanc_id} ready', 'new_result', -1)

def on_eval_result(ch, method, properties, body):
    try:
        print(f'received eval result {body}')
        message = json.loads(body)
        eval_id = message['id']
        result = message['output']
        msg_type = message['type']
        print('recieved result: ', result)
        if msg_type == 'START':
            messaging_service.send_notification(f'Finished evaluation {eval_id}', 'new_result', -1)

            eval_service.set_eval_as_running(eval_id)
            return
        if msg_type == 'FAIL' or type(result) is not dict:
            eval_service.fail_dicom_eval(eval_id)
            return
        # write result to db
        e = eval_service.write_eval_results(result, eval_id)

        study = study_service.get_study_by_eval_id(eval_id)
        # orthanc_service.delete_study_dicom(study['orthancStudyId'])
        # send notification to frontend
        messaging_service.send_notification(f'Finished evaluation {eval_id}', 'new_result', -1)
    except:
        eval_service.fail_dicom_eval(eval_id)
        print('failed to get result', body)
        traceback.print_stack()

def on_eval_log(ch, method, properties, body):
    try:
        print(f'received eval log {body}')
        message = json.loads(body)
        eval_id = message['id']
        result = message['output'].split('\n')
        type = message['type']
        print(result)
        eval_service.add_stdout_to_eval([eval_id], result)
    except:
        print('failed to log', body)
        # traceback.print_stack()

if __name__  == "__main__":
    print('starting results watcher')
    init_rabbit()
    init_db()
    with RabbitConn() as channel:
        channel.queue_declare(messaging_service.EVAL_QUEUE)
        channel.queue_declare(messaging_service.CLASSIFIER_QUEUE)
        channel.queue_declare(messaging_service.LOG_QUEUE)

        channel.basic_consume(queue=messaging_service.CLASSIFIER_QUEUE,
                            on_message_callback=on_classifier_result,
                            auto_ack=True)
        channel.basic_consume(queue=messaging_service.EVAL_QUEUE,
                            on_message_callback=on_eval_result,
                            auto_ack=True)
        channel.basic_consume(queue=messaging_service.LOG_QUEUE,
                            on_message_callback=on_eval_log,
                            auto_ack=True)
        channel.start_consuming()


import shapes
from circle_point_selection import edge_point_selection as eps
from circle_point_selection import inner_point_selection as ips
from converters import coordinates, degree
import simulator
import matplotlib.pyplot as plt
import os

# 52.173701, 4.462163
# 52.174073, 4.463023
# 937

# https://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters
# 111.32 km = 1 degree lat
# 40075 km * cos(lat) / 360 = 1 degree long
# 40075 km * cos(4.46) / 360 = 27.57 km

n_trips = 1000

path = "./fake_experiments_v2/"

# 100 m
#lat_in_meter = round(1.0 / (150 / 0.1), 6)
lat_in_meter = 0.00092163008

# 100 m
#long_in_meter = round(1.0 / (120 / 0.1), 6)
long_in_meter = 0.00146985054

def main(start_lat=0, start_long=0, width=1, n_trips=100):
    source = (52.173701, 4.462163)
    x_to_lat = lat_in_meter * 0.1
    y_to_long = long_in_meter * 0.1

    circle = shapes.Circle(start_lat, start_long, width)
    for i in range(n_trips):
        create_trip(circle, i, source, x_to_lat, y_to_long)

def create_trip(circle, experiment_id, source_coordinates, x_to_lat, y_to_long):
    points = eps.x_potential_points(circle.degrees, 25)

    cor_points = []
    for point in points:
        cor_point = degree.degree_to_xy(point, circle)
        cor_points.append(cor_point)
    changing_point = ips.best_n_point_selection(circle, cor_points[0], cor_points[1])
    walks = simulator.simulate_walks(cor_points[0], cor_points[1], changing_point, 29)

    index = 0
    for walk in walks:
        trip = coordinates.list_of_x_y_to_coordinates(walk, source_coordinates, x_to_lat, y_to_long)
        write_trip(trip, experiment_id, False, index, path)
        index += 1

    simulator.simulate_meeting(walks, 5)

    index = 0
    for walk in walks:
        trip = coordinates.list_of_x_y_to_coordinates(walk, source_coordinates, x_to_lat, y_to_long)
        write_trip(trip,experiment_id, True, index, path)
        #xs = []
        #ys = []

        #for item in walk:
        #    xs.append(item[0])
        #    ys.append(item[1])
        index += 1
        #plt.plot(xs, ys)
    #plt.show()

def write_trip(trip, id, will_meet, index, path):
    header = "Date, Time, Latitude, Longitude, Altitude, Speed, Course, Type, Distance, Essential\n"
    data = "2020/1/1"
    time = 0

    if will_meet:
        meet = "True"
    else:
        meet = "False"

    if not os.path.exists(path):
        os.mkdir(path)

    f = open(path + "trip_" + meet + "_" + str(id) + "_" + str(index) + ".csv","w+")
    f.write(header)
    for data_point in trip:
        lat = str(data_point[0])
        long= str(data_point[1])

        line = data + "," + "00:00:"+str(time) + "," + lat + "," + long +",0,-1,0,fake,-1,1\n"

        f.write(line)
        time += 1
    f.close()

# main(0, 0, 1, n_trips=n_trips)
main(0, 0, 1, n_trips=10)
# main(52.173701,4.462163,0.000937)


import hashlib
import hmac
import optparse
import sys
import time
from contextlib import closing
from urllib.parse import urlencode

import requests
from flask import Flask, Response, abort, request
from werkzeug.datastructures import MultiDict

app = Flask(__name__)

def build_indico_request(path, params, api_key=None, secret_key=None, only_public=False):
    items = list(params.items()) if hasattr(params, 'items') else list(params)
    if api_key:
        items.append(('apikey', api_key))
    if only_public:
        items.append(('onlypublic', 'yes'))
    if secret_key:
        items.append(('timestamp', str(int(time.time()))))
        items = sorted(items, key=lambda x: x[0].lower())
        url = f'{path}?{urlencode(items)}'
        signature = hmac.new(secret_key.encode(), url.encode(), hashlib.sha1).hexdigest()
        items.append(('signature', signature))
    return items

def indico_request(path):
    request_values = MultiDict(request.values)
    method = request_values.pop('_method', request.method).upper()
    params = request_values.items(multi=True)
    data = build_indico_request(path, params, app.config['INDICO_API_KEY'], app.config['INDICO_SECRET_KEY'])
    request_args = {'params': data} if method == 'GET' else {'data': data}
    try:
        response = requests.request(method, app.config['INDICO_URL'] + path, verify=False, **request_args)
    except requests.HTTPError as e:
        response = e.response
    except requests.ConnectionError as e:
        return 'text/plain', str(e)
    content_type = response.headers.get('Content-Type', '').split(';')[0]
    with closing(response):
        return content_type, response.text

@app.route('/')
def index():
    return 'Please add an Indico HTTP API request to the path.'

@app.route('/<path:path>', methods=('GET', 'POST'))
def indicoproxy(path):
    if app.config['ALLOWED_IPS'] and request.remote_addr not in app.config['ALLOWED_IPS']:
        abort(403)
    content_type, resp = indico_request('/' + path)
    if not content_type:
        print('WARNING: Did not receive a content type, falling back to text/plain')
        content_type = 'text/plain'
    return Response(resp, mimetype=content_type)

def main():
    parser = optparse.OptionParser()
    parser.add_option('-H', '--host', dest='host', default='127.0.0.1',
                      help='Host to listen on')
    parser.add_option('-p', '--port', type='int', dest='port', default=10081,
                      help='Port to listen on')
    parser.add_option('-d', '--debug', action='store_true', dest='debug', help='Debug mode')
    parser.add_option('--force-evalex', action='store_true', dest='evalex',
                      help='Enable evalex (remote code execution) even when listening on a host' +
                           ' that is not localhost - use with care!')
    parser.add_option('-I', '--allow-ip', dest='allowed_ips', action='append',
                      help='Only allow the given IP to access the script. Can be used multiple times.')
    parser.add_option('-i', '--indico', dest='indico_url', default='https://indico.cern.ch',
                      help='The base URL of your indico installation')
    parser.add_option('-a', '--apikey', dest='api_key', help='The API key to use')
    parser.add_option('-s', '--secretkey', dest='secret_key', help='The secret key to use')
    options, args = parser.parse_args()

    use_evalex = options.debug
    if options.host not in ('::1', '127.0.0.1'):
        if not options.allowed_ips:
            print('Listening on a non-loopback interface is not permitted without IP restriction!')
            sys.exit(1)
        if use_evalex:
            if options.evalex:
                print('Binding to non-loopback host with evalex enabled.')
                print('This means anyone with access to this app is able to execute arbitrary python code!')
            else:
                print('Binding to non-loopback host; disabling evalex (aka remote code execution).')
                use_evalex = False

    app.config['ALLOWED_IPS'] = options.allowed_ips
    app.config['INDICO_URL'] = options.indico_url.rstrip('/')
    app.config['INDICO_API_KEY'] = options.api_key
    app.config['INDICO_SECRET_KEY'] = options.secret_key

    print(' * Using indico at {}'.format(app.config['INDICO_URL']))
    print(' * To use this script, simply append a valid Indico HTTP API request to the URL shown below. '
          'It MUST NOT contain an API key, secret key or timestamp!')
    app.debug = options.debug
    app.run(host=options.host, port=options.port, use_evalex=use_evalex)

if __name__ == '__main__':
    main()


from webargs import fields, validate
from .. import constants

filter_args = {
    "resolution": fields.Str(
        missing="1D", validate=lambda r: r in constants.INTERVALS
    ),
    "after": fields.Int(
        missing=None, validate=lambda v: v > 0
    )
}

transactions_args = filter_args
transactions_args["currency"] = fields.Str(
    missing="AOK"
)


from pnmlpy import WorkflowVerifier

class TestControlFlow:

    def test_file(self):
        errors = WorkflowVerifier.run_verifier('testResources/runningexample.pnml')
        import json
        js = json.loads(json.dumps(errors, sort_keys=False, indent=4))
        assert True == js["soundness"]
        assert 3 == int(js["cycles"])