James McCool commited on
Commit
eb2b4ba
·
1 Parent(s): 86a7117

Refactor session state management and streamline player selection in Streamlit app

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +29 -74
src/streamlit_app.py CHANGED
@@ -8,16 +8,6 @@ print(f"Streamlit version: {st.__version__}")
8
 
9
  st.set_page_config(layout="wide")
10
 
11
- @st.cache_data
12
- def initialize_session_state():
13
- """Initialize session state variables"""
14
- if 'handbuilder_lineup' not in st.session_state:
15
- st.session_state['handbuilder_lineup'] = pd.DataFrame(columns=['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot'])
16
- if 'handbuilder_select_key' not in st.session_state:
17
- st.session_state['handbuilder_select_key'] = 0
18
- if 'current_tab' not in st.session_state:
19
- st.session_state['current_tab'] = "Handbuilder"
20
-
21
  @st.cache_resource
22
  def init_conn():
23
  uri = st.secrets['mongo_uri']
@@ -315,8 +305,6 @@ def convert_hb_df(array, column_names):
315
  array = pd.DataFrame(array, columns=column_names)
316
  return array.to_csv().encode('utf-8')
317
 
318
- initialize_session_state()
319
-
320
  col1, col2 = st.columns([1, 9])
321
  with col1:
322
  if st.button("Load/Reset Data", key='reset'):
@@ -338,12 +326,7 @@ player_stats, dk_stacks_raw, fd_stacks_raw, dk_roo_raw, fd_roo_raw, dk_sd_roo_ra
338
 
339
  t_stamp = f"Last Update: " + str(dk_roo_raw['timestamp'][0]) + f" CST"
340
 
341
- tab_names = ["Stacks ROO", "Player ROO", "Optimals", "Handbuilder"]
342
-
343
- if 'current_tab' not in st.session_state:
344
- st.session_state['current_tab'] = "Handbuilder"
345
-
346
- tab1, tab2, tab3, tab4 = st.tabs(tab_names)
347
 
348
  with tab1:
349
  with st.expander("Info and Filters"):
@@ -1128,71 +1111,43 @@ with tab4:
1128
  col1, col2 = st.columns([1, 2])
1129
  with col2:
1130
  st.subheader("Player Select")
1131
-
1132
- # Use a button-based approach for better performance
1133
- selected_rows = st.dataframe(
1134
  player_select_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
 
1135
  selection_mode=["single-row"],
1136
  key=f"handbuilder_select_{st.session_state['handbuilder_select_key']}",
1137
  height=500,
1138
  hide_index=True
1139
  )
1140
-
1141
- # Add a button to confirm selection
1142
- if selected_rows and "rows" in selected_rows.selection and len(selected_rows.selection["rows"]) > 0:
1143
- idx = selected_rows.selection["rows"][0]
1144
  player_row = player_select_df.iloc[[idx]]
1145
-
1146
- # Show selected player info
1147
- st.info(f"Selected: {player_row['Player'].iloc[0]} ({player_row['Position'].iloc[0]} - {player_row['Team'].iloc[0]})")
1148
-
1149
- # Add button to confirm selection
1150
- if st.button(f"Add {player_row['Player'].iloc[0]} to Lineup", key=f"add_player_{st.session_state['handbuilder_select_key']}"):
1151
- eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
1152
- slot_to_fill = None
1153
-
1154
- # Count current positions
1155
- current_lineup = st.session_state['handbuilder_lineup']
1156
- slot_counts = current_lineup['Slot'].value_counts() if not current_lineup.empty else {}
1157
-
1158
- for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
1159
- if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
1160
- if slot == 'UTIL':
1161
- if 'DST' not in eligible_positions and 'QB' not in eligible_positions:
1162
- slot_to_fill = slot
1163
- break
1164
- elif slot in eligible_positions:
1165
  slot_to_fill = slot
1166
  break
