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

Implement session state initialization and enhance player selection process in Streamlit app

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +74 -29
src/streamlit_app.py CHANGED
@@ -8,6 +8,16 @@ print(f"Streamlit version: {st.__version__}")
8
 
9
  st.set_page_config(layout="wide")
10
 
 
 
 
 
 
 
 
 
 
 
11
  @st.cache_resource
12
  def init_conn():
13
  uri = st.secrets['mongo_uri']
@@ -305,6 +315,8 @@ def convert_hb_df(array, column_names):
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,7 +338,12 @@ player_stats, dk_stacks_raw, fd_stacks_raw, dk_roo_raw, fd_roo_raw, dk_sd_roo_ra
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,43 +1128,71 @@ with tab4:
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:
 
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
  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
 
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
  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: