James McCool commited on
Commit
efc18fb
·
1 Parent(s): f6bf4e8

Refactor app.py to replace Google Sheets integration with MongoDB for data retrieval. Updated data loading functions to support NBA and NFL datasets, adjusted caching mechanisms, and streamlined user interface for sport selection. Removed deprecated code related to Google Sheets and improved data handling for player projections.

Browse files
Files changed (1) hide show
  1. app.py +156 -161
app.py CHANGED
@@ -2,34 +2,22 @@ import pulp
2
  import numpy as np
3
  import pandas as pd
4
  import streamlit as st
5
- import gspread
6
  from itertools import combinations
7
  import time
8
 
9
  @st.cache_resource
10
  def init_conn():
11
- scope = ['https://www.googleapis.com/auth/spreadsheets',
12
- "https://www.googleapis.com/auth/drive"]
13
-
14
- credentials = {
15
- "type": "service_account",
16
- "project_id": st.secrets["sheets_api_connect_pk"],
17
- "private_key_id": "1005124050c80d085e2c5b344345715978dd9cc9",
18
- "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtKa01beXwc88R\nnPZVQTNPVQuBnbwoOfc66gW3547ja/UEyIGAF112dt/VqHprRafkKGmlg55jqJNt\na4zceLKV+wTm7vBu7lDISTJfGzCf2TrxQYNqwMKE2LOjI69dBM8u4Dcb4k0wcp9v\ntW1ZzLVVuwTvmrg7JBHjiSaB+x5wxm/r3FOiJDXdlAgFlytzqgcyeZMJVKKBQHyJ\njEGg/1720A0numuOCt71w/2G0bDmijuj1e6tH32MwRWcvRNZ19K9ssyDz2S9p68s\nYDhIxX69OWxwScTIHLY6J2t8txf/XMivL/636fPlDADvBEVTdlT606n8CcKUVQeq\npUVdG+lfAgMBAAECggEAP38SUA7B69eTfRpo658ycOs3Amr0JW4H/bb1rNeAul0K\nZhwd/HnU4E07y81xQmey5kN5ZeNrD5EvqkZvSyMJHV0EEahZStwhjCfnDB/cxyix\nZ+kFhv4y9eK+kFpUAhBy5nX6T0O+2T6WvzAwbmbVsZ+X8kJyPuF9m8ldcPlD0sce\ntj8NwVq1ys52eosqs7zi2vjt+eMcaY393l4ls+vNq8Yf27cfyFw45W45CH/97/Nu\n5AmuzlCOAfFF+z4OC5g4rei4E/Qgpxa7/uom+BVfv9G0DIGW/tU6Sne0+37uoGKt\nW6DzhgtebUtoYkG7ZJ05BTXGp2lwgVcNRoPwnKJDxQKBgQDT5wYPUBDW+FHbvZSp\nd1m1UQuXyerqOTA9smFaM8sr/UraeH85DJPEIEk8qsntMBVMhvD3Pw8uIUeFNMYj\naLmZFObsL+WctepXrVo5NB6RtLB/jZYxiKMatMLUJIYtcKIp+2z/YtKiWcLnwotB\nWdCjVnPTxpkurmF2fWP/eewZ+wKBgQDRMtJg7etjvKyjYNQ5fARnCc+XsI3gkBe1\nX9oeXfhyfZFeBXWnZzN1ITgFHplDznmBdxAyYGiQdbbkdKQSghviUQ0igBvoDMYy\n1rWcy+a17Mj98uyNEfmb3X2cC6WpvOZaGHwg9+GY67BThwI3FqHIbyk6Ko09WlTX\nQpRQjMzU7QKBgAfi1iflu+q0LR+3a3vvFCiaToskmZiD7latd9AKk2ocsBd3Woy9\n+hXXecJHPOKV4oUJlJgvAZqe5HGBqEoTEK0wyPNLSQlO/9ypd+0fEnArwFHO7CMF\nycQprAKHJXM1eOOFFuZeQCaInqdPZy1UcV5Szla4UmUZWkk1m24blHzXAoGBAMcA\nyH4qdbxX9AYrC1dvsSRvgcnzytMvX05LU0uF6tzGtG0zVlub4ahvpEHCfNuy44UT\nxRWW/oFFaWjjyFxO5sWggpUqNuHEnRopg3QXx22SRRTGbN45li/+QAocTkgsiRh1\nqEcYZsO4mPCsQqAy6E2p6RcK+Xa+omxvSnVhq0x1AoGAKr8GdkCl4CF6rieLMAQ7\nLNBuuoYGaHoh8l5E2uOQpzwxVy/nMBcAv+2+KqHEzHryUv1owOi6pMLv7A9mTFoS\n18B0QRLuz5fSOsVnmldfC9fpUc6H8cH1SINZpzajqQA74bPwELJjnzrCnH79TnHG\nJuElxA33rFEjbgbzdyrE768=\n-----END PRIVATE KEY-----\n",
19
- "client_email": "gspread-connection@sheets-api-connect-378620.iam.gserviceaccount.com",
20
- "client_id": "106625872877651920064",
21
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
22
- "token_uri": "https://oauth2.googleapis.com/token",
23
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
24
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40sheets-api-connect-378620.iam.gserviceaccount.com"
25
- }
26
 
