Spaces:
Sleeping
Sleeping
James McCool commited on
Commit ·
34e54fd
1
Parent(s): ab25e47
Refactor player selection handling in Handbuilder tab of Streamlit app to support multiple selections, allowing users to add and remove players from the lineup more intuitively. Update selection state management to improve data accuracy and user experience during lineup updates.
Browse files- src/streamlit_app.py +29 -25
src/streamlit_app.py
CHANGED
|
@@ -619,17 +619,28 @@ if selected_tab == 'Handbuilder':
|
|
| 619 |
event = st.dataframe(
|
| 620 |
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),
|
| 621 |
on_select="rerun",
|
| 622 |
-
selection_mode=
|
| 623 |
key="player_select_dataframe",
|
| 624 |
height=500,
|
| 625 |
hide_index=True
|
| 626 |
)
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 630 |
player_row = st.session_state['player_select_df'].iloc[[idx]]
|
| 631 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
| 632 |
-
# Find the first eligible slot that is not full
|
| 633 |
slot_to_fill = None
|
| 634 |
|
| 635 |
for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
|
|
@@ -645,14 +656,22 @@ if selected_tab == 'Handbuilder':
|
|
| 645 |
if slot_to_fill is not None:
|
| 646 |
# Avoid duplicates
|
| 647 |
if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
|
| 648 |
-
# Add the slot info
|
| 649 |
player_row = player_row.assign(Slot=slot_to_fill)
|
| 650 |
st.session_state['handbuilder_lineup'] = pd.concat(
|
| 651 |
[st.session_state['handbuilder_lineup'], player_row[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot']]],
|
| 652 |
ignore_index=True
|
| 653 |
)
|
| 654 |
-
|
| 655 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 656 |
|
| 657 |
with handbuilder_lineup_build_column:
|
| 658 |
st.subheader("Lineup Build")
|
|
@@ -697,28 +716,13 @@ if selected_tab == 'Handbuilder':
|
|
| 697 |
|
| 698 |
st.session_state['lineup_display_df'] = pd.DataFrame(display_rows, columns=display_columns)
|
| 699 |
|
| 700 |
-
# Show the lineup table
|
| 701 |
-
|
| 702 |
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),
|
| 703 |
-
on_select="rerun",
|
| 704 |
-
selection_mode=["single-row"],
|
| 705 |
-
key="lineup_remove_dataframe",
|
| 706 |
height=445,
|
| 707 |
hide_index=True
|
| 708 |
)
|
| 709 |
|
| 710 |
-
# If a row is selected and not blank, remove that player from the lineup
|
| 711 |
-
if event_remove and "rows" in event_remove.selection and len(event_remove.selection["rows"]) > 0:
|
| 712 |
-
idx = event_remove.selection["rows"][0]
|
| 713 |
-
player_to_remove = st.session_state['lineup_display_df'].iloc[idx]['Player']
|
| 714 |
-
slot_to_remove = st.session_state['lineup_display_df'].iloc[idx]['Slot']
|
| 715 |
-
if player_to_remove: # Only remove if not blank
|
| 716 |
-
st.session_state['handbuilder_lineup'] = filled_lineup[
|
| 717 |
-
~((filled_lineup['Player'] == player_to_remove) & (filled_lineup['Slot'] == slot_to_remove))
|
| 718 |
-
]
|
| 719 |
-
event_remove.selection = {"rows": []}
|
| 720 |
-
st.rerun()
|
| 721 |
-
|
| 722 |
# --- SUMMARY ROW ---
|
| 723 |
if not filled_lineup.empty:
|
| 724 |
total_salary = filled_lineup['Salary'].sum()
|
|
|
|
| 619 |
event = st.dataframe(
|
| 620 |
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),
|
| 621 |
on_select="rerun",
|
| 622 |
+
selection_mode="multiple", # Changed to multiple selection
|
| 623 |
key="player_select_dataframe",
|
| 624 |
height=500,
|
| 625 |
hide_index=True
|
| 626 |
)
|
| 627 |
+
|
| 628 |
+
# Get current selection state
|
| 629 |
+
current_selection = set()
|
| 630 |
+
if event and "rows" in event.selection:
|
| 631 |
+
current_selection = set(event.selection["rows"])
|
| 632 |
+
|
| 633 |
+
# Get previous selection state from session
|
| 634 |
+
previous_selection = set(st.session_state.get('previous_player_selection', []))
|
| 635 |
+
|
| 636 |
+
# Find newly selected and newly unselected players
|
| 637 |
+
newly_selected = current_selection - previous_selection
|
| 638 |
+
newly_unselected = previous_selection - current_selection
|
| 639 |
+
|
| 640 |
+
# Handle newly selected players (add to lineup)
|
| 641 |
+
for idx in newly_selected:
|
| 642 |
player_row = st.session_state['player_select_df'].iloc[[idx]]
|
| 643 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
|
|
|
| 644 |
slot_to_fill = None
|
| 645 |
|
| 646 |
for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
|
|
|
|
| 656 |
if slot_to_fill is not None:
|
| 657 |
# Avoid duplicates
|
| 658 |
if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
|
|
|
|
| 659 |
player_row = player_row.assign(Slot=slot_to_fill)
|
| 660 |
st.session_state['handbuilder_lineup'] = pd.concat(
|
| 661 |
[st.session_state['handbuilder_lineup'], player_row[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot']]],
|
| 662 |
ignore_index=True
|
| 663 |
)
|
| 664 |
+
|
| 665 |
+
# Handle newly unselected players (remove from lineup)
|
| 666 |
+
for idx in newly_unselected:
|
| 667 |
+
player_to_remove = st.session_state['player_select_df'].iloc[idx]['Player']
|
| 668 |
+
if player_to_remove in st.session_state['handbuilder_lineup']['Player'].values:
|
| 669 |
+
st.session_state['handbuilder_lineup'] = st.session_state['handbuilder_lineup'][
|
| 670 |
+
st.session_state['handbuilder_lineup']['Player'] != player_to_remove
|
| 671 |
+
]
|
| 672 |
+
|
| 673 |
+
# Store current selection for next comparison
|
| 674 |
+
st.session_state['previous_player_selection'] = list(current_selection)
|
| 675 |
|
| 676 |
with handbuilder_lineup_build_column:
|
| 677 |
st.subheader("Lineup Build")
|
|
|
|
| 716 |
|
| 717 |
st.session_state['lineup_display_df'] = pd.DataFrame(display_rows, columns=display_columns)
|
| 718 |
|
| 719 |
+
# Show the lineup table as a static display (no selection needed)
|
| 720 |
+
st.dataframe(
|
| 721 |
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),
|
|
|
|
|
|
|
|
|
|
| 722 |
height=445,
|
| 723 |
hide_index=True
|
| 724 |
)
|
| 725 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 726 |
# --- SUMMARY ROW ---
|
| 727 |
if not filled_lineup.empty:
|
| 728 |
total_salary = filled_lineup['Salary'].sum()
|