James McCool commited on
Commit
1fd8c30
·
1 Parent(s): 0d43ef4

Refactor UI layout and improve data filtering options

Browse files
Files changed (1) hide show
  1. app.py +244 -282
app.py CHANGED
@@ -58,7 +58,7 @@ def init_stat_load():
58
  raw_display = pd.DataFrame(list(cursor))
59
  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%',
60
  'Own', 'Small_Own', 'Large_Own', 'Cash_Own', 'CPT_Own', 'LevX', 'ValX', 'site', 'version', 'slate', 'timestamp', 'player_ID']]
61
-
62
  raw_display = raw_display[['Player', 'Salary', 'Position', 'Team', 'Minutes', 'Median', 'Own', 'site', 'slate', 'timestamp']]
63
  raw_display.replace("", 'Welp', inplace=True)
64
  raw_display = raw_display.loc[raw_display['Player'] != 'Welp']
@@ -77,290 +77,252 @@ def convert_df_to_csv(df):
77
  proj_raw, timestamp = init_stat_load()
78
  t_stamp = f"Last Update: " + str(timestamp) + f" CST"
79
 
80
- tab1, tab2 = st.tabs(['Pivot Finder', 'Uploads and Info'])
81
-
82
- with tab2:
83
- st.info("The Projections file can have any columns in any order, but must contain columns explicitly named: 'Player', 'Salary', 'Position', 'Team', 'Minutes', 'Median', 'Own'.")
84
- col1, col2 = st.columns([1, 5])
85
-
86
- with col1:
87
- proj_file = st.file_uploader("Upload Projections File", key = 'proj_uploader')
88
-
89
- if proj_file is not None:
90
- try:
91
- proj_dataframe = pd.read_csv(proj_file)
92
- try:
93
- proj_dataframe = proj_dataframe.replace(',','', regex=True)
94
- proj_dataframe['Salary'] = proj_dataframe['Salary'].astype(int)
95
- except:
96
- pass
97
- except:
98
- proj_dataframe = pd.read_excel(proj_file)
99
- try:
100
- proj_dataframe = proj_dataframe.replace(',','', regex=True)
101
- proj_dataframe['Salary'] = proj_dataframe['Salary'].astype(int)
102
- except:
103
- pass
104
- with col2:
105
- if proj_file is not None:
106
- st.dataframe(proj_dataframe.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
 
 
108
 
109
- with tab1:
110
- col1, col2 = st.columns([1, 9])
111
- with col1:
112
- st.info(t_stamp)
113
- if st.button("Load/Reset Data", key='reset1'):
114
- st.cache_data.clear()
115
- proj_raw, timestamp = init_stat_load()
116
- t_stamp = f"Last Update: " + str(timestamp) + f" CST"
117
- for key in st.session_state.keys():
118
- del st.session_state[key]
119
- data_var1 = st.radio("Which data are you loading?", ('Paydirt', 'User'), key='data_var1')
120
- site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='site_var1')
121
- slate_var1 = st.radio("What slate are you working with?", ('Main Slate', 'Secondary Slate'), key='slate_var1')
122
  if site_var1 == 'Draftkings':
123
- if data_var1 == 'User':
124
- raw_baselines = proj_dataframe
125
- elif data_var1 != 'User':
126
- raw_baselines = proj_raw[proj_raw['site'] == 'Draftkings']
127
- if slate_var1 == 'Main Slate':
128
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Main Slate']
129
- elif slate_var1 == 'Secondary Slate':
130
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Secondary Slate']
131
- raw_baselines = raw_baselines.sort_values(by='Own', ascending=False)
132
- elif site_var1 == 'Fanduel':
133
- if data_var1 == 'User':
134
- raw_baselines = proj_dataframe
135
- elif data_var1 != 'User':
136
- raw_baselines = proj_raw[proj_raw['site'] == 'Fanduel']
137
- if slate_var1 == 'Main Slate':
138
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Main Slate']
139
- elif slate_var1 == 'Secondary Slate':
140
- raw_baselines = raw_baselines[raw_baselines['slate'] == 'Secondary Slate']
141
- raw_baselines = raw_baselines.sort_values(by='Own', ascending=False)
142
- check_seq = st.radio("Do you want to check a single player or the top 10 in ownership?", ('Single Player', 'Top X Owned'), key='check_seq')
143
  if check_seq == 'Single Player':
