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
Files changed (1) hide show
  1. 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=["single-row"],
623
  key="player_select_dataframe",
624
  height=500,
625
  hide_index=True
626
  )
627
- # If a row is selected, add that player to the lineup and reset selection
628
- if event and "rows" in event.selection and len(event.selection["rows"]) > 0:
629
- idx = event.selection["rows"][0]
 
 
 
 
 
 
 
 
 
 
 
 
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
- event.selection = {"rows": []}
655
- st.rerun()
 
 
 
 
 
 
 
 
 
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 with single-row selection for removal
701
- event_remove = st.dataframe(
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()