1167
-
1168
- if slot_to_fill is not None:
1169
- # Avoid duplicates
1170
- if not player_row['Player'].iloc[0] in current_lineup['Player'].values:
1171
- # Add the slot info
1172
- new_player = pd.DataFrame([{
1173
- 'Player': player_row['Player'].iloc[0],
1174
- 'Position': player_row['Position'].iloc[0],
1175
- 'Team': player_row['Team'].iloc[0],
1176
- 'Salary': player_row['Salary'].iloc[0],
1177
- 'Median': player_row['Median'].iloc[0],
1178
- '2x%': player_row['2x%'].iloc[0],
1179
- 'Own': player_row['Own'].iloc[0],
1180
- 'Slot': slot_to_fill
1181
- }])
1182
-
1183
- st.session_state['handbuilder_lineup'] = pd.concat(
1184
- [st.session_state['handbuilder_lineup'], new_player],
1185
- ignore_index=True
1186
- )
1187
-
1188
- # Clear the selection and increment key
1189
- st.session_state['handbuilder_select_key'] += 1
1190
- st.success(f"✅ Added {player_row['Player'].iloc[0]} to {slot_to_fill} slot!")
1191
- st.rerun()
1192
- else:
1193
- st.error(f"❌ {player_row['Player'].iloc[0]} is already in the lineup!")
1194
- else:
1195
- st.error(f"❌ No available slots for {player_row['Player'].iloc[0]}!")
1196
 
1197
 
1198
  with col1:
 
8
 
9
  st.set_page_config(layout="wide")
10
 
 
 
 
 
 
 
 
 
 
 
11
  @st.cache_resource
12
  def init_conn():
13
  uri = st.secrets['mongo_uri']
 
305
  array = pd.DataFrame(array, columns=column_names)
306
  return array.to_csv().encode('utf-8')
307
 
 
 
308
  col1, col2 = st.columns([1, 9])
309
  with col1:
310
  if st.button("Load/Reset Data", key='reset'):
 
326
 
327
  t_stamp = f"Last Update: " + str(dk_roo_raw['timestamp'][0]) + f" CST"
328
 
329
+ tab1, tab2, tab3, tab4 = st.tabs(["Stacks ROO", "Player ROO", "Optimals", "Handbuilder"])
 
 
 
 
 
330
 
331
  with tab1:
332
  with st.expander("Info and Filters"):
 
1111
  col1, col2 = st.columns([1, 2])
1112
  with col2:
1113
  st.subheader("Player Select")
1114
+ event = st.dataframe(
 
 
1115
  player_select_df.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Salary', 'Own']).format(precision=2),
1116
+ on_select="rerun",
1117
  selection_mode=["single-row"],
1118
  key=f"handbuilder_select_{st.session_state['handbuilder_select_key']}",
1119
  height=500,
1120
  hide_index=True
1121
  )
1122
+ # If a row is selected, add that player to the lineup and reset selection
1123
+ if event and "rows" in event.selection and len(event.selection["rows"]) > 0:
1124
+ idx = event.selection["rows"][0]
 
1125
  player_row = player_select_df.iloc[[idx]]
1126
+ eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
1127
+ # Find the first eligible slot that is not full
1128
+ slot_to_fill = None
1129
+
1130
+ for slot in ['QB', 'RB', 'WR', 'TE', 'UTIL', 'DST']:
1131
+ if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
1132
+ if slot == 'UTIL':
1133
+ if 'DST' not in eligible_positions and 'QB' not in eligible_positions:
 
 
 
 
 
 
 
 
 
 
 
 
1134
  slot_to_fill = slot
1135
  break
1136
+ elif slot in eligible_positions:
1137
+ slot_to_fill = slot
1138
+ break
1139
+
1140
+ if slot_to_fill is not None:
1141
+ # Avoid duplicates
1142
+ if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
1143
+ # Add the slot info
1144
+ player_row = player_row.assign(Slot=slot_to_fill)
1145
+ st.session_state['handbuilder_lineup'] = pd.concat(
1146
+ [st.session_state['handbuilder_lineup'], player_row[['Player', 'Position', 'Team', 'Salary', 'Median', '2x%', 'Own', 'Slot']]],
1147
+ ignore_index=True
1148
+ )
1149
+ st.session_state['handbuilder_select_key'] += 1
1150
+ st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1151
 
1152
 
1153
  with col1: