James McCool commited on
Commit
92e6a09
·
1 Parent(s): 545350e

optimizing for tabs to segmentation, UI upgrades, and some optimizations around segmented queries

Browse files
Files changed (2) hide show
  1. src/database.py +2 -18
  2. src/streamlit_app.py +197 -166
src/database.py CHANGED
@@ -5,26 +5,10 @@ import os
5
 
6
  @st.cache_resource
7
  def init_conn():
8
- scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
9
-
10
- credentials = {
11
- "type": "service_account",
12
- "project_id": "model-sheets-connect",
13
- "private_key_id": "0e0bc2fdef04e771172fe5807392b9d6639d945e",
14
- "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDiu1v/e6KBKOcK\ncx0KQ23nZK3ZVvADYy8u/RUn/EDI82QKxTd/DizRLIV81JiNQxDJXSzgkbwKYEDm\n48E8zGvupU8+Nk76xNPakrQKy2Y8+VJlq5psBtGchJTuUSHcXU5Mg2JhQsB376PJ\nsCw552K6Pw8fpeMDJDZuxpKSkaJR6k9G5Dhf5q8HDXnC5Rh/PRFuKJ2GGRpX7n+2\nhT/sCax0J8jfdTy/MDGiDfJqfQrOPrMKELtsGHR9Iv6F4vKiDqXpKfqH+02E9ptz\nBk+MNcbZ3m90M8ShfRu28ebebsASfarNMzc3dk7tb3utHOGXKCf4tF8yYKo7x8BZ\noO9X4gSfAgMBAAECggEAU8ByyMpSKlTCF32TJhXnVJi/kS+IhC/Qn5JUDMuk4LXr\naAEWsWO6kV/ZRVXArjmuSzuUVrXumISapM9Ps5Ytbl95CJmGDiLDwRL815nvv6k3\nUyAS8EGKjz74RpoIoH6E7EWCAzxlnUgTn+5oP9Flije97epYk3H+e2f1f5e1Nn1d\nYNe8U+1HqJgILcxA1TAUsARBfoD7+K3z/8DVPHI8IpzAh6kTHqhqC23Rram4XoQ6\nzj/ZdVBjvnKuazETfsD+Vl3jGLQA8cKQVV70xdz3xwLcNeHsbPbpGBpZUoF73c65\nkAXOrjYl0JD5yAk+hmYhXr6H9c6z5AieuZGDrhmlFQKBgQDzV6LRXmjn4854DP/J\nI82oX2GcI4eioDZPRukhiQLzYerMQBmyqZIRC+/LTCAhYQSjNgMa+ZKyvLqv48M0\n/x398op/+n3xTs+8L49SPI48/iV+mnH7k0WI/ycd4OOKh8rrmhl/0EWb9iitwJYe\nMjTV/QxNEpPBEXfR1/mvrN/lVQKBgQDuhomOxUhWVRVH6x03slmyRBn0Oiw4MW+r\nrt1hlNgtVmTc5Mu+4G0USMZwYuOB7F8xG4Foc7rIlwS7Ic83jMJxemtqAelwOLdV\nXRLrLWJfX8+O1z/UE15l2q3SUEnQ4esPHbQnZowHLm0mdL14qSVMl1mu1XfsoZ3z\nJZTQb48CIwKBgEWbzQRtKD8lKDupJEYqSrseRbK/ax43DDITS77/DWwHl33D3FYC\nMblUm8ygwxQpR4VUfwDpYXBlklWcJovzamXpSnsfcYVkkQH47NuOXPXPkXQsw+w+\nDYcJzeu7F/vZqk9I7oBkWHUrrik9zPNoUzrfPvSRGtkAoTDSwibhoc5dAoGBAMHE\nK0T/ANeZQLNuzQps6S7G4eqjwz5W8qeeYxsdZkvWThOgDd/ewt3ijMnJm5X05hOn\ni4XF1euTuvUl7wbqYx76Wv3/1ZojiNNgy7ie4rYlyB/6vlBS97F4ZxJdxMlabbCW\n6b3EMWa4EVVXKoA1sCY7IVDE+yoQ1JYsZmq45YzPAoGBANWWHuVueFGZRDZlkNlK\nh5OmySmA0NdNug3G1upaTthyaTZ+CxGliwBqMHAwpkIRPwxUJpUwBTSEGztGTAxs\nWsUOVWlD2/1JaKSmHE8JbNg6sxLilcG6WEDzxjC5dLL1OrGOXj9WhC9KX3sq6qb6\nF/j9eUXfXjAlb042MphoF3ZC\n-----END PRIVATE KEY-----\n",
15
- "client_email": "gspread-connection@model-sheets-connect.iam.gserviceaccount.com",
16
- "client_id": "100369174533302798535",
17
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
18
- "token_uri": "https://oauth2.googleapis.com/token",
19
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
20
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40model-sheets-connect.iam.gserviceaccount.com"
21
- }
22
  uri = "mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
23
  client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=100000)
