James McCool
commited on
Commit
·
eb2b4ba
1
Parent(s):
86a7117
Refactor session state management and streamline player selection in Streamlit app
Browse files- 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 |
-
|
| 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 |
-
|
| 1142 |
-
|
| 1143 |
-
idx = selected_rows.selection["rows"][0]
|
| 1144 |
player_row = player_select_df.iloc[[idx]]
|
| 1145 |
-
|
| 1146 |
-
#
|
| 1147 |
-
|
| 1148 |
-
|
| 1149 |
-
|
| 1150 |
-
|
| 1151 |
-
|
| 1152 |
-
|
| 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 |
-
|
| 1169 |
-
|
| 1170 |
-
|
| 1171 |
-
|
| 1172 |
-
|
| 1173 |
-
|
| 1174 |
-
|
| 1175 |
-
|
| 1176 |
-
|
| 1177 |
-
|
| 1178 |
-
|
| 1179 |
-
|
| 1180 |
-
|
| 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:
|