27
- gc = gspread.service_account_from_dict(credentials)
28
- return gc
29
 
30
  st.set_page_config(layout="wide")
31
 
32
- gc = init_conn()
33
 
34
  wrong_acro = ['WSH', 'AZ']
35
  right_acro = ['WAS', 'ARI']
@@ -47,91 +35,102 @@ expose_format = {'Proj Own': '{:.2%}','Exposure': '{:.2%}'}
47
 
48
  all_dk_player_projections = st.secrets["NFL_data"]
49
 
50
- @st.cache_resource(ttl=300)
51
  def init_baselines():
52
- sh = gc.open_by_url(all_dk_player_projections)
53
- worksheet = sh.worksheet('DK_SD_ROO')
54
- load_display = pd.DataFrame(worksheet.get_all_records())
55
- load_display.replace('', np.nan, inplace=True)
56
- load_display['Salary'] = load_display['Salary'] / 1.5
57
- dk_roo_raw = load_display.loc[load_display['Median'] > 0]
 
 
 
 
 
58
 
59
- dk_ids = dict(zip(dk_roo_raw['Player'], dk_roo_raw['player_id']))
 
60
 
61
- worksheet = sh.worksheet('FD_SD_ROO')
62
- load_display = pd.DataFrame(worksheet.get_all_records())
63
- load_display.replace('', np.nan, inplace=True)
64
- fd_roo_raw = load_display.loc[load_display['Median'] > 0]
 
 
65
 
66
- fd_ids = dict(zip(fd_roo_raw['Player'], fd_roo_raw['player_id']))
 
 
 
 
 
 
 
 
67
 
68
- return dk_roo_raw, fd_roo_raw, dk_ids, fd_ids
 
 
 
 
 
 
 
 
69
 
70
- dk_roo_raw, fd_roo_raw, dkid_dict, fdid_dict = init_baselines()
71
 
72
  @st.cache_data
73
  def convert_df_to_csv(df):
74
  return df.to_csv().encode('utf-8')
75
 
76
- tab1, tab2, tab3 = st.tabs(['Range of Outcomes', 'Optimizer', 'Uploads and Info'])
77
-
78
- with tab3:
79
- st.info("The Projections file can have any columns in any order, but must contain columns explicitly named: 'Player', 'Salary', 'Position', 'Team', 'Opp', 'rush_yards', 'rec', 'Median', and 'Own'. For the purposes of this showdown optimizer, only include FLEX positions, salaries, and medians. The optimizer logic will handle the rest!")
80
- col1, col2 = st.columns([1, 5])
81
-
82
- with col1:
83
- proj_file = st.file_uploader("Upload Projections File", key = 'proj_uploader')
84
-
85
- if proj_file is not None:
86
- try:
87
- proj_dataframe = pd.read_csv(proj_file)
88
- proj_dataframe = proj_dataframe.loc[proj_dataframe['Median'] > 0]
89
- try:
90
- proj_dataframe['Own'] = proj_dataframe['Own'].str.replace('%', '').astype(float)
91
- except:
92
- pass
93
- except:
94
- proj_dataframe = pd.read_excel(proj_file)
95
- proj_dataframe = proj_dataframe.loc[proj_dataframe['Median'] > 0]
96
- try:
97
- proj_dataframe['Own'] = proj_dataframe['Own'].str.replace('%', '').astype(float)
98
- except:
99
- pass
100
- with col2:
101
- if proj_file is not None:
102
- st.dataframe(proj_dataframe.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
103
 
104
  with tab1:
105
  col1, col2 = st.columns([1, 5])
106
  with col1:
107
  if st.button("Load/Reset Data", key='reset2'):
108
  st.cache_data.clear()
109
- dk_roo_raw, fd_roo_raw, dkid_dict, fdid_dict = init_baselines()
110
- slate_var2 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'User'), key='slate_var2')
 
 
 
 
 
 
 
111
  site_var2 = st.radio("What table would you like to display?", ('Draftkings', 'Fanduel'), key='site_var2')
112
- if slate_var2 == 'User':
113
- raw_baselines = proj_dataframe
114
- elif slate_var2 != 'User':
115
- if site_var2 == 'Draftkings':
116
- if slate_var2 == 'Paydirt (Main)':
117
- raw_baselines = dk_roo_raw
118
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
119
- elif slate_var2 == 'Paydirt (Secondary)':
120
- raw_baselines = dk_roo_raw
121
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
122
-
123
- elif site_var2 == 'Fanduel':
124
- if slate_var2 == 'Paydirt (Main)':
125
- raw_baselines = fd_roo_raw
126
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
127
- elif slate_var2 == 'Paydirt (Secondary)':
128
- raw_baselines = fd_roo_raw
129
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
 
 
 
130
 
131
  with col2:
132
  hold_container = st.empty()
133
 
134
- display_Proj = raw_baselines[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'CPT_Own', 'LevX']]
 
 
 
135
  display_Proj = display_Proj.set_index('Player')
136
  display_Proj = display_Proj.sort_values(by='Median', ascending=False)
137
 
@@ -152,32 +151,41 @@ with tab2:
152
  with col1:
153
  if st.button("Load/Reset Data", key='reset1'):
154
  st.cache_data.clear()
155
- dk_roo_raw, fd_roo_raw, dkid_dict, fdid_dict = init_baselines()
156
  for key in st.session_state.keys():
157
  del st.session_state[key]
158
- slate_var1 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'User'), key='slate_var1')
 
 
 
 
 
 
 
159
  site_var1 = st.selectbox("What site is the showdown on?", ('Draftkings', 'Fanduel'), key='site_var1')
160
  if site_var1 == 'Draftkings':
161
- if slate_var1 == 'User':
162
- raw_baselines = proj_dataframe
163
- elif slate_var1 == 'Paydirt (Main)':
164
- raw_baselines = dk_roo_raw
165
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
166
- elif slate_var1 == 'Paydirt (Secondary)':
167
- raw_baselines = dk_roo_raw
168
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
 
169
  elif site_var1 == 'Fanduel':
170
- if slate_var1 == 'User':
171
- st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen")
172
- raw_baselines = proj_dataframe
173
- elif slate_var1 == 'Paydirt (Main)':
174
- st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen")
175
- raw_baselines = fd_roo_raw
176
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
177
- elif slate_var1 == 'Paydirt (Secondary)':
178
- st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen")
179
- raw_baselines = fd_roo_raw
180
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
 
181
 
182
  contest_var1 = st.selectbox("What contest type are you optimizing for?", ('Cash', 'Small Field GPP', 'Large Field GPP'), key='contest_var1')
183
  lock_var1 = st.multiselect("Are there any players you want to use in all lineups in the CAPTAIN (Lock Button)?", options = raw_baselines['Player'].unique(), key='lock_var1')
@@ -195,58 +203,30 @@ with tab2:
195
  elif site_var1 == 'Fanduel':