24
  db = client["testing_db"]
25
-
26
- gc_con = gspread.service_account_from_dict(credentials, scope)
27
 
28
- return gc_con, db
29
 
30
- gcservice_account, db = init_conn()
 
5
 
6
  @st.cache_resource
7
  def init_conn():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  uri = "mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
9
  client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=100000)
10
  db = client["testing_db"]
 
 
11
 
12
+ return db
13
 
14
+ db = init_conn()
src/streamlit_app.py CHANGED
@@ -13,84 +13,170 @@ import plotly.graph_objects as go
13
  import plotly.io as pio
14
  import certifi
15
  ca = certifi.where()
16
- from database import gcservice_account, db
17
 
18
  NBA_Data = 'https://docs.google.com/spreadsheets/d/1Yq0vGriWK-bS79e-bD6_u9pqrYE6Yrlbb_wEkmH-ot0/edit#gid=1808117109'
19
 
20
  percentages_format = {'PG': '{:.2%}', 'SG': '{:.2%}', 'SF': '{:.2%}', 'PF': '{:.2%}', 'C': '{:.2%}'}
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  @st.cache_resource(ttl = 599)
23
- def init_baselines():
24
- sh = gcservice_account.open_by_url(NBA_Data)
25
- collection = db["gamelog"]
26
- cursor = collection.find() # Finds all documents in the collection
27
-
28
- raw_display = pd.DataFrame(list(cursor))
29
- gamelog_table = raw_display[raw_display['PLAYER_NAME'] != ""]
30
- gamelog_table = gamelog_table[['PLAYER_NAME', 'POS', 'GAME_ID', 'TEAM_NAME', 'OPP_NAME', 'SEASON_ID', 'GAME_DATE', 'MATCHUP', 'MIN', 'touches', 'PTS', 'FGM', 'FGA', 'FG_PCT', 'FG3M', 'FG3A',
31
- 'FG3_PCT', 'FTM', 'FTA', 'FT_PCT', 'reboundChancesOffensive', 'OREB', 'reboundChancesDefensive', 'DREB', 'reboundChancesTotal', 'REB',
32
- 'passes', 'secondaryAssists', 'freeThrowAssists', 'assists', 'STL', 'BLK', 'TOV', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy', 'FPPM']]
33
- gamelog_table['assists'].replace("", 0, inplace=True)
34
- gamelog_table['reboundChancesTotal'].replace("", 0, inplace=True)
35
- gamelog_table['passes'].replace("", 0, inplace=True)
36
- gamelog_table['touches'].replace("", 0, inplace=True)
37
- gamelog_table['MIN'].replace("", 0, inplace=True)
38
- gamelog_table['Fantasy'].replace("", 0, inplace=True)
39
- gamelog_table['FD_Fantasy'].replace("", 0, inplace=True)
40
- gamelog_table['FPPM'].replace("", 0, inplace=True)
41
- gamelog_table['REB'] = gamelog_table['REB'].astype(int)
42
- gamelog_table['assists'] = gamelog_table['assists'].astype(int)
43
- gamelog_table['reboundChancesTotal'] = gamelog_table['reboundChancesTotal'].astype(int)
44
- gamelog_table['passes'] = gamelog_table['passes'].astype(int)
45
- gamelog_table['touches'] = gamelog_table['touches'].astype(int)
46
- gamelog_table['MIN'] = gamelog_table['MIN'].astype(int)
47
- gamelog_table['Fantasy'] = gamelog_table['Fantasy'].astype(float)
48
- gamelog_table['FD_Fantasy'] = gamelog_table['FD_Fantasy'].astype(float)
49
- gamelog_table['FPPM'] = gamelog_table['FPPM'].astype(float)
50
- gamelog_table['rebound%'] = gamelog_table['REB'] / gamelog_table['reboundChancesTotal']
51
- gamelog_table['assists_per_pass'] = gamelog_table['assists'] / gamelog_table['passes']
52
- gamelog_table['Touch_per_min'] = gamelog_table['touches'] / gamelog_table['MIN']
53
- gamelog_table['Fantasy_per_touch'] = gamelog_table['Fantasy'] / gamelog_table['touches']
54
- gamelog_table['FD_Fantasy_per_touch'] = gamelog_table['FD_Fantasy'] / gamelog_table['touches']
55
- data_cols = gamelog_table.columns.drop(['PLAYER_NAME', 'POS', 'TEAM_NAME', 'OPP_NAME', 'SEASON_ID', 'GAME_DATE', 'MATCHUP'])
56
- gamelog_table[data_cols] = gamelog_table[data_cols].apply(pd.to_numeric, errors='coerce')
57
- gamelog_table['team_score'] = gamelog_table.groupby(['TEAM_NAME', 'GAME_ID'], sort=False)['PTS'].transform('sum')
58
- gamelog_table['opp_score'] = gamelog_table.groupby(['GAME_ID'], sort=False)['PTS'].transform('sum') - gamelog_table['team_score']
59
- gamelog_table['spread'] = (gamelog_table['opp_score'] - gamelog_table['team_score']).abs()
60
- gamelog_table['GAME_DATE'] = pd.to_datetime(gamelog_table['GAME_DATE']).dt.date
61
-
62
- spread_dict = dict(zip(gamelog_table['GAME_ID'], gamelog_table['spread']))
63
-
64
- gamelog_table = gamelog_table.set_axis(['Player', 'Pos', 'game_id', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
65
- 'FG3A', 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
66
- 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy', 'FPPM',
67
- 'Rebound%', 'Assists/Pass', 'Touch_per_min', 'Fantasy/Touch', 'FD Fantasy/Touch', 'team_score', 'opp_score', 'spread'], axis=1)
68
-
69
- worksheet = sh.worksheet('Rotations')
70
- raw_display = pd.DataFrame(worksheet.get_values())
71
- raw_display.columns = raw_display.iloc[0]
72
- raw_display = raw_display[1:]
73
- raw_display = raw_display.reset_index(drop=True)
74
- rot_table = raw_display[raw_display['Player'] != ""]
75
- rot_table = rot_table[['Player', 'Team', 'PG', 'SG', 'SF', 'PF', 'C', 'Given_Pos']]
76
- data_cols = ['PG', 'SG', 'SF', 'PF', 'C']
77
- rot_table[data_cols] = rot_table[data_cols].apply(pd.to_numeric, errors='coerce')
78
- rot_table = rot_table[rot_table['Player'] != 0]
79
-
80
- collection = db["rotations"]
81
- cursor = collection.find() # Finds all documents in the collection
82
-
83
- raw_display = pd.DataFrame(list(cursor))
84
- game_rot = raw_display[raw_display['PLAYER_NAME'] != ""]
85
- data_cols = game_rot.columns.drop(['PLAYER_NAME', 'POS', 'TEAM_ABBREVIATION', 'OPP_ABBREVIATION', 'TEAM_NAME', 'OPP_NAME', 'GAME_DATE',
86
- 'MATCHUP', 'WL', 'backlog_lookup', 'Task', 'game_players'])
87
- game_rot[data_cols] = game_rot[data_cols].apply(pd.to_numeric, errors='coerce')
88
- game_rot['spread'] = game_rot['GAME_ID'].map(spread_dict)
89
- game_rot['GAME_DATE'] = pd.to_datetime(game_rot['GAME_DATE']).dt.date
90
-
91
- timestamp = gamelog_table['Date'].max()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- return gamelog_table, rot_table, game_rot, timestamp
94
 
95
  @st.cache_data(show_spinner=False)
96
  def seasonlong_build(data_sample):
@@ -192,39 +278,46 @@ def split_frame(input_df, rows):
192
  def convert_df_to_csv(df):
193
  return df.to_csv().encode('utf-8')
194
 
195
- gamelog_table, rot_table, game_rot, timestamp = init_baselines()
196
- t_stamp = f"Updated through: " + str(timestamp) + f" CST"
197
- basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
198
- basic_season_cols = ['Pos', 'Team', 'Min']
199
- data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
200
- 'FG3A', 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
201
- 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
202
- 'FPPM', 'Rebound%', 'Assists/Pass', 'Touch_per_min', 'Fantasy/Touch', 'FD Fantasy/Touch']
203
- season_data_cols = ['Touches', 'Touch/Min', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M', 'FG3A',
204
- 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
205
- 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
206
- 'FPPM', 'Rebound%', 'Assists/Pass', 'Fantasy/Touch', 'FD Fantasy/Touch']
207
- game_rot_cols = ['PLAYER_NAME', 'backlog_lookup', 'spread', 'MIN', 'PTS', 'FGM', 'FGA', 'FG3M', 'FG3A', 'FTM', 'FTA', 'REB', 'AST', 'STL', 'BLK', 'TOV', 'PF',
208
- 'Fantasy', 'FD_Fantasy']
209
- indv_teams = gamelog_table.drop_duplicates(subset='Team')
210
- total_teams = indv_teams.Team.values.tolist()
211
- indv_rot_teams = rot_table.drop_duplicates(subset='Team')
212
- total_rot_teams = indv_rot_teams.Team.values.tolist()
213
- indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
214
- total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
215
- indv_players = gamelog_table.drop_duplicates(subset='Player')
216
- total_players = indv_players.Player.values.tolist()
217
- total_dates = gamelog_table.Date.values.tolist()
218
 
219
- tab1, tab2, tab3, tab4, tab5 = st.tabs(['Gamelogs', 'Correlation Matrix', 'Position vs. Opp', 'Positional Percentages', 'Game Rotations'])
220
 
221
- with tab1:
222
- st.info(t_stamp)
 
 
 
 
 
 
 
 
 
223
  col1, col2 = st.columns([1, 9])
224
  with col1:
225
  if st.button("Reset Data", key='reset1'):
226
  st.cache_data.clear()
227
- gamelog_table, rot_table, game_rot, timestamp = init_baselines()
228
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
229
  basic_season_cols = ['Pos', 'Team', 'Min']
230
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
@@ -239,8 +332,6 @@ with tab1:
239
  'Fantasy', 'FD_Fantasy']
