James McCool
commited on
Commit
·
801e44a
1
Parent(s):
a73a1c5
Refactor Streamlit app to enhance handbuilder data handling by adding site filtering, updating collection names for DraftKings and FanDuel, and improving tab selection logic with segmented controls for better user experience.
Browse files- src/streamlit_app.py +656 -713
src/streamlit_app.py
CHANGED
|
@@ -81,6 +81,8 @@ def init_handbuilder_data(site_var):
|
|
| 81 |
raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
|
| 82 |
'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
|
| 83 |
load_display = raw_display[raw_display['Position'] != 'K']
|
|
|
|
|
|
|
| 84 |
return load_display.dropna(subset=['Median'])
|
| 85 |
else:
|
| 86 |
collection = db["FD_NFL_ROO"]
|
|
@@ -90,6 +92,8 @@ def init_handbuilder_data(site_var):
|
|
| 90 |
raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
|
| 91 |
'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
|
| 92 |
load_display = raw_display[raw_display['Position'] != 'K']
|
|
|
|
|
|
|
| 93 |
return load_display.dropna(subset=['Median'])
|
| 94 |
|
| 95 |
@st.cache_resource(ttl=60)
|
|
@@ -292,13 +296,13 @@ def init_FD_lineups(type_var, slate_var):
|
|
| 292 |
raw_display = pd.DataFrame(list(cursor))
|
| 293 |
raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
|
| 294 |
elif slate_var == 'Secondary':
|
| 295 |
-
collection = db['
|
| 296 |
cursor = collection.find().limit(10000)
|
| 297 |
|
| 298 |
raw_display = pd.DataFrame(list(cursor))
|
| 299 |
raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
|
| 300 |
elif slate_var == 'Auxiliary':
|
| 301 |
-
collection = db['
|
| 302 |
cursor = collection.find().limit(10000)
|
| 303 |
|
| 304 |
raw_display = pd.DataFrame(list(cursor))
|
|
@@ -348,28 +352,34 @@ player_stats, dk_stacks_raw, fd_stacks_raw, dk_roo_raw, fd_roo_raw, dk_sd_roo_ra
|
|
| 348 |
|
| 349 |
t_stamp = f"Last Update: " + str(dk_roo_raw['timestamp'][0]) + f" CST"
|
| 350 |
|
| 351 |
-
|
| 352 |
-
|
| 353 |
if 'current_tab' not in st.session_state:
|
| 354 |
st.session_state['current_tab'] = 'Handbuilder'
|
| 355 |
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
|
| 367 |
-
|
| 368 |
if site_var == 'Draftkings':
|
| 369 |
-
handbuild_roo =
|
| 370 |
else:
|
| 371 |
-
handbuild_roo =
|
| 372 |
|
|
|
|
| 373 |
handbuilder_header_column, handbuilder_slate_column = st.columns(2)
|
| 374 |
with handbuilder_header_column:
|
| 375 |
st.header("Handbuilder")
|
|
@@ -399,7 +409,6 @@ with handbuilder_tab:
|
|
| 399 |
'TE': 1,
|
| 400 |
'UTIL': 1,
|
| 401 |
'DST': 1,
|
| 402 |
-
# Add more as needed
|
| 403 |
}
|
| 404 |
max_salary = 50000
|
| 405 |
max_players = 9
|
|
@@ -411,7 +420,6 @@ with handbuilder_tab:
|
|
| 411 |
'TE': 1,
|
| 412 |
'UTIL': 1,
|
| 413 |
'DST': 1,
|
| 414 |
-
# Add more as needed
|
| 415 |
}
|
| 416 |
max_salary = 60000
|
| 417 |
max_players = 9
|
|
@@ -449,7 +457,7 @@ with handbuilder_tab:
|
|
| 449 |
if checked:
|
| 450 |
selected_teams.append(team)
|
| 451 |
|
| 452 |
-
#
|
| 453 |
if selected_teams:
|
| 454 |
player_select_df = handbuild_roo[
|
| 455 |
handbuild_roo['Team'].isin(selected_teams)
|
|
@@ -457,77 +465,45 @@ with handbuilder_tab:
|
|
| 457 |
else:
|
| 458 |
player_select_df = handbuild_roo[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 459 |
|
| 460 |
-
# If no teams selected, show all teams
|
| 461 |
if pos_select3:
|
| 462 |
position_mask_2 = handbuild_roo['Position'].apply(lambda x: any(pos in x for pos in pos_select3))
|
| 463 |
player_select_df = player_select_df[position_mask_2][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 464 |
-
else:
|
| 465 |
-
player_select_df = player_select_df[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 466 |
|
| 467 |
player_select_df = player_select_df[player_select_df['Salary'] <= salary_var]
|
| 468 |
|
| 469 |
-
|
| 470 |
with st.expander("Quick Fill Options"):
|
| 471 |
auto_team_var = st.selectbox("Auto Fill Team", options=all_teams, key='auto_team_selectbox')
|
| 472 |
auto_size_var = st.selectbox("Auto Fill Size", options=[3, 4, 5], key='auto_size_selectbox')
|
| 473 |
auto_range_var = st.selectbox("Auto Fill Options", options=['QB/WR', 'RB/WR/TE', 'QB/WR/TE/RB'], key='auto_range_selectbox')
|
| 474 |
-
|
| 475 |
if st.button("Quick Fill", key="quick_fill_button"):
|
| 476 |
-
#
|
| 477 |
current_players = set(st.session_state['handbuilder_lineup']['Player'])
|
| 478 |
team_players = player_select_df[
|
| 479 |
(player_select_df['Team'] == auto_team_var) &
|
| 480 |
(~player_select_df['Player'].isin(current_players))
|
| 481 |
].copy()
|
| 482 |
-
|
| 483 |
-
# 2. Sort by Order
|
| 484 |
team_players = team_players.sort_values(by='Median', ascending=False)
|
| 485 |
-
|
| 486 |
-
# 3. Select the order range
|
| 487 |
if auto_range_var == 'QB/WR':
|
| 488 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 489 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'] == 'WR'].head(auto_size_var - 1)])
|
| 490 |
-
if len(selected_players) < auto_size_var:
|
| 491 |
-
team_players = player_select_df[
|
| 492 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 493 |
-
(~player_select_df['Player'].isin(current_players))
|
| 494 |
-
].copy()
|
| 495 |
-
|
| 496 |
-
# 2. Sort by Order
|
| 497 |
-
team_players = team_players.sort_values(by='Median', ascending=False)
|
| 498 |
-
selected_players = team_players.head(auto_size_var + 1)
|
| 499 |
elif auto_range_var == 'QB/WR/TE':
|
| 500 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 501 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['WR', 'TE'])].head(auto_size_var - 1)])
|
| 502 |
-
if len(selected_players) < auto_size_var:
|
| 503 |
-
team_players = player_select_df[
|
| 504 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 505 |
-
(~player_select_df['Player'].isin(current_players))
|
| 506 |
-
].copy()
|
| 507 |
-
|
| 508 |
-
# 2. Sort by Order
|
| 509 |
-
team_players = team_players.sort_values(by='Median', ascending=False)
|
| 510 |
-
selected_players = team_players.head(auto_size_var + 1)
|
| 511 |
elif auto_range_var == 'QB/WR/TE/RB':
|
| 512 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 513 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['RB', 'WR', 'TE'])].head(auto_size_var - 1)])
|
| 514 |
-
if len(selected_players) < auto_size_var:
|
| 515 |
-
team_players = player_select_df[
|
| 516 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 517 |
-
(~player_select_df['Player'].isin(current_players))
|
| 518 |
-
].copy()
|
| 519 |
-
|
| 520 |
-
# 2. Sort by Order
|
| 521 |
-
team_players = team_players.sort_values(by='Median', ascending=False)
|
| 522 |
-
selected_players = team_players.head(auto_size_var + 1)
|
| 523 |
else:
|
| 524 |
selected_players = team_players.head(auto_size_var)
|
| 525 |
-
|
| 526 |
-
#
|
| 527 |
for _, player_row in selected_players.iterrows():
|
| 528 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'])
|
| 529 |
slot_to_fill = None
|
| 530 |
-
|
| 531 |
for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
|
| 532 |
if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
|
| 533 |
if slot == 'UTIL':
|
|
@@ -537,89 +513,79 @@ with handbuilder_tab:
|
|
| 537 |
elif slot in eligible_positions:
|
| 538 |
slot_to_fill = slot
|
| 539 |
break
|
| 540 |
-
|
| 541 |
if slot_to_fill is not None:
|
| 542 |
-
# Avoid duplicates
|
| 543 |
if player_row['Player'] not in st.session_state['handbuilder_lineup']['Player'].values:
|
| 544 |
add_row = player_row.copy()
|
| 545 |
add_row['Slot'] = slot_to_fill
|
| 546 |
st.session_state['handbuilder_lineup'] = pd.concat(
|
| 547 |
-
[st.session_state['handbuilder_lineup'], pd.DataFrame([add_row[[
|
| 548 |
-
'Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot'
|
| 549 |
-
]]])],
|
| 550 |
ignore_index=True
|
| 551 |
)
|
| 552 |
-
# Update slot_counts for next player
|
| 553 |
slot_counts[slot_to_fill] = slot_counts.get(slot_to_fill, 0) + 1
|
| 554 |
st.rerun()
|
| 555 |
|
| 556 |
-
# ---
|
| 557 |
-
def is_player_eligible(row):
|
| 558 |
-
eligible_positions = re.split(r'[/, ]+', row['Position'])
|
| 559 |
-
# Player is eligible if at least one of their positions is not at max
|
| 560 |
-
for pos in eligible_positions:
|
| 561 |
-
if slot_counts.get(pos, 0) < position_limits.get(pos, 0):
|
| 562 |
-
return True
|
| 563 |
-
return False
|
| 564 |
-
|
| 565 |
-
# player_select_df = player_select_df[player_select_df.apply(is_player_eligible, axis=1)]
|
| 566 |
-
print(player_select_df.head(10))
|
| 567 |
-
|
| 568 |
handbuilder_lineup_build_column, handbuilder_player_select_column = st.columns([1, 2])
|
|
|
|
| 569 |
with handbuilder_player_select_column:
|
| 570 |
st.subheader("Player Select")
|
| 571 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 572 |
player_select_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
|
| 573 |
-
on_select="rerun",
|
| 574 |
-
selection_mode=["single-row"],
|
| 575 |
-
key=f"handbuilder_select_{st.session_state['handbuilder_select_key']}",
|
| 576 |
height=500,
|
| 577 |
-
hide_index=True
|
|
|
|
| 578 |
)
|
| 579 |
-
# If a row is selected, add that player to the lineup and reset selection
|
| 580 |
-
if event and "rows" in event.selection and len(event.selection["rows"]) > 0:
|
| 581 |
-
idx = event.selection["rows"][0]
|
| 582 |
-
player_row = player_select_df.iloc[[idx]]
|
| 583 |
-
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
| 584 |
-
# Find the first eligible slot that is not full
|
| 585 |
-
slot_to_fill = None
|
| 586 |
-
|
| 587 |
-
for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
|
| 588 |
-
if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
|
| 589 |
-
if slot == 'UTIL':
|
| 590 |
-
if 'DST' not in eligible_positions and 'QB' not in eligible_positions:
|
| 591 |
-
slot_to_fill = slot
|
| 592 |
-
break
|
| 593 |
-
elif slot in eligible_positions:
|
| 594 |
-
slot_to_fill = slot
|
| 595 |
-
break
|
| 596 |
-
|
| 597 |
-
if slot_to_fill is not None:
|
| 598 |
-
# Avoid duplicates
|
| 599 |
-
if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
|
| 600 |
-
# Add the slot info
|
| 601 |
-
player_row = player_row.assign(Slot=slot_to_fill)
|
| 602 |
-
st.session_state['handbuilder_lineup'] = pd.concat(
|
| 603 |
-
[st.session_state['handbuilder_lineup'], player_row[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot']]],
|
| 604 |
-
ignore_index=True
|
| 605 |
-
)
|
| 606 |
-
st.session_state['handbuilder_select_key'] += 1
|
| 607 |
-
st.rerun()
|
| 608 |
-
|
| 609 |
|
| 610 |
with handbuilder_lineup_build_column:
|
| 611 |
st.subheader("Lineup Build")
|
| 612 |
-
|
| 613 |
-
#
|
| 614 |
if site_var == 'Draftkings':
|
| 615 |
lineup_slots = ['QB', 'RB', 'RB', 'WR', 'WR', 'WR', 'TE', 'UTIL', 'DST']
|
| 616 |
else:
|
| 617 |
lineup_slots = ['QB', 'RB', 'RB', 'WR', 'WR', 'WR', 'TE', 'UTIL', 'DST']
|
|
|
|
| 618 |
display_columns = ['Slot', 'Player', 'Position', 'Team', 'Salary', 'Median', 'Own']
|
| 619 |
-
|
| 620 |
filled_lineup = st.session_state['handbuilder_lineup']
|
| 621 |
display_rows = []
|
| 622 |
used_indices = set()
|
|
|
|
| 623 |
if not filled_lineup.empty:
|
| 624 |
for slot in lineup_slots:
|
| 625 |
match = filled_lineup[(filled_lineup['Slot'] == slot) & (~filled_lineup.index.isin(used_indices))]
|
|
@@ -647,52 +613,41 @@ with handbuilder_tab:
|
|
| 647 |
'2x%': np.nan,
|
| 648 |
'Own': np.nan
|
| 649 |
})
|
| 650 |
-
|
| 651 |
lineup_display_df = pd.DataFrame(display_rows, columns=display_columns)
|
| 652 |
-
|
| 653 |
-
#
|
| 654 |
-
|
| 655 |
lineup_display_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn', subset=['Median']).background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
|
| 656 |
-
on_select="rerun",
|
| 657 |
-
selection_mode=["single-row"],
|
| 658 |
-
key="lineup_remove_dataframe",
|
| 659 |
height=445,
|
| 660 |
-
hide_index=True
|
|
|
|
| 661 |
)
|
| 662 |
-
|
| 663 |
-
#
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
|
|
|
|
|
|
|
|
|
|
| 669 |
st.session_state['handbuilder_lineup'] = filled_lineup[
|
| 670 |
-
~((filled_lineup['Player'] == player_to_remove)
|
| 671 |
]
|
| 672 |
st.rerun()
|
| 673 |
-
|
| 674 |
-
#
|
| 675 |
if not filled_lineup.empty:
|
| 676 |
total_salary = filled_lineup['Salary'].sum()
|
| 677 |
total_median = filled_lineup['Median'].sum()
|
| 678 |
avg_2x = filled_lineup['2x%'].mean()
|
| 679 |
total_own = filled_lineup['Own'].sum()
|
| 680 |
most_common_team = filled_lineup['Team'].mode()[0] if not filled_lineup['Team'].mode().empty else ""
|
| 681 |
-
|
| 682 |
-
summary_row = pd.DataFrame({
|
| 683 |
-
'Slot': [''],
|
| 684 |
-
'Player': ['TOTAL'],
|
| 685 |
-
'Position': [''],
|
| 686 |
-
'Team': [most_common_team],
|
| 687 |
-
'Salary': [total_salary],
|
| 688 |
-
'Median': [total_median],
|
| 689 |
-
'2x%': [avg_2x],
|
| 690 |
-
'Own': [total_own]
|
| 691 |
-
})
|
| 692 |
-
summary_row = summary_row[['Salary', 'Median', 'Own']].head(max_players)
|
| 693 |
|
| 694 |
handbuilder_lineup_build_salary_column, handbuilder_lineup_build_median_column = st.columns([2, 3])
|
| 695 |
-
|
| 696 |
with handbuilder_lineup_build_salary_column:
|
| 697 |
if (max_players - len(filled_lineup)) > 0:
|
| 698 |
st.markdown(f"""
|
|
@@ -708,7 +663,7 @@ with handbuilder_tab:
|
|
| 708 |
</div>
|
| 709 |
""",
|
| 710 |
unsafe_allow_html=True)
|
| 711 |
-
|
| 712 |
with handbuilder_lineup_build_median_column:
|
| 713 |
if total_salary <= max_salary:
|
| 714 |
st.markdown(
|
|
@@ -730,25 +685,22 @@ with handbuilder_tab:
|
|
| 730 |
""",
|
| 731 |
unsafe_allow_html=True
|
| 732 |
)
|
| 733 |
-
|
| 734 |
-
#
|
| 735 |
clear_col, save_col, export_col, clear_saved_col, blank_col = st.columns([2, 2, 2, 2, 12])
|
| 736 |
with clear_col:
|
| 737 |
if st.button("Clear Lineup", key='clear_lineup_button'):
|
| 738 |
-
st.session_state['handbuilder_lineup'] = pd.DataFrame(columns=['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own'
|
| 739 |
st.rerun()
|
| 740 |
with save_col:
|
| 741 |
if st.button("Save Lineup", key='save_lineup_button'):
|
| 742 |
if 'saved_lineups' in st.session_state:
|
| 743 |
st.session_state['saved_lineups'].append(lineup_display_df['Player'].tolist())
|
| 744 |
-
print(st.session_state['saved_lineups'])
|
| 745 |
else:
|
| 746 |
st.session_state['saved_lineups'] = [lineup_display_df['Player'].tolist()]
|
| 747 |
-
print(st.session_state['saved_lineups'])
|
| 748 |
st.rerun()
|
| 749 |
with export_col:
|
| 750 |
if 'saved_lineups' in st.session_state and st.session_state['saved_lineups']:
|
| 751 |
-
# Convert list of lists to numpy array
|
| 752 |
saved_lineups_array = np.array(st.session_state['saved_lineups'])
|
| 753 |
st.download_button(
|
| 754 |
label="Export Handbuilds",
|
|
@@ -771,608 +723,599 @@ with handbuilder_tab:
|
|
| 771 |
del st.session_state['saved_lineups']
|
| 772 |
st.rerun()
|
| 773 |
|
| 774 |
-
|
| 775 |
-
|
| 776 |
-
|
| 777 |
-
|
| 778 |
-
st.info(t_stamp)
|
| 779 |
-
with st.container():
|
| 780 |
-
slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Late Slate', 'Thurs-Mon Slate'), key='slate_var1_radio')
|
| 781 |
-
split_var1 = st.radio("Would you like to view the whole slate or just specific games?", ('Full Slate Run', 'Specific Games'), key='split_var1_radio')
|
| 782 |
-
if site_var == 'Draftkings':
|
| 783 |
-
raw_baselines = dk_stacks_raw[dk_stacks_raw['slate'] == str(slate_var1)]
|
| 784 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'overall']
|
| 785 |
-
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 786 |
-
elif site_var == 'Fanduel':
|
| 787 |
-
raw_baselines = fd_stacks_raw[fd_stacks_raw['slate'] == str(slate_var1)]
|
| 788 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'overall']
|
| 789 |
-
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 790 |
-
if split_var1 == 'Specific Games':
|
| 791 |
-
team_var1 = st.multiselect('Which teams would you like to include in the ROO?', options = raw_baselines['Team'].unique(), key='team_var1_multiselect')
|
| 792 |
-
elif split_var1 == 'Full Slate Run':
|
| 793 |
-
team_var1 = raw_baselines.Team.values.tolist()
|
| 794 |
-
|
| 795 |
-
final_stacks = raw_baselines[raw_baselines['Team'].isin(team_var1)]
|
| 796 |
-
if view_var == 'Simple':
|
| 797 |
-
final_stacks = final_stacks[['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Salary', 'Median', '60+%', '4x%']]
|
| 798 |
-
elif view_var == 'Advanced':
|
| 799 |
-
final_stacks = final_stacks[['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Total', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish',
|
| 800 |
-
'Top_10_finish', '60+%', '2x%', '3x%', '4x%', 'Own', 'LevX']]
|
| 801 |
with st.container():
|
| 802 |
-
st.
|
| 803 |
-
st.
|
| 804 |
-
label="Export Tables",
|
| 805 |
-
data=convert_df_to_csv(final_stacks),
|
| 806 |
-
file_name='NFL_stacks_export.csv',
|
| 807 |
-
mime='text/csv',
|
| 808 |
-
key='stacks_export_button'
|
| 809 |
-
)
|
| 810 |
-
|
| 811 |
-
with player_tab:
|
| 812 |
-
st.session_state['current_tab'] = 'Player ROO'
|
| 813 |
-
if st.session_state['current_tab'] == 'Player ROO':
|
| 814 |
-
with st.expander("Info and Filters"):
|
| 815 |
-
st.info(t_stamp)
|
| 816 |
-
slate_var2 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Late Slate', 'Thurs-Mon Slate'), key='slate_var2_radio')
|
| 817 |
if site_var == 'Draftkings':
|
| 818 |
-
raw_baselines =
|
| 819 |
-
|
| 820 |
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 821 |
elif site_var == 'Fanduel':
|
| 822 |
-
raw_baselines =
|
|
|
|
| 823 |
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 824 |
-
|
| 825 |
-
|
| 826 |
-
|
| 827 |
-
|
| 828 |
-
|
| 829 |
-
|
| 830 |
-
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
elif site_var == 'Fanduel':
|
| 839 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_qbs']
|
| 840 |
-
elif pos_split2 == 'RB':
|
| 841 |
-
if site_var == 'Draftkings':
|
| 842 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_rbs']
|
| 843 |
-
elif site_var == 'Fanduel':
|
| 844 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_rbs']
|
| 845 |
-
elif pos_split2 == 'WR':
|
| 846 |
-
if site_var == 'Draftkings':
|
| 847 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_wrs']
|
| 848 |
-
elif site_var == 'Fanduel':
|
| 849 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_wrs']
|
| 850 |
-
elif pos_split2 == 'TE':
|
| 851 |
-
if site_var == 'Draftkings':
|
| 852 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_tes']
|
| 853 |
-
elif site_var == 'Fanduel':
|
| 854 |
-
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_tes']
|
| 855 |
-
raw_baselines = raw_baselines[raw_baselines['Position'].str.contains('|'.join(pos_combos2))]
|
| 856 |
-
final_Proj = raw_baselines[raw_baselines['Team'].isin(team_var2)]
|
| 857 |
-
final_Proj = final_Proj[final_Proj['Salary'] >= sal_var2[0]]
|
| 858 |
-
final_Proj = final_Proj[final_Proj['Salary'] <= sal_var2[1]]
|
| 859 |
-
|
| 860 |
-
if view_var == 'Simple':
|
| 861 |
-
final_Proj = final_Proj[['Player', 'Position', 'Team', 'Salary', 'Median', 'Top_5_finish', '4x%']]
|
| 862 |
-
disp_proj = final_Proj.set_index('Player')
|
| 863 |
-
elif view_var == 'Advanced':
|
| 864 |
-
final_Proj = final_Proj[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX']]
|
| 865 |
-
disp_proj = final_Proj.set_index('Player')
|
| 866 |
-
with st.container():
|
| 867 |
-
st.dataframe(disp_proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, key='player_dataframe')
|
| 868 |
-
st.download_button(
|
| 869 |
label="Export Tables",
|
| 870 |
-
data=convert_df_to_csv(
|
| 871 |
-
file_name='
|
| 872 |
mime='text/csv',
|
| 873 |
-
key='
|
| 874 |
-
|
| 875 |
|
| 876 |
-
|
| 877 |
-
|
| 878 |
-
|
| 879 |
-
st.
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
|
| 883 |
-
|
| 884 |
-
|
| 885 |
-
|
| 886 |
-
|
| 887 |
-
|
| 888 |
-
|
| 889 |
-
|
| 890 |
-
|
| 891 |
-
|
| 892 |
-
|
| 893 |
-
|
| 894 |
-
|
| 895 |
-
|
| 896 |
-
|
| 897 |
-
|
| 898 |
-
|
| 899 |
-
|
| 900 |
-
|
| 901 |
-
|
| 902 |
-
|
| 903 |
-
|
| 904 |
-
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
|
| 908 |
-
|
| 909 |
-
|
| 910 |
-
|
| 911 |
-
|
| 912 |
-
|
| 913 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 914 |
if site_var == 'Draftkings':
|
| 915 |
-
|
| 916 |
-
salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 50000, value = 50000, step = 100, key = 'salary_max_var_dk')
|
| 917 |
elif site_var == 'Fanduel':
|
| 918 |
-
|
| 919 |
-
|
| 920 |
-
with optimals_stacks_col:
|
| 921 |
if site_var == 'Draftkings':
|
| 922 |
-
|
| 923 |
-
max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 5, value = 5, step = 1, key = 'max_stacks_var_dk')
|
| 924 |
elif site_var == 'Fanduel':
|
| 925 |
-
|
| 926 |
-
|
| 927 |
-
|
| 928 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 929 |
if site_var == 'Draftkings':
|
| 930 |
-
|
| 931 |
-
|
| 932 |
-
|
| 933 |
-
|
| 934 |
-
|
| 935 |
-
|
| 936 |
-
|
| 937 |
-
|
| 938 |
-
|
| 939 |
-
|
| 940 |
elif site_var == 'Fanduel':
|
| 941 |
-
|
| 942 |
-
|
| 943 |
-
|
| 944 |
-
|
| 945 |
-
|
| 946 |
-
|
| 947 |
-
|
| 948 |
-
|
| 949 |
-
|
| 950 |
-
|
| 951 |
-
|
| 952 |
-
|
| 953 |
-
|
| 954 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 955 |
if site_var == 'Draftkings':
|
| 956 |
if slate_type_var3 == 'Regular':
|
| 957 |
-
|
| 958 |
-
for col_idx in map_columns:
|
| 959 |
-
data_export[col_idx] = data_export[col_idx].map(dk_id_map)
|
| 960 |
elif slate_type_var3 == 'Showdown':
|
| 961 |
-
|
| 962 |
-
for col_idx in map_columns:
|
| 963 |
-
data_export[col_idx] = data_export[col_idx].map(dk_sd_id_map)
|
| 964 |
elif site_var == 'Fanduel':
|
| 965 |
if slate_type_var3 == 'Regular':
|
| 966 |
-
|
| 967 |
-
for col_idx in map_columns:
|
| 968 |
-
data_export[col_idx] = data_export[col_idx].map(fd_id_map)
|
| 969 |
elif slate_type_var3 == 'Showdown':
|
| 970 |
-
|
| 971 |
-
|
| 972 |
-
|
| 973 |
-
|
| 974 |
-
|
| 975 |
-
|
| 976 |
-
|
| 977 |
-
|
| 978 |
-
|
| 979 |
-
mime='text/csv',
|
| 980 |
-
key='export_optimals_ids_button'
|
| 981 |
-
)
|
| 982 |
-
st.download_button(
|
| 983 |
-
label="Export optimals set (Names)",
|
| 984 |
-
data=convert_df(name_export),
|
| 985 |
-
file_name='NFL_optimals_export.csv',
|
| 986 |
-
mime='text/csv',
|
| 987 |
-
key='export_optimals_names_button'
|
| 988 |
-
)
|
| 989 |
-
with pm_opt_col:
|
| 990 |
-
if site_var == 'Draftkings':
|
| 991 |
-
if slate_type_var3 == 'Regular':
|
| 992 |
-
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 993 |
-
elif slate_type_var3 == 'Showdown':
|
| 994 |
-
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 995 |
-
elif site_var == 'Fanduel':
|
| 996 |
-
if slate_type_var3 == 'Regular':
|
| 997 |
-
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 998 |
-
elif slate_type_var3 == 'Showdown':
|
| 999 |
-
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1000 |
-
st.download_button(
|
| 1001 |
-
label="Portfolio Manager Export (IDs)",
|
| 1002 |
-
data=convert_pm_df(data_export),
|
| 1003 |
-
file_name='NFL_optimals_export.csv',
|
| 1004 |
-
mime='text/csv',
|
| 1005 |
-
key='export_pm_ids_button'
|
| 1006 |
-
)
|
| 1007 |
-
|
| 1008 |
-
if site_var == 'Draftkings':
|
| 1009 |
-
if slate_type_var3 == 'Regular':
|
| 1010 |
-
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1011 |
-
elif slate_type_var3 == 'Showdown':
|
| 1012 |
-
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1013 |
-
elif site_var == 'Fanduel':
|
| 1014 |
-
if slate_type_var3 == 'Regular':
|
| 1015 |
-
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1016 |
-
elif slate_type_var3 == 'Showdown':
|
| 1017 |
-
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1018 |
-
st.download_button(
|
| 1019 |
-
label="Portfolio Manager Export (Names)",
|
| 1020 |
-
data=convert_pm_df(name_export),
|
| 1021 |
-
file_name='NFL_optimals_export.csv',
|
| 1022 |
-
mime='text/csv',
|
| 1023 |
-
key='export_pm_names_button'
|
| 1024 |
-
)
|
| 1025 |
-
with filtered_dl_col:
|
| 1026 |
-
if st.button("Prepare full data export (Filtered)", key='data_export_filtered_button'):
|
| 1027 |
-
name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
|
| 1028 |
-
data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
|
| 1029 |
if site_var == 'Draftkings':
|
| 1030 |
if slate_type_var3 == 'Regular':
|
| 1031 |
-
|
| 1032 |
elif slate_type_var3 == 'Showdown':
|
| 1033 |
-
|
| 1034 |
-
for col_idx in map_columns:
|
| 1035 |
-
data_export[col_idx] = data_export[col_idx].map(dk_id_map)
|
| 1036 |
elif site_var == 'Fanduel':
|
| 1037 |
if slate_type_var3 == 'Regular':
|
| 1038 |
-
|
| 1039 |
elif slate_type_var3 == 'Showdown':
|
| 1040 |
-
|
| 1041 |
-
|
| 1042 |
-
|
| 1043 |
-
|
| 1044 |
-
|
| 1045 |
-
|
| 1046 |
-
|
| 1047 |
-
|
| 1048 |
-
|
| 1049 |
-
|
| 1050 |
-
|
| 1051 |
-
|
| 1052 |
-
|
| 1053 |
-
reg_opt_col, pm_opt_col = st.columns(2)
|
| 1054 |
-
with reg_opt_col:
|
| 1055 |
-
st.download_button(
|
| 1056 |
-
label="Export optimals set (IDs)",
|
| 1057 |
-
data=convert_df(data_export),
|
| 1058 |
-
file_name='NFL_optimals_export.csv',
|
| 1059 |
-
mime='text/csv',
|
| 1060 |
-
key='export_filtered_optimals_ids_button'
|
| 1061 |
-
)
|
| 1062 |
-
st.download_button(
|
| 1063 |
-
label="Export optimals set (Names)",
|
| 1064 |
-
data=convert_df(name_export),
|
| 1065 |
-
file_name='NFL_optimals_export.csv',
|
| 1066 |
-
mime='text/csv',
|
| 1067 |
-
key='export_filtered_optimals_names_button'
|
| 1068 |
-
)
|
| 1069 |
-
with pm_opt_col:
|
| 1070 |
-
if site_var == 'Draftkings':
|
| 1071 |
-
if slate_type_var3 == 'Regular':
|
| 1072 |
-
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1073 |
-
elif slate_type_var3 == 'Showdown':
|
| 1074 |
-
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1075 |
-
elif site_var == 'Fanduel':
|
| 1076 |
-
if slate_type_var3 == 'Regular':
|
| 1077 |
-
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1078 |
-
elif slate_type_var3 == 'Showdown':
|
| 1079 |
-
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1080 |
-
st.download_button(
|
| 1081 |
-
label="Portfolio Manager Export (IDs)",
|
| 1082 |
-
data=convert_pm_df(data_export),
|
| 1083 |
-
file_name='NFL_optimals_export.csv',
|
| 1084 |
-
mime='text/csv',
|
| 1085 |
-
key='export_filtered_pm_ids_button'
|
| 1086 |
-
)
|
| 1087 |
-
|
| 1088 |
-
if site_var == 'Draftkings':
|
| 1089 |
-
if slate_type_var3 == 'Regular':
|
| 1090 |
-
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1091 |
-
elif slate_type_var3 == 'Showdown':
|
| 1092 |
-
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1093 |
-
elif site_var == 'Fanduel':
|
| 1094 |
-
if slate_type_var3 == 'Regular':
|
| 1095 |
-
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1096 |
-
elif slate_type_var3 == 'Showdown':
|
| 1097 |
-
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1098 |
-
st.download_button(
|
| 1099 |
-
label="Portfolio Manager Export (Names)",
|
| 1100 |
-
data=convert_pm_df(name_export),
|
| 1101 |
-
file_name='NFL_optimals_export.csv',
|
| 1102 |
-
mime='text/csv',
|
| 1103 |
-
key='export_filtered_pm_names_button'
|
| 1104 |
-
)
|
| 1105 |
-
|
| 1106 |
-
if site_var == 'Draftkings':
|
| 1107 |
-
if 'working_seed' in st.session_state:
|
| 1108 |
-
st.session_state.working_seed = st.session_state.working_seed
|
| 1109 |
-
if player_var1 == 'Specific Players':
|
| 1110 |
-
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1111 |
-
elif player_var1 == 'Full Slate':
|
| 1112 |
-
st.session_state.working_seed = dk_lineups.copy()
|
| 1113 |
-
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1114 |
-
elif 'working_seed' not in st.session_state:
|
| 1115 |
-
st.session_state.working_seed = dk_lineups.copy()
|
| 1116 |
-
st.session_state.working_seed = st.session_state.working_seed
|
| 1117 |
-
if player_var1 == 'Specific Players':
|
| 1118 |
-
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1119 |
-
elif player_var1 == 'Full Slate':
|
| 1120 |
-
st.session_state.working_seed = dk_lineups.copy()
|
| 1121 |
-
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1122 |
-
|
| 1123 |
-
elif site_var == 'Fanduel':
|
| 1124 |
-
if 'working_seed' in st.session_state:
|
| 1125 |
-
st.session_state.working_seed = st.session_state.working_seed
|
| 1126 |
-
if player_var1 == 'Specific Players':
|
| 1127 |
-
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1128 |
-
elif player_var1 == 'Full Slate':
|
| 1129 |
-
st.session_state.working_seed = fd_lineups.copy()
|
| 1130 |
-
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1131 |
-
elif 'working_seed' not in st.session_state:
|
| 1132 |
-
st.session_state.working_seed = fd_lineups.copy()
|
| 1133 |
-
st.session_state.working_seed = st.session_state.working_seed
|
| 1134 |
-
if player_var1 == 'Specific Players':
|
| 1135 |
-
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1136 |
-
elif player_var1 == 'Full Slate':
|
| 1137 |
-
st.session_state.working_seed = fd_lineups.copy()
|
| 1138 |
-
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1139 |
-
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] >= salary_min_var]
|
| 1140 |
-
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] <= salary_max_var]
|
| 1141 |
-
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] >= min_stacks_var]
|
| 1142 |
-
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] <= max_stacks_var]
|
| 1143 |
-
export_file = st.session_state.data_export_display.copy()
|
| 1144 |
-
name_export = st.session_state.data_export_display.copy()
|
| 1145 |
-
if site_var == 'Draftkings':
|
| 1146 |
-
if slate_type_var3 == 'Regular':
|
| 1147 |
-
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 1148 |
-
elif slate_type_var3 == 'Showdown':
|
| 1149 |
-
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 1150 |
-
for col_idx in map_columns:
|
| 1151 |
-
export_file[col_idx] = export_file[col_idx].map(dk_id_map)
|
| 1152 |
-
elif site_var == 'Fanduel':
|
| 1153 |
-
if slate_type_var3 == 'Regular':
|
| 1154 |
-
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 1155 |
-
elif slate_type_var3 == 'Showdown':
|
| 1156 |
-
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 1157 |
-
for col_idx in map_columns:
|
| 1158 |
-
export_file[col_idx] = export_file[col_idx].map(fd_id_map)
|
| 1159 |
-
|
| 1160 |
-
with st.container():
|
| 1161 |
-
if st.button("Reset Optimals", key='reset_optimals_button'):
|
| 1162 |
-
for key in st.session_state.keys():
|
| 1163 |
-
del st.session_state[key]
|
| 1164 |
if site_var == 'Draftkings':
|
| 1165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1166 |
elif site_var == 'Fanduel':
|
| 1167 |
-
|
| 1168 |
-
|
| 1169 |
-
|
| 1170 |
-
|
| 1171 |
-
|
| 1172 |
-
|
| 1173 |
-
|
| 1174 |
-
|
| 1175 |
-
|
| 1176 |
-
|
| 1177 |
-
|
| 1178 |
-
|
| 1179 |
-
|
| 1180 |
-
|
| 1181 |
-
|
| 1182 |
-
|
| 1183 |
-
|
| 1184 |
-
|
| 1185 |
-
|
| 1186 |
-
|
| 1187 |
-
|
| 1188 |
-
|
| 1189 |
-
|
| 1190 |
-
|
| 1191 |
-
|
| 1192 |
-
|
| 1193 |
-
|
| 1194 |
-
|
| 1195 |
-
|
| 1196 |
-
|
| 1197 |
-
|
| 1198 |
-
|
| 1199 |
-
|
| 1200 |
-
|
| 1201 |
-
np.max(st.session_state.working_seed[:,10]),
|
| 1202 |
-
np.std(st.session_state.working_seed[:,10])
|
| 1203 |
-
],
|
| 1204 |
-
'Own': [
|
| 1205 |
-
np.min(st.session_state.working_seed[:,15]),
|
| 1206 |
-
np.mean(st.session_state.working_seed[:,15]),
|
| 1207 |
-
np.max(st.session_state.working_seed[:,15]),
|
| 1208 |
-
np.std(st.session_state.working_seed[:,15])
|
| 1209 |
-
]
|
| 1210 |
-
})
|
| 1211 |
-
elif site_var == 'Fanduel':
|
| 1212 |
-
summary_df = pd.DataFrame({
|
| 1213 |
-
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1214 |
-
'Salary': [
|
| 1215 |
-
np.min(st.session_state.working_seed[:,9]),
|
| 1216 |
-
np.mean(st.session_state.working_seed[:,9]),
|
| 1217 |
-
np.max(st.session_state.working_seed[:,9]),
|
| 1218 |
-
np.std(st.session_state.working_seed[:,9])
|
| 1219 |
-
],
|
| 1220 |
-
'Proj': [
|
| 1221 |
-
np.min(st.session_state.working_seed[:,10]),
|
| 1222 |
-
np.mean(st.session_state.working_seed[:,10]),
|
| 1223 |
-
np.max(st.session_state.working_seed[:,10]),
|
| 1224 |
-
np.std(st.session_state.working_seed[:,10])
|
| 1225 |
-
],
|
| 1226 |
-
'Own': [
|
| 1227 |
-
np.min(st.session_state.working_seed[:,15]),
|
| 1228 |
-
np.mean(st.session_state.working_seed[:,15]),
|
| 1229 |
-
np.max(st.session_state.working_seed[:,15]),
|
| 1230 |
-
np.std(st.session_state.working_seed[:,15])
|
| 1231 |
-
]
|
| 1232 |
-
})
|
| 1233 |
-
elif slate_type_var3 == 'Showdown':
|
| 1234 |
-
if 'working_seed' in st.session_state:
|
| 1235 |
-
# Create a new dataframe with summary statistics
|
| 1236 |
-
if site_var == 'Draftkings':
|
| 1237 |
-
summary_df = pd.DataFrame({
|
| 1238 |
-
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1239 |
-
'Salary': [
|
| 1240 |
-
np.min(st.session_state.working_seed[:,6]),
|
| 1241 |
-
np.mean(st.session_state.working_seed[:,6]),
|
| 1242 |
-
np.max(st.session_state.working_seed[:,6]),
|
| 1243 |
-
np.std(st.session_state.working_seed[:,6])
|
| 1244 |
-
],
|
| 1245 |
-
'Proj': [
|
| 1246 |
-
np.min(st.session_state.working_seed[:,7]),
|
| 1247 |
-
np.mean(st.session_state.working_seed[:,7]),
|
| 1248 |
-
np.max(st.session_state.working_seed[:,7]),
|
| 1249 |
-
np.std(st.session_state.working_seed[:,7])
|
| 1250 |
-
],
|
| 1251 |
-
'Own': [
|
| 1252 |
-
np.min(st.session_state.working_seed[:,12]),
|
| 1253 |
-
np.mean(st.session_state.working_seed[:,12]),
|
| 1254 |
-
np.max(st.session_state.working_seed[:,12]),
|
| 1255 |
-
np.std(st.session_state.working_seed[:,12])
|
| 1256 |
-
]
|
| 1257 |
-
})
|
| 1258 |
-
elif site_var == 'Fanduel':
|
| 1259 |
-
summary_df = pd.DataFrame({
|
| 1260 |
-
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1261 |
-
'Salary': [
|
| 1262 |
-
np.min(st.session_state.working_seed[:,6]),
|
| 1263 |
-
np.mean(st.session_state.working_seed[:,6]),
|
| 1264 |
-
np.max(st.session_state.working_seed[:,6]),
|
| 1265 |
-
np.std(st.session_state.working_seed[:,6])
|
| 1266 |
-
],
|
| 1267 |
-
'Proj': [
|
| 1268 |
-
np.min(st.session_state.working_seed[:,7]),
|
| 1269 |
-
np.mean(st.session_state.working_seed[:,7]),
|
| 1270 |
-
np.max(st.session_state.working_seed[:,7]),
|
| 1271 |
-
np.std(st.session_state.working_seed[:,7])
|
| 1272 |
-
],
|
| 1273 |
-
'Own': [
|
| 1274 |
-
np.min(st.session_state.working_seed[:,12]),
|
| 1275 |
-
np.mean(st.session_state.working_seed[:,12]),
|
| 1276 |
-
np.max(st.session_state.working_seed[:,12]),
|
| 1277 |
-
np.std(st.session_state.working_seed[:,12])
|
| 1278 |
-
]
|
| 1279 |
-
})
|
| 1280 |
-
|
| 1281 |
-
# Set the index of the summary dataframe as the "Metric" column
|
| 1282 |
-
summary_df = summary_df.set_index('Metric')
|
| 1283 |
-
|
| 1284 |
-
# Display the summary dataframe
|
| 1285 |
-
st.subheader("Optimal Statistics")
|
| 1286 |
-
st.dataframe(summary_df.style.format({
|
| 1287 |
-
'Salary': '{:.2f}',
|
| 1288 |
-
'Proj': '{:.2f}',
|
| 1289 |
-
'Own': '{:.2f}'
|
| 1290 |
-
}).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True, key='optimal_stats_dataframe')
|
| 1291 |
-
|
| 1292 |
-
with st.container():
|
| 1293 |
-
display_freq_tab, seed_frame_freq_tab = st.tabs(["Display Frequency", "Seed Frame Frequency"])
|
| 1294 |
-
with display_freq_tab:
|
| 1295 |
-
if 'data_export_display' in st.session_state:
|
| 1296 |
if site_var == 'Draftkings':
|
| 1297 |
if slate_type_var3 == 'Regular':
|
| 1298 |
-
|
| 1299 |
elif slate_type_var3 == 'Showdown':
|
| 1300 |
-
|
| 1301 |
elif site_var == 'Fanduel':
|
| 1302 |
if slate_type_var3 == 'Regular':
|
| 1303 |
-
|
| 1304 |
elif slate_type_var3 == 'Showdown':
|
| 1305 |
-
|
| 1306 |
-
|
| 1307 |
-
# Flatten the DataFrame and count unique values
|
| 1308 |
-
value_counts = player_columns.values.flatten().tolist()
|
| 1309 |
-
value_counts = pd.Series(value_counts).value_counts()
|
| 1310 |
-
|
| 1311 |
-
percentages = (value_counts / lineup_num_var * 100).round(2)
|
| 1312 |
-
|
| 1313 |
-
# Create a DataFrame with the results
|
| 1314 |
-
summary_df = pd.DataFrame({
|
| 1315 |
-
'Player': value_counts.index,
|
| 1316 |
-
'Frequency': value_counts.values,
|
| 1317 |
-
'Percentage': percentages.values
|
| 1318 |
-
})
|
| 1319 |
-
|
| 1320 |
-
# Sort by frequency in descending order
|
| 1321 |
-
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
| 1322 |
-
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
| 1323 |
-
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
| 1324 |
-
summary_df = summary_df.set_index('Player')
|
| 1325 |
-
|
| 1326 |
-
# Display the table
|
| 1327 |
-
st.write("Player Frequency Table:")
|
| 1328 |
-
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True, key='player_frequency_dataframe')
|
| 1329 |
-
|
| 1330 |
st.download_button(
|
| 1331 |
-
label="Export
|
| 1332 |
-
data=
|
| 1333 |
-
file_name='
|
| 1334 |
mime='text/csv',
|
| 1335 |
-
key='
|
| 1336 |
)
|
| 1337 |
-
|
| 1338 |
-
if 'working_seed' in st.session_state:
|
| 1339 |
if site_var == 'Draftkings':
|
| 1340 |
if slate_type_var3 == 'Regular':
|
| 1341 |
-
|
| 1342 |
elif slate_type_var3 == 'Showdown':
|
| 1343 |
-
|
| 1344 |
elif site_var == 'Fanduel':
|
| 1345 |
if slate_type_var3 == 'Regular':
|
| 1346 |
-
|
| 1347 |
elif slate_type_var3 == 'Showdown':
|
| 1348 |
-
|
| 1349 |
-
|
| 1350 |
-
# Flatten the DataFrame and count unique values
|
| 1351 |
-
value_counts = player_columns.flatten().tolist()
|
| 1352 |
-
value_counts = pd.Series(value_counts).value_counts()
|
| 1353 |
-
|
| 1354 |
-
percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
|
| 1355 |
-
# Create a DataFrame with the results
|
| 1356 |
-
summary_df = pd.DataFrame({
|
| 1357 |
-
'Player': value_counts.index,
|
| 1358 |
-
'Frequency': value_counts.values,
|
| 1359 |
-
'Percentage': percentages.values
|
| 1360 |
-
})
|
| 1361 |
-
|
| 1362 |
-
# Sort by frequency in descending order
|
| 1363 |
-
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
| 1364 |
-
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
| 1365 |
-
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
| 1366 |
-
summary_df = summary_df.set_index('Player')
|
| 1367 |
-
|
| 1368 |
-
# Display the table
|
| 1369 |
-
st.write("Seed Frame Frequency Table:")
|
| 1370 |
-
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True, key='seed_frame_frequency_dataframe')
|
| 1371 |
-
|
| 1372 |
st.download_button(
|
| 1373 |
-
label="
|
| 1374 |
-
data=
|
| 1375 |
-
file_name='
|
| 1376 |
mime='text/csv',
|
| 1377 |
-
key='
|
| 1378 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
|
| 82 |
'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
|
| 83 |
load_display = raw_display[raw_display['Position'] != 'K']
|
| 84 |
+
# Add site column for filtering
|
| 85 |
+
load_display['site'] = 'dk'
|
| 86 |
return load_display.dropna(subset=['Median'])
|
| 87 |
else:
|
| 88 |
collection = db["FD_NFL_ROO"]
|
|
|
|
| 92 |
raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
|
| 93 |
'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
|
| 94 |
load_display = raw_display[raw_display['Position'] != 'K']
|
| 95 |
+
# Add site column for filtering
|
| 96 |
+
load_display['site'] = 'fd'
|
| 97 |
return load_display.dropna(subset=['Median'])
|
| 98 |
|
| 99 |
@st.cache_resource(ttl=60)
|
|
|
|
| 296 |
raw_display = pd.DataFrame(list(cursor))
|
| 297 |
raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
|
| 298 |
elif slate_var == 'Secondary':
|
| 299 |
+
collection = db['DK_NFL_SD2_seed_frame']
|
| 300 |
cursor = collection.find().limit(10000)
|
| 301 |
|
| 302 |
raw_display = pd.DataFrame(list(cursor))
|
| 303 |
raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
|
| 304 |
elif slate_var == 'Auxiliary':
|
| 305 |
+
collection = db['DK_NFL_SD3_seed_frame']
|
| 306 |
cursor = collection.find().limit(10000)
|
| 307 |
|
| 308 |
raw_display = pd.DataFrame(list(cursor))
|
|
|
|
| 352 |
|
| 353 |
t_stamp = f"Last Update: " + str(dk_roo_raw['timestamp'][0]) + f" CST"
|
| 354 |
|
| 355 |
+
# Replace tabs with segmented control for conditional rendering
|
|
|
|
| 356 |
if 'current_tab' not in st.session_state:
|
| 357 |
st.session_state['current_tab'] = 'Handbuilder'
|
| 358 |
|
| 359 |
+
selected_tab = st.segmented_control(
|
| 360 |
+
"Select Tab",
|
| 361 |
+
options=["Handbuilder", "Stacks ROO", "Player ROO", "Optimals"],
|
| 362 |
+
default=st.session_state['current_tab'],
|
| 363 |
+
key='tab_selector'
|
| 364 |
+
)
|
| 365 |
+
|
| 366 |
+
# Update session state with selected tab
|
| 367 |
+
st.session_state['current_tab'] = selected_tab
|
| 368 |
+
|
| 369 |
+
# Conditionally render content based on selected tab
|
| 370 |
+
if selected_tab == 'Handbuilder':
|
| 371 |
+
# Load only handbuilder data for performance
|
| 372 |
+
if 'handbuilder_data' not in st.session_state or site_var not in st.session_state.get('handbuilder_site', ''):
|
| 373 |
+
st.session_state['handbuilder_data'] = init_handbuilder_data(site_var)
|
| 374 |
+
st.session_state['handbuilder_site'] = site_var
|
| 375 |
|
| 376 |
+
handbuild_roo = st.session_state['handbuilder_data']
|
| 377 |
if site_var == 'Draftkings':
|
| 378 |
+
handbuild_roo = handbuild_roo[handbuild_roo['site'] == 'dk']
|
| 379 |
else:
|
| 380 |
+
handbuild_roo = handbuild_roo[handbuild_roo['site'] == 'fd']
|
| 381 |
|
| 382 |
+
# Handbuilder content
|
| 383 |
handbuilder_header_column, handbuilder_slate_column = st.columns(2)
|
| 384 |
with handbuilder_header_column:
|
| 385 |
st.header("Handbuilder")
|
|
|
|
| 409 |
'TE': 1,
|
| 410 |
'UTIL': 1,
|
| 411 |
'DST': 1,
|
|
|
|
| 412 |
}
|
| 413 |
max_salary = 50000
|
| 414 |
max_players = 9
|
|
|
|
| 420 |
'TE': 1,
|
| 421 |
'UTIL': 1,
|
| 422 |
'DST': 1,
|
|
|
|
| 423 |
}
|
| 424 |
max_salary = 60000
|
| 425 |
max_players = 9
|
|
|
|
| 457 |
if checked:
|
| 458 |
selected_teams.append(team)
|
| 459 |
|
| 460 |
+
# Filter players based on selections
|
| 461 |
if selected_teams:
|
| 462 |
player_select_df = handbuild_roo[
|
| 463 |
handbuild_roo['Team'].isin(selected_teams)
|
|
|
|
| 465 |
else:
|
| 466 |
player_select_df = handbuild_roo[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 467 |
|
|
|
|
| 468 |
if pos_select3:
|
| 469 |
position_mask_2 = handbuild_roo['Position'].apply(lambda x: any(pos in x for pos in pos_select3))
|
| 470 |
player_select_df = player_select_df[position_mask_2][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
|
|
|
|
|
|
| 471 |
|
| 472 |
player_select_df = player_select_df[player_select_df['Salary'] <= salary_var]
|
| 473 |
|
| 474 |
+
# --- QUICK FILL OPTIONS ---
|
| 475 |
with st.expander("Quick Fill Options"):
|
| 476 |
auto_team_var = st.selectbox("Auto Fill Team", options=all_teams, key='auto_team_selectbox')
|
| 477 |
auto_size_var = st.selectbox("Auto Fill Size", options=[3, 4, 5], key='auto_size_selectbox')
|
| 478 |
auto_range_var = st.selectbox("Auto Fill Options", options=['QB/WR', 'RB/WR/TE', 'QB/WR/TE/RB'], key='auto_range_selectbox')
|
| 479 |
+
|
| 480 |
if st.button("Quick Fill", key="quick_fill_button"):
|
| 481 |
+
# Quick fill logic (existing code)
|
| 482 |
current_players = set(st.session_state['handbuilder_lineup']['Player'])
|
| 483 |
team_players = player_select_df[
|
| 484 |
(player_select_df['Team'] == auto_team_var) &
|
| 485 |
(~player_select_df['Player'].isin(current_players))
|
| 486 |
].copy()
|
| 487 |
+
|
|
|
|
| 488 |
team_players = team_players.sort_values(by='Median', ascending=False)
|
| 489 |
+
|
|
|
|
| 490 |
if auto_range_var == 'QB/WR':
|
| 491 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 492 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'] == 'WR'].head(auto_size_var - 1)])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 493 |
elif auto_range_var == 'QB/WR/TE':
|
| 494 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 495 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['WR', 'TE'])].head(auto_size_var - 1)])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 496 |
elif auto_range_var == 'QB/WR/TE/RB':
|
| 497 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 498 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['RB', 'WR', 'TE'])].head(auto_size_var - 1)])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 499 |
else:
|
| 500 |
selected_players = team_players.head(auto_size_var)
|
| 501 |
+
|
| 502 |
+
# Add players to lineup
|
| 503 |
for _, player_row in selected_players.iterrows():
|
| 504 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'])
|
| 505 |
slot_to_fill = None
|
| 506 |
+
|
| 507 |
for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
|
| 508 |
if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
|
| 509 |
if slot == 'UTIL':
|
|
|
|
| 513 |
elif slot in eligible_positions:
|
| 514 |
slot_to_fill = slot
|
| 515 |
break
|
| 516 |
+
|
| 517 |
if slot_to_fill is not None:
|
|
|
|
| 518 |
if player_row['Player'] not in st.session_state['handbuilder_lineup']['Player'].values:
|
| 519 |
add_row = player_row.copy()
|
| 520 |
add_row['Slot'] = slot_to_fill
|
| 521 |
st.session_state['handbuilder_lineup'] = pd.concat(
|
| 522 |
+
[st.session_state['handbuilder_lineup'], pd.DataFrame([add_row[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot']]])],
|
|
|
|
|
|
|
| 523 |
ignore_index=True
|
| 524 |
)
|
|
|
|
| 525 |
slot_counts[slot_to_fill] = slot_counts.get(slot_to_fill, 0) + 1
|
| 526 |
st.rerun()
|
| 527 |
|
| 528 |
+
# --- PLAYER SELECTION AND LINEUP BUILDING ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 529 |
handbuilder_lineup_build_column, handbuilder_player_select_column = st.columns([1, 2])
|
| 530 |
+
|
| 531 |
with handbuilder_player_select_column:
|
| 532 |
st.subheader("Player Select")
|
| 533 |
+
|
| 534 |
+
# Use a more efficient selection method
|
| 535 |
+
selected_player = st.selectbox(
|
| 536 |
+
"Select a player to add:",
|
| 537 |
+
options=player_select_df['Player'].tolist(),
|
| 538 |
+
key="player_selection_dropdown"
|
| 539 |
+
)
|
| 540 |
+
|
| 541 |
+
if st.button("Add Selected Player", key="add_selected_player_button"):
|
| 542 |
+
if selected_player:
|
| 543 |
+
player_row = player_select_df[player_select_df['Player'] == selected_player]
|
| 544 |
+
if not player_row.empty:
|
| 545 |
+
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
| 546 |
+
slot_to_fill = None
|
| 547 |
+
|
| 548 |
+
for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
|
| 549 |
+
if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
|
| 550 |
+
if slot == 'UTIL':
|
| 551 |
+
if 'DST' not in eligible_positions and 'QB' not in eligible_positions:
|
| 552 |
+
slot_to_fill = slot
|
| 553 |
+
break
|
| 554 |
+
elif slot in eligible_positions:
|
| 555 |
+
slot_to_fill = slot
|
| 556 |
+
break
|
| 557 |
+
|
| 558 |
+
if slot_to_fill is not None:
|
| 559 |
+
if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
|
| 560 |
+
player_row = player_row.assign(Slot=slot_to_fill)
|
| 561 |
+
st.session_state['handbuilder_lineup'] = pd.concat(
|
| 562 |
+
[st.session_state['handbuilder_lineup'], player_row[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot']]],
|
| 563 |
+
ignore_index=True
|
| 564 |
+
)
|
| 565 |
+
st.rerun()
|
| 566 |
+
|
| 567 |
+
# Display the dataframe for reference (without selection)
|
| 568 |
+
st.dataframe(
|
| 569 |
player_select_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
|
|
|
|
|
|
|
|
|
|
| 570 |
height=500,
|
| 571 |
+
hide_index=True,
|
| 572 |
+
key="handbuilder_player_display"
|
| 573 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 574 |
|
| 575 |
with handbuilder_lineup_build_column:
|
| 576 |
st.subheader("Lineup Build")
|
| 577 |
+
|
| 578 |
+
# Lineup display logic (existing code)
|
| 579 |
if site_var == 'Draftkings':
|
| 580 |
lineup_slots = ['QB', 'RB', 'RB', 'WR', 'WR', 'WR', 'TE', 'UTIL', 'DST']
|
| 581 |
else:
|
| 582 |
lineup_slots = ['QB', 'RB', 'RB', 'WR', 'WR', 'WR', 'TE', 'UTIL', 'DST']
|
| 583 |
+
|
| 584 |
display_columns = ['Slot', 'Player', 'Position', 'Team', 'Salary', 'Median', 'Own']
|
|
|
|
| 585 |
filled_lineup = st.session_state['handbuilder_lineup']
|
| 586 |
display_rows = []
|
| 587 |
used_indices = set()
|
| 588 |
+
|
| 589 |
if not filled_lineup.empty:
|
| 590 |
for slot in lineup_slots:
|
| 591 |
match = filled_lineup[(filled_lineup['Slot'] == slot) & (~filled_lineup.index.isin(used_indices))]
|
|
|
|
| 613 |
'2x%': np.nan,
|
| 614 |
'Own': np.nan
|
| 615 |
})
|
| 616 |
+
|
| 617 |
lineup_display_df = pd.DataFrame(display_rows, columns=display_columns)
|
| 618 |
+
|
| 619 |
+
# Display lineup with removal functionality
|
| 620 |
+
st.dataframe(
|
| 621 |
lineup_display_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn', subset=['Median']).background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
|
|
|
|
|
|
|
|
|
|
| 622 |
height=445,
|
| 623 |
+
hide_index=True,
|
| 624 |
+
key="lineup_display_dataframe"
|
| 625 |
)
|
| 626 |
+
|
| 627 |
+
# Remove player functionality
|
| 628 |
+
player_to_remove = st.selectbox(
|
| 629 |
+
"Select a player to remove:",
|
| 630 |
+
options=[row['Player'] for row in display_rows if row['Player']],
|
| 631 |
+
key="player_removal_dropdown"
|
| 632 |
+
)
|
| 633 |
+
|
| 634 |
+
if st.button("Remove Selected Player", key="remove_selected_player_button"):
|
| 635 |
+
if player_to_remove:
|
| 636 |
st.session_state['handbuilder_lineup'] = filled_lineup[
|
| 637 |
+
~((filled_lineup['Player'] == player_to_remove))
|
| 638 |
]
|
| 639 |
st.rerun()
|
| 640 |
+
|
| 641 |
+
# Summary row
|
| 642 |
if not filled_lineup.empty:
|
| 643 |
total_salary = filled_lineup['Salary'].sum()
|
| 644 |
total_median = filled_lineup['Median'].sum()
|
| 645 |
avg_2x = filled_lineup['2x%'].mean()
|
| 646 |
total_own = filled_lineup['Own'].sum()
|
| 647 |
most_common_team = filled_lineup['Team'].mode()[0] if not filled_lineup['Team'].mode().empty else ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 648 |
|
| 649 |
handbuilder_lineup_build_salary_column, handbuilder_lineup_build_median_column = st.columns([2, 3])
|
| 650 |
+
|
| 651 |
with handbuilder_lineup_build_salary_column:
|
| 652 |
if (max_players - len(filled_lineup)) > 0:
|
| 653 |
st.markdown(f"""
|
|
|
|
| 663 |
</div>
|
| 664 |
""",
|
| 665 |
unsafe_allow_html=True)
|
| 666 |
+
|
| 667 |
with handbuilder_lineup_build_median_column:
|
| 668 |
if total_salary <= max_salary:
|
| 669 |
st.markdown(
|
|
|
|
| 685 |
""",
|
| 686 |
unsafe_allow_html=True
|
| 687 |
)
|
| 688 |
+
|
| 689 |
+
# Action buttons
|
| 690 |
clear_col, save_col, export_col, clear_saved_col, blank_col = st.columns([2, 2, 2, 2, 12])
|
| 691 |
with clear_col:
|
| 692 |
if st.button("Clear Lineup", key='clear_lineup_button'):
|
| 693 |
+
st.session_state['handbuilder_lineup'] = pd.DataFrame(columns=['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own'])
|
| 694 |
st.rerun()
|
| 695 |
with save_col:
|
| 696 |
if st.button("Save Lineup", key='save_lineup_button'):
|
| 697 |
if 'saved_lineups' in st.session_state:
|
| 698 |
st.session_state['saved_lineups'].append(lineup_display_df['Player'].tolist())
|
|
|
|
| 699 |
else:
|
| 700 |
st.session_state['saved_lineups'] = [lineup_display_df['Player'].tolist()]
|
|
|
|
| 701 |
st.rerun()
|
| 702 |
with export_col:
|
| 703 |
if 'saved_lineups' in st.session_state and st.session_state['saved_lineups']:
|
|
|
|
| 704 |
saved_lineups_array = np.array(st.session_state['saved_lineups'])
|
| 705 |
st.download_button(
|
| 706 |
label="Export Handbuilds",
|
|
|
|
| 723 |
del st.session_state['saved_lineups']
|
| 724 |
st.rerun()
|
| 725 |
|
| 726 |
+
elif selected_tab == 'Stacks ROO':
|
| 727 |
+
# Stacks ROO content
|
| 728 |
+
with st.expander("Info and Filters"):
|
| 729 |
+
st.info(t_stamp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 730 |
with st.container():
|
| 731 |
+
slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Late Slate', 'Thurs-Mon Slate'), key='slate_var1_radio')
|
| 732 |
+
split_var1 = st.radio("Would you like to view the whole slate or just specific games?", ('Full Slate Run', 'Specific Games'), key='split_var1_radio')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 733 |
if site_var == 'Draftkings':
|
| 734 |
+
raw_baselines = dk_stacks_raw[dk_stacks_raw['slate'] == str(slate_var1)]
|
| 735 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'overall']
|
| 736 |
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 737 |
elif site_var == 'Fanduel':
|
| 738 |
+
raw_baselines = fd_stacks_raw[fd_stacks_raw['slate'] == str(slate_var1)]
|
| 739 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'overall']
|
| 740 |
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 741 |
+
if split_var1 == 'Specific Games':
|
| 742 |
+
team_var1 = st.multiselect('Which teams would you like to include in the ROO?', options = raw_baselines['Team'].unique(), key='team_var1_multiselect')
|
| 743 |
+
elif split_var1 == 'Full Slate Run':
|
| 744 |
+
team_var1 = raw_baselines.Team.values.tolist()
|
| 745 |
+
|
| 746 |
+
final_stacks = raw_baselines[raw_baselines['Team'].isin(team_var1)]
|
| 747 |
+
if view_var == 'Simple':
|
| 748 |
+
final_stacks = final_stacks[['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Salary', 'Median', '60+%', '4x%']]
|
| 749 |
+
elif view_var == 'Advanced':
|
| 750 |
+
final_stacks = final_stacks[['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Total', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish',
|
| 751 |
+
'Top_10_finish', '60+%', '2x%', '3x%', '4x%', 'Own', 'LevX']]
|
| 752 |
+
with st.container():
|
| 753 |
+
st.dataframe(final_stacks.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, key='stacks_dataframe')
|
| 754 |
+
st.download_button(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 755 |
label="Export Tables",
|
| 756 |
+
data=convert_df_to_csv(final_stacks),
|
| 757 |
+
file_name='NFL_stacks_export.csv',
|
| 758 |
mime='text/csv',
|
| 759 |
+
key='stacks_export_button'
|
| 760 |
+
)
|
| 761 |
|
| 762 |
+
elif selected_tab == 'Player ROO':
|
| 763 |
+
# Player ROO content
|
| 764 |
+
with st.expander("Info and Filters"):
|
| 765 |
+
st.info(t_stamp)
|
| 766 |
+
slate_var2 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Late Slate', 'Thurs-Mon Slate'), key='slate_var2_radio')
|
| 767 |
+
if site_var == 'Draftkings':
|
| 768 |
+
raw_baselines = dk_roo_raw[dk_roo_raw['slate'] == str(slate_var2)]
|
| 769 |
+
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 770 |
+
elif site_var == 'Fanduel':
|
| 771 |
+
raw_baselines = fd_roo_raw[fd_roo_raw['slate'] == str(slate_var2)]
|
| 772 |
+
raw_baselines = raw_baselines.iloc[:,:-2]
|
| 773 |
+
split_var2 = st.radio("Would you like to view the whole slate or just specific games?", ('Full Slate Run', 'Specific Games'), key='split_var2_radio')
|
| 774 |
+
if split_var2 == 'Specific Games':
|
| 775 |
+
team_var2 = st.multiselect('Which teams would you like to include in the ROO?', options = raw_baselines['Team'].unique(), key='team_var2_multiselect')
|
| 776 |
+
elif split_var2 == 'Full Slate Run':
|
| 777 |
+
team_var2 = raw_baselines.Team.values.tolist()
|
| 778 |
+
pos_split2 = st.selectbox('What Position table would you like to view?', options = ['Overall', 'QB', 'RB', 'WR', 'TE'], key='pos_split2_selectbox')
|
| 779 |
+
pos_combos2 = st.multiselect('If Overall, specific positions?', options = ['QB', 'RB', 'WR', 'TE', 'DST'], default = ['QB', 'RB', 'WR', 'TE', 'DST'], key='pos_combos2_multiselect')
|
| 780 |
+
sal_var2 = st.slider("Is there a certain price range you want to view?", 2000, 15000, (2000, 15000), key='sal_var2_slider')
|
| 781 |
+
|
| 782 |
+
if pos_split2 == 'Overall':
|
| 783 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'overall']
|
| 784 |
+
elif pos_split2 == 'QB':
|
| 785 |
+
if site_var == 'Draftkings':
|
| 786 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_qbs']
|
| 787 |
+
elif site_var == 'Fanduel':
|
| 788 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_qbs']
|
| 789 |
+
elif pos_split2 == 'RB':
|
| 790 |
+
if site_var == 'Draftkings':
|
| 791 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_rbs']
|
| 792 |
+
elif site_var == 'Fanduel':
|
| 793 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_rbs']
|
| 794 |
+
elif pos_split2 == 'WR':
|
| 795 |
+
if site_var == 'Draftkings':
|
| 796 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_wrs']
|
| 797 |
+
elif site_var == 'Fanduel':
|
| 798 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_wrs']
|
| 799 |
+
elif pos_split2 == 'TE':
|
| 800 |
+
if site_var == 'Draftkings':
|
| 801 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'dk_tes']
|
| 802 |
+
elif site_var == 'Fanduel':
|
| 803 |
+
raw_baselines = raw_baselines[raw_baselines['version'] == 'fd_tes']
|
| 804 |
+
raw_baselines = raw_baselines[raw_baselines['Position'].str.contains('|'.join(pos_combos2))]
|
| 805 |
+
final_Proj = raw_baselines[raw_baselines['Team'].isin(team_var2)]
|
| 806 |
+
final_Proj = final_Proj[final_Proj['Salary'] >= sal_var2[0]]
|
| 807 |
+
final_Proj = final_Proj[final_Proj['Salary'] <= sal_var2[1]]
|
| 808 |
+
|
| 809 |
+
if view_var == 'Simple':
|
| 810 |
+
final_Proj = final_Proj[['Player', 'Position', 'Team', 'Salary', 'Median', 'Top_5_finish', '4x%']]
|
| 811 |
+
disp_proj = final_Proj.set_index('Player')
|
| 812 |
+
elif view_var == 'Advanced':
|
| 813 |
+
final_Proj = final_Proj[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX']]
|
| 814 |
+
disp_proj = final_Proj.set_index('Player')
|
| 815 |
+
with st.container():
|
| 816 |
+
st.dataframe(disp_proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, key='player_dataframe')
|
| 817 |
+
st.download_button(
|
| 818 |
+
label="Export Tables",
|
| 819 |
+
data=convert_df_to_csv(final_Proj),
|
| 820 |
+
file_name='NFL_ROO_export.csv',
|
| 821 |
+
mime='text/csv',
|
| 822 |
+
key='player_export_button'
|
| 823 |
+
)
|
| 824 |
+
|
| 825 |
+
elif selected_tab == 'Optimals':
|
| 826 |
+
# Optimals content
|
| 827 |
+
st.header("Optimals")
|
| 828 |
+
with st.expander("Info and Filters"):
|
| 829 |
+
st.info("These filters will display various optimals in the table below to pick from. If you want to export the entire set of 10,000 optimals, hit the 'Prepare full data export' button. If you would like to apply the filters here to the 10,000 optimals before you export, use the 'Prepare full data export (Filter)' button.")
|
| 830 |
+
col1, col2, col3, col4 = st.columns(4)
|
| 831 |
+
with col1:
|
| 832 |
+
slate_type_var3 = st.radio("Which slate type are you loading?", ('Regular', 'Showdown'), key='slate_type_var3_radio')
|
| 833 |
+
if slate_type_var3 == 'Regular':
|
| 834 |
if site_var == 'Draftkings':
|
| 835 |
+
raw_baselines = dk_roo_raw
|
|
|
|
| 836 |
elif site_var == 'Fanduel':
|
| 837 |
+
raw_baselines = fd_roo_raw
|
| 838 |
+
elif slate_type_var3 == 'Showdown':
|
|
|
|
| 839 |
if site_var == 'Draftkings':
|
| 840 |
+
raw_baselines = dk_sd_roo_raw
|
|
|
|
| 841 |
elif site_var == 'Fanduel':
|
| 842 |
+
raw_baselines = fd_sd_roo_raw
|
| 843 |
+
slate_var3 = st.radio("Which slate data are you loading?", ('Main', 'Secondary', 'Auxiliary'), key='slate_var3_radio')
|
| 844 |
+
if slate_type_var3 == 'Regular':
|
| 845 |
+
if site_var == 'Draftkings':
|
| 846 |
+
dk_lineups = init_DK_lineups(slate_type_var3, slate_var3)
|
| 847 |
+
elif site_var == 'Fanduel':
|
| 848 |
+
fd_lineups = init_FD_lineups(slate_type_var3, slate_var3)
|
| 849 |
+
elif slate_type_var3 == 'Showdown':
|
| 850 |
+
if site_var == 'Draftkings':
|
| 851 |
+
dk_lineups = init_DK_lineups(slate_type_var3, slate_var3)
|
| 852 |
+
elif site_var == 'Fanduel':
|
| 853 |
+
fd_lineups = init_FD_lineups(slate_type_var3, slate_var3)
|
| 854 |
+
with col2:
|
| 855 |
+
lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1, key='lineup_num_var_input')
|
| 856 |
+
player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1_radio')
|
| 857 |
+
if player_var1 == 'Specific Players':
|
| 858 |
+
player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique(), key='player_var2_multiselect')
|
| 859 |
+
elif player_var1 == 'Full Slate':
|
| 860 |
+
player_var2 = raw_baselines.Player.values.tolist()
|
| 861 |
+
with col3:
|
| 862 |
if site_var == 'Draftkings':
|
| 863 |
+
salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 50000, value = 49000, step = 100, key = 'salary_min_var_dk')
|
| 864 |
+
salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 50000, value = 50000, step = 100, key = 'salary_max_var_dk')
|
| 865 |
+
elif site_var == 'Fanduel':
|
| 866 |
+
salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 60000, value = 59000, step = 100, key = 'salary_min_var_fd')
|
| 867 |
+
salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 60000, value = 60000, step = 100, key = 'salary_max_var_fd')
|
| 868 |
+
with col4:
|
| 869 |
+
if site_var == 'Draftkings':
|
| 870 |
+
min_stacks_var = st.number_input("Minimum stacks used", min_value = 0, max_value = 5, value = 1, step = 1, key = 'min_stacks_var_dk')
|
| 871 |
+
max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 5, value = 5, step = 1, key = 'max_stacks_var_dk')
|
|
|
|
| 872 |
elif site_var == 'Fanduel':
|
| 873 |
+
min_stacks_var = st.number_input("Minimum stacks used", min_value = 0, max_value = 4, value = 1, step = 1, key = 'min_stacks_var_fd')
|
| 874 |
+
max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 4, value = 4, step = 1, key = 'max_stacks_var_fd')
|
| 875 |
+
|
| 876 |
+
# Set up column names and player salaries
|
| 877 |
+
if site_var == 'Draftkings':
|
| 878 |
+
raw_baselines = dk_roo_raw
|
| 879 |
+
if slate_type_var3 == 'Regular':
|
| 880 |
+
ROO_slice = raw_baselines
|
| 881 |
+
player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
|
| 882 |
+
column_names = dk_columns
|
| 883 |
+
elif slate_type_var3 == 'Showdown':
|
| 884 |
+
player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
|
| 885 |
+
column_names = dk_sd_columns
|
| 886 |
+
elif site_var == 'Fanduel':
|
| 887 |
+
raw_baselines = fd_roo_raw
|
| 888 |
+
if slate_type_var3 == 'Regular':
|
| 889 |
+
ROO_slice = raw_baselines
|
| 890 |
+
player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
|
| 891 |
+
column_names = fd_columns
|
| 892 |
+
elif slate_type_var3 == 'Showdown':
|
| 893 |
+
player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
|
| 894 |
+
column_names = fd_sd_columns
|
| 895 |
+
|
| 896 |
+
# Export buttons
|
| 897 |
+
reg_dl_col, filtered_dl_col, blank_dl_col = st.columns([2, 2, 6])
|
| 898 |
+
with reg_dl_col:
|
| 899 |
+
if st.button("Prepare full data export", key='data_export_button'):
|
| 900 |
+
name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
|
| 901 |
+
data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
|
| 902 |
+
if site_var == 'Draftkings':
|
| 903 |
+
if slate_type_var3 == 'Regular':
|
| 904 |
+
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 905 |
+
for col_idx in map_columns:
|
| 906 |
+
data_export[col_idx] = data_export[col_idx].map(dk_id_map)
|
| 907 |
+
elif slate_type_var3 == 'Showdown':
|
| 908 |
+
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 909 |
+
for col_idx in map_columns:
|
| 910 |
+
data_export[col_idx] = data_export[col_idx].map(dk_sd_id_map)
|
| 911 |
+
elif site_var == 'Fanduel':
|
| 912 |
+
if slate_type_var3 == 'Regular':
|
| 913 |
+
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 914 |
+
for col_idx in map_columns:
|
| 915 |
+
data_export[col_idx] = data_export[col_idx].map(fd_id_map)
|
| 916 |
+
elif slate_type_var3 == 'Showdown':
|
| 917 |
+
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 918 |
+
for col_idx in map_columns:
|
| 919 |
+
data_export[col_idx] = data_export[col_idx].map(fd_sd_id_map)
|
| 920 |
+
|
| 921 |
+
reg_opt_col, pm_opt_col = st.columns(2)
|
| 922 |
+
with reg_opt_col:
|
| 923 |
+
st.download_button(
|
| 924 |
+
label="Export optimals set (IDs)",
|
| 925 |
+
data=convert_df(data_export),
|
| 926 |
+
file_name='NFL_optimals_export.csv',
|
| 927 |
+
mime='text/csv',
|
| 928 |
+
key='export_optimals_ids_button'
|
| 929 |
+
)
|
| 930 |
+
st.download_button(
|
| 931 |
+
label="Export optimals set (Names)",
|
| 932 |
+
data=convert_df(name_export),
|
| 933 |
+
file_name='NFL_optimals_export.csv',
|
| 934 |
+
mime='text/csv',
|
| 935 |
+
key='export_optimals_names_button'
|
| 936 |
+
)
|
| 937 |
+
with pm_opt_col:
|
| 938 |
if site_var == 'Draftkings':
|
| 939 |
if slate_type_var3 == 'Regular':
|
| 940 |
+
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
|
|
|
|
|
|
| 941 |
elif slate_type_var3 == 'Showdown':
|
| 942 |
+
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
|
|
|
|
|
|
| 943 |
elif site_var == 'Fanduel':
|
| 944 |
if slate_type_var3 == 'Regular':
|
| 945 |
+
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
|
|
|
|
|
|
| 946 |
elif slate_type_var3 == 'Showdown':
|
| 947 |
+
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 948 |
+
st.download_button(
|
| 949 |
+
label="Portfolio Manager Export (IDs)",
|
| 950 |
+
data=convert_pm_df(data_export),
|
| 951 |
+
file_name='NFL_optimals_export.csv',
|
| 952 |
+
mime='text/csv',
|
| 953 |
+
key='export_pm_ids_button'
|
| 954 |
+
)
|
| 955 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 956 |
if site_var == 'Draftkings':
|
| 957 |
if slate_type_var3 == 'Regular':
|
| 958 |
+
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 959 |
elif slate_type_var3 == 'Showdown':
|
| 960 |
+
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
|
|
|
|
|
|
| 961 |
elif site_var == 'Fanduel':
|
| 962 |
if slate_type_var3 == 'Regular':
|
| 963 |
+
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 964 |
elif slate_type_var3 == 'Showdown':
|
| 965 |
+
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 966 |
+
st.download_button(
|
| 967 |
+
label="Portfolio Manager Export (Names)",
|
| 968 |
+
data=convert_pm_df(name_export),
|
| 969 |
+
file_name='NFL_optimals_export.csv',
|
| 970 |
+
mime='text/csv',
|
| 971 |
+
key='export_pm_names_button'
|
| 972 |
+
)
|
| 973 |
+
|
| 974 |
+
with filtered_dl_col:
|
| 975 |
+
if st.button("Prepare full data export (Filtered)", key='data_export_filtered_button'):
|
| 976 |
+
name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
|
| 977 |
+
data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 978 |
if site_var == 'Draftkings':
|
| 979 |
+
if slate_type_var3 == 'Regular':
|
| 980 |
+
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 981 |
+
elif slate_type_var3 == 'Showdown':
|
| 982 |
+
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 983 |
+
for col_idx in map_columns:
|
| 984 |
+
data_export[col_idx] = data_export[col_idx].map(dk_id_map)
|
| 985 |
elif site_var == 'Fanduel':
|
| 986 |
+
if slate_type_var3 == 'Regular':
|
| 987 |
+
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 988 |
+
elif slate_type_var3 == 'Showdown':
|
| 989 |
+
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 990 |
+
for col_idx in map_columns:
|
| 991 |
+
data_export[col_idx] = data_export[col_idx].map(fd_id_map)
|
| 992 |
+
|
| 993 |
+
data_export = data_export[data_export['salary'] >= salary_min_var]
|
| 994 |
+
data_export = data_export[data_export['salary'] <= salary_max_var]
|
| 995 |
+
data_export = data_export[data_export['Team_count'] >= min_stacks_var]
|
| 996 |
+
data_export = data_export[data_export['Team_count'] <= max_stacks_var]
|
| 997 |
+
|
| 998 |
+
name_export = name_export[name_export['salary'] >= salary_min_var]
|
| 999 |
+
name_export = name_export[name_export['salary'] <= salary_max_var]
|
| 1000 |
+
name_export = name_export[name_export['Team_count'] >= min_stacks_var]
|
| 1001 |
+
name_export = name_export[name_export['Team_count'] <= max_stacks_var]
|
| 1002 |
+
|
| 1003 |
+
reg_opt_col, pm_opt_col = st.columns(2)
|
| 1004 |
+
with reg_opt_col:
|
| 1005 |
+
st.download_button(
|
| 1006 |
+
label="Export optimals set (IDs)",
|
| 1007 |
+
data=convert_df(data_export),
|
| 1008 |
+
file_name='NFL_optimals_export.csv',
|
| 1009 |
+
mime='text/csv',
|
| 1010 |
+
key='export_filtered_optimals_ids_button'
|
| 1011 |
+
)
|
| 1012 |
+
st.download_button(
|
| 1013 |
+
label="Export optimals set (Names)",
|
| 1014 |
+
data=convert_df(name_export),
|
| 1015 |
+
file_name='NFL_optimals_export.csv',
|
| 1016 |
+
mime='text/csv',
|
| 1017 |
+
key='export_filtered_optimals_names_button'
|
| 1018 |
+
)
|
| 1019 |
+
with pm_opt_col:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1020 |
if site_var == 'Draftkings':
|
| 1021 |
if slate_type_var3 == 'Regular':
|
| 1022 |
+
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1023 |
elif slate_type_var3 == 'Showdown':
|
| 1024 |
+
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1025 |
elif site_var == 'Fanduel':
|
| 1026 |
if slate_type_var3 == 'Regular':
|
| 1027 |
+
data_export = data_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1028 |
elif slate_type_var3 == 'Showdown':
|
| 1029 |
+
data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1030 |
st.download_button(
|
| 1031 |
+
label="Portfolio Manager Export (IDs)",
|
| 1032 |
+
data=convert_pm_df(data_export),
|
| 1033 |
+
file_name='NFL_optimals_export.csv',
|
| 1034 |
mime='text/csv',
|
| 1035 |
+
key='export_filtered_pm_ids_button'
|
| 1036 |
)
|
| 1037 |
+
|
|
|
|
| 1038 |
if site_var == 'Draftkings':
|
| 1039 |
if slate_type_var3 == 'Regular':
|
| 1040 |
+
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1041 |
elif slate_type_var3 == 'Showdown':
|
| 1042 |
+
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1043 |
elif site_var == 'Fanduel':
|
| 1044 |
if slate_type_var3 == 'Regular':
|
| 1045 |
+
name_export = name_export.set_index('QB').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
| 1046 |
elif slate_type_var3 == 'Showdown':
|
| 1047 |
+
name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1048 |
st.download_button(
|
| 1049 |
+
label="Portfolio Manager Export (Names)",
|
| 1050 |
+
data=convert_pm_df(name_export),
|
| 1051 |
+
file_name='NFL_optimals_export.csv',
|
| 1052 |
mime='text/csv',
|
| 1053 |
+
key='export_filtered_pm_names_button'
|
| 1054 |
)
|
| 1055 |
+
|
| 1056 |
+
# Process lineups
|
| 1057 |
+
if site_var == 'Draftkings':
|
| 1058 |
+
if 'working_seed' in st.session_state:
|
| 1059 |
+
st.session_state.working_seed = st.session_state.working_seed
|
| 1060 |
+
if player_var1 == 'Specific Players':
|
| 1061 |
+
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1062 |
+
elif player_var1 == 'Full Slate':
|
| 1063 |
+
st.session_state.working_seed = dk_lineups.copy()
|
| 1064 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1065 |
+
elif 'working_seed' not in st.session_state:
|
| 1066 |
+
st.session_state.working_seed = dk_lineups.copy()
|
| 1067 |
+
st.session_state.working_seed = st.session_state.working_seed
|
| 1068 |
+
if player_var1 == 'Specific Players':
|
| 1069 |
+
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1070 |
+
elif player_var1 == 'Full Slate':
|
| 1071 |
+
st.session_state.working_seed = dk_lineups.copy()
|
| 1072 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1073 |
+
|
| 1074 |
+
elif site_var == 'Fanduel':
|
| 1075 |
+
if 'working_seed' in st.session_state:
|
| 1076 |
+
st.session_state.working_seed = st.session_state.working_seed
|
| 1077 |
+
if player_var1 == 'Specific Players':
|
| 1078 |
+
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1079 |
+
elif player_var1 == 'Full Slate':
|
| 1080 |
+
st.session_state.working_seed = fd_lineups.copy()
|
| 1081 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1082 |
+
elif 'working_seed' not in st.session_state:
|
| 1083 |
+
st.session_state.working_seed = fd_lineups.copy()
|
| 1084 |
+
st.session_state.working_seed = st.session_state.working_seed
|
| 1085 |
+
if player_var1 == 'Specific Players':
|
| 1086 |
+
st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
|
| 1087 |
+
elif player_var1 == 'Full Slate':
|
| 1088 |
+
st.session_state.working_seed = fd_lineups.copy()
|
| 1089 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
| 1090 |
+
|
| 1091 |
+
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] >= salary_min_var]
|
| 1092 |
+
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] <= salary_max_var]
|
| 1093 |
+
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] >= min_stacks_var]
|
| 1094 |
+
st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] <= max_stacks_var]
|
| 1095 |
+
|
| 1096 |
+
export_file = st.session_state.data_export_display.copy()
|
| 1097 |
+
name_export = st.session_state.data_export_display.copy()
|
| 1098 |
+
if site_var == 'Draftkings':
|
| 1099 |
+
if slate_type_var3 == 'Regular':
|
| 1100 |
+
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 1101 |
+
elif slate_type_var3 == 'Showdown':
|
| 1102 |
+
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 1103 |
+
for col_idx in map_columns:
|
| 1104 |
+
export_file[col_idx] = export_file[col_idx].map(dk_id_map)
|
| 1105 |
+
elif site_var == 'Fanduel':
|
| 1106 |
+
if slate_type_var3 == 'Regular':
|
| 1107 |
+
map_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
|
| 1108 |
+
elif slate_type_var3 == 'Showdown':
|
| 1109 |
+
map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
|
| 1110 |
+
for col_idx in map_columns:
|
| 1111 |
+
export_file[col_idx] = export_file[col_idx].map(fd_id_map)
|
| 1112 |
+
|
| 1113 |
+
with st.container():
|
| 1114 |
+
if st.button("Reset Optimals", key='reset_optimals_button'):
|
| 1115 |
+
for key in st.session_state.keys():
|
| 1116 |
+
del st.session_state[key]
|
| 1117 |
+
if site_var == 'Draftkings':
|
| 1118 |
+
st.session_state.working_seed = dk_lineups.copy()
|
| 1119 |
+
elif site_var == 'Fanduel':
|
| 1120 |
+
st.session_state.working_seed = fd_lineups.copy()
|
| 1121 |
+
if 'data_export_display' in st.session_state:
|
| 1122 |
+
st.dataframe(st.session_state.data_export_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height=500, use_container_width = True, key='optimals_dataframe')
|
| 1123 |
+
st.download_button(
|
| 1124 |
+
label="Export display optimals (IDs)",
|
| 1125 |
+
data=convert_df(export_file),
|
| 1126 |
+
file_name='NFL_display_optimals.csv',
|
| 1127 |
+
mime='text/csv',
|
| 1128 |
+
key='export_display_optimals_ids_button'
|
| 1129 |
+
)
|
| 1130 |
+
st.download_button(
|
| 1131 |
+
label="Export display optimals (Names)",
|
| 1132 |
+
data=convert_df(name_export),
|
| 1133 |
+
file_name='NFL_display_optimals.csv',
|
| 1134 |
+
mime='text/csv',
|
| 1135 |
+
key='export_display_optimals_names_button'
|
| 1136 |
+
)
|
| 1137 |
+
|
| 1138 |
+
# Summary statistics
|
| 1139 |
+
with st.container():
|
| 1140 |
+
if slate_type_var3 == 'Regular':
|
| 1141 |
+
if 'working_seed' in st.session_state:
|
| 1142 |
+
if site_var == 'Draftkings':
|
| 1143 |
+
summary_df = pd.DataFrame({
|
| 1144 |
+
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1145 |
+
'Salary': [
|
| 1146 |
+
np.min(st.session_state.working_seed[:,9]),
|
| 1147 |
+
np.mean(st.session_state.working_seed[:,9]),
|
| 1148 |
+
np.max(st.session_state.working_seed[:,9]),
|
| 1149 |
+
np.std(st.session_state.working_seed[:,9])
|
| 1150 |
+
],
|
| 1151 |
+
'Proj': [
|
| 1152 |
+
np.min(st.session_state.working_seed[:,10]),
|
| 1153 |
+
np.mean(st.session_state.working_seed[:,10]),
|
| 1154 |
+
np.max(st.session_state.working_seed[:,10]),
|
| 1155 |
+
np.std(st.session_state.working_seed[:,10])
|
| 1156 |
+
],
|
| 1157 |
+
'Own': [
|
| 1158 |
+
np.min(st.session_state.working_seed[:,15]),
|
| 1159 |
+
np.mean(st.session_state.working_seed[:,15]),
|
| 1160 |
+
np.max(st.session_state.working_seed[:,15]),
|
| 1161 |
+
np.std(st.session_state.working_seed[:,15])
|
| 1162 |
+
]
|
| 1163 |
+
})
|
| 1164 |
+
elif site_var == 'Fanduel':
|
| 1165 |
+
summary_df = pd.DataFrame({
|
| 1166 |
+
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1167 |
+
'Salary': [
|
| 1168 |
+
np.min(st.session_state.working_seed[:,9]),
|
| 1169 |
+
np.mean(st.session_state.working_seed[:,9]),
|
| 1170 |
+
np.max(st.session_state.working_seed[:,9]),
|
| 1171 |
+
np.std(st.session_state.working_seed[:,9])
|
| 1172 |
+
],
|
| 1173 |
+
'Proj': [
|
| 1174 |
+
np.min(st.session_state.working_seed[:,10]),
|
| 1175 |
+
np.mean(st.session_state.working_seed[:,10]),
|
| 1176 |
+
np.max(st.session_state.working_seed[:,10]),
|
| 1177 |
+
np.std(st.session_state.working_seed[:,10])
|
| 1178 |
+
],
|
| 1179 |
+
'Own': [
|
| 1180 |
+
np.min(st.session_state.working_seed[:,15]),
|
| 1181 |
+
np.mean(st.session_state.working_seed[:,15]),
|
| 1182 |
+
np.max(st.session_state.working_seed[:,15]),
|
| 1183 |
+
np.std(st.session_state.working_seed[:,15])
|
| 1184 |
+
]
|
| 1185 |
+
})
|
| 1186 |
+
elif slate_type_var3 == 'Showdown':
|
| 1187 |
+
if 'working_seed' in st.session_state:
|
| 1188 |
+
if site_var == 'Draftkings':
|
| 1189 |
+
summary_df = pd.DataFrame({
|
| 1190 |
+
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1191 |
+
'Salary': [
|
| 1192 |
+
np.min(st.session_state.working_seed[:,6]),
|
| 1193 |
+
np.mean(st.session_state.working_seed[:,6]),
|
| 1194 |
+
np.max(st.session_state.working_seed[:,6]),
|
| 1195 |
+
np.std(st.session_state.working_seed[:,6])
|
| 1196 |
+
],
|
| 1197 |
+
'Proj': [
|
| 1198 |
+
np.min(st.session_state.working_seed[:,7]),
|
| 1199 |
+
np.mean(st.session_state.working_seed[:,7]),
|
| 1200 |
+
np.max(st.session_state.working_seed[:,7]),
|
| 1201 |
+
np.std(st.session_state.working_seed[:,7])
|
| 1202 |
+
],
|
| 1203 |
+
'Own': [
|
| 1204 |
+
np.min(st.session_state.working_seed[:,12]),
|
| 1205 |
+
np.mean(st.session_state.working_seed[:,12]),
|
| 1206 |
+
np.max(st.session_state.working_seed[:,12]),
|
| 1207 |
+
np.std(st.session_state.working_seed[:,12])
|
| 1208 |
+
]
|
| 1209 |
+
})
|
| 1210 |
+
elif site_var == 'Fanduel':
|
| 1211 |
+
summary_df = pd.DataFrame({
|
| 1212 |
+
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
| 1213 |
+
'Salary': [
|
| 1214 |
+
np.min(st.session_state.working_seed[:,6]),
|
| 1215 |
+
np.mean(st.session_state.working_seed[:,6]),
|
| 1216 |
+
np.max(st.session_state.working_seed[:,6]),
|
| 1217 |
+
np.std(st.session_state.working_seed[:,6])
|
| 1218 |
+
],
|
| 1219 |
+
'Proj': [
|
| 1220 |
+
np.min(st.session_state.working_seed[:,7]),
|
| 1221 |
+
np.mean(st.session_state.working_seed[:,7]),
|
| 1222 |
+
np.max(st.session_state.working_seed[:,7]),
|
| 1223 |
+
np.std(st.session_state.working_seed[:,7])
|
| 1224 |
+
],
|
| 1225 |
+
'Own': [
|
| 1226 |
+
np.min(st.session_state.working_seed[:,12]),
|
| 1227 |
+
np.mean(st.session_state.working_seed[:,12]),
|
| 1228 |
+
np.max(st.session_state.working_seed[:,12]),
|
| 1229 |
+
np.std(st.session_state.working_seed[:,12])
|
| 1230 |
+
]
|
| 1231 |
+
})
|
| 1232 |
+
|
| 1233 |
+
if 'summary_df' in locals():
|
| 1234 |
+
summary_df = summary_df.set_index('Metric')
|
| 1235 |
+
st.subheader("Optimal Statistics")
|
| 1236 |
+
st.dataframe(summary_df.style.format({
|
| 1237 |
+
'Salary': '{:.2f}',
|
| 1238 |
+
'Proj': '{:.2f}',
|
| 1239 |
+
'Own': '{:.2f}'
|
| 1240 |
+
}).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True, key='optimal_stats_dataframe')
|
| 1241 |
+
|
| 1242 |
+
# Frequency analysis
|
| 1243 |
+
with st.container():
|
| 1244 |
+
display_freq_tab, seed_frame_freq_tab = st.tabs(["Display Frequency", "Seed Frame Frequency"])
|
| 1245 |
+
with display_freq_tab:
|
| 1246 |
+
if 'data_export_display' in st.session_state:
|
| 1247 |
+
if site_var == 'Draftkings':
|
| 1248 |
+
if slate_type_var3 == 'Regular':
|
| 1249 |
+
player_columns = st.session_state.data_export_display.iloc[:, :9]
|
| 1250 |
+
elif slate_type_var3 == 'Showdown':
|
| 1251 |
+
player_columns = st.session_state.data_export_display.iloc[:, :6]
|
| 1252 |
+
elif site_var == 'Fanduel':
|
| 1253 |
+
if slate_type_var3 == 'Regular':
|
| 1254 |
+
player_columns = st.session_state.data_export_display.iloc[:, :9]
|
| 1255 |
+
elif slate_type_var3 == 'Showdown':
|
| 1256 |
+
player_columns = st.session_state.data_export_display.iloc[:, :6]
|
| 1257 |
+
|
| 1258 |
+
value_counts = player_columns.values.flatten().tolist()
|
| 1259 |
+
value_counts = pd.Series(value_counts).value_counts()
|
| 1260 |
+
percentages = (value_counts / lineup_num_var * 100).round(2)
|
| 1261 |
+
|
| 1262 |
+
summary_df = pd.DataFrame({
|
| 1263 |
+
'Player': value_counts.index,
|
| 1264 |
+
'Frequency': value_counts.values,
|
| 1265 |
+
'Percentage': percentages.values
|
| 1266 |
+
})
|
| 1267 |
+
|
| 1268 |
+
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
| 1269 |
+
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
| 1270 |
+
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
| 1271 |
+
summary_df = summary_df.set_index('Player')
|
| 1272 |
+
|
| 1273 |
+
st.write("Player Frequency Table:")
|
| 1274 |
+
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True, key='player_frequency_dataframe')
|
| 1275 |
+
|
| 1276 |
+
st.download_button(
|
| 1277 |
+
label="Export player frequency",
|
| 1278 |
+
data=convert_df_to_csv(summary_df),
|
| 1279 |
+
file_name='NFL_player_frequency.csv',
|
| 1280 |
+
mime='text/csv',
|
| 1281 |
+
key='export_player_frequency_button'
|
| 1282 |
+
)
|
| 1283 |
+
|
| 1284 |
+
with seed_frame_freq_tab:
|
| 1285 |
+
if 'working_seed' in st.session_state:
|
| 1286 |
+
if site_var == 'Draftkings':
|
| 1287 |
+
if slate_type_var3 == 'Regular':
|
| 1288 |
+
player_columns = st.session_state.working_seed[:, :9]
|
| 1289 |
+
elif slate_type_var3 == 'Showdown':
|
| 1290 |
+
player_columns = st.session_state.working_seed[:, :6]
|
| 1291 |
+
elif site_var == 'Fanduel':
|
| 1292 |
+
if slate_type_var3 == 'Regular':
|
| 1293 |
+
player_columns = st.session_state.working_seed[:, :9]
|
| 1294 |
+
elif slate_type_var3 == 'Showdown':
|
| 1295 |
+
player_columns = st.session_state.working_seed[:, :6]
|
| 1296 |
+
|
| 1297 |
+
value_counts = player_columns.flatten().tolist()
|
| 1298 |
+
value_counts = pd.Series(value_counts).value_counts()
|
| 1299 |
+
percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
|
| 1300 |
+
|
| 1301 |
+
summary_df = pd.DataFrame({
|
| 1302 |
+
'Player': value_counts.index,
|
| 1303 |
+
'Frequency': value_counts.values,
|
| 1304 |
+
'Percentage': percentages.values
|
| 1305 |
+
})
|
| 1306 |
+
|
| 1307 |
+
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
| 1308 |
+
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
| 1309 |
+
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
| 1310 |
+
summary_df = summary_df.set_index('Player')
|
| 1311 |
+
|
| 1312 |
+
st.write("Seed Frame Frequency Table:")
|
| 1313 |
+
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True, key='seed_frame_frequency_dataframe')
|
| 1314 |
+
|
| 1315 |
+
st.download_button(
|
| 1316 |
+
label="Export seed frame frequency",
|
| 1317 |
+
data=convert_df_to_csv(summary_df),
|
| 1318 |
+
file_name='NFL_seed_frame_frequency.csv',
|
| 1319 |
+
mime='text/csv',
|
| 1320 |
+
key='export_seed_frame_frequency_button'
|
| 1321 |
+
)
|