196
  min_sal1 = st.number_input('Min Salary', min_value = 45000, max_value = 59900, value = 59000, step = 100, key='min_sal1')
197
  max_sal1 = st.number_input('Max Salary', min_value = 45000, max_value = 60000, value = 60000, step = 100, key='max_sal1')
198
-
199
  if contest_var1 == 'Small Field GPP':
200
- if site_var1 == 'Draftkings':
201
- ownframe = raw_baselines.copy()
202
- ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own'])
203
- ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%'])
204
- ownframe['Own%'] = np.where(ownframe['Own%'] > 85, 85, ownframe['Own%'])
205
- ownframe['Own'] = ownframe['Own%'] * (600 / ownframe['Own%'].sum())
206
- cpt_div = 6
207
- elif site_var1 == 'Fanduel':
208
- ownframe = raw_baselines.copy()
209
- ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/50) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own'])
210
- ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/150) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%'])
211
- ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%'])
212
- ownframe['Own'] = ownframe['Own%'] * (500 / ownframe['Own%'].sum())
213
- cpt_div = 5
214
  elif contest_var1 == 'Large Field GPP':
215
- if site_var1 == 'Draftkings':
216
- ownframe = raw_baselines.copy()
217
- ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own'])
218
- ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%'])
219
- ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%'])
220
- ownframe['Own'] = ownframe['Own%'] * (600 / ownframe['Own%'].sum())
221
- cpt_div = 6
222
- elif site_var1 == 'Fanduel':
223
- ownframe = raw_baselines.copy()
224
- ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/50) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own'])
225
- ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/150) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%'])
226
- ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%'])
227
- ownframe['Own'] = ownframe['Own%'] * (500 / ownframe['Own%'].sum())
228
- cpt_div = 5
229
  elif contest_var1 == 'Cash':
230
- if site_var1 == 'Draftkings':
231
- ownframe = raw_baselines.copy()
232
- ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own'])
233
- ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%'])
234
- ownframe['Own%'] = np.where(ownframe['Own%'] > 90, 90, ownframe['Own%'])
235
- ownframe['Own'] = ownframe['Own%'] * (600 / ownframe['Own%'].sum())
236
- cpt_div = 6
237
- elif site_var1 == 'Fanduel':
238
- ownframe = raw_baselines.copy()
239
- ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/50) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own'])
240
- ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/150) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%'])
241
- ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%'])
242
- cpt_div = 5
243
- ownframe['Own'] = ownframe['Own%'] * (500 / ownframe['Own%'].sum())
244
- export_baselines = ownframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own']]
245
  export_baselines['CPT_Proj'] = export_baselines['Median'] * 1.5
246
  export_baselines['CPT_Salary'] = export_baselines['Salary'] * 1.5
247
- export_baselines['ID'] = export_baselines['Player'].map(dkid_dict)
248
- display_baselines = ownframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own']]
249
- display_baselines['CPT Own'] = display_baselines['Own'] / cpt_div
250
  display_baselines = display_baselines.sort_values(by='Median', ascending=False)
251
  display_baselines['cpt_lock'] = np.where(display_baselines['Player'].isin(lock_var1), 1, 0)
252
  display_baselines['lock'] = np.where(display_baselines['Player'].isin(lock_var2), 1, 0)
@@ -525,12 +505,20 @@ with tab2:
525
  final_outcomes_export['FLEX4'] = split_portfolio['FLEX4']
526
  final_outcomes_export['FLEX5'] = split_portfolio['FLEX5']
527
 
528
- final_outcomes_export['CPT'].replace(dkid_dict, inplace=True)
529
- final_outcomes_export['FLEX1'].replace(dkid_dict, inplace=True)
530
- final_outcomes_export['FLEX2'].replace(dkid_dict, inplace=True)
531
- final_outcomes_export['FLEX3'].replace(dkid_dict, inplace=True)
532
- final_outcomes_export['FLEX4'].replace(dkid_dict, inplace=True)
533
- final_outcomes_export['FLEX5'].replace(dkid_dict, inplace=True)
 
 
 
 
 
 
 
 
534
  final_outcomes_export['Salary'] = final_outcomes['Cost']