240
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
241
  total_teams = indv_teams.Team.values.tolist()
242
- indv_rot_teams = rot_table.drop_duplicates(subset='Team')
243
- total_rot_teams = indv_rot_teams.Team.values.tolist()
244
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
245
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
246
  indv_players = gamelog_table.drop_duplicates(subset='Player')
@@ -347,13 +438,12 @@ with tab1:
347
  mime='text/csv',
348
  )
349
 
350
- with tab2:
351
- st.info(t_stamp)
352
  col1, col2 = st.columns([1, 9])
353
  with col1:
354
  if st.button("Reset Data", key='reset2'):
355
  st.cache_data.clear()
356
- gamelog_table, rot_table, game_rot, timestamp = init_baselines()
357
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
358
  basic_season_cols = ['Pos', 'Team', 'Min']
359
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
@@ -368,8 +458,6 @@ with tab2:
368
  'Fantasy', 'FD_Fantasy']
369
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
370
  total_teams = indv_teams.Team.values.tolist()
371
- indv_rot_teams = rot_table.drop_duplicates(subset='Team')
372
- total_rot_teams = indv_rot_teams.Team.values.tolist()
373
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
374
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
375
  indv_players = gamelog_table.drop_duplicates(subset='Player')
@@ -442,13 +530,12 @@ with tab2:
442
  mime='text/csv',
