Spaces:
Running
Running
James McCool
commited on
Commit
·
2f2fe43
1
Parent(s):
3e7ecca
Enhance lineup building logic in app.py to support both Draftkings and Fanduel platforms
Browse filesUpdated player selection and position limits based on the selected site, ensuring accurate handling of player positions and salary constraints for each platform. This change improves the user experience by providing tailored lineup building options for Draftkings and Fanduel.
app.py
CHANGED
@@ -824,24 +824,48 @@ with tab4:
|
|
824 |
st.header("Handbuilder")
|
825 |
with col2:
|
826 |
slate_var3 = st.selectbox("Slate Selection", options=['Main', 'Secondary', 'Auxiliary'])
|
827 |
-
if
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
833 |
|
834 |
# --- POSITION LIMITS ---
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
845 |
|
846 |
# --- LINEUP STATE ---
|
847 |
if 'handbuilder_lineup' not in st.session_state:
|
@@ -926,10 +950,29 @@ with tab4:
|
|
926 |
for _, player_row in selected_players.iterrows():
|
927 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'])
|
928 |
slot_to_fill = None
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
933 |
if slot_to_fill is not None:
|
934 |
# Avoid duplicates
|
935 |
if player_row['Player'] not in st.session_state['handbuilder_lineup']['Player'].values:
|
@@ -974,10 +1017,29 @@ with tab4:
|
|
974 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
975 |
# Find the first eligible slot that is not full
|
976 |
slot_to_fill = None
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
981 |
if slot_to_fill is not None:
|
982 |
# Avoid duplicates
|
983 |
if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
|
@@ -995,7 +1057,10 @@ with tab4:
|
|
995 |
st.subheader("Lineup Build")
|
996 |
|
997 |
# --- EXPLICIT LINEUP ORDER ---
|
998 |
-
|
|
|
|
|
|
|
999 |
display_columns = ['Slot', 'Player', 'Order', 'Team', 'Salary', 'Median', 'Own%']
|
1000 |
|
1001 |
filled_lineup = st.session_state['handbuilder_lineup']
|
@@ -1073,7 +1138,7 @@ with tab4:
|
|
1073 |
'2x%': [avg_2x],
|
1074 |
'Own%': [total_own]
|
1075 |
})
|
1076 |
-
summary_row = summary_row[['Salary', 'Median', 'Own%']].head(
|
1077 |
|
1078 |
col1, col3 = st.columns([2, 3])
|
1079 |
|
@@ -1081,20 +1146,20 @@ with tab4:
|
|
1081 |
if (10 - len(filled_lineup)) > 0:
|
1082 |
st.markdown(f"""
|
1083 |
<div style='text-align: left; vertical-align: top; margin-top: 0; padding-top: 0;''>
|
1084 |
-
<b>💰 Per Player:</b> ${round((
|
1085 |
</div>
|
1086 |
""",
|
1087 |
unsafe_allow_html=True)
|
1088 |
else:
|
1089 |
st.markdown(f"""
|
1090 |
<div style='text-align: left; vertical-align: top; margin-top: 0; padding-top: 0;''>
|
1091 |
-
<b>💰 Leftover:</b> ${round(
|
1092 |
</div>
|
1093 |
""",
|
1094 |
unsafe_allow_html=True)
|
1095 |
|
1096 |
with col3:
|
1097 |
-
if total_salary <=
|
1098 |
st.markdown(
|
1099 |
f"""
|
1100 |
<div style='text-align: right; vertical-align: top; margin-top: 0; padding-top: 0;''>
|
|
|
824 |
st.header("Handbuilder")
|
825 |
with col2:
|
826 |
slate_var3 = st.selectbox("Slate Selection", options=['Main', 'Secondary', 'Auxiliary'])
|
827 |
+
if site_var == 'Draftkings':
|
828 |
+
if slate_var3 == 'Main':
|
829 |
+
handbuild_roo = dk_roo[dk_roo['Slate'] == 'main_slate']
|
830 |
+
elif slate_var3 == 'Secondary':
|
831 |
+
handbuild_roo = dk_roo[dk_roo['Slate'] == 'secondary_slate']
|
832 |
+
elif slate_var3 == 'Auxiliary':
|
833 |
+
handbuild_roo = dk_roo[dk_roo['Slate'] == 'turbo_slate']
|
834 |
+
else:
|
835 |
+
if slate_var3 == 'Main':
|
836 |
+
handbuild_roo = fd_roo[fd_roo['Slate'] == 'main_slate']
|
837 |
+
elif slate_var3 == 'Secondary':
|
838 |
+
handbuild_roo = fd_roo[fd_roo['Slate'] == 'secondary_slate']
|
839 |
+
elif slate_var3 == 'Auxiliary':
|
840 |
+
handbuild_roo = fd_roo[fd_roo['Slate'] == 'turbo_slate']
|
841 |
|
842 |
# --- POSITION LIMITS ---
|
843 |
+
if site_var == 'Draftkings':
|
844 |
+
position_limits = {
|
845 |
+
'SP': 2,
|
846 |
+
'C': 1,
|
847 |
+
'1B': 1,
|
848 |
+
'2B': 1,
|
849 |
+
'3B': 1,
|
850 |
+
'SS': 1,
|
851 |
+
'OF': 3,
|
852 |
+
# Add more as needed
|
853 |
+
}
|
854 |
+
max_salary = 50000
|
855 |
+
max_players = 10
|
856 |
+
else:
|
857 |
+
position_limits = {
|
858 |
+
'P': 1,
|
859 |
+
'C_1B': 1,
|
860 |
+
'2B': 1,
|
861 |
+
'3B': 1,
|
862 |
+
'SS': 1,
|
863 |
+
'OF': 3,
|
864 |
+
'UTIL': 1,
|
865 |
+
# Add more as needed
|
866 |
+
}
|
867 |
+
max_salary = 35000
|
868 |
+
max_players = 9
|
869 |
|
870 |
# --- LINEUP STATE ---
|
871 |
if 'handbuilder_lineup' not in st.session_state:
|
|
|
950 |
for _, player_row in selected_players.iterrows():
|
951 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'])
|
952 |
slot_to_fill = None
|
953 |
+
|
954 |
+
if site_var == 'Fanduel':
|
955 |
+
# Logic for handling Fanduel Positions (with C/1B and UTIL)
|
956 |
+
for slot in ['P', 'C_1B', '2B', '3B', 'SS', 'OF', 'UTIL']:
|
957 |
+
if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
|
958 |
+
if slot == 'C_1B':
|
959 |
+
if any(pos in eligible_positions for pos in ['C', '1B']):
|
960 |
+
slot_to_fill = slot
|
961 |
+
break
|
962 |
+
elif slot == 'UTIL':
|
963 |
+
if 'P' not in eligible_positions:
|
964 |
+
slot_to_fill = slot
|
965 |
+
break
|
966 |
+
elif slot in eligible_positions:
|
967 |
+
slot_to_fill = slot
|
968 |
+
break
|
969 |
+
else:
|
970 |
+
# General logic for handling Draftkings Positions
|
971 |
+
for pos in eligible_positions:
|
972 |
+
if slot_counts.get(pos, 0) < position_limits.get(pos, 0):
|
973 |
+
slot_to_fill = pos
|
974 |
+
break
|
975 |
+
|
976 |
if slot_to_fill is not None:
|
977 |
# Avoid duplicates
|
978 |
if player_row['Player'] not in st.session_state['handbuilder_lineup']['Player'].values:
|
|
|
1017 |
eligible_positions = re.split(r'[/, ]+', player_row['Position'].iloc[0])
|
1018 |
# Find the first eligible slot that is not full
|
1019 |
slot_to_fill = None
|
1020 |
+
|
1021 |
+
if site_var == 'Fanduel':
|
1022 |
+
# Logic for handling Fanduel Positions (with C/1B and UTIL)
|
1023 |
+
for slot in ['P', 'C_1B', '2B', '3B', 'SS', 'OF', 'UTIL']:
|
1024 |
+
if slot_counts.get(slot, 0) < position_limits.get(slot, 0):
|
1025 |
+
if slot == 'C_1B':
|
1026 |
+
if any(pos in eligible_positions for pos in ['C', '1B']):
|
1027 |
+
slot_to_fill = slot
|
1028 |
+
break
|
1029 |
+
elif slot == 'UTIL':
|
1030 |
+
if 'P' not in eligible_positions:
|
1031 |
+
slot_to_fill = slot
|
1032 |
+
break
|
1033 |
+
elif slot in eligible_positions:
|
1034 |
+
slot_to_fill = slot
|
1035 |
+
break
|
1036 |
+
else:
|
1037 |
+
# General logic for handling Draftkings Positions
|
1038 |
+
for pos in eligible_positions:
|
1039 |
+
if slot_counts.get(pos, 0) < position_limits.get(pos, 0):
|
1040 |
+
slot_to_fill = pos
|
1041 |
+
break
|
1042 |
+
|
1043 |
if slot_to_fill is not None:
|
1044 |
# Avoid duplicates
|
1045 |
if not player_row['Player'].iloc[0] in st.session_state['handbuilder_lineup']['Player'].values:
|
|
|
1057 |
st.subheader("Lineup Build")
|
1058 |
|
1059 |
# --- EXPLICIT LINEUP ORDER ---
|
1060 |
+
if site_var == 'Draftkings':
|
1061 |
+
lineup_slots = ['SP', 'SP', 'C', '1B', '2B', '3B', 'SS', 'OF', 'OF', 'OF']
|
1062 |
+
else:
|
1063 |
+
lineup_slots = ['P', 'C_1B', '2B', '3B', 'SS', 'OF', 'OF', 'OF', 'UTIL']
|
1064 |
display_columns = ['Slot', 'Player', 'Order', 'Team', 'Salary', 'Median', 'Own%']
|
1065 |
|
1066 |
filled_lineup = st.session_state['handbuilder_lineup']
|
|
|
1138 |
'2x%': [avg_2x],
|
1139 |
'Own%': [total_own]
|
1140 |
})
|
1141 |
+
summary_row = summary_row[['Salary', 'Median', 'Own%']].head(max_players)
|
1142 |
|
1143 |
col1, col3 = st.columns([2, 3])
|
1144 |
|
|
|
1146 |
if (10 - len(filled_lineup)) > 0:
|
1147 |
st.markdown(f"""
|
1148 |
<div style='text-align: left; vertical-align: top; margin-top: 0; padding-top: 0;''>
|
1149 |
+
<b>💰 Per Player:</b> ${round((max_salary - total_salary) / (max_players - len(filled_lineup)), 0)}
|
1150 |
</div>
|
1151 |
""",
|
1152 |
unsafe_allow_html=True)
|
1153 |
else:
|
1154 |
st.markdown(f"""
|
1155 |
<div style='text-align: left; vertical-align: top; margin-top: 0; padding-top: 0;''>
|
1156 |
+
<b>💰 Leftover:</b> ${round(max_salary - total_salary, 0)}
|
1157 |
</div>
|
1158 |
""",
|
1159 |
unsafe_allow_html=True)
|
1160 |
|
1161 |
with col3:
|
1162 |
+
if total_salary <= max_salary:
|
1163 |
st.markdown(
|
1164 |
f"""
|
1165 |
<div style='text-align: right; vertical-align: top; margin-top: 0; padding-top: 0;''>
|