# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# <center><h1>Data 245: Project</h1>
#     <h2>NBA Prediction</h2>

# <h3>Imports

import numpy as np, scipy as sc, pandas as pd, requests
import xml.etree.ElementTree as ET
from nba_api.stats.static import players
from nba_api.stats.endpoints import playercareerstats, playergamelog, playergamelogs, fantasywidget
from nba_api.stats.endpoints import infographicfanduelplayer, playerdashboardbylastngames, playernextngames
from nba_api.stats.endpoints import commonplayerinfo, commonallplayers
import json
import time
import unidecode
from IPython.display import Audio
from bs4 import BeautifulSoup
from urllib.request import urlopen
#pd.set_option('display.max_rows', None)
#pd.set_option('display.max_columns', None)

# <h3>Notes

# Scoring Rules:
# - point +1
# - 3pt made +0.5
# - rebound +1.25
# - assist +1.5
# - steal +2
# - turnover -0.5
# - 10x2 +1.5
# - 10x3 +3
#
# Gen restrictions:
# - 8 players
# - min 2 teams
# - 1x5 basic positions, 1G, 1F, 1 Util

# <h3>Sound (not neccessary for function)

'''
Audio Source:
https://mixkit.co/free-sound-effects/beep/
Positive Interface Beep
'''
sound_file = './sound/beep.wav'

# <h3>Injuries Dataframe

'''
url = 'https://www.fantasybasketballnerd.com/service/injuries'
res = requests.get(url)
content = res.text
tree = ET.ElementTree(ET.fromstring(content))
team = ""
player = []
injuries = []
cols = ["name","injury","notes","updated"]
for elem in tree.iter():
    if elem.tag == "Team":
        team = elem.attrib['code']
    elif elem.tag == "Player":
        player.append(team)
    elif elem.tag in cols:
        player.append(elem.text)
    if elem.tag == "updated":
        injuries.append(player)
        player = []
injuries
cols.insert(0,"team")
injuries_df = pd.DataFrame.from_records(injuries,columns=cols)'''

# <h3>Get Active Players

x = commonallplayers.CommonAllPlayers().get_data_frames()[0]

active_players = x[x['TO_YEAR'] == '2020']

ap = list(active_players['PERSON_ID'])

len(ap)

# <h3>Season Stats Data Frame Building

t_df = commonplayerinfo.CommonPlayerInfo(player_id=2544).get_data_frames()[0]
headers = list(t_df.columns.values)

df = pd.DataFrame(columns = headers)

e = 0
for player in ap:
    try:
        base = commonplayerinfo.CommonPlayerInfo(player_id=player, timeout=1000).get_data_frames()
        df = df.append(base[0])
        time.sleep(0.600)
    except:
        if e < 7:
            e+=1
            time.sleep(45)
            #print(e)
            base = commonplayerinfo.CommonPlayerInfo(player_id=player, timeout=1000).get_data_frames()
            df = df.append(base[0])
            continue
        else:
            print('break')
            break
Audio(sound_file, autoplay=True)

f_df = fantasywidget.FantasyWidget().get_data_frames()[0]

df.columns

f_df.columns

df = df.rename(columns={"PERSON_ID": "PLAYER_ID"})

df = df.drop(['TEAM_ID', 'TEAM_ABBREVIATION'], axis = 1)

df =  df.join(f_df.set_index('PLAYER_ID'), on='PLAYER_ID')

keep = ['PLAYER_ID', 'FIRST_NAME', 'LAST_NAME',
       'BIRTHDATE', 'HEIGHT',
       'WEIGHT', 'SEASON_EXP', 'ROSTERSTATUS',
       'TEAM_ID', 'TEAM_NAME',
       'TEAM_ABBREVIATION', 'TEAM_CODE', 'TEAM_CITY',
       'DRAFT_YEAR', 'DRAFT_NUMBER', 'PLAYER_POSITION',
       'GP', 'MIN',
       'PTS', 'REB', 'AST', 'BLK', 'STL', 'TOV', 'FG3M', 'FGA', 'FG_PCT',
       'FTA', 'FT_PCT', 'DISPLAY_FIRST_LAST']

df = df.drop([i for i in df.columns if i not in keep], axis = 1)

df['DRAFT_NUMBER'].unique()

dic = {}
for i in ['GP', 'MIN', 'PTS', 'REB', 'AST', 'BLK', 'STL', 'TOV', 'FG3M', 'FGA', 'FG_PCT','FTA', 'FT_PCT']:
    dic[i] = 'CURRENT_SEASON_'+i    

df = df.rename(columns=dic)

df['DRAFT_NUMBER'] = df['DRAFT_NUMBER'].replace({'Undrafted':61, None:61})

df.columns

# URL page we will scraping (see image above)
url = "https://www.basketball-reference.com/friv/injuries.fcgi"
# this is the HTML from the given URL
html = urlopen(url)
soup = BeautifulSoup(html)