443
  )
444
 
445
- with tab3:
446
- st.info(t_stamp)
447
  col1, col2 = st.columns([1, 9])
448
  with col1:
449
  if st.button("Reset Data", key='reset3'):
450
  st.cache_data.clear()
451
- gamelog_table, rot_table, game_rot, timestamp = init_baselines()
452
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
453
  basic_season_cols = ['Pos', 'Team', 'Min']
454
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
@@ -463,8 +550,6 @@ with tab3:
463
  'Fantasy', 'FD_Fantasy']
464
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
465
  total_teams = indv_teams.Team.values.tolist()
466
- indv_rot_teams = rot_table.drop_duplicates(subset='Team')
467
- total_rot_teams = indv_rot_teams.Team.values.tolist()
468
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
469
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
470
  indv_players = gamelog_table.drop_duplicates(subset='Player')
@@ -529,64 +614,12 @@ with tab3:
529
  mime='text/csv',
530
  )
531
 
532
- with tab4:
533
- st.info(t_stamp)
534
- col1, col2 = st.columns([1, 9])
535
- with col1:
536
- if st.button("Reset Data", key='reset4'):
537
- st.cache_data.clear()
538
- gamelog_table, rot_table, game_rot, timestamp = init_baselines()
539
- basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
540
- basic_season_cols = ['Pos', 'Team', 'Min']
541
- data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
542
- 'FG3A', 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
543
- 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
544
- 'FPPM', 'Rebound%', 'Assists/Pass', 'Touch_per_min', 'Fantasy/Touch', 'FD Fantasy/Touch']
545
- season_data_cols = ['Touches', 'Touch/Min', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M', 'FG3A',
546
- 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
547
- 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
548
- 'FPPM', 'Rebound%', 'Assists/Pass', 'Fantasy/Touch', 'FD Fantasy/Touch']
549
- game_rot_cols = ['PLAYER_NAME', 'backlog_lookup', 'spread', 'MIN', 'PTS', 'FGM', 'FGA', 'FG3M', 'FG3A', 'FTM', 'FTA', 'REB', 'AST', 'STL', 'BLK', 'TOV', 'PF',
550
- 'Fantasy', 'FD_Fantasy']
551
- indv_teams = gamelog_table.drop_duplicates(subset='Team')
552
- total_teams = indv_teams.Team.values.tolist()
553
- indv_rot_teams = rot_table.drop_duplicates(subset='Team')
554
- total_rot_teams = indv_rot_teams.Team.values.tolist()
555
- indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
556
- total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
557
- indv_players = gamelog_table.drop_duplicates(subset='Player')
558
- total_players = indv_players.Player.values.tolist()
559
- total_dates = gamelog_table.Date.values.tolist()
560
-
561
- split_var5 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var5')
562
-
563
- if split_var5 == 'Specific Teams':
564
- team_var4 = st.multiselect('Which teams would you like to view?', options = total_rot_teams, key='team_var4')
565
- elif split_var5 == 'All':
566
- team_var4 = total_rot_teams
567
-
568
-
569
- with col2:
570
- working_data = rot_table
571
- rot_display = working_data[working_data['Team'].isin(team_var4)]
572
- display = st.container()
573
-
574
- # rot_display = rot_display.set_index('Player')
575
- display.dataframe(rot_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), height=500, use_container_width=True)
576
- st.download_button(
577
- label="Export Rotations Model",
578
- data=convert_df_to_csv(rot_display),
579
- file_name='Rotations_NBA_View.csv',
580
- mime='text/csv',
581
- )
582
-
583
- with tab5:
584
- st.info(t_stamp)
585
  col1, col2 = st.columns([1, 9])