535
  final_outcomes_export['Own'] = final_outcomes['Own']
536
  final_outcomes_export['Proj'] = final_outcomes['Proj']
@@ -557,11 +545,18 @@ with tab2:
557
  final_outcomes_export['FLEX3'] = split_portfolio['FLEX3']
558
  final_outcomes_export['FLEX4'] = split_portfolio['FLEX4']
559
 
560
- final_outcomes_export['MVP'].replace(fdid_dict, inplace=True)
561
- final_outcomes_export['FLEX1'].replace(fdid_dict, inplace=True)
562
- final_outcomes_export['FLEX2'].replace(fdid_dict, inplace=True)
563
- final_outcomes_export['FLEX3'].replace(fdid_dict, inplace=True)
564
- final_outcomes_export['FLEX4'].replace(fdid_dict, inplace=True)
 
 
 
 
 
 
 
565
  final_outcomes_export['Salary'] = final_outcomes['Cost']
566
  final_outcomes_export['Own'] = final_outcomes['Own']
567
  final_outcomes_export['Proj'] = final_outcomes['Proj']
 
2
  import numpy as np
3
  import pandas as pd
4
  import streamlit as st
5
+ import pymongo
6
  from itertools import combinations
7
  import time
8
 
9
  @st.cache_resource
10
  def init_conn():
11
+ uri = st.secrets['mongo_uri']
12
+ client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)
13
+ nba_db = client["NBA_DFS"]
14
+ nfl_db = client["NFL_Database"]
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ return nba_db, nfl_db
 
17
 
18
  st.set_page_config(layout="wide")
19
 
20
+ nba_db, nfl_db = init_conn()
21
 
22
  wrong_acro = ['WSH', 'AZ']
23
  right_acro = ['WAS', 'ARI']
 
35
 
36
  all_dk_player_projections = st.secrets["NFL_data"]
37
 
38
+ @st.cache_resource(ttl=60)
39
  def init_baselines():
40
+ collection = nba_db["Player_SD_Range_Of_Outcomes"]
41
+ cursor = collection.find()
42
+
43
+ raw_display = pd.DataFrame(list(cursor))
44
+ raw_display = raw_display[['Player', 'Minutes Proj', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%',
45
+ 'Own', 'Small_Own', 'Large_Own', 'Cash_Own', 'CPT_Own', 'LevX', 'ValX', 'site', 'version', 'slate', 'timestamp']]
46
+ raw_display['player_id'] = raw_display['Player'] ##### Need to fix this later on
47
+ raw_display = raw_display.loc[raw_display['Median'] > 0]
48
+ raw_display = raw_display.sort_values(by='Median', ascending=False)
49
+ nba_dk_sd_raw = raw_display[raw_display['site'] == 'Draftkings']
50
+ nba_fd_sd_raw = raw_display[raw_display['site'] == 'Fanduel']
51
 
52
+ collection = nfl_db["DK_SD_NFL_ROO"]
53
+ cursor = collection.find()
54
 
55
+ raw_display = pd.DataFrame(list(cursor))
56
+ raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
57
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
58
+ raw_display = raw_display.loc[raw_display['Median'] > 0]
59
+ raw_display = raw_display.apply(pd.to_numeric, errors='ignore')
60
+ nfl_dk_sd_raw = raw_display.sort_values(by='Median', ascending=False)
61
 
62
+ collection = nfl_db["FD_SD_NFL_ROO"]
63
+ cursor = collection.find()
64
+
65
+ raw_display = pd.DataFrame(list(cursor))
66
+ raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
67
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
68
+ raw_display = raw_display.loc[raw_display['Median'] > 0]
69
+ raw_display = raw_display.apply(pd.to_numeric, errors='ignore')
70
+ nfl_fd_sd_raw = raw_display.sort_values(by='Median', ascending=False)
71
 
