James McCool commited on
Commit
f89dec6
·
1 Parent(s): b5c6df7

Refactor Streamlit app to remove redundant name conversion messages and enhance data loading/reset functionality. Added buttons for data export and improved layout with segmented controls for better user experience.

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +464 -460
src/streamlit_app.py CHANGED
@@ -75,7 +75,6 @@ def init_DK_seed_frames(sharp_split):
75
  raw_display = pd.DataFrame(list(cursor))
76
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
77
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
78
- st.write("converting names")
79
  for col in dict_columns:
80
  raw_display[col] = raw_display[col].map(names_dict)
81
  DK_seed = raw_display.to_numpy()
@@ -96,7 +95,6 @@ def init_DK_Secondary_seed_frames(sharp_split):
96
  raw_display = pd.DataFrame(list(cursor))
97
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
98
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
99
- st.write("converting names")
100
  for col in dict_columns:
101
  raw_display[col] = raw_display[col].map(names_dict)
102
  DK_seed = raw_display.to_numpy()
@@ -117,7 +115,6 @@ def init_FD_seed_frames(sharp_split):
117
  raw_display = pd.DataFrame(list(cursor))
118
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
119
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
120
- st.write("converting names")
121
  for col in dict_columns:
122
  raw_display[col] = raw_display[col].map(names_dict)
123
  FD_seed = raw_display.to_numpy()
@@ -138,7 +135,6 @@ def init_FD_Secondary_seed_frames(sharp_split):
138
  raw_display = pd.DataFrame(list(cursor))
139
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
140
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
141
- st.write("converting names")
142
  for col in dict_columns:
143
  raw_display[col] = raw_display[col].map(names_dict)
144
  FD_seed = raw_display.to_numpy()
@@ -219,6 +215,16 @@ def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size):
219
 
220
  return Sim_Winners
221
 
 
 
 
 
 
 
 
 
 
 
222
  selected_tab = st.segmented_control(
223
  "Select Tab",
224
  options=["Contest Sims", "Data Export"],
@@ -230,483 +236,481 @@ selected_tab = st.segmented_control(
230
  )
231
 
232
  if selected_tab == "Contest Sims":
233
- col1, col2 = st.columns([1, 7])
234
- with col1:
235
- if st.button("Load/Reset Data", key='reset2'):
236
- st.cache_data.clear()
237
- for key in st.session_state.keys():
238
- del st.session_state[key]
239
- DK_seed = init_DK_seed_frames(10000)
240
- FD_seed = init_FD_seed_frames(10000)
241
- dk_raw, fd_raw = init_baselines('Main Slate')
242
- dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
243
- fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
244
-
245
- sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate'), key='sim_slate_var1')
246
- sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
248
- contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom'))
249
- if contest_var1 == 'Small':
250
- Contest_Size = 1000
251
- elif contest_var1 == 'Medium':
252
- Contest_Size = 5000
253
- elif contest_var1 == 'Large':
254
- Contest_Size = 10000
255
- elif contest_var1 == 'Custom':
256
- Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
257
- strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
258
- if strength_var1 == 'Not Very':
259
- sharp_split = 500000
260
- elif strength_var1 == 'Below Average':
261
- sharp_split = 250000
262
- elif strength_var1 == 'Average':
263
- sharp_split = 100000
264
- elif strength_var1 == 'Above Average':
265
- sharp_split = 50000
266
- elif strength_var1 == 'Very':
267
- sharp_split = 10000
268
-
269
-
270
- with col2:
271
- if st.button("Run Contest Sim"):
272
- if 'working_seed' in st.session_state:
273
- st.session_state.maps_dict = {
274
- 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
275
- 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
276
- 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
277
- 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
278
- 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
279
- 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
280
- }
281
-
282
- Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
283
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
284
-
285
- # Initial setup
286
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
287
- Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
288
- Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
289
- Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
290
-
291
- # Type Casting
292
- type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
293
- Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
294
-
295
- # Sorting
296
- st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
297
- st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
298
-
299
- # Data Copying
300
- st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
301
-
302
- # Data Copying
303
- st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
304
-
305
- else:
306
- if sim_site_var1 == 'Draftkings':
307
- if sim_slate_var1 == 'Main Slate':
308
- st.session_state.working_seed = init_DK_seed_frames(sharp_split)
309
- dk_raw, fd_raw = init_baselines('Main Slate')
310
- dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
311
- elif sim_slate_var1 == 'Secondary Slate':
312
- st.session_state.working_seed = init_DK_Secondary_seed_frames(sharp_split)
313
- dk_raw, fd_raw = init_baselines('Secondary Slate')
314
- dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
315
-
316
- raw_baselines = dk_raw
317
- column_names = dk_columns
318
- elif sim_site_var1 == 'Fanduel':
319
- if sim_slate_var1 == 'Main Slate':
320
- st.session_state.working_seed = init_FD_seed_frames(sharp_split)
321
- dk_raw, fd_raw = init_baselines('Main Slate')
322
- fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
323
- elif sim_slate_var1 == 'Secondary Slate':
324
- st.session_state.working_seed = init_FD_Secondary_seed_frames(sharp_split)
325
- dk_raw, fd_raw = init_baselines('Secondary Slate')
326
- fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
327
-
328
- raw_baselines = fd_raw
329
- column_names = fd_columns
330
- st.session_state.maps_dict = {
331
- 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
332
- 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
333
- 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
334
- 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
335
- 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
336
- 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
337
- }
338
-
339
- Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
340
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
341
-
342
- #st.table(Sim_Winner_Frame)
343
-
344
- # Initial setup
345
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
346
- Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
347
- Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
348
- Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
349
-
350
- # Type Casting
351
- type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
352
- Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
353
-
354
- # Sorting
355
- st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
356
- st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
357
-
358
- # Data Copying
359
- st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
360
- if sim_site_var1 == 'Draftkings':
361
- for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
362
- st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)
363
- elif sim_site_var1 == 'Fanduel':
364
- for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
365
- st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(fd_id_dict)
366
-
367
- # Data Copying
368
- st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
369
- st.session_state.freq_copy = st.session_state.Sim_Winner_Display
370
-
371
- if sim_site_var1 == 'Draftkings':
372
- freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
373
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
374
- elif sim_site_var1 == 'Fanduel':
375
- freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
376
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
377
- freq_working['Freq'] = freq_working['Freq'].astype(int)
378
- freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])
379
- freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])
380
- freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
381
- freq_working['Exposure'] = freq_working['Freq']/(1000)
382
- freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
383
- freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])
384
- st.session_state.player_freq = freq_working.copy()
385
-
386
  if sim_site_var1 == 'Draftkings':
387
- qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
388
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
 
 
 
 
 
 
 
 
 
389
  elif sim_site_var1 == 'Fanduel':
390
- qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
391
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
392
- qb_working['Freq'] = qb_working['Freq'].astype(int)
393
- qb_working['Position'] = qb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
394
- qb_working['Salary'] = qb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
395
- qb_working['Proj Own'] = qb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
396
- qb_working['Exposure'] = qb_working['Freq']/(1000)
397
- qb_working['Edge'] = qb_working['Exposure'] - qb_working['Proj Own']
398
- qb_working['Team'] = qb_working['Player'].map(st.session_state.maps_dict['Team_map'])
399
- st.session_state.qb_freq = qb_working.copy()
 
 
 
 
 
 
 
 
 
400
 
401
- if sim_site_var1 == 'Draftkings':
402
- rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
403
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
404
- elif sim_site_var1 == 'Fanduel':
405
- rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
406
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
407
- rbwrte_working['Freq'] = rbwrte_working['Freq'].astype(int)
408
- rbwrte_working['Position'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Pos_map'])
409
- rbwrte_working['Salary'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Salary_map'])
410
- rbwrte_working['Proj Own'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
411
- rbwrte_working['Exposure'] = rbwrte_working['Freq']/(1000)
412
- rbwrte_working['Edge'] = rbwrte_working['Exposure'] - rbwrte_working['Proj Own']
413
- rbwrte_working['Team'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Team_map'])
414
- st.session_state.rbwrte_freq = rbwrte_working.copy()
415
 
416
- if sim_site_var1 == 'Draftkings':
417
- rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
418
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
419
- elif sim_site_var1 == 'Fanduel':
420
- rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
421
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
422
- rb_working['Freq'] = rb_working['Freq'].astype(int)
423
- rb_working['Position'] = rb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
424
- rb_working['Salary'] = rb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
425
- rb_working['Proj Own'] = rb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
426
- rb_working['Exposure'] = rb_working['Freq']/(1000)
427
- rb_working['Edge'] = rb_working['Exposure'] - rb_working['Proj Own']
428
- rb_working['Team'] = rb_working['Player'].map(st.session_state.maps_dict['Team_map'])
429
- st.session_state.rb_freq = rb_working.copy()
430
 
431
- if sim_site_var1 == 'Draftkings':
432
- wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
433
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
434
- elif sim_site_var1 == 'Fanduel':
435
- wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
436
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
437
- wr_working['Freq'] = wr_working['Freq'].astype(int)
438
- wr_working['Position'] = wr_working['Player'].map(st.session_state.maps_dict['Pos_map'])
439
- wr_working['Salary'] = wr_working['Player'].map(st.session_state.maps_dict['Salary_map'])
440
- wr_working['Proj Own'] = wr_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
441
- wr_working['Exposure'] = wr_working['Freq']/(1000)
442
- wr_working['Edge'] = wr_working['Exposure'] - wr_working['Proj Own']
443
- wr_working['Team'] = wr_working['Player'].map(st.session_state.maps_dict['Team_map'])
444
- st.session_state.wr_freq = wr_working.copy()
445
 
446
- if sim_site_var1 == 'Draftkings':
447
- te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
448
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
449
- elif sim_site_var1 == 'Fanduel':
450
- te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
451
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
452
- te_working['Freq'] = te_working['Freq'].astype(int)
453
- te_working['Position'] = te_working['Player'].map(st.session_state.maps_dict['Pos_map'])
454
- te_working['Salary'] = te_working['Player'].map(st.session_state.maps_dict['Salary_map'])
455
- te_working['Proj Own'] = te_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
456
- te_working['Exposure'] = te_working['Freq']/(1000)
457
- te_working['Edge'] = te_working['Exposure'] - te_working['Proj Own']
458
- te_working['Team'] = te_working['Player'].map(st.session_state.maps_dict['Team_map'])
459
- st.session_state.te_freq = te_working.copy()
460
 
 
 
461
  if sim_site_var1 == 'Draftkings':
462
- flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
463
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
464
  elif sim_site_var1 == 'Fanduel':
465
- flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
466
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
467
- flex_working['Freq'] = flex_working['Freq'].astype(int)
468
- flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map'])
469
- flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map'])
470
- flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
471
- flex_working['Exposure'] = flex_working['Freq']/(1000)
472
- flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
473
- flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map'])
474
- st.session_state.flex_freq = flex_working.copy()
475
 
476
- if sim_site_var1 == 'Draftkings':
477
- dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
478
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
479
- elif sim_site_var1 == 'Fanduel':
480
- dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
481
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
482
- dst_working['Freq'] = dst_working['Freq'].astype(int)
483
- dst_working['Position'] = dst_working['Player'].map(st.session_state.maps_dict['Pos_map'])
484
- dst_working['Salary'] = dst_working['Player'].map(st.session_state.maps_dict['Salary_map'])
485
- dst_working['Proj Own'] = dst_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
486
- dst_working['Exposure'] = dst_working['Freq']/(1000)
487
- dst_working['Edge'] = dst_working['Exposure'] - dst_working['Proj Own']
488
- dst_working['Team'] = dst_working['Player'].map(st.session_state.maps_dict['Team_map'])
489
- st.session_state.dst_freq = dst_working.copy()
490
-
491
- if sim_site_var1 == 'Draftkings':
492
- team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
493
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
494
- elif sim_site_var1 == 'Fanduel':
495
- team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
496
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
497
- team_working['Freq'] = team_working['Freq'].astype(int)
498
- team_working['Exposure'] = team_working['Freq']/(1000)
499
- st.session_state.team_freq = team_working.copy()
500
 
501
- with st.container():
502
- if st.button("Reset Sim", key='reset_sim'):
503
- for key in st.session_state.keys():
504
- del st.session_state[key]
505
- if 'player_freq' in st.session_state:
506
- player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
507
- if player_split_var2 == 'Specific Players':
508
- find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
509
- elif player_split_var2 == 'Full Players':
510
- find_var2 = st.session_state.player_freq.Player.values.tolist()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
 
512
- if player_split_var2 == 'Specific Players':
513
- st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]
514
- if player_split_var2 == 'Full Players':
515
- st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
516
- if 'Sim_Winner_Display' in st.session_state:
517
- st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
518
- if 'Sim_Winner_Export' in st.session_state:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  st.download_button(
520
- label="Export Full Frame",
521
- data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
522
- file_name='MLB_consim_export.csv',
523
  mime='text/csv',
524
- )
525
- tab1, tab2 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics'])
526
-
527
- with tab1:
528
- if 'Sim_Winner_Display' in st.session_state:
529
- # Create a new dataframe with summary statistics
530
- summary_df = pd.DataFrame({
531
- 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
532
- 'Salary': [
533
- st.session_state.Sim_Winner_Display['salary'].min(),
534
- st.session_state.Sim_Winner_Display['salary'].mean(),
535
- st.session_state.Sim_Winner_Display['salary'].max(),
536
- st.session_state.Sim_Winner_Display['salary'].std()
537
- ],
538
- 'Proj': [
539
- st.session_state.Sim_Winner_Display['proj'].min(),
540
- st.session_state.Sim_Winner_Display['proj'].mean(),
541
- st.session_state.Sim_Winner_Display['proj'].max(),
542
- st.session_state.Sim_Winner_Display['proj'].std()
543
- ],
544
- 'Own': [
545
- st.session_state.Sim_Winner_Display['Own'].min(),
546
- st.session_state.Sim_Winner_Display['Own'].mean(),
547
- st.session_state.Sim_Winner_Display['Own'].max(),
548
- st.session_state.Sim_Winner_Display['Own'].std()
549
- ],
550
- 'Fantasy': [
551
- st.session_state.Sim_Winner_Display['Fantasy'].min(),
552
- st.session_state.Sim_Winner_Display['Fantasy'].mean(),
553
- st.session_state.Sim_Winner_Display['Fantasy'].max(),
554
- st.session_state.Sim_Winner_Display['Fantasy'].std()
555
- ],
556
- 'GPP_Proj': [
557
- st.session_state.Sim_Winner_Display['GPP_Proj'].min(),
558
- st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),
559
- st.session_state.Sim_Winner_Display['GPP_Proj'].max(),
560
- st.session_state.Sim_Winner_Display['GPP_Proj'].std()
561
- ]
562
- })
563
-
564
- # Set the index of the summary dataframe as the "Metric" column
565
- summary_df = summary_df.set_index('Metric')
566
-
567
- # Display the summary dataframe
568
- st.subheader("Winning Frame Statistics")
569
- st.dataframe(summary_df.style.format({
570
- 'Salary': '{:.2f}',
571
- 'Proj': '{:.2f}',
572
- 'Fantasy': '{:.2f}',
573
- 'GPP_Proj': '{:.2f}'
574
- }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)
575
-
576
  with tab2:
577
- if 'Sim_Winner_Display' in st.session_state:
578
- # Apply position mapping to FLEX column
579
- flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map'])
580
 
581
- # Count occurrences of each position in FLEX
582
- flex_counts = flex_positions.value_counts()
 
 
 
 
 
 
 
 
583
 
584
- # Calculate average statistics for each FLEX position
585
- flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({
586
- 'proj': 'mean',
587
- 'Own': 'mean',
588
- 'Fantasy': 'mean',
589
- 'GPP_Proj': 'mean'
590
- })
 
 
 
591
 
592
- # Combine counts and average statistics
593
- flex_summary = pd.concat([flex_counts, flex_stats], axis=1)
594
- flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
595
- flex_summary = flex_summary.reset_index()
596
- flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
 
 
 
 
 
597
 
598
- # Display the summary dataframe
599
- st.subheader("FLEX Position Statistics")
600
- st.dataframe(flex_summary.style.format({
601
- 'Count': '{:.0f}',
602
- 'Avg Proj': '{:.2f}',
603
- 'Avg Fantasy': '{:.2f}',
604
- 'Avg GPP_Proj': '{:.2f}'
605
- }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)
 
 
606
 
607
- else:
608
- st.write("Simulation data or position mapping not available.")
609
- with st.container():
610
- tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9 = st.tabs(['Overall Exposures', 'QB Exposures', 'RB-WR-TE Exposures', 'RB Exposures', 'WR Exposures', 'TE Exposures', 'FLEX Exposures', 'DST Exposures', 'Team Exposures'])
611
- with tab1:
612
- if 'player_freq' in st.session_state:
613
-
614
- st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
615
- st.download_button(
616
- label="Export Exposures",
617
- data=st.session_state.player_freq.to_csv().encode('utf-8'),
618
- file_name='player_freq_export.csv',
619
- mime='text/csv',
620
- key='overall'
621
- )
622
- with tab2:
623
- if 'qb_freq' in st.session_state:
624
-
625
- st.dataframe(st.session_state.qb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
626
- st.download_button(
627
- label="Export Exposures",
628
- data=st.session_state.qb_freq.to_csv().encode('utf-8'),
629
- file_name='qb_freq.csv',
630
- mime='text/csv',
631
- key='qb'
632
- )
633
- with tab3:
634
- if 'rbwrte_freq' in st.session_state:
635
-
636
- st.dataframe(st.session_state.rbwrte_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
637
- st.download_button(
638
- label="Export Exposures",
639
- data=st.session_state.rbwrte_freq.to_csv().encode('utf-8'),
640
- file_name='rbwrte_freq.csv',
641
- mime='text/csv',
642
- key='rbwrte'
643
- )
644
- with tab4:
645
- if 'rb_freq' in st.session_state:
646
-
647
- st.dataframe(st.session_state.rb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
648
- st.download_button(
649
- label="Export Exposures",
650
- data=st.session_state.rb_freq.to_csv().encode('utf-8'),
651
- file_name='rb_freq.csv',
652
- mime='text/csv',
653
- key='rb'
654
- )
655
- with tab5:
656
- if 'wr_freq' in st.session_state:
657
-
658
- st.dataframe(st.session_state.wr_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
659
- st.download_button(
660
- label="Export Exposures",
661
- data=st.session_state.wr_freq.to_csv().encode('utf-8'),
662
- file_name='wr_freq.csv',
663
- mime='text/csv',
664
- key='wr'
665
- )
666
- with tab6:
667
- if 'te_freq' in st.session_state:
668
-
669
- st.dataframe(st.session_state.te_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
670
- st.download_button(
671
- label="Export Exposures",
672
- data=st.session_state.te_freq.to_csv().encode('utf-8'),
673
- file_name='te_freq.csv',
674
- mime='text/csv',
675
- key='te'
676
- )
677
- with tab7:
678
- if 'flex_freq' in st.session_state:
679
-
680
- st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
681
- st.download_button(
682
- label="Export Exposures",
683
- data=st.session_state.flex_freq.to_csv().encode('utf-8'),
684
- file_name='flex_freq.csv',
685
- mime='text/csv',
686
- key='flex'
687
- )
688
- with tab8:
689
- if 'dst_freq' in st.session_state:
690
-
691
- st.dataframe(st.session_state.dst_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
692
- st.download_button(
693
- label="Export Exposures",
694
- data=st.session_state.dst_freq.to_csv().encode('utf-8'),
695
- file_name='dst_freq.csv',
696
- mime='text/csv',
697
- key='dst'
698
- )
699
- with tab9:
700
- if 'team_freq' in st.session_state:
701
-
702
- st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
703
- st.download_button(
704
- label="Export Exposures",
705
- data=st.session_state.team_freq.to_csv().encode('utf-8'),
706
- file_name='team_freq.csv',
707
- mime='text/csv',
708
- key='team'
709
- )
710
 
711
  if selected_tab == "Data Export":
712
  col1, col2 = st.columns([1, 7])
 
75
  raw_display = pd.DataFrame(list(cursor))
76
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
77
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
 
78
  for col in dict_columns:
79
  raw_display[col] = raw_display[col].map(names_dict)
80
  DK_seed = raw_display.to_numpy()
 
95
  raw_display = pd.DataFrame(list(cursor))
96
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
97
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
 
98
  for col in dict_columns:
99
  raw_display[col] = raw_display[col].map(names_dict)
100
  DK_seed = raw_display.to_numpy()
 
115
  raw_display = pd.DataFrame(list(cursor))
116
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
117
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
 
118
  for col in dict_columns:
119
  raw_display[col] = raw_display[col].map(names_dict)
120
  FD_seed = raw_display.to_numpy()
 
135
  raw_display = pd.DataFrame(list(cursor))
136
  raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
137
  dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
 
138
  for col in dict_columns:
139
  raw_display[col] = raw_display[col].map(names_dict)
140
  FD_seed = raw_display.to_numpy()
 
215
 
216
  return Sim_Winners
217
 
218
+ if st.button("Load/Reset Data", key='reset2'):
219
+ st.cache_data.clear()
220
+ for key in st.session_state.keys():
221
+ del st.session_state[key]
222
+ DK_seed = init_DK_seed_frames(10000)
223
+ FD_seed = init_FD_seed_frames(10000)
224
+ dk_raw, fd_raw = init_baselines('Main Slate')
225
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
226
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
227
+
228
  selected_tab = st.segmented_control(
229
  "Select Tab",
230
  options=["Contest Sims", "Data Export"],
 
236
  )
237
 
238
  if selected_tab == "Contest Sims":
239
+ dk_raw, fd_raw = init_baselines('Main Slate')
240
+ raw_baselines = dk_raw
241
+ column_names = dk_columns
242
+ with st.expander("Info and Filters"):
243
+ slate_data_col, sim_data_col, sim_lock_options, sim_remove_options = st.columns([1, 1, 1, 1])
244
+ with slate_data_col:
245
+ sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate'), key='sim_slate_var1')
246
+ sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
247
+ with sim_data_col:
248
+ contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large'))
249
+ if contest_var1 == 'Small':
250
+ Contest_Size = 1000
251
+ elif contest_var1 == 'Medium':
252
+ Contest_Size = 5000
253
+ elif contest_var1 == 'Large':
254
+ Contest_Size = 10000
255
+ elif contest_var1 == 'Custom':
256
+ Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
257
+ strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
258
+ if strength_var1 == 'Not Very':
259
+ sharp_split = 500000
260
+ elif strength_var1 == 'Below Average':
261
+ sharp_split = 250000
262
+ elif strength_var1 == 'Average':
263
+ sharp_split = 100000
264
+ elif strength_var1 == 'Above Average':
265
+ sharp_split = 50000
266
+ elif strength_var1 == 'Very':
267
+ sharp_split = 10000
268
+ with sim_lock_options:
269
+ player_lock_var1 = st.multiselect("Sim around specific players?", raw_baselines.Player, default=[])
270
+ team_lock_var1 = st.multiselect("Sim around specific teams?", raw_baselines.Team, default=[])
271
+ with sim_remove_options:
272
+ player_remove_var1 = st.multiselect("Remove specific players?", raw_baselines.Player, default=[])
273
+ team_remove_var1 = st.multiselect("Remove specific teams?", raw_baselines.Team, default=[])
274
+
275
+ if st.button("Run Contest Sim"):
276
 
277
+ if 'working_seed' not in st.session_state:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  if sim_site_var1 == 'Draftkings':
279
+ if sim_slate_var1 == 'Main Slate':
280
+ st.session_state.working_seed = init_DK_seed_frames(sharp_split)
281
+ dk_raw, fd_raw = init_baselines('Main Slate')
282
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
283
+ elif sim_slate_var1 == 'Secondary Slate':
284
+ st.session_state.working_seed = init_DK_Secondary_seed_frames(sharp_split)
285
+ dk_raw, fd_raw = init_baselines('Secondary Slate')
286
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
287
+
288
+ raw_baselines = dk_raw
289
+ column_names = dk_columns
290
  elif sim_site_var1 == 'Fanduel':
291
+ if sim_slate_var1 == 'Main Slate':
292
+ st.session_state.working_seed = init_FD_seed_frames(sharp_split)
293
+ dk_raw, fd_raw = init_baselines('Main Slate')
294
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
295
+ elif sim_slate_var1 == 'Secondary Slate':
296
+ st.session_state.working_seed = init_FD_Secondary_seed_frames(sharp_split)
297
+ dk_raw, fd_raw = init_baselines('Secondary Slate')
298
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
299
+
300
+ raw_baselines = fd_raw
301
+ column_names = fd_columns
302
+ st.session_state.maps_dict = {
303
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
304
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
305
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
306
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
307
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
308
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
309
+ }
310
 
311
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
312
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
+ #st.table(Sim_Winner_Frame)
315
+
316
+ # Initial setup
317
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
318
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
319
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
320
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
 
 
 
 
 
 
 
321
 
322
+ # Type Casting
323
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
324
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
 
 
 
 
 
 
 
 
 
 
 
325
 
326
+ # Sorting
327
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
328
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
 
 
 
 
 
 
 
 
 
 
 
329
 
330
+ # Data Copying
331
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
332
  if sim_site_var1 == 'Draftkings':
333
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
334
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)
335
  elif sim_site_var1 == 'Fanduel':
336
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
337
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(fd_id_dict)
 
 
 
 
 
 
 
 
338
 
339
+ # Data Copying
340
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
341
+ st.session_state.freq_copy = st.session_state.Sim_Winner_Display
342
+ else:
343
+ st.session_state.maps_dict = {
344
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
345
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
346
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
347
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
348
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
349
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
350
+ }
 
 
 
 
 
 
 
 
 
 
 
 
351
 
352
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
353
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
354
+
355
+ # Initial setup
356
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
357
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
358
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
359
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
360
+
361
+ # Type Casting
362
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
363
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
364
+
365
+ # Sorting
366
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
367
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
368
+
369
+ # Data Copying
370
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
371
+
372
+ # Data Copying
373
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
374
+
375
+ if sim_site_var1 == 'Draftkings':
376
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
377
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
378
+ elif sim_site_var1 == 'Fanduel':
379
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
380
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
381
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
382
+ freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])
383
+ freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])
384
+ freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
385
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
386
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
387
+ freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])
388
+ st.session_state.player_freq = freq_working.copy()
389
+
390
+ if sim_site_var1 == 'Draftkings':
391
+ qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
392
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
393
+ elif sim_site_var1 == 'Fanduel':
394
+ qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
395
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
396
+ qb_working['Freq'] = qb_working['Freq'].astype(int)
397
+ qb_working['Position'] = qb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
398
+ qb_working['Salary'] = qb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
399
+ qb_working['Proj Own'] = qb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
400
+ qb_working['Exposure'] = qb_working['Freq']/(1000)
401
+ qb_working['Edge'] = qb_working['Exposure'] - qb_working['Proj Own']
402
+ qb_working['Team'] = qb_working['Player'].map(st.session_state.maps_dict['Team_map'])
403
+ st.session_state.qb_freq = qb_working.copy()
404
+
405
+ if sim_site_var1 == 'Draftkings':
406
+ rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
407
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
408
+ elif sim_site_var1 == 'Fanduel':
409
+ rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
410
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
411
+ rbwrte_working['Freq'] = rbwrte_working['Freq'].astype(int)
412
+ rbwrte_working['Position'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Pos_map'])
413
+ rbwrte_working['Salary'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Salary_map'])
414
+ rbwrte_working['Proj Own'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
415
+ rbwrte_working['Exposure'] = rbwrte_working['Freq']/(1000)
416
+ rbwrte_working['Edge'] = rbwrte_working['Exposure'] - rbwrte_working['Proj Own']
417
+ rbwrte_working['Team'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Team_map'])
418
+ st.session_state.rbwrte_freq = rbwrte_working.copy()
419
+
420
+ if sim_site_var1 == 'Draftkings':
421
+ rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
422
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
423
+ elif sim_site_var1 == 'Fanduel':
424
+ rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
425
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
426
+ rb_working['Freq'] = rb_working['Freq'].astype(int)
427
+ rb_working['Position'] = rb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
428
+ rb_working['Salary'] = rb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
429
+ rb_working['Proj Own'] = rb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
430
+ rb_working['Exposure'] = rb_working['Freq']/(1000)
431
+ rb_working['Edge'] = rb_working['Exposure'] - rb_working['Proj Own']
432
+ rb_working['Team'] = rb_working['Player'].map(st.session_state.maps_dict['Team_map'])
433
+ st.session_state.rb_freq = rb_working.copy()
434
+
435
+ if sim_site_var1 == 'Draftkings':
436
+ wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
437
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
438
+ elif sim_site_var1 == 'Fanduel':
439
+ wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
440
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
441
+ wr_working['Freq'] = wr_working['Freq'].astype(int)
442
+ wr_working['Position'] = wr_working['Player'].map(st.session_state.maps_dict['Pos_map'])
443
+ wr_working['Salary'] = wr_working['Player'].map(st.session_state.maps_dict['Salary_map'])
444
+ wr_working['Proj Own'] = wr_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
445
+ wr_working['Exposure'] = wr_working['Freq']/(1000)
446
+ wr_working['Edge'] = wr_working['Exposure'] - wr_working['Proj Own']
447
+ wr_working['Team'] = wr_working['Player'].map(st.session_state.maps_dict['Team_map'])
448
+ st.session_state.wr_freq = wr_working.copy()
449
+
450
+ if sim_site_var1 == 'Draftkings':
451
+ te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
452
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
453
+ elif sim_site_var1 == 'Fanduel':
454
+ te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
455
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
456
+ te_working['Freq'] = te_working['Freq'].astype(int)
457
+ te_working['Position'] = te_working['Player'].map(st.session_state.maps_dict['Pos_map'])
458
+ te_working['Salary'] = te_working['Player'].map(st.session_state.maps_dict['Salary_map'])
459
+ te_working['Proj Own'] = te_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
460
+ te_working['Exposure'] = te_working['Freq']/(1000)
461
+ te_working['Edge'] = te_working['Exposure'] - te_working['Proj Own']
462
+ te_working['Team'] = te_working['Player'].map(st.session_state.maps_dict['Team_map'])
463
+ st.session_state.te_freq = te_working.copy()
464
+
465
+ if sim_site_var1 == 'Draftkings':
466
+ flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
467
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
468
+ elif sim_site_var1 == 'Fanduel':
469
+ flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
470
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
471
+ flex_working['Freq'] = flex_working['Freq'].astype(int)
472
+ flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map'])
473
+ flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map'])
474
+ flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
475
+ flex_working['Exposure'] = flex_working['Freq']/(1000)
476
+ flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
477
+ flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map'])
478
+ st.session_state.flex_freq = flex_working.copy()
479
+
480
+ if sim_site_var1 == 'Draftkings':
481
+ dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
482
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
483
+ elif sim_site_var1 == 'Fanduel':
484
+ dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
485
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
486
+ dst_working['Freq'] = dst_working['Freq'].astype(int)
487
+ dst_working['Position'] = dst_working['Player'].map(st.session_state.maps_dict['Pos_map'])
488
+ dst_working['Salary'] = dst_working['Player'].map(st.session_state.maps_dict['Salary_map'])
489
+ dst_working['Proj Own'] = dst_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
490
+ dst_working['Exposure'] = dst_working['Freq']/(1000)
491
+ dst_working['Edge'] = dst_working['Exposure'] - dst_working['Proj Own']
492
+ dst_working['Team'] = dst_working['Player'].map(st.session_state.maps_dict['Team_map'])
493
+ st.session_state.dst_freq = dst_working.copy()
494
+
495
+ if sim_site_var1 == 'Draftkings':
496
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
497
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
498
+ elif sim_site_var1 == 'Fanduel':
499
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
500
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
501
+ team_working['Freq'] = team_working['Freq'].astype(int)
502
+ team_working['Exposure'] = team_working['Freq']/(1000)
503
+ st.session_state.team_freq = team_working.copy()
504
+
505
+ with st.container():
506
+ if st.button("Reset Sim", key='reset_sim'):
507
+ for key in st.session_state.keys():
508
+ del st.session_state[key]
509
+ if 'player_freq' in st.session_state:
510
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
511
+ if player_split_var2 == 'Specific Players':
512
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
513
+ elif player_split_var2 == 'Full Players':
514
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
515
+
516
+ if player_split_var2 == 'Specific Players':
517
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]
518
+ if player_split_var2 == 'Full Players':
519
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
520
+ if 'Sim_Winner_Display' in st.session_state:
521
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
522
+ if 'Sim_Winner_Export' in st.session_state:
523
+ st.download_button(
524
+ label="Export Full Frame",
525
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
526
+ file_name='MLB_consim_export.csv',
527
+ mime='text/csv',
528
+ )
529
+ tab1, tab2 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics'])
530
 
531
+ with tab1:
532
+ if 'Sim_Winner_Display' in st.session_state:
533
+ # Create a new dataframe with summary statistics
534
+ summary_df = pd.DataFrame({
535
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
536
+ 'Salary': [
537
+ st.session_state.Sim_Winner_Display['salary'].min(),
538
+ st.session_state.Sim_Winner_Display['salary'].mean(),
539
+ st.session_state.Sim_Winner_Display['salary'].max(),
540
+ st.session_state.Sim_Winner_Display['salary'].std()
541
+ ],
542
+ 'Proj': [
543
+ st.session_state.Sim_Winner_Display['proj'].min(),
544
+ st.session_state.Sim_Winner_Display['proj'].mean(),
545
+ st.session_state.Sim_Winner_Display['proj'].max(),
546
+ st.session_state.Sim_Winner_Display['proj'].std()
547
+ ],
548
+ 'Own': [
549
+ st.session_state.Sim_Winner_Display['Own'].min(),
550
+ st.session_state.Sim_Winner_Display['Own'].mean(),
551
+ st.session_state.Sim_Winner_Display['Own'].max(),
552
+ st.session_state.Sim_Winner_Display['Own'].std()
553
+ ],
554
+ 'Fantasy': [
555
+ st.session_state.Sim_Winner_Display['Fantasy'].min(),
556
+ st.session_state.Sim_Winner_Display['Fantasy'].mean(),
557
+ st.session_state.Sim_Winner_Display['Fantasy'].max(),
558
+ st.session_state.Sim_Winner_Display['Fantasy'].std()
559
+ ],
560
+ 'GPP_Proj': [
561
+ st.session_state.Sim_Winner_Display['GPP_Proj'].min(),
562
+ st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),
563
+ st.session_state.Sim_Winner_Display['GPP_Proj'].max(),
564
+ st.session_state.Sim_Winner_Display['GPP_Proj'].std()
565
+ ]
566
+ })
567
+
568
+ # Set the index of the summary dataframe as the "Metric" column
569
+ summary_df = summary_df.set_index('Metric')
570
+
571
+ # Display the summary dataframe
572
+ st.subheader("Winning Frame Statistics")
573
+ st.dataframe(summary_df.style.format({
574
+ 'Salary': '{:.2f}',
575
+ 'Proj': '{:.2f}',
576
+ 'Fantasy': '{:.2f}',
577
+ 'GPP_Proj': '{:.2f}'
578
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)
579
+
580
+ with tab2:
581
+ if 'Sim_Winner_Display' in st.session_state:
582
+ # Apply position mapping to FLEX column
583
+ flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map'])
584
+
585
+ # Count occurrences of each position in FLEX
586
+ flex_counts = flex_positions.value_counts()
587
+
588
+ # Calculate average statistics for each FLEX position
589
+ flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({
590
+ 'proj': 'mean',
591
+ 'Own': 'mean',
592
+ 'Fantasy': 'mean',
593
+ 'GPP_Proj': 'mean'
594
+ })
595
+
596
+ # Combine counts and average statistics
597
+ flex_summary = pd.concat([flex_counts, flex_stats], axis=1)
598
+ flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
599
+ flex_summary = flex_summary.reset_index()
600
+ flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
601
+
602
+ # Display the summary dataframe
603
+ st.subheader("FLEX Position Statistics")
604
+ st.dataframe(flex_summary.style.format({
605
+ 'Count': '{:.0f}',
606
+ 'Avg Proj': '{:.2f}',
607
+ 'Avg Fantasy': '{:.2f}',
608
+ 'Avg GPP_Proj': '{:.2f}'
609
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)
610
+
611
+ else:
612
+ st.write("Simulation data or position mapping not available.")
613
+ with st.container():
614
+ tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9 = st.tabs(['Overall Exposures', 'QB Exposures', 'RB-WR-TE Exposures', 'RB Exposures', 'WR Exposures', 'TE Exposures', 'FLEX Exposures', 'DST Exposures', 'Team Exposures'])
615
+ with tab1:
616
+ if 'player_freq' in st.session_state:
617
+
618
+ st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
619
  st.download_button(
620
+ label="Export Exposures",
621
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
622
+ file_name='player_freq_export.csv',
623
  mime='text/csv',
624
+ key='overall'
625
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
626
  with tab2:
627
+ if 'qb_freq' in st.session_state:
 
 
628
 
629
+ st.dataframe(st.session_state.qb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
630
+ st.download_button(
631
+ label="Export Exposures",
632
+ data=st.session_state.qb_freq.to_csv().encode('utf-8'),
633
+ file_name='qb_freq.csv',
634
+ mime='text/csv',
635
+ key='qb'
636
+ )
637
+ with tab3:
638
+ if 'rbwrte_freq' in st.session_state:
639
 
640
+ st.dataframe(st.session_state.rbwrte_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
641
+ st.download_button(
642
+ label="Export Exposures",
643
+ data=st.session_state.rbwrte_freq.to_csv().encode('utf-8'),
644
+ file_name='rbwrte_freq.csv',
645
+ mime='text/csv',
646
+ key='rbwrte'
647
+ )
648
+ with tab4:
649
+ if 'rb_freq' in st.session_state:
650
 
651
+ st.dataframe(st.session_state.rb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
652
+ st.download_button(
653
+ label="Export Exposures",
654
+ data=st.session_state.rb_freq.to_csv().encode('utf-8'),
655
+ file_name='rb_freq.csv',
656
+ mime='text/csv',
657
+ key='rb'
658
+ )
659
+ with tab5:
660
+ if 'wr_freq' in st.session_state:
661
 
662
+ st.dataframe(st.session_state.wr_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
663
+ st.download_button(
664
+ label="Export Exposures",
665
+ data=st.session_state.wr_freq.to_csv().encode('utf-8'),
666
+ file_name='wr_freq.csv',
667
+ mime='text/csv',
668
+ key='wr'
669
+ )
670
+ with tab6:
671
+ if 'te_freq' in st.session_state:
672
 
673
+ st.dataframe(st.session_state.te_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
674
+ st.download_button(
675
+ label="Export Exposures",
676
+ data=st.session_state.te_freq.to_csv().encode('utf-8'),
677
+ file_name='te_freq.csv',
678
+ mime='text/csv',
679
+ key='te'
680
+ )
681
+ with tab7:
682
+ if 'flex_freq' in st.session_state:
683
+
684
+ st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
685
+ st.download_button(
686
+ label="Export Exposures",
687
+ data=st.session_state.flex_freq.to_csv().encode('utf-8'),
688
+ file_name='flex_freq.csv',
689
+ mime='text/csv',
690
+ key='flex'
691
+ )
692
+ with tab8:
693
+ if 'dst_freq' in st.session_state:
694
+
695
+ st.dataframe(st.session_state.dst_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
696
+ st.download_button(
697
+ label="Export Exposures",
698
+ data=st.session_state.dst_freq.to_csv().encode('utf-8'),
699
+ file_name='dst_freq.csv',
700
+ mime='text/csv',
701
+ key='dst'
702
+ )
703
+ with tab9:
704
+ if 'team_freq' in st.session_state:
705
+
706
+ st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
707
+ st.download_button(
708
+ label="Export Exposures",
709
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
710
+ file_name='team_freq.csv',
711
+ mime='text/csv',
712
+ key='team'
713
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
714
 
715
  if selected_tab == "Data Export":
716
  col1, col2 = st.columns([1, 7])