586
  with col1:
587
  if st.button("Reset Data", key='reset5'):
588
  st.cache_data.clear()
589
- gamelog_table, rot_table, game_rot, timestamp = init_baselines()
590
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
591
  basic_season_cols = ['Pos', 'Team', 'Min']
592
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
@@ -601,8 +634,6 @@ with tab5:
601
  'Fantasy', 'FD_Fantasy']
602
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
603
  total_teams = indv_teams.Team.values.tolist()
604
- indv_rot_teams = rot_table.drop_duplicates(subset='Team')
605
- total_rot_teams = indv_rot_teams.Team.values.tolist()
606
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
607
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
608
  indv_players = gamelog_table.drop_duplicates(subset='Player')
 
13
  import plotly.io as pio
14
  import certifi
15
  ca = certifi.where()
16
+ from database import db
17
 
18
  NBA_Data = 'https://docs.google.com/spreadsheets/d/1Yq0vGriWK-bS79e-bD6_u9pqrYE6Yrlbb_wEkmH-ot0/edit#gid=1808117109'
19
 
20
  percentages_format = {'PG': '{:.2%}', 'SG': '{:.2%}', 'SF': '{:.2%}', 'PF': '{:.2%}', 'C': '{:.2%}'}
21
 
22
+ st.markdown("""
23
+ <style>
24
+ /* Tab styling */
25
+ .stElementContainer [data-baseweb="button-group"] {
26
+ gap: 2.000rem;
27
+ padding: 4px;
28
+ }
29
+ .stElementContainer [kind="segmented_control"] {
30
+ height: 2.000rem;
31
+ white-space: pre-wrap;
32
+ background-color: #DAA520;
33
+ color: white;
34
+ border-radius: 20px;
35
+ gap: 1px;
36
+ padding: 10px 20px;
37
+ font-weight: bold;
38
+ transition: all 0.3s ease;
39
+ }
40
+ .stElementContainer [kind="segmented_controlActive"] {
41
+ height: 3.000rem;
42
+ background-color: #DAA520;
43
+ border: 3px solid #FFD700;
44
+ border-radius: 10px;
45
+ color: black;
46
+ }
47
+ .stElementContainer [kind="segmented_control"]:hover {
48
+ background-color: #FFD700;
49
+ cursor: pointer;
50
+ }
51
+
52
+ div[data-baseweb="select"] > div {
53
+ background-color: #DAA520;
54
+ color: white;
55
+ }
56
+
57
+ </style>""", unsafe_allow_html=True)
58
+
59
  @st.cache_resource(ttl = 599)
