Spaces:
Runtime error
Runtime error
Upload 4 files
Browse files- app.py +487 -149
- sleep_emoji.png +0 -0
- team_abv.csv +33 -0
- yahoo_weeks.csv +28 -0
app.py
CHANGED
|
@@ -1,155 +1,493 @@
|
|
| 1 |
-
|
| 2 |
-
from typing import List, Dict, Tuple
|
| 3 |
-
import matplotlib.colors as mpl_colors
|
| 4 |
-
|
| 5 |
import pandas as pd
|
| 6 |
import seaborn as sns
|
| 7 |
-
import
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
from
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
@output
|
| 71 |
-
@render.
|
| 72 |
-
def
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
# The plotting function to use depends on whether margins are desired
|
| 76 |
-
plotfunc = sns.jointplot if input.show_margins() else sns.scatterplot
|
| 77 |
-
|
| 78 |
-
plotfunc(
|
| 79 |
-
data=filtered_df(),
|
| 80 |
-
x=input.xvar(),
|
| 81 |
-
y=input.yvar(),
|
| 82 |
-
palette=palette,
|
| 83 |
-
hue="Species" if input.by_species() else None,
|
| 84 |
-
hue_order=species,
|
| 85 |
-
legend=False,
|
| 86 |
-
)
|
| 87 |
|
| 88 |
@output
|
| 89 |
-
@render.
|
| 90 |
-
def
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
)
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
]
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
|
|
|
|
|
|
|
|
|
| 2 |
import pandas as pd
|
| 3 |
import seaborn as sns
|
| 4 |
+
import matplotlib.pyplot as plt
|
| 5 |
+
from matplotlib.pyplot import figure
|
| 6 |
+
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
|
| 7 |
+
from scipy import stats
|
| 8 |
+
import matplotlib.lines as mlines
|
| 9 |
+
import matplotlib.transforms as mtransforms
|
| 10 |
+
import numpy as np
|
| 11 |
+
import plotly.express as px
|
| 12 |
+
#!pip install chart_studio
|
| 13 |
+
# import chart_studio.tools as tls
|
| 14 |
+
from bs4 import BeautifulSoup
|
| 15 |
+
import matplotlib.pyplot as plt
|
| 16 |
+
import numpy as np
|
| 17 |
+
import matplotlib.font_manager as font_manager
|
| 18 |
+
from datetime import datetime
|
| 19 |
+
import pytz
|
| 20 |
+
from datetime import date
|
| 21 |
+
datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y')
|
| 22 |
+
# Configure Notebook
|
| 23 |
+
#%matplotlib inline
|
| 24 |
+
plt.style.use('fivethirtyeight')
|
| 25 |
+
sns.set_context("notebook")
|
| 26 |
+
import warnings
|
| 27 |
+
warnings.filterwarnings('ignore')
|
| 28 |
+
from urllib.request import urlopen
|
| 29 |
+
import json
|
| 30 |
+
from datetime import date, timedelta
|
| 31 |
+
import dataframe_image as dfi
|
| 32 |
+
from os import listdir
|
| 33 |
+
from os.path import isfile, join
|
| 34 |
+
import datetime
|
| 35 |
+
import seaborn as sns
|
| 36 |
+
import os
|
| 37 |
+
import calendar
|
| 38 |
+
from IPython.display import display, HTML
|
| 39 |
+
import matplotlib.image as mpimg
|
| 40 |
+
from skimage import io
|
| 41 |
+
import difflib
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
from datetime import datetime
|
| 45 |
+
import pytz
|
| 46 |
+
datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y')
|
| 47 |
+
# Configure Notebook
|
| 48 |
+
#%matplotlib inline
|
| 49 |
+
plt.style.use('fivethirtyeight')
|
| 50 |
+
sns.set_context("notebook")
|
| 51 |
+
import warnings
|
| 52 |
+
warnings.filterwarnings('ignore')
|
| 53 |
+
# import yfpy
|
| 54 |
+
# from yfpy.query import YahooFantasySportsQuery
|
| 55 |
+
# import yahoo_oauth
|
| 56 |
+
import json
|
| 57 |
+
import openpyxl
|
| 58 |
+
from sklearn import preprocessing
|
| 59 |
+
from PIL import Image
|
| 60 |
+
import logging
|
| 61 |
+
import matplotlib.patches as patches
|
| 62 |
+
from matplotlib.patches import Rectangle
|
| 63 |
+
from matplotlib.font_manager import FontProperties
|
| 64 |
+
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
|
| 65 |
+
|
| 66 |
+
import requests
|
| 67 |
+
import pickle
|
| 68 |
+
import pandas as pd
|
| 69 |
+
|
| 70 |
+
# # Loop over the counter and format the API call
|
| 71 |
+
r = requests.get('https://statsapi.web.nhl.com/api/v1/schedule?startDate=2023-10-01&endDate=2024-06-01')
|
| 72 |
+
schedule = r.json()
|
| 73 |
+
|
| 74 |
+
def flatten(t):
|
| 75 |
+
return [item for sublist in t for item in sublist]
|
| 76 |
+
|
| 77 |
+
game_id = flatten([[x['gamePk'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
|
| 78 |
+
game_date = flatten([[x['gameDate'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
|
| 79 |
+
game_home = flatten([[x['teams']['home']['team']['name'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
|
| 80 |
+
game_away = flatten([[x['teams']['away']['team']['name'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
|
| 81 |
+
|
| 82 |
+
schedule_df = pd.DataFrame(data={'game_id': game_id, 'game_date' : game_date, 'game_home' : game_home, 'game_away' : game_away})
|
| 83 |
+
schedule_df.game_date = pd.to_datetime(schedule_df['game_date']).dt.tz_convert(tz='US/Eastern').dt.date
|
| 84 |
+
schedule_df = schedule_df.replace('Montréal Canadiens','Montreal Canadiens')
|
| 85 |
+
schedule_df.head()
|
| 86 |
+
|
| 87 |
+
team_abv = pd.read_csv('team_abv.csv')
|
| 88 |
+
yahoo_weeks = pd.read_csv('yahoo_weeks.csv')
|
| 89 |
+
#yahoo_weeks['Number'] = yahoo_weeks['Number'].astype(int)
|
| 90 |
+
yahoo_weeks['Start'] = pd.to_datetime(yahoo_weeks['Start'])
|
| 91 |
+
yahoo_weeks['End'] = pd.to_datetime(yahoo_weeks['End'])
|
| 92 |
+
yahoo_weeks.head(5)
|
| 93 |
+
|
| 94 |
+
def highlight_cols(s):
|
| 95 |
+
color = '#C2FEE9'
|
| 96 |
+
return 'background-color: %s' % color
|
| 97 |
+
def highlight_cells(val):
|
| 98 |
+
color = 'white' if val == ' ' else ''
|
| 99 |
+
return 'background-color: {}'.format(color)
|
| 100 |
+
|
| 101 |
+
import matplotlib.pyplot as plt
|
| 102 |
+
import matplotlib.colors
|
| 103 |
+
cmap_total = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#56B4E9","#FFFFFF","#F0E442"])
|
| 104 |
+
cmap_off = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"])
|
| 105 |
+
cmap_back = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#56B4E9"])
|
| 106 |
+
cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"])
|
| 107 |
+
|
| 108 |
+
schedule_df = schedule_df.merge(right=team_abv,left_on='game_away',right_on='team_name',how='inner',suffixes=['','_away'])
|
| 109 |
+
schedule_df = schedule_df.merge(right=team_abv,left_on='game_home',right_on='team_name',how='inner',suffixes=['','_home'])
|
| 110 |
+
schedule_df['away_sym'] = '@'
|
| 111 |
+
schedule_df['home_sym'] = 'vs'
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
if not os.path.isfile('standings/standings_'+str(date.today())+'.csv'):
|
| 115 |
+
standings_df_old = pd.read_html('https://www.hockey-reference.com/leagues/NHL_2023_standings.html')[0].append(pd.read_html('https://www.hockey-reference.com/leagues/NHL_2023_standings.html')[1])
|
| 116 |
+
standings_df_old.to_csv('standings/standings_'+str(date.today())+'.csv')
|
| 117 |
+
standings_df_old = pd.read_csv('standings/standings_'+str(date.today())+'.csv',index_col=[0])
|
| 118 |
+
|
| 119 |
+
standings_df = standings_df_old[standings_df_old['Unnamed: 0'].str[-8:] != 'Division'].sort_values('Unnamed: 0').reset_index(drop=True).rename(columns={'Unnamed: 0':'Team'})#.drop(columns='Unnamed: 0')
|
| 120 |
+
#standings_df = standings_df.replace('St. Louis Blues','St Louis Blues')
|
| 121 |
+
standings_df['GF/GP'] = standings_df['GF'].astype(int)/standings_df['GP'].astype(int)
|
| 122 |
+
standings_df['GA/GP'] = standings_df['GA'].astype(int)/standings_df['GP'].astype(int)
|
| 123 |
+
standings_df['GF_Rank'] = standings_df['GF/GP'].rank(ascending=True,method='first')/10-1.65
|
| 124 |
+
standings_df['GA_Rank'] = standings_df['GA/GP'].rank(ascending=False,method='first')/10-1.65
|
| 125 |
+
standings_df.Team = standings_df.Team.str.strip('*')
|
| 126 |
+
standings_df = standings_df.merge(right=team_abv,left_on='Team',right_on='team_name')
|
| 127 |
+
|
| 128 |
+
schedule_stack = pd.DataFrame()
|
| 129 |
+
schedule_stack['date'] = pd.to_datetime(list(schedule_df['game_date'])+list(schedule_df['game_date']))
|
| 130 |
+
schedule_stack['team'] = list(schedule_df['team_name'])+list(schedule_df['team_name_home'])
|
| 131 |
+
schedule_stack['team_abv'] = list(schedule_df['team_abv'])+list(schedule_df['team_abv_home'])
|
| 132 |
+
schedule_stack['symbol'] = list(schedule_df['away_sym'])+list(schedule_df['home_sym'])
|
| 133 |
+
schedule_stack['team_opponent'] = list(schedule_df['team_name_home'])+list(schedule_df['team_name'])
|
| 134 |
+
schedule_stack['team_abv_home'] = list(schedule_df['team_abv_home'])+list(schedule_df['team_abv'])
|
| 135 |
+
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GF_Rank']],left_on='team_abv',right_on='team_abv',how='inner',suffixes=("",'_y'))
|
| 136 |
+
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GA_Rank']],left_on='team_abv_home',right_on='team_abv',how='inner',suffixes=("",'_y'))
|
| 137 |
+
|
| 138 |
+
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GF_Rank']],left_on='team_abv',right_on='team_abv',how='inner',suffixes=("",'_y'))
|
| 139 |
+
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GA_Rank']],left_on='team_abv_home',right_on='team_abv',how='inner',suffixes=("",'_y'))
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
list_o = schedule_stack.sort_values(['team','date'],ascending=[True,True]).reset_index(drop=True)
|
| 143 |
+
new_list = [x - y for x, y in zip(list_o['date'][1:], list_o['date'])]
|
| 144 |
+
b2b_list = [0] + [x.days for x in new_list]
|
| 145 |
+
b2b_list = [1 if x==1 else 0 for x in b2b_list]
|
| 146 |
+
test = list(schedule_stack.groupby(by='date').count()['team'])
|
| 147 |
+
offnight = [1 if x<15 else 0 for x in test]
|
| 148 |
+
offnight_df = pd.DataFrame({'date':schedule_stack.sort_values('date').date.unique(),'offnight':offnight}).sort_values('date').reset_index(drop=True)
|
| 149 |
+
schedule_stack = schedule_stack.merge(right=offnight_df,left_on='date',right_on='date',how='right')
|
| 150 |
+
schedule_stack = schedule_stack.sort_values(['team','date'],ascending=[True,True]).reset_index(drop=True)
|
| 151 |
+
schedule_stack['b2b'] = b2b_list
|
| 152 |
+
|
| 153 |
+
schedule_stack.date = pd.to_datetime(schedule_stack.date)
|
| 154 |
+
|
| 155 |
+
away_b2b = []
|
| 156 |
+
home_b2b = []
|
| 157 |
+
for i in range(0,len(schedule_stack)):
|
| 158 |
+
away_b2b.append(schedule_stack[(schedule_stack.date[i]==schedule_stack.date)&(schedule_stack.team_opponent[i]==schedule_stack.team)].reset_index(drop=True)['b2b'][0])
|
| 159 |
+
home_b2b.append(schedule_stack[(schedule_stack.date[i]==schedule_stack.date)&(schedule_stack.team[i]==schedule_stack.team)].reset_index(drop=True)['b2b'][0])
|
| 160 |
+
|
| 161 |
+
schedule_stack['away_b2b'] = away_b2b
|
| 162 |
+
schedule_stack['home_b2b'] = home_b2b
|
| 163 |
+
|
| 164 |
+
schedule_stack['away_b2b'] = schedule_stack['away_b2b'].replace(1,' 😴')
|
| 165 |
+
schedule_stack['away_b2b'] = schedule_stack['away_b2b'].replace(0,'')
|
| 166 |
+
schedule_stack.head()
|
| 167 |
+
|
| 168 |
+
FontProperties(fname='/System/Library/Fonts/Apple Color Emoji.ttc')
|
| 169 |
+
|
| 170 |
+
data_r = requests.get("https://pub-api-ro.fantasysports.yahoo.com/fantasy/v2/league/427.l.public;out=settings/players;position=ALL;start=0;count=3000;sort=rank_season;search=;out=percent_owned;out=auction_values,ranks;ranks=season;ranks_by_position=season;out=expert_ranks;expert_ranks.rank_type=projected_season_remaining/draft_analysis;cut_types=diamond;slices=last7days?format=json_f").json()
|
| 171 |
+
|
| 172 |
+
total_list = []
|
| 173 |
+
|
| 174 |
+
for x in data_r['fantasy_content']['league']['players']:
|
| 175 |
+
single_list = []
|
| 176 |
+
|
| 177 |
+
single_list.append(int(x['player']['player_id']))
|
| 178 |
+
single_list.append(int(x['player']['player_ranks'][0]['player_rank']['rank_value']))
|
| 179 |
+
single_list.append(x['player']['name']['full'])
|
| 180 |
+
single_list.append(x['player']['name']['first'])
|
| 181 |
+
single_list.append(x['player']['name']['last'])
|
| 182 |
+
single_list.append(x['player']['draft_analysis']['average_pick'])
|
| 183 |
+
single_list.append(x['player']['average_auction_cost'])
|
| 184 |
+
single_list.append(x['player']['display_position'])
|
| 185 |
+
single_list.append(x['player']['editorial_team_abbr'])
|
| 186 |
+
if 'value' in x['player']['percent_owned']:
|
| 187 |
+
single_list.append(x['player']['percent_owned']['value']/100)
|
| 188 |
+
else:
|
| 189 |
+
single_list.append(0)
|
| 190 |
+
total_list.append(single_list)
|
| 191 |
+
|
| 192 |
+
df_2023 = pd.DataFrame(data=total_list,columns=['player_id','rank_value','full','first','last','average_pick', 'average_cost','display_position','editorial_team_abbr','percent_owned'])
|
| 193 |
+
|
| 194 |
+
week_dict = yahoo_weeks.set_index('Number')['Week'].sort_index().to_dict()
|
| 195 |
+
|
| 196 |
+
from shiny import ui, render, App
|
| 197 |
+
import matplotlib.image as mpimg
|
| 198 |
+
# app_ui = ui.page_fluid(
|
| 199 |
+
|
| 200 |
+
# # ui.output_plot("plot"),
|
| 201 |
+
# #ui.h2('MLB Batter Launch Angle vs Exit Velocity'),
|
| 202 |
+
# ui.layout_sidebar(
|
| 203 |
+
# ui.panel_sidebar(
|
| 204 |
+
# ui.input_select("id", "Select Batter",batter_dict),
|
| 205 |
+
|
| 206 |
+
# ui.input_select("plot_id", "Select Plot",{'scatter':'Scatter Plot','dist':'Distribution Plot'})))
|
| 207 |
+
# ,
|
| 208 |
+
|
| 209 |
+
# ui.panel_main(ui.output_plot("plot",height = "750px",width="1250px")),
|
| 210 |
+
# #ui.download_button('test','Download'),
|
| 211 |
+
# )
|
| 212 |
+
app_ui = ui.page_fluid(ui.layout_sidebar(
|
| 213 |
+
# Available themes:
|
| 214 |
+
# cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux,
|
| 215 |
+
# materia, minty, morph, pulse, quartz, sandstone, simplex, sketchy, slate,
|
| 216 |
+
# solar, spacelab, superhero, united, vapor, yeti, zephyr
|
| 217 |
+
|
| 218 |
+
ui.panel_sidebar(
|
| 219 |
+
ui.input_select("week_id", "Select Week (Set as Season for Custom Date Range)",week_dict,width=1),
|
| 220 |
+
ui.input_select("sort_id", "Sort Column",['Score','Team','Total','Off-Night','B2B'],width=1),
|
| 221 |
+
ui.input_switch("a_d_id", "Ascending?"),
|
| 222 |
+
#ui.input_select("date_id", "Select Date",yahoo_weeks['Week'],width=1),
|
| 223 |
+
ui.input_date_range("date_range_id", "Date range input",start = datetime.today().date(), end = datetime.today().date() + timedelta(days=6)),
|
| 224 |
+
ui.output_table("result"),width=3),
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
ui.panel_main(ui.tags.h3(""),
|
| 228 |
+
ui.div({"style": "font-size:2em;"},ui.output_text("txt_title")),
|
| 229 |
+
#ui.tags.h2("Fantasy Hockey Schedule Summary"),
|
| 230 |
+
ui.tags.h5("Created By: @TJStats, Data: NHL"),
|
| 231 |
+
ui.div({"style": "font-size:1.2em;"},ui.output_text("txt")),
|
| 232 |
+
ui.output_table("schedule_result"),
|
| 233 |
+
ui.tags.h5('Legend'),
|
| 234 |
+
ui.output_table("schedule_result_legend"),
|
| 235 |
+
ui.tags.h6('An Off Night is defined as a day in which less than half the teams in the NHL are playing'),
|
| 236 |
+
ui.tags.h6('The scores are determined by using games played, off-nights, B2B, and strength of opponents') )
|
| 237 |
+
|
| 238 |
+
))
|
| 239 |
+
# ui.row(
|
| 240 |
+
# ui.column(
|
| 241 |
+
# 3,
|
| 242 |
+
# ui.input_date("x", "Date input"),),
|
| 243 |
+
# ui.column(
|
| 244 |
+
# 1,
|
| 245 |
+
# ui.input_select("level_id", "Select Level",level_dict,width=1)),
|
| 246 |
+
# ui.column(
|
| 247 |
+
# 3,
|
| 248 |
+
# ui.input_select("stat_id", "Select Stat",plot_dict_small,width=1)),
|
| 249 |
+
# ui.column(
|
| 250 |
+
# 2,
|
| 251 |
+
# ui.input_numeric("n", "Rolling Window Size", value=50)),
|
| 252 |
+
# ),
|
| 253 |
+
# ui.output_table("result_batters")),
|
| 254 |
+
|
| 255 |
+
# ui.nav(
|
| 256 |
+
# "Pitchers",
|
| 257 |
+
|
| 258 |
+
# ui.row(
|
| 259 |
+
# ui.column(
|
| 260 |
+
# 3,
|
| 261 |
+
# ui.input_select("id_pitch", "Select Pitcher",pitcher_dict,width=1,selected=675911),
|
| 262 |
+
# ),
|
| 263 |
+
# ui.column(
|
| 264 |
+
# 1,
|
| 265 |
+
# ui.input_select("level_id_pitch", "Select Level",level_dict,width=1)),
|
| 266 |
+
# ui.column(
|
| 267 |
+
# 3,
|
| 268 |
+
# ui.input_select("stat_id_pitch", "Select Stat",plot_dict_small_pitch,width=1)),
|
| 269 |
+
# ui.column(
|
| 270 |
+
# 2,
|
| 271 |
+
# ui.input_numeric("n_pitch", "Rolling Window Size", value=50)),
|
| 272 |
+
# ),
|
| 273 |
+
# ui.output_table("result_pitchers")),
|
| 274 |
+
# )
|
| 275 |
+
# )
|
| 276 |
+
# )
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
from urllib.request import Request, urlopen
|
| 282 |
+
# importing OpenCV(cv2) module
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
|
| 286 |
+
|
| 287 |
+
def server(input, output, session):
|
| 288 |
+
|
| 289 |
+
@output
|
| 290 |
+
@render.text
|
| 291 |
+
def txt():
|
| 292 |
+
|
| 293 |
+
week_set = int(input.week_id())
|
| 294 |
+
if week_set != 0:
|
| 295 |
+
if pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]['Start'].values[0]).year != pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]['End'].values[0]).year:
|
| 296 |
+
|
| 297 |
+
return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d, %Y")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%B %d, %Y")}'
|
| 298 |
+
else:
|
| 299 |
+
if pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).month != pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).month:
|
| 300 |
+
return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%B %d, %Y")}'
|
| 301 |
+
else:
|
| 302 |
+
return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%d, %Y")}'
|
| 303 |
+
else:
|
| 304 |
+
if input.date_range_id()[0].year != input.date_range_id()[1].year:
|
| 305 |
+
|
| 306 |
+
return f'{input.date_range_id()[0].strftime("%B %d, %Y")} to {input.date_range_id()[1].strftime("%B %d, %Y")}'
|
| 307 |
+
else:
|
| 308 |
+
if input.date_range_id()[0].month != input.date_range_id()[1].month:
|
| 309 |
+
return f'{input.date_range_id()[0].strftime("%B %d")} to {input.date_range_id()[1].strftime("%B %d, %Y")}'
|
| 310 |
+
else:
|
| 311 |
+
return f'{input.date_range_id()[0].strftime("%B %d")} to {input.date_range_id()[1].strftime("%d, %Y")}'
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
@output
|
| 315 |
+
@render.text
|
| 316 |
+
def txt_title():
|
| 317 |
+
week_set = int(input.week_id())
|
| 318 |
+
if week_set != 0:
|
| 319 |
+
return f'Fantasy Hockey Schedule Summary - Yahoo - Week {input.week_id()}'
|
| 320 |
+
else:
|
| 321 |
+
return f'Fantasy Hockey Schedule Summary'
|
| 322 |
|
| 323 |
@output
|
| 324 |
+
@render.table
|
| 325 |
+
def result():
|
| 326 |
+
#print(yahoo_weeks)
|
| 327 |
+
return yahoo_weeks
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
@output
|
| 330 |
+
@render.table
|
| 331 |
+
def schedule_result():
|
| 332 |
+
|
| 333 |
+
|
| 334 |
+
week_set = int(input.week_id())
|
| 335 |
+
print(week_set)
|
| 336 |
+
|
| 337 |
+
if week_set == 0:
|
| 338 |
+
start_point = input.date_range_id()[0]
|
| 339 |
+
end_point = input.date_range_id()[1]
|
| 340 |
+
else:
|
| 341 |
+
start_point = yahoo_weeks[yahoo_weeks.Number==week_set].reset_index(drop=True)['Start'][0]
|
| 342 |
+
end_point = yahoo_weeks[yahoo_weeks.Number==week_set].reset_index(drop=True)['End'][0]
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
sort_value='Score'
|
| 346 |
+
ascend=False
|
| 347 |
+
|
| 348 |
+
weekly_stack = schedule_stack[(schedule_stack['date'].dt.date>=start_point)&(schedule_stack['date'].dt.date<=end_point)]
|
| 349 |
+
date_list = pd.date_range(start_point,end_point,freq='d')
|
| 350 |
+
test_list = [[]] * len(date_list)
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
|
| 354 |
+
for i in range(0,len(date_list)):
|
| 355 |
+
test_list[i] = team_abv.merge(right=weekly_stack[weekly_stack['date']==date_list[i]],left_on='team_abv',right_on='team_abv',how='left')
|
| 356 |
+
test_list[i] = test_list[i].fillna("")
|
| 357 |
+
test_list[i]['new_text'] = test_list[i]['symbol'] + ' '+ test_list[i]['team_abv_home'] + test_list[i]['away_b2b']
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
test_df = pd.DataFrame()
|
| 361 |
+
test_df['Team'] = list(team_abv['team_abv'])
|
| 362 |
+
test_df['Total'] = test_df.merge(right=weekly_stack.groupby('team_abv')['team_abv'].apply(lambda x: x[x != ''].count()),left_on=['Team'],right_index=True,how='left').fillna(0)['team_abv']
|
| 363 |
+
test_df['Off-Night'] = test_df.merge(right=weekly_stack.groupby('team_abv').sum()['offnight'],left_on=['Team'],right_index=True,how='left').fillna(0)['offnight']
|
| 364 |
+
test_df['B2B']= test_df.merge(right=weekly_stack.groupby('team_abv').sum()['b2b'],left_on=['Team'],right_index=True,how='left').fillna(0)['b2b']
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
gf_rank = np.array(test_df.merge(right=weekly_stack.groupby('team_abv').mean()['GF_Rank'],left_on=['Team'],right_index=True,how='left').fillna(0)['GF_Rank'])
|
| 369 |
+
ga_rank = np.array(test_df.merge(right=weekly_stack.groupby('team_abv').mean()['GA_Rank'],left_on=['Team'],right_index=True,how='left').fillna(0)['GA_Rank'])
|
| 370 |
+
|
| 371 |
+
|
| 372 |
+
#games_vs_tired = np.array([float(i)*0.4 for i in list(weekly_stack.groupby('team_abv')['away_b2b'].apply(lambda x: x[x != ''].count()))])
|
| 373 |
+
|
| 374 |
+
games_vs_tired = 0.4*np.array(test_df.merge(right=weekly_stack.groupby('team_abv')['away_b2b'].apply(lambda x: x[x != ''].count()),left_on=['Team'],right_index=True,how='left').fillna(0)['away_b2b'])
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
team_score = test_df['Total']+test_df['Off-Night']*0.5+test_df['B2B']*-0.2+games_vs_tired*0.3+gf_rank*0.1+ga_rank*0.1
|
| 378 |
+
|
| 379 |
+
test_df['Score'] = team_score
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
cols = test_df.columns.tolist();
|
| 383 |
+
L = len(cols)
|
| 384 |
+
test_df = test_df[cols[4:]+cols[0:4]]
|
| 385 |
+
#return test_df#[cols[4:]+cols[0:4]]
|
| 386 |
+
|
| 387 |
+
test_df = test_df.sort_values(by=[sort_value,'Score'],ascending = ascend)
|
| 388 |
+
|
| 389 |
+
for i in range(0,len(date_list)):
|
| 390 |
+
test_df[calendar.day_name[date_list[i].weekday()]+'<br>'+str(date_list[i].month)+'-'+'{:02d}'.format(date_list[i].day)] = test_list[i]['new_text']
|
| 391 |
+
|
| 392 |
+
row = ['']*L
|
| 393 |
+
for x in test_df[test_df.columns[L:]]:
|
| 394 |
+
row.append(int(sum(test_df[x]!=" ")/2))
|
| 395 |
+
|
| 396 |
+
test_df = test_df.sort_values(by=input.sort_id(),ascending=input.a_d_id())
|
| 397 |
+
|
| 398 |
+
test_df.loc[32] = row
|
| 399 |
+
#test_df_html = HTML( test_df.to_html().replace("\\n","<br>") )
|
| 400 |
+
offnight_list = [True if x <8 else False for x in test_df.iloc[-1][L:]]
|
| 401 |
+
|
| 402 |
+
test_df.style.applymap(highlight_cols,subset = ((list(test_df.index[:-1]),test_df.columns[L:][offnight_list])))
|
| 403 |
+
test_df_style = test_df.style.set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{
|
| 404 |
+
'selector': 'caption',
|
| 405 |
+
'props': [
|
| 406 |
+
('color', ''),
|
| 407 |
+
('fontname', 'Century Gothic'),
|
| 408 |
+
('font-size', '20px'),
|
| 409 |
+
('font-style', 'italic'),
|
| 410 |
+
('font-weight', ''),
|
| 411 |
+
('text-align', 'centre'),
|
| 412 |
+
]
|
| 413 |
+
|
| 414 |
+
},{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),('border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties(
|
| 415 |
+
**{'background-color':'White','index':'White','min-width':'75px'},overwrite=False).set_properties(
|
| 416 |
+
**{'background-color':'White','index':'White','min-width':'100px'},overwrite=False,subset = ((list(test_df.index[:]),test_df.columns[5:]))).set_table_styles(
|
| 417 |
+
[{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
|
| 418 |
+
[{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
|
| 419 |
+
[{'selector': 'tr', 'props': [('line-height', '20px')]}],overwrite=False).set_properties(
|
| 420 |
+
**{'Height': '8px'},**{'text-align': 'center'},overwrite=False).hide_index()
|
| 421 |
+
|
| 422 |
+
test_df_style = test_df_style.applymap(highlight_cols,subset = ((list(test_df.index[:-1]),test_df.columns[L:][offnight_list])))
|
| 423 |
+
|
| 424 |
+
test_df_style = test_df_style.applymap(highlight_cells)
|
| 425 |
+
test_df_style = test_df_style.background_gradient(cmap=cmap_total,subset = ((list(test_df.index[:-1]),test_df.columns[0])))
|
| 426 |
+
test_df_style = test_df_style.background_gradient(cmap=cmap_total,vmin=0,vmax=np.max(test_df.Total[:len(test_df)-1]),subset = ((list(test_df.index[:-1]),test_df.columns[2])))
|
| 427 |
+
test_df_style = test_df_style.background_gradient(cmap=cmap_off,subset = ((list(test_df.index[:-1]),test_df.columns[3])))
|
| 428 |
+
test_df_style = test_df_style.background_gradient(cmap=cmap_back,subset = ((list(test_df.index[:-1]),test_df.columns[4])))
|
| 429 |
+
test_df_style = test_df_style.background_gradient(cmap=cmap_sum,subset = ((list(test_df.index[-1:]),test_df.columns[L:])),axis=1)
|
| 430 |
+
test_df_style = test_df_style.set_properties(
|
| 431 |
+
**{'border': '1px black solid !important'},subset = ((list(test_df.index[:-1]),test_df.columns[:]))).set_properties(
|
| 432 |
+
**{'min-width':'85px'},subset = ((list(test_df.index[:-1]),test_df.columns[L:])),overwrite=False).set_properties(**{
|
| 433 |
+
'color': 'black'},overwrite=False).set_properties(
|
| 434 |
+
**{'border': '1px black solid !important'},subset = ((list(test_df.index[:]),test_df.columns[L:])))
|
| 435 |
+
|
| 436 |
+
test_df_style = test_df_style.format(
|
| 437 |
+
'{:.0f}',subset=(test_df.index[:-1],test_df.columns[2:L]))
|
| 438 |
+
|
| 439 |
+
test_df_style = test_df_style.format(
|
| 440 |
+
'{:.1f}',subset=(test_df.index[:-1],test_df.columns[0]))
|
| 441 |
+
|
| 442 |
+
|
| 443 |
+
print('made it to teh end')
|
| 444 |
+
return test_df_style
|
| 445 |
+
|
| 446 |
+
|
| 447 |
+
#return exit_velo_df_codes_summ_time_style_set
|
| 448 |
+
|
| 449 |
+
# @output
|
| 450 |
+
# @render.plot(alt="A histogram")
|
| 451 |
+
# def plot_pitch():
|
| 452 |
+
# p
|
| 453 |
+
@output
|
| 454 |
+
@render.table
|
| 455 |
+
def schedule_result_legend():
|
| 456 |
+
|
| 457 |
+
off_b2b_df = pd.DataFrame(data={'off':'Off-Night','b2b':'Tired Opp. 😴'},index=[0])
|
| 458 |
+
#off_b2b_df.style.applymap(highlight_cols,subset = ((list(off_b2b_df.index[:-1]),off_b2b_df.columns[0])))
|
| 459 |
+
off_b2b_df_style = off_b2b_df.style.set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{
|
| 460 |
+
'selector': 'caption',
|
| 461 |
+
'props': [
|
| 462 |
+
('color', ''),
|
| 463 |
+
('fontname', 'Century Gothic'),
|
| 464 |
+
('font-size', '20px'),
|
| 465 |
+
('font-style', 'italic'),
|
| 466 |
+
('font-weight', ''),
|
| 467 |
+
('text-align', 'centre'),
|
| 468 |
+
]
|
| 469 |
+
|
| 470 |
+
},{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),(
|
| 471 |
+
'border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties(
|
| 472 |
+
**{'background-color':'White','index':'White','min-width':'150px'},overwrite=False).set_table_styles(
|
| 473 |
+
[{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
|
| 474 |
+
[{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
|
| 475 |
+
[{'selector': 'tr', 'props': [('line-height', '20px')]}],overwrite=False).set_properties(
|
| 476 |
+
**{'Height': '8px'},**{'text-align': 'center'},overwrite=False).set_properties(
|
| 477 |
+
**{'background-color':'#C2FEE9'},subset=off_b2b_df.columns[0]).set_properties(
|
| 478 |
+
**{'color':'black'},subset=off_b2b_df.columns[:]).hide_index().set_table_styles([
|
| 479 |
+
{'selector': 'thead', 'props': [('display', 'none')]}
|
| 480 |
+
]).set_properties(**{'border': '3 px','color':'black'},overwrite=False).set_properties(
|
| 481 |
+
**{'border': '1px black solid !important'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:]))).set_properties(
|
| 482 |
+
**{'min-width':'130'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:])),overwrite=False).set_properties(**{
|
| 483 |
+
'color': 'black'},overwrite=False).set_properties(
|
| 484 |
+
**{'border': '1px black solid !important'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:])))
|
| 485 |
+
|
| 486 |
+
return off_b2b_df_style
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
app = App(app_ui, server)
|
sleep_emoji.png
ADDED
|
team_abv.csv
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
team_abv,team_name
|
| 2 |
+
ANA,Anaheim Ducks
|
| 3 |
+
ARI,Arizona Coyotes
|
| 4 |
+
BOS,Boston Bruins
|
| 5 |
+
BUF,Buffalo Sabres
|
| 6 |
+
CAR,Carolina Hurricanes
|
| 7 |
+
CBJ,Columbus Blue Jackets
|
| 8 |
+
CGY,Calgary Flames
|
| 9 |
+
CHI,Chicago Blackhawks
|
| 10 |
+
COL,Colorado Avalanche
|
| 11 |
+
DAL,Dallas Stars
|
| 12 |
+
DET,Detroit Red Wings
|
| 13 |
+
EDM,Edmonton Oilers
|
| 14 |
+
FLA,Florida Panthers
|
| 15 |
+
L.A,Los Angeles Kings
|
| 16 |
+
MIN,Minnesota Wild
|
| 17 |
+
MTL,Montreal Canadiens
|
| 18 |
+
N.J,New Jersey Devils
|
| 19 |
+
NSH,Nashville Predators
|
| 20 |
+
NYI,New York Islanders
|
| 21 |
+
NYR,New York Rangers
|
| 22 |
+
OTT,Ottawa Senators
|
| 23 |
+
PHI,Philadelphia Flyers
|
| 24 |
+
PIT,Pittsburgh Penguins
|
| 25 |
+
S.J,San Jose Sharks
|
| 26 |
+
SEA,Seattle Kraken
|
| 27 |
+
STL,St. Louis Blues
|
| 28 |
+
T.B,Tampa Bay Lightning
|
| 29 |
+
TOR,Toronto Maple Leafs
|
| 30 |
+
VAN,Vancouver Canucks
|
| 31 |
+
VGK,Vegas Golden Knights
|
| 32 |
+
WPG,Winnipeg Jets
|
| 33 |
+
WSH,Washington Capitals
|
yahoo_weeks.csv
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Week,Number,Start,End
|
| 2 |
+
Week 1,1,2023-10-10,2023-10-15
|
| 3 |
+
Week 2,2,2023-10-16,2023-10-22
|
| 4 |
+
Week 3,3,2023-10-23,2023-10-29
|
| 5 |
+
Week 4,4,2023-10-30,2023-11-05
|
| 6 |
+
Week 5,5,2023-11-06,2023-11-12
|
| 7 |
+
Week 6,6,2023-11-13,2023-11-19
|
| 8 |
+
Week 7,7,2023-11-20,2023-11-26
|
| 9 |
+
Week 8,8,2023-11-27,2023-12-03
|
| 10 |
+
Week 9,9,2023-12-04,2023-12-10
|
| 11 |
+
Week 10,10,2023-12-11,2023-12-17
|
| 12 |
+
Week 11,11,2023-12-18,2023-12-24
|
| 13 |
+
Week 12,12,2023-12-25,2023-12-31
|
| 14 |
+
Week 13,13,2024-01-01,2024-01-07
|
| 15 |
+
Week 14,14,2024-01-08,2024-01-14
|
| 16 |
+
Week 15,15,2024-01-15,2024-01-21
|
| 17 |
+
Week 16,16,2024-01-22,2024-01-28
|
| 18 |
+
Week 17,17,2024-01-29,2024-02-11
|
| 19 |
+
Week 18,18,2024-02-12,2024-02-18
|
| 20 |
+
Week 19,19,2024-02-19,2024-02-25
|
| 21 |
+
Week 20,20,2024-02-26,2024-03-03
|
| 22 |
+
Week 21,21,2024-03-04,2024-03-10
|
| 23 |
+
Week 22,22,2024-03-11,2024-03-17
|
| 24 |
+
Week 23,23,2024-03-18,2024-03-24
|
| 25 |
+
Week 24,24,2024-03-25,2024-03-31
|
| 26 |
+
Week 25,25,2024-04-01,2024-04-07
|
| 27 |
+
Week 26,26,2024-04-08,2024-04-18
|
| 28 |
+
Season,0,2023-10-10,2024-04-18
|