James McCool
commited on
Commit
·
861486b
1
Parent(s):
b739f76
Refactor player selection handling in Streamlit app to utilize session state for storing filtered player data. This change enhances data management and ensures consistent access to player selections across different operations, improving overall functionality and user experience.
Browse files- src/streamlit_app.py +35 -35
src/streamlit_app.py
CHANGED
|
@@ -446,20 +446,20 @@ if selected_tab == 'Handbuilder':
|
|
| 446 |
|
| 447 |
# If no teams selected, show all teams
|
| 448 |
if selected_teams:
|
| 449 |
-
player_select_df = handbuild_roo[
|
| 450 |
handbuild_roo['Team'].isin(selected_teams)
|
| 451 |
][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 452 |
else:
|
| 453 |
-
player_select_df = handbuild_roo[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 454 |
|
| 455 |
# If no teams selected, show all teams
|
| 456 |
if pos_select3:
|
| 457 |
position_mask_2 = handbuild_roo['Position'].apply(lambda x: any(pos in x for pos in pos_select3))
|
| 458 |
-
player_select_df = player_select_df[position_mask_2][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 459 |
else:
|
| 460 |
-
player_select_df = player_select_df[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 461 |
|
| 462 |
-
player_select_df = player_select_df[player_select_df['Salary'] <= salary_var]
|
| 463 |
|
| 464 |
|
| 465 |
with st.expander("Quick Fill Options"):
|
|
@@ -470,9 +470,9 @@ if selected_tab == 'Handbuilder':
|
|
| 470 |
if st.button("Quick Fill", key="quick_fill_button"):
|
| 471 |
# 1. Get all eligible players from the selected team, not already in the lineup
|
| 472 |
current_players = set(st.session_state['handbuilder_lineup']['Player'])
|
| 473 |
-
team_players = player_select_df[
|
| 474 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 475 |
-
(~player_select_df['Player'].isin(current_players))
|
| 476 |
].copy()
|
| 477 |
|
| 478 |
# 2. Sort by Order
|
|
@@ -483,9 +483,9 @@ if selected_tab == 'Handbuilder':
|
|
| 483 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 484 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'] == 'WR'].head(auto_size_var - 1)])
|
| 485 |
if len(selected_players) < auto_size_var:
|
| 486 |
-
team_players = player_select_df[
|
| 487 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 488 |
-
(~player_select_df['Player'].isin(current_players))
|
| 489 |
].copy()
|
| 490 |
|
| 491 |
# 2. Sort by Order
|
|
@@ -495,9 +495,9 @@ if selected_tab == 'Handbuilder':
|
|
| 495 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 496 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['WR', 'TE'])].head(auto_size_var - 1)])
|
| 497 |
if len(selected_players) < auto_size_var:
|
| 498 |
-
team_players = player_select_df[
|
| 499 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 500 |
-
(~player_select_df['Player'].isin(current_players))
|
| 501 |
].copy()
|
| 502 |
|
| 503 |
# 2. Sort by Order
|
|
@@ -507,9 +507,9 @@ if selected_tab == 'Handbuilder':
|
|
| 507 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 508 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['RB', 'WR', 'TE'])].head(auto_size_var - 1)])
|
| 509 |
if len(selected_players) < auto_size_var:
|
| 510 |
-
team_players = player_select_df[
|
| 511 |
-
(player_select_df['Team'] == auto_team_var) &
|
| 512 |
-
(~player_select_df['Player'].isin(current_players))
|
| 513 |
].copy()
|
| 514 |
|
| 515 |
# 2. Sort by Order
|
|
@@ -556,14 +556,14 @@ if selected_tab == 'Handbuilder':
|
|
| 556 |
return True
|
| 557 |
return False
|
| 558 |
|
| 559 |
-
# player_select_df = player_select_df[player_select_df.apply(is_player_eligible, axis=1)]
|
| 560 |
-
print(player_select_df.head(10))
|
| 561 |
|
| 562 |
handbuilder_lineup_build_column, handbuilder_player_select_column = st.columns([1, 2])
|
| 563 |
with handbuilder_player_select_column:
|
| 564 |
st.subheader("Player Select")
|
| 565 |
event = st.dataframe(
|
| 566 |
-
player_select_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
|
| 567 |
on_select="rerun",
|
| 568 |
selection_mode=["single-row"],
|
| 569 |
key="player_select_dataframe",
|
|
@@ -573,7 +573,7 @@ if selected_tab == 'Handbuilder':
|
|
| 573 |
# If a row is selected, add that player to the lineup and reset selection
|
| 574 |
if event and "rows" in event.selection and len(event.selection["rows"]) > 0:
|
| 575 |
idx = event.selection["rows"][0]
|
| 576 |
-
player_row = player_select_df.iloc[[idx]]
|
| 577 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
| 578 |
# Find the first eligible slot that is not full
|
| 579 |
slot_to_fill = None
|
|
@@ -640,11 +640,11 @@ if selected_tab == 'Handbuilder':
|
|
| 640 |
'Own': np.nan
|
| 641 |
})
|
| 642 |
|
| 643 |
-
lineup_display_df = pd.DataFrame(display_rows, columns=display_columns)
|
| 644 |
|
| 645 |
# Show the lineup table with single-row selection for removal
|
| 646 |
event_remove = st.dataframe(
|
| 647 |
-
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),
|
| 648 |
on_select="rerun",
|
| 649 |
selection_mode=["single-row"],
|
| 650 |
key="lineup_remove_dataframe",
|
|
@@ -655,8 +655,8 @@ if selected_tab == 'Handbuilder':
|
|
| 655 |
# If a row is selected and not blank, remove that player from the lineup
|
| 656 |
if event_remove and "rows" in event_remove.selection and len(event_remove.selection["rows"]) > 0:
|
| 657 |
idx = event_remove.selection["rows"][0]
|
| 658 |
-
player_to_remove = lineup_display_df.iloc[idx]['Player']
|
| 659 |
-
slot_to_remove = lineup_display_df.iloc[idx]['Slot']
|
| 660 |
if player_to_remove: # Only remove if not blank
|
| 661 |
st.session_state['handbuilder_lineup'] = filled_lineup[
|
| 662 |
~((filled_lineup['Player'] == player_to_remove) & (filled_lineup['Slot'] == slot_to_remove))
|
|
@@ -730,10 +730,10 @@ if selected_tab == 'Handbuilder':
|
|
| 730 |
with save_col:
|
| 731 |
if st.button("Save Lineup", key='save_lineup_button'):
|
| 732 |
if 'saved_lineups' in st.session_state:
|
| 733 |
-
st.session_state['saved_lineups'].append(lineup_display_df['Player'].tolist())
|
| 734 |
print(st.session_state['saved_lineups'])
|
| 735 |
else:
|
| 736 |
-
st.session_state['saved_lineups'] = [lineup_display_df['Player'].tolist()]
|
| 737 |
print(st.session_state['saved_lineups'])
|
| 738 |
with export_col:
|
| 739 |
if 'saved_lineups' in st.session_state and st.session_state['saved_lineups']:
|
|
@@ -780,17 +780,17 @@ elif selected_tab == 'Stacks ROO':
|
|
| 780 |
elif split_var1 == 'Full Slate Run':
|
| 781 |
team_var1 = raw_baselines.Team.values.tolist()
|
| 782 |
|
| 783 |
-
final_stacks = raw_baselines[raw_baselines['Team'].isin(team_var1)]
|
| 784 |
if view_var == 'Simple':
|
| 785 |
-
final_stacks = final_stacks[['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Salary', 'Median', '60+%', '4x%']]
|
| 786 |
elif view_var == 'Advanced':
|
| 787 |
-
final_stacks = final_stacks[['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Total', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish',
|
| 788 |
'Top_10_finish', '60+%', '2x%', '3x%', '4x%', 'Own', 'LevX']]
|
| 789 |
with st.container():
|
| 790 |
-
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')
|
| 791 |
st.download_button(
|
| 792 |
label="Export Tables",
|
| 793 |
-
data=convert_df_to_csv(final_stacks),
|
| 794 |
file_name='NFL_stacks_export.csv',
|
| 795 |
mime='text/csv',
|
| 796 |
key='stacks_export_button'
|
|
@@ -847,12 +847,12 @@ elif selected_tab == 'Player ROO':
|
|
| 847 |
|
| 848 |
if view_var == 'Simple':
|
| 849 |
final_Proj = final_Proj[['Player', 'Position', 'Team', 'Salary', 'Median', 'Top_5_finish', '4x%']]
|
| 850 |
-
disp_proj = final_Proj.set_index('Player')
|
| 851 |
elif view_var == 'Advanced':
|
| 852 |
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']]
|
| 853 |
-
disp_proj = final_Proj.set_index('Player')
|
| 854 |
with st.container():
|
| 855 |
-
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')
|
| 856 |
st.download_button(
|
| 857 |
label="Export Tables",
|
| 858 |
data=convert_df_to_csv(final_Proj),
|
|
|
|
| 446 |
|
| 447 |
# If no teams selected, show all teams
|
| 448 |
if selected_teams:
|
| 449 |
+
st.session_state['player_select_df'] = handbuild_roo[
|
| 450 |
handbuild_roo['Team'].isin(selected_teams)
|
| 451 |
][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 452 |
else:
|
| 453 |
+
st.session_state['player_select_df'] = handbuild_roo[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 454 |
|
| 455 |
# If no teams selected, show all teams
|
| 456 |
if pos_select3:
|
| 457 |
position_mask_2 = handbuild_roo['Position'].apply(lambda x: any(pos in x for pos in pos_select3))
|
| 458 |
+
st.session_state['player_select_df'] = st.session_state['player_select_df'][position_mask_2][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 459 |
else:
|
| 460 |
+
st.session_state['player_select_df'] = st.session_state['player_select_df'][['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own']].drop_duplicates(subset=['Player', 'Team']).copy()
|
| 461 |
|
| 462 |
+
st.session_state['player_select_df'] = st.session_state['player_select_df'][st.session_state['player_select_df']['Salary'] <= salary_var]
|
| 463 |
|
| 464 |
|
| 465 |
with st.expander("Quick Fill Options"):
|
|
|
|
| 470 |
if st.button("Quick Fill", key="quick_fill_button"):
|
| 471 |
# 1. Get all eligible players from the selected team, not already in the lineup
|
| 472 |
current_players = set(st.session_state['handbuilder_lineup']['Player'])
|
| 473 |
+
team_players = st.session_state['player_select_df'][
|
| 474 |
+
(st.session_state['player_select_df']['Team'] == auto_team_var) &
|
| 475 |
+
(~st.session_state['player_select_df']['Player'].isin(current_players))
|
| 476 |
].copy()
|
| 477 |
|
| 478 |
# 2. Sort by Order
|
|
|
|
| 483 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 484 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'] == 'WR'].head(auto_size_var - 1)])
|
| 485 |
if len(selected_players) < auto_size_var:
|
| 486 |
+
team_players = st.session_state['player_select_df'][
|
| 487 |
+
(st.session_state['player_select_df']['Team'] == auto_team_var) &
|
| 488 |
+
(~st.session_state['player_select_df']['Player'].isin(current_players))
|
| 489 |
].copy()
|
| 490 |
|
| 491 |
# 2. Sort by Order
|
|
|
|
| 495 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 496 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['WR', 'TE'])].head(auto_size_var - 1)])
|
| 497 |
if len(selected_players) < auto_size_var:
|
| 498 |
+
team_players = st.session_state['player_select_df'][
|
| 499 |
+
(st.session_state['player_select_df']['Team'] == auto_team_var) &
|
| 500 |
+
(~st.session_state['player_select_df']['Player'].isin(current_players))
|
| 501 |
].copy()
|
| 502 |
|
| 503 |
# 2. Sort by Order
|
|
|
|
| 507 |
selected_players = team_players[team_players['Position'] == 'QB'].head(1)
|
| 508 |
selected_players = pd.concat([selected_players, team_players[team_players['Position'].isin(['RB', 'WR', 'TE'])].head(auto_size_var - 1)])
|
| 509 |
if len(selected_players) < auto_size_var:
|
| 510 |
+
team_players = st.session_state['player_select_df'][
|
| 511 |
+
(st.session_state['player_select_df']['Team'] == auto_team_var) &
|
| 512 |
+
(~st.session_state['player_select_df']['Player'].isin(current_players))
|
| 513 |
].copy()
|
| 514 |
|
| 515 |
# 2. Sort by Order
|
|
|
|
| 556 |
return True
|
| 557 |
return False
|
| 558 |
|
| 559 |
+
# st.session_state['player_select_df'] = st.session_state['player_select_df'][st.session_state['player_select_df'].apply(is_player_eligible, axis=1)]
|
| 560 |
+
print(st.session_state['player_select_df'].head(10))
|
| 561 |
|
| 562 |
handbuilder_lineup_build_column, handbuilder_player_select_column = st.columns([1, 2])
|
| 563 |
with handbuilder_player_select_column:
|
| 564 |
st.subheader("Player Select")
|
| 565 |
event = st.dataframe(
|
| 566 |
+
st.session_state['player_select_df'].style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
|
| 567 |
on_select="rerun",
|
| 568 |
selection_mode=["single-row"],
|
| 569 |
key="player_select_dataframe",
|
|
|
|
| 573 |
# If a row is selected, add that player to the lineup and reset selection
|
| 574 |
if event and "rows" in event.selection and len(event.selection["rows"]) > 0:
|
| 575 |
idx = event.selection["rows"][0]
|
| 576 |
+
player_row = st.session_state['player_select_df'].iloc[[idx]]
|
| 577 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
| 578 |
# Find the first eligible slot that is not full
|
| 579 |
slot_to_fill = None
|
|
|
|
| 640 |
'Own': np.nan
|
| 641 |
})
|
| 642 |
|
| 643 |
+
st.session_state['lineup_display_df'] = pd.DataFrame(display_rows, columns=display_columns)
|
| 644 |
|
| 645 |
# Show the lineup table with single-row selection for removal
|
| 646 |
event_remove = st.dataframe(
|
| 647 |
+
st.session_state['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),
|
| 648 |
on_select="rerun",
|
| 649 |
selection_mode=["single-row"],
|
| 650 |
key="lineup_remove_dataframe",
|
|
|
|
| 655 |
# If a row is selected and not blank, remove that player from the lineup
|
| 656 |
if event_remove and "rows" in event_remove.selection and len(event_remove.selection["rows"]) > 0:
|
| 657 |
idx = event_remove.selection["rows"][0]
|
| 658 |
+
player_to_remove = st.session_state['lineup_display_df'].iloc[idx]['Player']
|
| 659 |
+
slot_to_remove = st.session_state['lineup_display_df'].iloc[idx]['Slot']
|
| 660 |
if player_to_remove: # Only remove if not blank
|
| 661 |
st.session_state['handbuilder_lineup'] = filled_lineup[
|
| 662 |
~((filled_lineup['Player'] == player_to_remove) & (filled_lineup['Slot'] == slot_to_remove))
|
|
|
|
| 730 |
with save_col:
|
| 731 |
if st.button("Save Lineup", key='save_lineup_button'):
|
| 732 |
if 'saved_lineups' in st.session_state:
|
| 733 |
+
st.session_state['saved_lineups'].append(st.session_state['lineup_display_df']['Player'].tolist())
|
| 734 |
print(st.session_state['saved_lineups'])
|
| 735 |
else:
|
| 736 |
+
st.session_state['saved_lineups'] = [st.session_state['lineup_display_df']['Player'].tolist()]
|
| 737 |
print(st.session_state['saved_lineups'])
|
| 738 |
with export_col:
|
| 739 |
if 'saved_lineups' in st.session_state and st.session_state['saved_lineups']:
|
|
|
|
| 780 |
elif split_var1 == 'Full Slate Run':
|
| 781 |
team_var1 = raw_baselines.Team.values.tolist()
|
| 782 |
|
| 783 |
+
st.session_state['final_stacks'] = raw_baselines[raw_baselines['Team'].isin(team_var1)]
|
| 784 |
if view_var == 'Simple':
|
| 785 |
+
st.session_state['final_stacks'] = st.session_state['final_stacks'][['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Salary', 'Median', '60+%', '4x%']]
|
| 786 |
elif view_var == 'Advanced':
|
| 787 |
+
st.session_state['final_stacks'] = st.session_state['final_stacks'][['Team', 'QB', 'WR1_TE', 'WR2_TE', 'Total', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish',
|
| 788 |
'Top_10_finish', '60+%', '2x%', '3x%', '4x%', 'Own', 'LevX']]
|
| 789 |
with st.container():
|
| 790 |
+
st.dataframe(st.session_state['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')
|
| 791 |
st.download_button(
|
| 792 |
label="Export Tables",
|
| 793 |
+
data=convert_df_to_csv(st.session_state['final_stacks']),
|
| 794 |
file_name='NFL_stacks_export.csv',
|
| 795 |
mime='text/csv',
|
| 796 |
key='stacks_export_button'
|
|
|
|
| 847 |
|
| 848 |
if view_var == 'Simple':
|
| 849 |
final_Proj = final_Proj[['Player', 'Position', 'Team', 'Salary', 'Median', 'Top_5_finish', '4x%']]
|
| 850 |
+
st.session_state['disp_proj'] = final_Proj.set_index('Player')
|
| 851 |
elif view_var == 'Advanced':
|
| 852 |
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']]
|
| 853 |
+
st.session_state['disp_proj'] = final_Proj.set_index('Player')
|
| 854 |
with st.container():
|
| 855 |
+
st.dataframe(st.session_state['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')
|
| 856 |
st.download_button(
|
| 857 |
label="Export Tables",
|
| 858 |
data=convert_df_to_csv(final_Proj),
|