72
+ nba_timestamp = nba_dk_sd_raw['timestamp'].values[0]
73
+ nfl_dk_timestamp = nfl_dk_sd_raw['timestamp'].values[0]
74
+
75
+ nba_dk_id_dict = dict(zip(nba_dk_sd_raw['player_id'], nba_dk_sd_raw['player_id']))
76
+ nfl_dk_id_dict = dict(zip(nfl_dk_sd_raw['player_id'], nfl_dk_sd_raw['player_id']))
77
+ nba_fd_id_dict = dict(zip(nba_fd_sd_raw['player_id'], nba_fd_sd_raw['player_id']))
78
+ nfl_fd_id_dict = dict(zip(nfl_fd_sd_raw['player_id'], nfl_fd_sd_raw['player_id']))
79
+
80
+ return nba_dk_sd_raw, nba_fd_sd_raw, nfl_dk_sd_raw, nfl_fd_sd_raw, nba_timestamp, nfl_dk_timestamp, nba_dk_id_dict, nfl_dk_id_dict, nba_fd_id_dict, nfl_fd_id_dict
81
 
82
+ nba_dk_sd_raw, nba_fd_sd_raw, nfl_dk_sd_raw, nfl_fd_sd_raw, nba_timestamp, nfl_dk_timestamp, nba_dk_id_dict, nfl_dk_id_dict, nba_fd_id_dict, nfl_fd_id_dict = init_baselines()
83
 
84
  @st.cache_data
85
  def convert_df_to_csv(df):
86
  return df.to_csv().encode('utf-8')
87
 
88
+ tab1, tab2 = st.tabs(['Range of Outcomes', 'Optimizer'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  with tab1:
91
  col1, col2 = st.columns([1, 5])
92
  with col1:
93
  if st.button("Load/Reset Data", key='reset2'):
94
  st.cache_data.clear()
95
+ nba_dk_sd_raw, nba_fd_sd_raw, nfl_dk_sd_raw, nfl_fd_sd_raw, nba_timestamp, nfl_dk_timestamp, nba_dk_id_dict, nfl_dk_id_dict, nba_fd_id_dict, nfl_fd_id_dict = init_baselines()
96
+ sport_var2 = st.radio("What sport are you loading?", ('NBA', 'NFL'), key='sport_var2')
97
+ if sport_var2 == 'NBA':
98
+ dk_roo_raw = nba_dk_sd_raw
99
+ fd_roo_raw = nba_fd_sd_raw
100
+ elif sport_var2 == 'NFL':
101
+ dk_roo_raw = nfl_dk_sd_raw
102
+ fd_roo_raw = nfl_fd_sd_raw
103
+ slate_var2 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'Paydirt (Auxiliary)'), key='slate_var2')
104
  site_var2 = st.radio("What table would you like to display?", ('Draftkings', 'Fanduel'), key='site_var2')
105
+ if site_var2 == 'Draftkings':
106
+ if slate_var2 == 'Paydirt (Main)':
107
+ raw_baselines = dk_roo_raw
108
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
109
+ elif slate_var2 == 'Paydirt (Secondary)':
110
+ raw_baselines = dk_roo_raw
111
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
112
+ elif slate_var2 == 'Paydirt (Auxiliary)':
113
+ raw_baselines = dk_roo_raw
114
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #3']
115
+
116
+ elif site_var2 == 'Fanduel':
117
+ if slate_var2 == 'Paydirt (Main)':
118
+ raw_baselines = fd_roo_raw
119
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
120
+ elif slate_var2 == 'Paydirt (Secondary)':
121
+ raw_baselines = fd_roo_raw
122
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
123
+ elif slate_var2 == 'Paydirt (Auxiliary)':
124
+ raw_baselines = fd_roo_raw
125
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #3']
126
 
127
  with col2:
128
  hold_container = st.empty()
129
 