60
+ def init_baselines(data_req: str):
61
+ if data_req == 'gamelogs':
62
+ collection = db["gamelog"]
63
+ cursor = collection.find() # Finds all documents in the collection
64
+
65
+ raw_display = pd.DataFrame(list(cursor))
66
+ gamelog_table = raw_display[raw_display['PLAYER_NAME'] != ""]
67
+ gamelog_table = gamelog_table[['PLAYER_NAME', 'POS', 'GAME_ID', 'TEAM_NAME', 'OPP_NAME', 'SEASON_ID', 'GAME_DATE', 'MATCHUP', 'MIN', 'touches', 'PTS', 'FGM', 'FGA', 'FG_PCT', 'FG3M', 'FG3A',
68
+ 'FG3_PCT', 'FTM', 'FTA', 'FT_PCT', 'reboundChancesOffensive', 'OREB', 'reboundChancesDefensive', 'DREB', 'reboundChancesTotal', 'REB',
69
+ 'passes', 'secondaryAssists', 'freeThrowAssists', 'assists', 'STL', 'BLK', 'TOV', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy', 'FPPM']]
70
+ gamelog_table['assists'].replace("", 0, inplace=True)
71
+ gamelog_table['reboundChancesTotal'].replace("", 0, inplace=True)
72
+ gamelog_table['passes'].replace("", 0, inplace=True)
73
+ gamelog_table['touches'].replace("", 0, inplace=True)
74
+ gamelog_table['MIN'].replace("", 0, inplace=True)
75
+ gamelog_table['Fantasy'].replace("", 0, inplace=True)
76
+ gamelog_table['FD_Fantasy'].replace("", 0, inplace=True)
77
+ gamelog_table['FPPM'].replace("", 0, inplace=True)
78
+ gamelog_table['REB'] = gamelog_table['REB'].astype(int)
79
+ gamelog_table['assists'] = gamelog_table['assists'].astype(int)
80
+ gamelog_table['reboundChancesTotal'] = gamelog_table['reboundChancesTotal'].astype(int)
81
+ gamelog_table['passes'] = gamelog_table['passes'].astype(int)
82
+ gamelog_table['touches'] = gamelog_table['touches'].astype(int)
83
+ gamelog_table['MIN'] = gamelog_table['MIN'].astype(int)
84
+ gamelog_table['Fantasy'] = gamelog_table['Fantasy'].astype(float)
85
+ gamelog_table['FD_Fantasy'] = gamelog_table['FD_Fantasy'].astype(float)
86
+ gamelog_table['FPPM'] = gamelog_table['FPPM'].astype(float)
87
+ gamelog_table['rebound%'] = gamelog_table['REB'] / gamelog_table['reboundChancesTotal']
88
+ gamelog_table['assists_per_pass'] = gamelog_table['assists'] / gamelog_table['passes']
89
+ gamelog_table['Touch_per_min'] = gamelog_table['touches'] / gamelog_table['MIN']
90
+ gamelog_table['Fantasy_per_touch'] = gamelog_table['Fantasy'] / gamelog_table['touches']
91
+ gamelog_table['FD_Fantasy_per_touch'] = gamelog_table['FD_Fantasy'] / gamelog_table['touches']
92
+ data_cols = gamelog_table.columns.drop(['PLAYER_NAME', 'POS', 'TEAM_NAME', 'OPP_NAME', 'SEASON_ID', 'GAME_DATE', 'MATCHUP'])
93
+ gamelog_table[data_cols] = gamelog_table[data_cols].apply(pd.to_numeric, errors='coerce')
94
+ gamelog_table['team_score'] = gamelog_table.groupby(['TEAM_NAME', 'GAME_ID'], sort=False)['PTS'].transform('sum')
95
+ gamelog_table['opp_score'] = gamelog_table.groupby(['GAME_ID'], sort=False)['PTS'].transform('sum') - gamelog_table['team_score']
96
+ gamelog_table['spread'] = (gamelog_table['opp_score'] - gamelog_table['team_score']).abs()
97
+ gamelog_table['GAME_DATE'] = pd.to_datetime(gamelog_table['GAME_DATE']).dt.date
98
+
99
+ spread_dict = dict(zip(gamelog_table['GAME_ID'], gamelog_table['spread']))
100
+
101
+ gamelog_table = gamelog_table.set_axis(['Player', 'Pos', 'game_id', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
102
+ 'FG3A', 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
103
+ 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy', 'FPPM',
104
+ 'Rebound%', 'Assists/Pass', 'Touch_per_min', 'Fantasy/Touch', 'FD Fantasy/Touch', 'team_score', 'opp_score', 'spread'], axis=1)
105
+ game_rot = None
106
+ timestamp = gamelog_table['Date'].max()
107
+ elif data_req == 'game_rotations':
108
+ collection = db["rotations"]
109
+ cursor = collection.find() # Finds all documents in the collection
110
+
111
+ raw_display = pd.DataFrame(list(cursor))
112
+ game_rot = raw_display[raw_display['PLAYER_NAME'] != ""]
113
+ data_cols = game_rot.columns.drop(['PLAYER_NAME', 'POS', 'TEAM_ABBREVIATION', 'OPP_ABBREVIATION', 'TEAM_NAME', 'OPP_NAME', 'GAME_DATE',
114
+ 'MATCHUP', 'WL', 'backlog_lookup', 'Task', 'game_players'])
115
+ game_rot[data_cols] = game_rot[data_cols].apply(pd.to_numeric, errors='coerce')
116
+ game_rot['spread'] = game_rot['GAME_ID'].map(spread_dict)
117
+ game_rot['GAME_DATE'] = pd.to_datetime(game_rot['GAME_DATE']).dt.date
118
+
119
+ gamelog_table = None
120
+ timestamp = None
121
+ elif data_req == 'all':
122
+ collection = db["gamelog"]
123
+ cursor = collection.find() # Finds all documents in the collection
124
+
125
+ raw_display = pd.DataFrame(list(cursor))
126
+ gamelog_table = raw_display[raw_display['PLAYER_NAME'] != ""]
127
+ gamelog_table = gamelog_table[['PLAYER_NAME', 'POS', 'GAME_ID', 'TEAM_NAME', 'OPP_NAME', 'SEASON_ID', 'GAME_DATE', 'MATCHUP', 'MIN', 'touches', 'PTS', 'FGM', 'FGA', 'FG_PCT', 'FG3M', 'FG3A',
128
+ 'FG3_PCT', 'FTM', 'FTA', 'FT_PCT', 'reboundChancesOffensive', 'OREB', 'reboundChancesDefensive', 'DREB', 'reboundChancesTotal', 'REB',
129
+ 'passes', 'secondaryAssists', 'freeThrowAssists', 'assists', 'STL', 'BLK', 'TOV', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy', 'FPPM']]
130
+ gamelog_table['assists'].replace("", 0, inplace=True)
131
+ gamelog_table['reboundChancesTotal'].replace("", 0, inplace=True)
132
+ gamelog_table['passes'].replace("", 0, inplace=True)
133
+ gamelog_table['touches'].replace("", 0, inplace=True)
134
+ gamelog_table['MIN'].replace("", 0, inplace=True)
135
+ gamelog_table['Fantasy'].replace("", 0, inplace=True)
136
+ gamelog_table['FD_Fantasy'].replace("", 0, inplace=True)
137
+ gamelog_table['FPPM'].replace("", 0, inplace=True)
138
+ gamelog_table['REB'] = gamelog_table['REB'].astype(int)
139
+ gamelog_table['assists'] = gamelog_table['assists'].astype(int)
140
+ gamelog_table['reboundChancesTotal'] = gamelog_table['reboundChancesTotal'].astype(int)
141
+ gamelog_table['passes'] = gamelog_table['passes'].astype(int)
142
+ gamelog_table['touches'] = gamelog_table['touches'].astype(int)
143
+ gamelog_table['MIN'] = gamelog_table['MIN'].astype(int)
144
+ gamelog_table['Fantasy'] = gamelog_table['Fantasy'].astype(float)
145
+ gamelog_table['FD_Fantasy'] = gamelog_table['FD_Fantasy'].astype(float)
146
+ gamelog_table['FPPM'] = gamelog_table['FPPM'].astype(float)
147
+ gamelog_table['rebound%'] = gamelog_table['REB'] / gamelog_table['reboundChancesTotal']
148
+ gamelog_table['assists_per_pass'] = gamelog_table['assists'] / gamelog_table['passes']
149
+ gamelog_table['Touch_per_min'] = gamelog_table['touches'] / gamelog_table['MIN']
150
+ gamelog_table['Fantasy_per_touch'] = gamelog_table['Fantasy'] / gamelog_table['touches']
151
+ gamelog_table['FD_Fantasy_per_touch'] = gamelog_table['FD_Fantasy'] / gamelog_table['touches']
152
+ data_cols = gamelog_table.columns.drop(['PLAYER_NAME', 'POS', 'TEAM_NAME', 'OPP_NAME', 'SEASON_ID', 'GAME_DATE', 'MATCHUP'])
153
+ gamelog_table[data_cols] = gamelog_table[data_cols].apply(pd.to_numeric, errors='coerce')
154
+ gamelog_table['team_score'] = gamelog_table.groupby(['TEAM_NAME', 'GAME_ID'], sort=False)['PTS'].transform('sum')
155
+ gamelog_table['opp_score'] = gamelog_table.groupby(['GAME_ID'], sort=False)['PTS'].transform('sum') - gamelog_table['team_score']
156
+ gamelog_table['spread'] = (gamelog_table['opp_score'] - gamelog_table['team_score']).abs()
157
+ gamelog_table['GAME_DATE'] = pd.to_datetime(gamelog_table['GAME_DATE']).dt.date
158
+
159
+ spread_dict = dict(zip(gamelog_table['GAME_ID'], gamelog_table['spread']))
160
+
161
+ gamelog_table = gamelog_table.set_axis(['Player', 'Pos', 'game_id', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
162
+ 'FG3A', 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
163
+ 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy', 'FPPM',
164
+ 'Rebound%', 'Assists/Pass', 'Touch_per_min', 'Fantasy/Touch', 'FD Fantasy/Touch', 'team_score', 'opp_score', 'spread'], axis=1)
165
+
166
+ timestamp = gamelog_table['Date'].max()
167
+
168
+ collection = db["rotations"]
169
+ cursor = collection.find() # Finds all documents in the collection
170
+
171
+ raw_display = pd.DataFrame(list(cursor))
172
+ game_rot = raw_display[raw_display['PLAYER_NAME'] != ""]
173
+ data_cols = game_rot.columns.drop(['PLAYER_NAME', 'POS', 'TEAM_ABBREVIATION', 'OPP_ABBREVIATION', 'TEAM_NAME', 'OPP_NAME', 'GAME_DATE',
174
+ 'MATCHUP', 'WL', 'backlog_lookup', 'Task', 'game_players'])
175
+ game_rot[data_cols] = game_rot[data_cols].apply(pd.to_numeric, errors='coerce')
176
+ game_rot['spread'] = game_rot['GAME_ID'].map(spread_dict)
177
+ game_rot['GAME_DATE'] = pd.to_datetime(game_rot['GAME_DATE']).dt.date
178
 
179
+ return gamelog_table, game_rot, timestamp
180
 
181
  @st.cache_data(show_spinner=False)
182
  def seasonlong_build(data_sample):
 
278
  def convert_df_to_csv(df):
279
  return df.to_csv().encode('utf-8')
280
 
281
+ # gamelog_table, game_rot, timestamp = init_baselines('all')
282
+ # t_stamp = f"Updated through: " + str(timestamp) + f" CST"
283
+ # basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
284
+ # basic_season_cols = ['Pos', 'Team', 'Min']
285
+ # data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
286
+ # 'FG3A', 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
287
+ # 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
288
+ # 'FPPM', 'Rebound%', 'Assists/Pass', 'Touch_per_min', 'Fantasy/Touch', 'FD Fantasy/Touch']
289
+ # season_data_cols = ['Touches', 'Touch/Min', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M', 'FG3A',
290
+ # 'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
291
+ # 'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
292
+ # 'FPPM', 'Rebound%', 'Assists/Pass', 'Fantasy/Touch', 'FD Fantasy/Touch']
293
+ # game_rot_cols = ['PLAYER_NAME', 'backlog_lookup', 'spread', 'MIN', 'PTS', 'FGM', 'FGA', 'FG3M', 'FG3A', 'FTM', 'FTA', 'REB', 'AST', 'STL', 'BLK', 'TOV', 'PF',
294
+ # 'Fantasy', 'FD_Fantasy']
295
+ # indv_teams = gamelog_table.drop_duplicates(subset='Team')
296
+ # total_teams = indv_teams.Team.values.tolist()
297
+ # indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
298
+ # total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
299
+ # indv_players = gamelog_table.drop_duplicates(subset='Player')
300
+ # total_players = indv_players.Player.values.tolist()
301
+ # total_dates = gamelog_table.Date.values.tolist()
 
 
302
 
303
+ # tab1, tab2, tab3, tab4, tab5 = st.tabs(['Gamelogs', 'Correlation Matrix', 'Position vs. Opp', 'Positional Percentages', 'Game Rotations'])
304
 
305
+ selected_tab = st.segmented_control(
306
+ "Select Tab",
307
+ options=['Gamelogs', 'Correlation Matrix', 'Position vs. Opp', 'Game Rotations'],
308
+ selection_mode='single',
309
+ default='Gamelogs',
310
+ width='stretch',
311
+ label_visibility='collapsed',
312
+ key='tab_selector'
313
+ )
314
+
315
+ with selected_tab == 'Gamelogs':
316
  col1, col2 = st.columns([1, 9])
317
  with col1:
318
  if st.button("Reset Data", key='reset1'):
319
  st.cache_data.clear()
320
+ gamelog_table, game_rot, timestamp = init_baselines('gamelogs')
321
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
322
  basic_season_cols = ['Pos', 'Team', 'Min']
323
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
 
332
  'Fantasy', 'FD_Fantasy']
333
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
334
  total_teams = indv_teams.Team.values.tolist()
 
 
335
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
336
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
337
  indv_players = gamelog_table.drop_duplicates(subset='Player')
 
438
  mime='text/csv',
439
  )
440
 
441
+ with selected_tab == 'Correlation Matrix':
 
442
  col1, col2 = st.columns([1, 9])
443
  with col1:
444
  if st.button("Reset Data", key='reset2'):
445
  st.cache_data.clear()
446
+ gamelog_table, game_rot, timestamp = init_baselines('gamelogs')
447
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
448
  basic_season_cols = ['Pos', 'Team', 'Min']
449
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
 
458
  'Fantasy', 'FD_Fantasy']
459
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
460
  total_teams = indv_teams.Team.values.tolist()
 
 
461
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
462
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
463
  indv_players = gamelog_table.drop_duplicates(subset='Player')
 
530
  mime='text/csv',
531
  )
532
 
533
+ with selected_tab == 'Position vs. Opp':
 
534
  col1, col2 = st.columns([1, 9])
535
  with col1:
536
  if st.button("Reset Data", key='reset3'):
537
  st.cache_data.clear()
538
+ gamelog_table, game_rot, timestamp = init_baselines('gamelogs')
539
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
540
  basic_season_cols = ['Pos', 'Team', 'Min']
541
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
 
550
  'Fantasy', 'FD_Fantasy']
551
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
552
  total_teams = indv_teams.Team.values.tolist()
 
 
553
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
554
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
555
  indv_players = gamelog_table.drop_duplicates(subset='Player')
 
614
  mime='text/csv',
615
  )
616
 
617
+ with selected_tab == 'Game Rotations':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
618
  col1, col2 = st.columns([1, 9])
619
  with col1:
620
  if st.button("Reset Data", key='reset5'):
621
  st.cache_data.clear()
622
+ gamelog_table, game_rot, timestamp = init_baselines('game_rotations')
623
  basic_cols = ['Player', 'Pos', 'Team', 'Opp', 'Season', 'Date', 'Matchup', 'Min']
624
  basic_season_cols = ['Pos', 'Team', 'Min']
625
  data_cols = ['team_score', 'opp_score', 'spread', 'Touches', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
 
634
  'Fantasy', 'FD_Fantasy']
635
  indv_teams = gamelog_table.drop_duplicates(subset='Team')
636
  total_teams = indv_teams.Team.values.tolist()
 
 
637
  indv_game_rot_teams = game_rot.drop_duplicates(subset='TEAM_ABBREVIATION')
638
  total_game_rot_teams = indv_game_rot_teams.TEAM_ABBREVIATION.values.tolist()
639
  indv_players = gamelog_table.drop_duplicates(subset='Player')