injuries = []
for tr in soup.findAll('tr')[1:]:
    injury = tr.findAll('th')[0].getText()
    injuries.append(injury)
injuries

df = df.query("DISPLAY_FIRST_LAST not in @injuries")
df

# <h4>Gamelog Dictionary

Game_Logs = {}

e = 0
for player in ap:
    try:
        base = playergamelog.PlayerGameLog(player_id=player, timeout=1000).get_data_frames()
        Game_Logs[player] = base[0]
        time.sleep(0.600)
    except:
        if e < 7:
            e+=1
            time.sleep(45)
            #print(e)
            base = playergamelog.PlayerGameLog(player_id=player, timeout=1000).get_data_frames()
            Game_Logs[player] = base[0]
            continue
        else:
            print('break')
            break
Audio(sound_file, autoplay=True)

for player in ap:
    if len(Game_Logs[player]) == 0:
        Game_Logs.pop(player)


def dkings_score(row):
    try:
        threes = row['FG3M']
        r = row['REB']
        a = row['AST']
        s = row['STL']
        b = row['BLK']
        t = row['TOV']
        p = row['PTS']
        score = 0.5*threes + 1.25*r + 1.5*a + 2*s +2*b + -0.5*t + p
        dd = sum(1 for i in [p, r, a, s, b] if i>=10)
        if dd == 2:
            score += 1.5
        if dd > 2:
            score += 4.5
        return(score)
    except:
        print(row)
        pass


# +
# Add rest days into dataframe

def resting(select_df):
    
    # Transform string of game_date to datetime format

    select_df['GAME_DATETIME'] = pd.to_datetime(select_df['GAME_DATE'], format='%b %d, %Y')
    select_df['GAME_DATENEW'] = select_df['GAME_DATETIME'].dt.date
    
    # Take diff between each date

    select_df['GAME_DATENEW']=pd.to_datetime(select_df['GAME_DATENEW'])
    select_df['rest_days'] = select_df['GAME_DATENEW'].diff()
    
    # Rest days column is added

    select_df['rest_days'] = select_df['rest_days'].abs()


# -

to_be_averaged= ['MIN', 'FGM', 'FGA', 'FG3M', 'FG3A', 'FTM', 'FTA',
       'OREB', 'DREB', 'AST', 'STL', 'BLK', 'TOV',
       'PTS']

for frame in Game_Logs:
    x = Game_Logs[frame]
    x['DKING_SCORE'] = x.apply(lambda row: dkings_score(row), axis=1)
    x['TEAM'] = x.apply(lambda row: row['MATCHUP'][:3], axis=1)
    x['OPPOSING_TEAM'] = x.apply(lambda row: row['MATCHUP'][-3:], axis=1)
    x['HOME_AWAY'] = x.apply(lambda row: 1 if '@' in row['MATCHUP'] else 0, axis = 1)
    x.rename({'WL': 'PREVIOUS_WL'})
    for column in to_be_averaged:
        x['SEASON_'+ column] = x[column].rolling(window = len(x), min_periods = 1).mean()
        x['5_GAME_AVG_'+ column] = x[column].rolling(window = 5, min_periods = 1).mean()
    Game_Logs[frame] = x.drop(['MIN', 'MATCHUP', 'FGM', 'FGA', 'FG_PCT', 'FG3M', 'FG3A', 'FG3_PCT', 'FTM', 'FTA',
       'FT_PCT', 'OREB', 'DREB', 'REB', 'AST', 'STL', 'BLK', 'TOV', 'PF',
       'PTS', 'PLUS_MINUS', 'VIDEO_AVAILABLE'], axis = 1)

not_shift = ['SEASON_ID', 'Player_ID', 'Game_ID', 'GAME_DATE','DKING_SCORE',
       'TEAM', 'OPPOSING_TEAM', 'HOME_AWAY']

testing = Game_Logs[ap[0]]

to_shift = [i for i in testing.columns if i not in not_shift]

for frame in Game_Logs:
    for column in to_shift:
        Game_Logs[frame][column]= Game_Logs[frame][column].shift(1)
    resting(Game_Logs[frame])
    Game_Logs[frame] = Game_Logs[frame][[c for c in Game_Logs[frame] if c != 'DKING_SCORE'] 
       + ['DKING_SCORE']]
    Game_Logs[frame] = Game_Logs[frame].iloc[1:]

testing = Game_Logs[ap[0]]
testing.head()

final_df = pd.concat(Game_Logs, axis= 0)
final_df = final_df.drop(['SEASON_ID', 'Player_ID', 'Game_ID', 'GAME_DATE', 'GAME_DATETIME', 'GAME_DATENEW'], axis = 1)

final_df

StarcoderdataJupyterScriptsDedupFiltered