130
+ if sport_var2 == 'NBA':
131
+ display_Proj = raw_baselines[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own', 'Small_Own', 'Large_Own', 'Cash_Own', 'CPT_Own', 'LevX']]
132
+ elif sport_var2 == 'NFL':
133
+ display_Proj = raw_baselines[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX']]
134
  display_Proj = display_Proj.set_index('Player')
135
  display_Proj = display_Proj.sort_values(by='Median', ascending=False)
136
 
 
151
  with col1:
152
  if st.button("Load/Reset Data", key='reset1'):
153
  st.cache_data.clear()
154
+ nba_dk_sd_raw, nba_fd_sd_raw, nfl_dk_sd_raw, nfl_fd_sd_raw, nba_timestamp, nfl_dk_timestamp, nba_dk_id_dict, nfl_dk_id_dict, nba_fd_id_dict, nfl_fd_id_dict = init_baselines()
155
  for key in st.session_state.keys():
156
  del st.session_state[key]
157
+ sport_var1 = st.radio("What sport are you optimizing?", ('NBA', 'NFL'), key='sport_var1')
158
+ if sport_var1 == 'NBA':
159
+ dk_roo_raw = nba_dk_sd_raw
160
+ fd_roo_raw = nba_fd_sd_raw
161
+ elif sport_var1 == 'NFL':
162
+ dk_roo_raw = nfl_dk_sd_raw
163
+ fd_roo_raw = nfl_fd_sd_raw
164
+ slate_var1 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'Paydirt (Auxiliary)'), key='slate_var1')
165
  site_var1 = st.selectbox("What site is the showdown on?", ('Draftkings', 'Fanduel'), key='site_var1')
166
  if site_var1 == 'Draftkings':
167
+ if slate_var1 == 'Paydirt (Main)':
168
+ raw_baselines = dk_roo_raw
169
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
170
+ elif slate_var1 == 'Paydirt (Secondary)':
171
+ raw_baselines = dk_roo_raw
172
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
173
+ elif slate_var1 == 'Paydirt (Auxiliary)':
174
+ raw_baselines = dk_roo_raw
175
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #3']
176
  elif site_var1 == 'Fanduel':
177
+ if slate_var1 == 'Paydirt (Main)':
178
+ st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen")
179
+ raw_baselines = fd_roo_raw
180
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #1']
181
+ elif slate_var1 == 'Paydirt (Secondary)':
182
+ st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen")
183
+ raw_baselines = fd_roo_raw
184
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #2']
185
+ elif slate_var1 == 'Paydirt (Auxiliary)':
186
+ st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen")
187
+ raw_baselines = fd_roo_raw
188
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Showdown #3']
189
 
190
  contest_var1 = st.selectbox("What contest type are you optimizing for?", ('Cash', 'Small Field GPP', 'Large Field GPP'), key='contest_var1')
191
  lock_var1 = st.multiselect("Are there any players you want to use in all lineups in the CAPTAIN (Lock Button)?", options = raw_baselines['Player'].unique(), key='lock_var1')
 
203
  elif site_var1 == 'Fanduel':
204
  min_sal1 = st.number_input('Min Salary', min_value = 45000, max_value = 59900, value = 59000, step = 100, key='min_sal1')
205
  max_sal1 = st.number_input('Max Salary', min_value = 45000, max_value = 60000, value = 60000, step = 100, key='max_sal1')
206
+
207
  if contest_var1 == 'Small Field GPP':
208
+ ownframe = raw_baselines.copy()
209
+ if sport_var1 == 'NBA':
210
+ ownframe['Own'] = ownframe['Small_Own']
211
+ elif sport_var1 == 'NFL':
212
+ ownframe['Own'] = ownframe['Small_Field_Own']
 
 
 
 
 
 
 
 
 
213
  elif contest_var1 == 'Large Field GPP':
214
+ ownframe = raw_baselines.copy()
215
+ if sport_var1 == 'NBA':
216
+ ownframe['Own'] = ownframe['Large_Own']
217
+ elif sport_var1 == 'NFL':
218
+ ownframe['Own'] = ownframe['Large_Field_Own']
 
 
 
 
 
 
 
 
 
219
  elif contest_var1 == 'Cash':
220
+ ownframe = raw_baselines.copy()
221
+ if sport_var1 == 'NBA':
222
+ ownframe['Own'] = ownframe['Cash_Own']
223
+ elif sport_var1 == 'NFL':
224
+ ownframe['Own'] = ownframe['Cash_Field_Own']
225
+ export_baselines = ownframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own', 'CPT_Own', 'player_id']]
 
 
 
 
 
 
 
 
 
226
  export_baselines['CPT_Proj'] = export_baselines['Median'] * 1.5
227
  export_baselines['CPT_Salary'] = export_baselines['Salary'] * 1.5
228
+ export_baselines['ID'] = export_baselines['player_id']
229
+ display_baselines = ownframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own', 'CPT_Own']]
 
230
  display_baselines = display_baselines.sort_values(by='Median', ascending=False)
231
  display_baselines['cpt_lock'] = np.where(display_baselines['Player'].isin(lock_var1), 1, 0)
232
  display_baselines['lock'] = np.where(display_baselines['Player'].isin(lock_var2), 1, 0)
 
505
  final_outcomes_export['FLEX4'] = split_portfolio['FLEX4']
506
  final_outcomes_export['FLEX5'] = split_portfolio['FLEX5']
507
 
508
+ if sport_var1 == 'NFL':
509
+ final_outcomes_export['CPT'].replace(nfl_dk_id_dict, inplace=True)
510
+ final_outcomes_export['FLEX1'].replace(nfl_dk_id_dict, inplace=True)
511
+ final_outcomes_export['FLEX2'].replace(nfl_dk_id_dict, inplace=True)
512
+ final_outcomes_export['FLEX3'].replace(nfl_dk_id_dict, inplace=True)
513
+ final_outcomes_export['FLEX4'].replace(nfl_dk_id_dict, inplace=True)
514
+ final_outcomes_export['FLEX5'].replace(nfl_dk_id_dict, inplace=True)
515
+ elif sport_var1 == 'NBA':
516
+ final_outcomes_export['CPT'].replace(nba_dk_id_dict, inplace=True)
517
+ final_outcomes_export['FLEX1'].replace(nba_dk_id_dict, inplace=True)
518
+ final_outcomes_export['FLEX2'].replace(nba_dk_id_dict, inplace=True)
519
+ final_outcomes_export['FLEX3'].replace(nba_dk_id_dict, inplace=True)
520
+ final_outcomes_export['FLEX4'].replace(nba_dk_id_dict, inplace=True)
521
+ final_outcomes_export['FLEX5'].replace(nba_dk_id_dict, inplace=True)
522
  final_outcomes_export['Salary'] = final_outcomes['Cost']
523
  final_outcomes_export['Own'] = final_outcomes['Own']
524
  final_outcomes_export['Proj'] = final_outcomes['Proj']
 
545
  final_outcomes_export['FLEX3'] = split_portfolio['FLEX3']
546
  final_outcomes_export['FLEX4'] = split_portfolio['FLEX4']
547
 
548
+ if sport_var1 == 'NFL':
549
+ final_outcomes_export['MVP'].replace(nfl_fd_id_dict, inplace=True)
550
+ final_outcomes_export['FLEX1'].replace(nfl_fd_id_dict, inplace=True)
551
+ final_outcomes_export['FLEX2'].replace(nfl_fd_id_dict, inplace=True)
552
+ final_outcomes_export['FLEX3'].replace(nfl_fd_id_dict, inplace=True)
553
+ final_outcomes_export['FLEX4'].replace(nfl_fd_id_dict, inplace=True)
554
+ elif sport_var1 == 'NBA':
555
+ final_outcomes_export['MVP'].replace(nba_fd_id_dict, inplace=True)
556
+ final_outcomes_export['FLEX1'].replace(nba_fd_id_dict, inplace=True)
557
+ final_outcomes_export['FLEX2'].replace(nba_fd_id_dict, inplace=True)
558
+ final_outcomes_export['FLEX3'].replace(nba_fd_id_dict, inplace=True)
559
+ final_outcomes_export['FLEX4'].replace(nba_fd_id_dict, inplace=True)
560
  final_outcomes_export['Salary'] = final_outcomes['Cost']
561
  final_outcomes_export['Own'] = final_outcomes['Own']
562
  final_outcomes_export['Proj'] = final_outcomes['Proj']