144
- player_check = st.selectbox('Select player to create comps', options = raw_baselines['Player'].unique(), key='dk_player')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  elif check_seq == 'Top X Owned':
146
- top_x_var = st.number_input('How many players would you like to check?', min_value = 1, max_value = 10, value = 5, step = 1)
147
- Salary_var = st.number_input('Acceptable +/- Salary range', min_value = 0, max_value = 1000, value = 300, step = 100)
148
- Median_var = st.number_input('Acceptable +/- Median range', min_value = 0, max_value = 10, value = 3, step = 1)
149
- pos_var1 = st.radio("Compare to all positions or specific positions?", ('All Positions', 'Specific Positions'), key='pos_var1')
150
- if pos_var1 == 'Specific Positions':
151
- pos_var_list = st.multiselect('Which positions would you like to include?', options = ['PG', 'SG', 'SF', 'PF', 'C'], key='pos_var_list')
152
- elif pos_var1 == 'All Positions':
153
- pos_var_list = ['PG', 'SG', 'SF', 'PF', 'C']
154
- split_var1 = st.radio("Are you running the full slate or certain games?", ('Full Slate Run', 'Specific Games'), key='split_var1')
155
- if split_var1 == 'Specific Games':
156
- team_var1 = st.multiselect('Which teams would you like to include?', options = raw_baselines['Team'].unique(), key='team_var1')
157
- elif split_var1 == 'Full Slate Run':
158
- team_var1 = raw_baselines.Team.values.tolist()
159
-
160
- with col2:
161
- placeholder = st.empty()
162
- displayholder = st.empty()
163
-
164
- if st.button('Simulate appropriate pivots'):
165
- with placeholder:
166
- if site_var1 == 'Draftkings':
167
- working_roo = raw_baselines
168
- working_roo.replace('', 0, inplace=True)
169
- if site_var1 == 'Fanduel':
170
- working_roo = raw_baselines
171
- working_roo.replace('', 0, inplace=True)
172
-
173
- own_dict = dict(zip(working_roo.Player, working_roo.Own))
174
- team_dict = dict(zip(working_roo.Player, working_roo.Team))
175
- pos_dict = dict(zip(working_roo.Player, working_roo.Position))
176
- min_dict = dict(zip(working_roo.Player, working_roo.Minutes))
177
- total_sims = 1000
178
-
179
- if check_seq == 'Single Player':
180
- player_var = working_roo.loc[working_roo['Player'] == player_check]
181
- player_var = player_var.reset_index()
182
- working_roo = working_roo[working_roo['Position'].apply(lambda x: any(pos in x.split('/') for pos in pos_var_list))]
183
- working_roo = working_roo[working_roo['Team'].isin(team_var1)]
184
- working_roo = working_roo.loc[(working_roo['Salary'] >= player_var['Salary'][0] - Salary_var) & (working_roo['Salary'] <= player_var['Salary'][0] + Salary_var)]
185
- working_roo = working_roo.loc[(working_roo['Median'] >= player_var['Median'][0] - Median_var) & (working_roo['Median'] <= player_var['Median'][0] + Median_var)]
186
-
187
- flex_file = working_roo[['Player', 'Position', 'Salary', 'Median', 'Minutes']]
188
- flex_file['Floor'] = (flex_file['Median'] * .25) + (flex_file['Minutes'] * .25)
189
- flex_file['Ceiling'] = flex_file['Median'] + 10 + (flex_file['Minutes'] * .25)
190
- flex_file['STD'] = (flex_file['Median']/4)
191
- flex_file = flex_file[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD']]
192
- hold_file = flex_file.copy()
193
- overall_file = flex_file.copy()
194
- salary_file = flex_file.copy()
195
-
196
- overall_players = overall_file[['Player']]
197
-
198
- for x in range(0,total_sims):
199
- salary_file[x] = salary_file['Salary']
200
-
201
- salary_file=salary_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
202
-
203
- salary_file = salary_file.div(1000)
204
-
205
- for x in range(0,total_sims):
206
- overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])
207
-
208
- overall_file=overall_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
209
-
210
- players_only = hold_file[['Player']]
211
- raw_lineups_file = players_only
212
-
213
- for x in range(0,total_sims):
214
- maps_dict = {'proj_map':dict(zip(hold_file.Player,overall_file[x]))}
215
- raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
216
- players_only[x] = raw_lineups_file[x].rank(ascending=False)
217
-
218
- players_only=players_only.drop(['Player'], axis=1)
219
-
220
- salary_4x_check = (overall_file - (salary_file*4))
221
- salary_5x_check = (overall_file - (salary_file*5))
222
- salary_6x_check = (overall_file - (salary_file*6))
223
- gpp_check = (overall_file - ((salary_file*5)+10))
224
-
225
- players_only['Average_Rank'] = players_only.mean(axis=1)
226
- players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
227
- players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
228
- players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
229
- players_only['20+%'] = overall_file[overall_file >= 20].count(axis=1)/float(total_sims)
230
- players_only['4x%'] = salary_4x_check[salary_4x_check >= 1].count(axis=1)/float(total_sims)
231
- players_only['5x%'] = salary_5x_check[salary_5x_check >= 1].count(axis=1)/float(total_sims)
232
- players_only['6x%'] = salary_6x_check[salary_6x_check >= 1].count(axis=1)/float(total_sims)
233
- players_only['GPP%'] = salary_4x_check[gpp_check >= 1].count(axis=1)/float(total_sims)
234
-
235
- players_only['Player'] = hold_file[['Player']]
236
-
237
- final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
238
-
239
- final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
240
- final_Proj = final_Proj[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
241
-
242
- final_Proj['Own'] = final_Proj['Player'].map(own_dict)
243
- final_Proj['Minutes Proj'] = final_Proj['Player'].map(min_dict)
244
- final_Proj['Team'] = final_Proj['Player'].map(team_dict)
245
- final_Proj['Own'] = final_Proj['Own'].astype('float')
246
- final_Proj = final_Proj[['Player', 'Minutes Proj', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own']]
247
- final_Proj['Projection Rank'] = final_Proj.Top_finish.rank(pct = True)
248
- final_Proj['Own Rank'] = final_Proj.Own.rank(pct = True)
249
- final_Proj['LevX'] = (final_Proj['Projection Rank'] - final_Proj['Own Rank']) * 100
250
- final_Proj['ValX'] = ((final_Proj[['4x%', '5x%']].mean(axis=1))*100) + final_Proj['LevX']
251
- final_Proj['ValX'] = np.where(final_Proj['ValX'] > 100, 100, final_Proj['ValX'])
252
- final_Proj['ValX'] = np.where(final_Proj['ValX'] < 0, 0, final_Proj['ValX'])
253
-
254
- final_Proj = final_Proj[['Player', 'Minutes Proj', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own', 'LevX', 'ValX']]
255
- final_Proj = final_Proj.set_index('Player')
256
-
257
- st.session_state.final_Proj = final_Proj.sort_values(by='Top_finish', ascending=False)
258
-
259
- elif check_seq == 'Top X Owned':
260
- if pos_var1 == 'Specific Positions':
261
- raw_baselines = raw_baselines[raw_baselines['Position'].apply(lambda x: any(pos in x.split('/') for pos in pos_var_list))]
262
- player_check = raw_baselines['Player'].head(top_x_var).tolist()
263
- st.write(player_check)
264
- final_proj_list = []
265
- for players in player_check:
266
- players_pos = pos_dict[players]
267
- player_var = working_roo.loc[working_roo['Player'] == players]
268
- player_var = player_var.reset_index()
269
- working_roo_temp = working_roo[working_roo['Team'].isin(team_var1)]
270
-
271
- working_roo_temp = working_roo_temp.loc[(working_roo_temp['Salary'] >= player_var['Salary'][0] - Salary_var) & (working_roo_temp['Salary'] <= player_var['Salary'][0] + Salary_var)]
272
- working_roo_temp = working_roo_temp.loc[(working_roo_temp['Median'] >= player_var['Median'][0] - Median_var) & (working_roo_temp['Median'] <= player_var['Median'][0] + Median_var)]
273
-
274
- flex_file = working_roo_temp[['Player', 'Position', 'Salary', 'Median', 'Minutes']]
275
- flex_file['Floor'] = (flex_file['Median'] * .25) + (flex_file['Minutes'] * .25)
276
- flex_file['Ceiling'] = flex_file['Median'] + 10 + (flex_file['Minutes'] * .25)
277
- flex_file['STD'] = (flex_file['Median']/4)
278
- flex_file = flex_file[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD']]
279
- hold_file = flex_file.copy()
280
- overall_file = flex_file.copy()
281
- salary_file = flex_file.copy()
282
-
283
- overall_players = overall_file[['Player']]
284
-
285
- for x in range(0,total_sims):
286
- salary_file[x] = salary_file['Salary']
287
-
288
- salary_file=salary_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
289
-
290
- salary_file = salary_file.div(1000)
291
-
292
- for x in range(0,total_sims):
293
- overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])
294
-
295
- overall_file=overall_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
296
-
297
- players_only = hold_file[['Player']]
298
- raw_lineups_file = players_only
299
-
300
- for x in range(0,total_sims):
301
- maps_dict = {'proj_map':dict(zip(hold_file.Player,overall_file[x]))}
302
- raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
303
- players_only[x] = raw_lineups_file[x].rank(ascending=False)
304
-
305
- players_only=players_only.drop(['Player'], axis=1)
306
-
307
- salary_4x_check = (overall_file - (salary_file*4))
308
- salary_5x_check = (overall_file - (salary_file*5))
309
- salary_6x_check = (overall_file - (salary_file*6))
310
- gpp_check = (overall_file - ((salary_file*5)+10))
311
-
312
- players_only['Average_Rank'] = players_only.mean(axis=1)
313
- players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
314
- players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
315
- players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
316
- players_only['20+%'] = overall_file[overall_file >= 20].count(axis=1)/float(total_sims)
317
- players_only['4x%'] = salary_4x_check[salary_4x_check >= 1].count(axis=1)/float(total_sims)
318
- players_only['5x%'] = salary_5x_check[salary_5x_check >= 1].count(axis=1)/float(total_sims)
319
- players_only['6x%'] = salary_6x_check[salary_6x_check >= 1].count(axis=1)/float(total_sims)
320
- players_only['GPP%'] = salary_4x_check[gpp_check >= 1].count(axis=1)/float(total_sims)
321
-
322
- players_only['Player'] = hold_file[['Player']]
323
-
324
- final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
325
-
326
- final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
327
- final_Proj = final_Proj[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
328
-
329
- final_Proj['Own'] = final_Proj['Player'].map(own_dict)
330
- final_Proj['Minutes Proj'] = final_Proj['Player'].map(min_dict)
331
- final_Proj['Team'] = final_Proj['Player'].map(team_dict)
332
- final_Proj['Own'] = final_Proj['Own'].astype('float')
333
- final_Proj['Projection Rank'] = final_Proj.Top_finish.rank(pct = True)
334
- final_Proj['Own Rank'] = final_Proj.Own.rank(pct = True)
335
- final_Proj['LevX'] = (final_Proj['Projection Rank'] - final_Proj['Own Rank']) * 100
336
- final_Proj['ValX'] = ((final_Proj[['4x%', '5x%']].mean(axis=1))*100) + final_Proj['LevX']
337
- final_Proj['ValX'] = np.where(final_Proj['ValX'] > 100, 100, final_Proj['ValX'])
338
- final_Proj['ValX'] = np.where(final_Proj['ValX'] < 0, 0, final_Proj['ValX'])
339
- final_Proj['Pivot_source'] = players
340
-
341
- final_Proj = final_Proj[['Player', 'Pivot_source', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own', 'LevX', 'ValX']]
342
-
343
- final_Proj = final_Proj.sort_values(by='Top_finish', ascending=False)
344
- final_proj_list.append(final_Proj)
345
- st.write(f'finished run for {players}')
346
 
347
- # Concatenate all the final_Proj dataframes
348
- final_Proj_combined = pd.concat(final_proj_list)
349
- final_Proj_combined = final_Proj_combined.sort_values(by='LevX', ascending=False)
350
- final_Proj_combined = final_Proj_combined[final_Proj_combined['Player'] != final_Proj_combined['Pivot_source']]
351
- st.session_state.final_Proj = final_Proj_combined.reset_index(drop=True) # Assign the combined dataframe back to final_Proj
352
-
353
- placeholder.empty()
354
-
355
- with displayholder.container():
356
- if 'final_Proj' in st.session_state:
357
- st.dataframe(st.session_state.final_Proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), use_container_width = True)
358
-
359
- st.download_button(
360
- label="Export Tables",
361
- data=convert_df_to_csv(st.session_state.final_Proj),
362
- file_name='NBA_pivot_export.csv',
363
- mime='text/csv',
364
- )
365
- else:
366
- st.write("Run some pivots my dude/dudette")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  raw_display = pd.DataFrame(list(cursor))
59
  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%',
60
  'Own', 'Small_Own', 'Large_Own', 'Cash_Own', 'CPT_Own', 'LevX', 'ValX', 'site', 'version', 'slate', 'timestamp', 'player_ID']]
61
+ raw_display = raw_display.rename(columns={'Minutes Proj': 'Minutes'})
62
  raw_display = raw_display[['Player', 'Salary', 'Position', 'Team', 'Minutes', 'Median', 'Own', 'site', 'slate', 'timestamp']]
63
  raw_display.replace("", 'Welp', inplace=True)
64
  raw_display = raw_display.loc[raw_display['Player'] != 'Welp']
 
77
  proj_raw, timestamp = init_stat_load()
78
  t_stamp = f"Last Update: " + str(timestamp) + f" CST"
79
 
80
+ with st.expander("Info and Filters"):
81
+ st.info(t_stamp)
82
+ if st.button("Load/Reset Data", key='reset1'):
83
+ st.cache_data.clear()
84
+ proj_raw, timestamp = init_stat_load()
85
+ t_stamp = f"Last Update: " + str(timestamp) + f" CST"
86
+ for key in st.session_state.keys():
87
+ del st.session_state[key]
88
+ data_var1 = st.radio("Which data are you loading?", ('Paydirt', 'User'), key='data_var1')
89
+ site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='site_var1')
90
+ slate_var1 = st.radio("What slate are you working with?", ('Main Slate', 'Secondary Slate'), key='slate_var1')
91
+ if site_var1 == 'Draftkings':
92
+ raw_baselines = proj_raw[proj_raw['site'] == 'Draftkings']
93
+ if slate_var1 == 'Main Slate':
94
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Main Slate']
95
+ elif slate_var1 == 'Secondary Slate':
96
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Secondary Slate']
97
+ raw_baselines = raw_baselines.sort_values(by='Own', ascending=False)
98
+ elif site_var1 == 'Fanduel':
99
+ raw_baselines = proj_raw[proj_raw['site'] == 'Fanduel']
100
+ if slate_var1 == 'Main Slate':
101
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Main Slate']
102
+ elif slate_var1 == 'Secondary Slate':
103
+ raw_baselines = raw_baselines[raw_baselines['slate'] == 'Secondary Slate']
104
+ raw_baselines = raw_baselines.sort_values(by='Own', ascending=False)
105
+ check_seq = st.radio("Do you want to check a single player or the top 10 in ownership?", ('Single Player', 'Top X Owned'), key='check_seq')
106
+ if check_seq == 'Single Player':
107
+ player_check = st.selectbox('Select player to create comps', options = raw_baselines['Player'].unique(), key='dk_player')
108
+ elif check_seq == 'Top X Owned':
109
+ top_x_var = st.number_input('How many players would you like to check?', min_value = 1, max_value = 10, value = 5, step = 1)
110
+ Salary_var = st.number_input('Acceptable +/- Salary range', min_value = 0, max_value = 1000, value = 300, step = 100)
111
+ Median_var = st.number_input('Acceptable +/- Median range', min_value = 0, max_value = 10, value = 3, step = 1)
112
+ pos_var1 = st.radio("Compare to all positions or specific positions?", ('All Positions', 'Specific Positions'), key='pos_var1')
113
+ if pos_var1 == 'Specific Positions':
114
+ pos_var_list = st.multiselect('Which positions would you like to include?', options = ['PG', 'SG', 'SF', 'PF', 'C'], key='pos_var_list')
115
+ elif pos_var1 == 'All Positions':
116
+ pos_var_list = ['PG', 'SG', 'SF', 'PF', 'C']
117
+ split_var1 = st.radio("Are you running the full slate or certain games?", ('Full Slate Run', 'Specific Games'), key='split_var1')
118
+ if split_var1 == 'Specific Games':
119
+ team_var1 = st.multiselect('Which teams would you like to include?', options = raw_baselines['Team'].unique(), key='team_var1')
120
+ elif split_var1 == 'Full Slate Run':
121
+ team_var1 = raw_baselines.Team.values.tolist()
122
 
123
+ placeholder = st.empty()
124
+ displayholder = st.empty()
125
 
126
+ if st.button('Simulate appropriate pivots'):
127
+ with placeholder:
 
 
 
 
 
 
 
 
 
 
 
128
  if site_var1 == 'Draftkings':
129
+ working_roo = raw_baselines
130
+ working_roo.replace('', 0, inplace=True)
131
+ if site_var1 == 'Fanduel':
132
+ working_roo = raw_baselines
133
+ working_roo.replace('', 0, inplace=True)
134
+
135
+ own_dict = dict(zip(working_roo.Player, working_roo.Own))
136
+ team_dict = dict(zip(working_roo.Player, working_roo.Team))
137
+ pos_dict = dict(zip(working_roo.Player, working_roo.Position))
138
+ min_dict = dict(zip(working_roo.Player, working_roo.Minutes))
139
+ total_sims = 1000
140
+
 
 
 
 
 
 
 
 
141
  if check_seq == 'Single Player':
142
+ player_var = working_roo.loc[working_roo['Player'] == player_check]
143
+ player_var = player_var.reset_index()
144
+ working_roo = working_roo[working_roo['Position'].apply(lambda x: any(pos in x.split('/') for pos in pos_var_list))]
145
+ working_roo = working_roo[working_roo['Team'].isin(team_var1)]
146
+ working_roo = working_roo.loc[(working_roo['Salary'] >= player_var['Salary'][0] - Salary_var) & (working_roo['Salary'] <= player_var['Salary'][0] + Salary_var)]
147
+ working_roo = working_roo.loc[(working_roo['Median'] >= player_var['Median'][0] - Median_var) & (working_roo['Median'] <= player_var['Median'][0] + Median_var)]
148
+
149
+ flex_file = working_roo[['Player', 'Position', 'Salary', 'Median', 'Minutes']]
150
+ flex_file['Floor'] = (flex_file['Median'] * .25) + (flex_file['Minutes'] * .25)
151
+ flex_file['Ceiling'] = flex_file['Median'] + 10 + (flex_file['Minutes'] * .25)
152
+ flex_file['STD'] = (flex_file['Median']/4)
153
+ flex_file = flex_file[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD']]
154
+ hold_file = flex_file.copy()
155
+ overall_file = flex_file.copy()
156
+ salary_file = flex_file.copy()
157
+
158
+ overall_players = overall_file[['Player']]
159
+
160
+ for x in range(0,total_sims):
161
+ salary_file[x] = salary_file['Salary']
162
+
163
+ salary_file=salary_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
164
+
165
+ salary_file = salary_file.div(1000)
166
+
167
+ for x in range(0,total_sims):
168
+ overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])
169
+
170
+ overall_file=overall_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
171
+
172
+ players_only = hold_file[['Player']]
173
+ raw_lineups_file = players_only
174
+
175
+ for x in range(0,total_sims):
176
+ maps_dict = {'proj_map':dict(zip(hold_file.Player,overall_file[x]))}
177
+ raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
178
+ players_only[x] = raw_lineups_file[x].rank(ascending=False)
179
+
180
+ players_only=players_only.drop(['Player'], axis=1)
181
+
182
+ salary_4x_check = (overall_file - (salary_file*4))
183
+ salary_5x_check = (overall_file - (salary_file*5))
184
+ salary_6x_check = (overall_file - (salary_file*6))
185
+ gpp_check = (overall_file - ((salary_file*5)+10))
186
+
187
+ players_only['Average_Rank'] = players_only.mean(axis=1)
188
+ players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
189
+ players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
190
+ players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
191
+ players_only['20+%'] = overall_file[overall_file >= 20].count(axis=1)/float(total_sims)
192
+ players_only['4x%'] = salary_4x_check[salary_4x_check >= 1].count(axis=1)/float(total_sims)
193
+ players_only['5x%'] = salary_5x_check[salary_5x_check >= 1].count(axis=1)/float(total_sims)
194
+ players_only['6x%'] = salary_6x_check[salary_6x_check >= 1].count(axis=1)/float(total_sims)
195
+ players_only['GPP%'] = salary_4x_check[gpp_check >= 1].count(axis=1)/float(total_sims)
196
+
197
+ players_only['Player'] = hold_file[['Player']]
198
+
199
+ final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
200
+
201
+ final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
202
+ final_Proj = final_Proj[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
203
+
204
+ final_Proj['Own'] = final_Proj['Player'].map(own_dict)
205
+ final_Proj['Minutes Proj'] = final_Proj['Player'].map(min_dict)
206
+ final_Proj['Team'] = final_Proj['Player'].map(team_dict)
207
+ final_Proj['Own'] = final_Proj['Own'].astype('float')
208
+ final_Proj = final_Proj[['Player', 'Minutes Proj', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own']]
209
+ final_Proj['Projection Rank'] = final_Proj.Top_finish.rank(pct = True)
210
+ final_Proj['Own Rank'] = final_Proj.Own.rank(pct = True)
211
+ final_Proj['LevX'] = (final_Proj['Projection Rank'] - final_Proj['Own Rank']) * 100
212
+ final_Proj['ValX'] = ((final_Proj[['4x%', '5x%']].mean(axis=1))*100) + final_Proj['LevX']
213
+ final_Proj['ValX'] = np.where(final_Proj['ValX'] > 100, 100, final_Proj['ValX'])
214
+ final_Proj['ValX'] = np.where(final_Proj['ValX'] < 0, 0, final_Proj['ValX'])
215
+
216
+ final_Proj = final_Proj[['Player', 'Minutes Proj', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own', 'LevX', 'ValX']]
217
+ final_Proj = final_Proj.set_index('Player')
218
+
219
+ st.session_state.final_Proj = final_Proj.sort_values(by='Top_finish', ascending=False)
220
+
221
  elif check_seq == 'Top X Owned':
222
+ if pos_var1 == 'Specific Positions':
223
+ raw_baselines = raw_baselines[raw_baselines['Position'].apply(lambda x: any(pos in x.split('/') for pos in pos_var_list))]
224
+ player_check = raw_baselines['Player'].head(top_x_var).tolist()
225
+ st.write(player_check)
226
+ final_proj_list = []
227
+ for players in player_check:
228
+ players_pos = pos_dict[players]
229
+ player_var = working_roo.loc[working_roo['Player'] == players]
230
+ player_var = player_var.reset_index()
231
+ working_roo_temp = working_roo[working_roo['Team'].isin(team_var1)]
232
+
233
+ working_roo_temp = working_roo_temp.loc[(working_roo_temp['Salary'] >= player_var['Salary'][0] - Salary_var) & (working_roo_temp['Salary'] <= player_var['Salary'][0] + Salary_var)]
234
+ working_roo_temp = working_roo_temp.loc[(working_roo_temp['Median'] >= player_var['Median'][0] - Median_var) & (working_roo_temp['Median'] <= player_var['Median'][0] + Median_var)]
235
+
236
+ flex_file = working_roo_temp[['Player', 'Position', 'Salary', 'Median', 'Minutes']]
237
+ flex_file['Floor'] = (flex_file['Median'] * .25) + (flex_file['Minutes'] * .25)
238
+ flex_file['Ceiling'] = flex_file['Median'] + 10 + (flex_file['Minutes'] * .25)
239
+ flex_file['STD'] = (flex_file['Median']/4)
240
+ flex_file = flex_file[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD']]
241
+ hold_file = flex_file.copy()
242
+ overall_file = flex_file.copy()
243
+ salary_file = flex_file.copy()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
+ overall_players = overall_file[['Player']]
246
+
247
+ for x in range(0,total_sims):
248
+ salary_file[x] = salary_file['Salary']
249
+
250
+ salary_file=salary_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
251
+
252
+ salary_file = salary_file.div(1000)
253
+
254
+ for x in range(0,total_sims):
255
+ overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])
256
+
257
+ overall_file=overall_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
258
+
259
+ players_only = hold_file[['Player']]
260
+ raw_lineups_file = players_only
261
+
262
+ for x in range(0,total_sims):
263
+ maps_dict = {'proj_map':dict(zip(hold_file.Player,overall_file[x]))}
264
+ raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
265
+ players_only[x] = raw_lineups_file[x].rank(ascending=False)
266
+
267
+ players_only=players_only.drop(['Player'], axis=1)
268
+
269
+ salary_4x_check = (overall_file - (salary_file*4))
270
+ salary_5x_check = (overall_file - (salary_file*5))
271
+ salary_6x_check = (overall_file - (salary_file*6))
272
+ gpp_check = (overall_file - ((salary_file*5)+10))
273
+
274
+ players_only['Average_Rank'] = players_only.mean(axis=1)
275
+ players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
276
+ players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
277
+ players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
278
+ players_only['20+%'] = overall_file[overall_file >= 20].count(axis=1)/float(total_sims)
279
+ players_only['4x%'] = salary_4x_check[salary_4x_check >= 1].count(axis=1)/float(total_sims)
280
+ players_only['5x%'] = salary_5x_check[salary_5x_check >= 1].count(axis=1)/float(total_sims)
281
+ players_only['6x%'] = salary_6x_check[salary_6x_check >= 1].count(axis=1)/float(total_sims)
282
+ players_only['GPP%'] = salary_4x_check[gpp_check >= 1].count(axis=1)/float(total_sims)
283
+
284
+ players_only['Player'] = hold_file[['Player']]
285
+
286
+ final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
287
+
288
+ final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
289
+ final_Proj = final_Proj[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%']]
290
+
291
+ final_Proj['Own'] = final_Proj['Player'].map(own_dict)
292
+ final_Proj['Minutes Proj'] = final_Proj['Player'].map(min_dict)
293
+ final_Proj['Team'] = final_Proj['Player'].map(team_dict)
294
+ final_Proj['Own'] = final_Proj['Own'].astype('float')
295
+ final_Proj['Projection Rank'] = final_Proj.Top_finish.rank(pct = True)
296
+ final_Proj['Own Rank'] = final_Proj.Own.rank(pct = True)
297
+ final_Proj['LevX'] = (final_Proj['Projection Rank'] - final_Proj['Own Rank']) * 100
298
+ final_Proj['ValX'] = ((final_Proj[['4x%', '5x%']].mean(axis=1))*100) + final_Proj['LevX']
299
+ final_Proj['ValX'] = np.where(final_Proj['ValX'] > 100, 100, final_Proj['ValX'])
300
+ final_Proj['ValX'] = np.where(final_Proj['ValX'] < 0, 0, final_Proj['ValX'])
301
+ final_Proj['Pivot_source'] = players
302
+
303
+ final_Proj = final_Proj[['Player', 'Pivot_source', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '4x%', '5x%', '6x%', 'GPP%', 'Own', 'LevX', 'ValX']]
304
+
305
+ final_Proj = final_Proj.sort_values(by='Top_finish', ascending=False)
306
+ final_proj_list.append(final_Proj)
307
+ st.write(f'finished run for {players}')
308
+
309
+ # Concatenate all the final_Proj dataframes
310
+ final_Proj_combined = pd.concat(final_proj_list)
311
+ final_Proj_combined = final_Proj_combined.sort_values(by='LevX', ascending=False)
312
+ final_Proj_combined = final_Proj_combined[final_Proj_combined['Player'] != final_Proj_combined['Pivot_source']]
313
+ st.session_state.final_Proj = final_Proj_combined.reset_index(drop=True) # Assign the combined dataframe back to final_Proj
314
+
315
+ placeholder.empty()
316
+
317
+ with displayholder.container():
318
+ if 'final_Proj' in st.session_state:
319
+ st.dataframe(st.session_state.final_Proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), use_container_width = True)
320
+
321
+ st.download_button(
322
+ label="Export Tables",
323
+ data=convert_df_to_csv(st.session_state.final_Proj),
324
+ file_name='NBA_pivot_export.csv',
325
+ mime='text/csv',
326
+ )
327
+ else:
328
+ st.write("Run some pivots my dude/dudette")