import streamlit as st st.set_page_config(layout="wide") for name in dir(): if not name.startswith('_'): del globals()[name] import pulp import numpy as np import pandas as pd import streamlit as st import gspread import pymongo from itertools import combinations import math @st.cache_resource def init_conn(): uri = st.secrets['mongo_uri'] client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000) db = client["NHL_Database"] return db db = init_conn() player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '20+%': '{:.2%}', '2x%': '{:.2%}', '3x%': '{:.2%}', '4x%': '{:.2%}'} dk_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'] fd_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'] dk_hb_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX'] fd_hb_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G'] dk_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'] fd_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'] st.markdown(""" """, unsafe_allow_html=True) @st.cache_resource(ttl=200) def player_stat_table(): collection = db["Player_Level_ROO"] cursor = collection.find() player_frame = pd.DataFrame(cursor) player_frame = player_frame[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'Small Field Own%', 'Large Field Own%', 'Cash Own%', 'CPT_Own', 'Site', 'Type', 'Slate', 'player_id', 'timestamp']] collection = db["Player_Lines_ROO"] cursor = collection.find() line_frame = pd.DataFrame(cursor) line_frame = line_frame[['Player', 'SK1', 'SK2', 'SK3', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '50+%', '2x%', '3x%', '4x%', 'Own', 'Site', 'Type', 'Slate']] collection = db["Player_Powerplay_ROO"] cursor = collection.find() pp_frame = pd.DataFrame(cursor) pp_frame = pp_frame[['Player', 'SK1', 'SK2', 'SK3', 'SK4', 'SK5', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '75+%', '2x%', '3x%', '4x%', 'Own', 'Site', 'Type', 'Slate']] timestamp = player_frame['timestamp'].values[0] return player_frame, line_frame, pp_frame, timestamp @st.cache_resource(ttl = 60) def init_DK_lineups(prio_var, prio_mix, lineup_num, player_var2): if prio_var == 'Mix': prio_var = None collection = db['DK_NHL_seed_frame'] if prio_var == None: if player_var2 != []: player_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX'] query_conditions = [] for player in player_var2: # Create a condition for each player to check if they appear in any column player_condition = {'$or': [{col: player} for col in player_columns]} query_conditions.append(player_condition) # Combine all player conditions with $or if query_conditions: filter_query = {'$or': query_conditions} cursor1 = collection.find(filter_query).limit(math.ceil(lineup_num * (prio_mix / 100))) cursor2 = collection.find(filter_query).sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100))) else: cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100))) cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100))) raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))]) else: cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100))) cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100))) raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))]) else: cursor = collection.find().sort(prio_var, -1).limit(lineup_num) raw_display = pd.DataFrame(list(cursor)) raw_display = raw_display.drop_duplicates(subset=['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX']) raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']] DK_seed = raw_display.to_numpy() return DK_seed @st.cache_resource(ttl = 60) def init_FD_lineups(prio_var, prio_mix, lineup_num, player_var2): if prio_var == 'Mix': prio_var = None collection = db['FD_NHL_seed_frame'] if prio_var == None: if player_var2 != []: player_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G'] query_conditions = [] for player in player_var2: # Create a condition for each player to check if they appear in any column player_condition = {'$or': [{col: player} for col in player_columns]} query_conditions.append(player_condition) # Combine all player conditions with $or if query_conditions: filter_query = {'$or': query_conditions} cursor1 = collection.find(filter_query).limit(math.ceil(lineup_num * (prio_mix / 100))) cursor2 = collection.find(filter_query).sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100))) else: cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100))) cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100))) raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))]) else: cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100))) cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100))) raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))]) else: cursor = collection.find().sort(prio_var, -1).limit(lineup_num) raw_display = pd.DataFrame(list(cursor)) raw_display = raw_display.drop_duplicates(subset=['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G']) raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']] FD_seed = raw_display.to_numpy() return FD_seed @st.cache_data def convert_df_to_csv(df): return df.to_csv().encode('utf-8') @st.cache_data def convert_df(array): array = pd.DataFrame(array, columns=column_names) return array.to_csv().encode('utf-8') @st.cache_data def convert_pm_df(array): array = pd.DataFrame(array) return array.to_csv().encode('utf-8') @st.cache_data def convert_hb_df(array, column_names): array = pd.DataFrame(array, columns=column_names) return array.to_csv().encode('utf-8') player_frame, line_frame, pp_frame, timestamp = player_stat_table() dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) t_stamp = f"Last Update: " + str(timestamp) + f" CST" app_load_reset_column, app_view_site_column, = st.columns([1, 9]) with app_load_reset_column: if st.button("Load/Reset Data", key='reset_data_button'): st.cache_data.clear() player_frame, line_frame, pp_frame, timestamp = player_stat_table() dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_lineups = init_DK_lineups('proj', 50, 25000, []) fd_lineups = init_FD_lineups('proj', 50, 25000, []) for key in st.session_state.keys(): del st.session_state[key] with app_view_site_column: with st.container(): app_view_column, app_site_column, app_type_column, hatter_column = st.columns([3, 3, 3, 3]) with app_view_column: view_var = st.selectbox("Select view", ["Simple", "Advanced"], key='view_selectbox') with app_site_column: site_var = st.selectbox("What site do you want to view?", ('Draftkings', 'Fanduel'), key='site_selectbox') with app_type_column: type_var = st.selectbox("What type of data do you want to view?", ('Regular', 'Showdown'), key='type_selectbox') with hatter_column: hatter_var = st.selectbox("Flowchart:", ('No Hatter', 'Hatter'), key='hatter_selectbox') # selected_tab = st.segmented_control( # "Select Tab", # options=["Player Range of Outcomes", "Line Combo Range of Outcomes", "Power Play Range of Outcomes", "Optimals"], # selection_mode='single', # default='Player Range of Outcomes', # width='stretch', # label_visibility='collapsed', # key='tab_selector' # ) tab1, tab2, tab3, tab4 = st.tabs(["Player Range of Outcomes", "Line Combo Range of Outcomes", "Power Play Range of Outcomes", "Optimals"]) with tab1: with st.expander("Info and Filters"): with st.container(): st.info("Advanced view includes all stats and thresholds, simple includes just basic columns for ease of use on mobile") st.info(t_stamp) if st.button("Load/Reset Data", key='reset1'): st.cache_data.clear() player_frame, line_frame, pp_frame, timestamp = player_stat_table() dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_lineups = init_DK_lineups('proj', 50, 25000, []) fd_lineups = init_FD_lineups('proj', 50, 25000, []) t_stamp = f"Last Update: " + str(timestamp) + f" CST" split_var1 = st.radio("Would you like to view the whole slate or just specific games?", ('Full Slate Run', 'Specific Games'), key='split_var1') if split_var1 == 'Specific Games': team_var1 = st.multiselect('Which teams would you like to include in the ROO?', options = player_frame['Team'].unique(), key='team_var1') elif split_var1 == 'Full Slate Run': team_var1 = player_frame.Team.values.tolist() pos_split1 = st.radio("Are you viewing all positions, specific groups, or specific positions?", ('All Positions', 'Specific Positions'), key='pos_split1') if pos_split1 == 'Specific Positions': pos_var1 = st.multiselect('What Positions would you like to view?', options = ['C', 'W', 'D', 'G']) elif pos_split1 == 'All Positions': pos_var1 = 'All' sal_var1 = st.slider("Is there a certain price range you want to view?", 2000, 10000, (2000, 20000), key='sal_var1') final_Proj = player_frame[player_frame['Site'] == str(site_var)] final_Proj = final_Proj[final_Proj['Type'] == 'Basic'] final_Proj = final_Proj[final_Proj['Slate'] == 'Main Slate'] final_Proj = final_Proj[player_frame['Team'].isin(team_var1)] final_Proj = final_Proj[final_Proj['Salary'] >= sal_var1[0]] final_Proj = final_Proj[final_Proj['Salary'] <= sal_var1[1]] if hatter_var == 'Hatter': final_Proj = final_Proj[final_Proj['Team'] == 'COL'] if pos_var1 != 'All': final_Proj = final_Proj[final_Proj['Position'].str.contains('|'.join(pos_var1))] final_Proj = final_Proj.sort_values(by='Median', ascending=False) if pos_var1 == 'All': final_Proj = final_Proj.sort_values(by='Median', ascending=False) if type_var == 'Regular': pm_export = final_Proj[['Player', 'Position', 'Team', 'Salary', 'Median', 'Own']] pm_export['captain ownership'] = pm_export['Own'] / 6 pm_export = pm_export.rename(columns={'Own': 'ownership', 'Median': 'median', 'Player': 'player_names', 'Position': 'position', 'Team': 'team', 'Salary': 'salary'}) elif type_var == 'Showdown': pm_export = final_Proj[['Player', 'Position', 'Team', 'Salary', 'Median', 'Own', 'CPT_Own']] pm_export['Salary'] = pm_export['Salary'] / 1.6 pm_export = pm_export.rename(columns={'Own': 'ownership', 'Median': 'median', 'Player': 'player_names', 'Position': 'position', 'Team': 'team', 'Salary': 'salary', 'CPT_Own': 'captain ownership'}) player_reg_dl_col, player_pm_dl_col, player_dl_blank_col = st.columns([2, 2, 10]) with player_reg_dl_col: st.download_button( label="Export ROO (Regular)", data=convert_df_to_csv(final_Proj), file_name='NHL_ROO_export.csv', mime='text/csv', ) with player_pm_dl_col: st.download_button( label="Export ROO (Portfolio Manager)", data=convert_df_to_csv(pm_export), file_name='NHL_ROO_export.csv', mime='text/csv', ) if view_var == 'Advanced': display_proj = final_Proj[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'Small Field Own%', 'Large Field Own%', 'Cash Own%', 'CPT_Own']] elif view_var == 'Simple': display_proj = final_Proj[['Player', 'Position', 'Salary', 'Median', '3x%', 'Own']] st.dataframe(display_proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height = 1000, use_container_width = True, hide_index=True) st.download_button( label="Export Tables", data=convert_df_to_csv(display_proj), file_name='NHL_player_export.csv', mime='text/csv', ) with tab2: with st.expander("Info and Filters"): with st.container(): st.info("Advanced view includes all stats and thresholds, simple includes just basic columns for ease of use on mobile") st.info(t_stamp) if st.button("Load/Reset Data", key='reset2'): st.cache_data.clear() player_frame, line_frame, pp_frame, timestamp = player_stat_table() dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_lineups = init_DK_lineups('proj', 50, 25000, []) fd_lineups = init_FD_lineups('proj', 50, 25000, []) t_stamp = f"Last Update: " + str(timestamp) + f" CST" sal_var2 = st.slider("Is there a certain price range you want to view?", 5000, 40000, (5000, 40000), key='sal_var2') final_line_combos = line_frame[line_frame['Site'] == str(site_var)] final_line_combos = final_line_combos[final_line_combos['Type'] == 'Basic'] final_line_combos = final_line_combos[final_line_combos['Slate'] == 'Main Slate'] final_line_combos = final_line_combos[final_line_combos['Salary'] >= sal_var2[0]] final_line_combos = final_line_combos[final_line_combos['Salary'] <= sal_var2[1]] final_line_combos = final_line_combos.drop_duplicates(subset=['Player']) final_line_combos = final_line_combos.sort_values(by='Median', ascending=False) if hatter_var == 'Hatter': final_line_combos = final_line_combos[final_line_combos['Player'].str.contains('COL')] if view_var == 'Advanced': display_proj_lines = final_line_combos[['Player', 'SK1', 'SK2', 'SK3', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '50+%', '2x%', '3x%', '4x%', 'Own']] elif view_var == 'Simple': display_proj_lines = final_line_combos[['SK1', 'SK2', 'SK3', 'Salary', 'Median', '3x%', 'Own']] st.dataframe(display_proj_lines.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height = 1000, use_container_width = True, hide_index=True) st.download_button( label="Export Tables", data=convert_df_to_csv(display_proj_lines), file_name='NHL_linecombos_export.csv', mime='text/csv', ) with tab3: with st.expander("Info and Filters"): with st.container(): st.info("Advanced view includes all stats and thresholds, simple includes just basic columns for ease of use on mobile") st.info(t_stamp) if st.button("Load/Reset Data", key='reset3'): st.cache_data.clear() player_frame, line_frame, pp_frame, timestamp = player_stat_table() dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_lineups = init_DK_lineups('proj', 50, 25000, []) fd_lineups = init_FD_lineups('proj', 50, 25000, []) t_stamp = f"Last Update: " + str(timestamp) + f" CST" sal_var3 = st.slider("Is there a certain price range you want to view?", 5000, 40000, (5000, 40000), key='sal_var3') final_pp_combos = pp_frame[pp_frame['Site'] == str(site_var)] final_pp_combos = final_pp_combos[final_pp_combos['Type'] == 'Basic'] final_pp_combos = final_pp_combos[final_pp_combos['Slate'] == 'Main Slate'] final_pp_combos = final_pp_combos[final_pp_combos['Salary'] >= sal_var3[0]] final_pp_combos = final_pp_combos[final_pp_combos['Salary'] <= sal_var3[1]] final_pp_combos = final_pp_combos.drop_duplicates(subset=['Player']) final_pp_combos = final_pp_combos.sort_values(by='Median', ascending=False) if hatter_var == 'Hatter': final_pp_combos = final_pp_combos[final_pp_combos['Player'].str.contains('COL')] if view_var == 'Advanced': display_proj_pp = final_pp_combos[['Player', 'SK1', 'SK2', 'SK3', 'SK4', 'SK5', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '75+%', '2x%', '3x%', '4x%', 'Own']] elif view_var == 'Simple': display_proj_pp = final_pp_combos[['SK1', 'SK2', 'SK3', 'SK4', 'SK5', 'Salary', 'Median', '3x%', 'Own']] st.dataframe(display_proj_pp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True, hide_index=True) st.download_button( label="Export Tables", data=convert_df_to_csv(display_proj_pp), file_name='NHL_powerplay_export.csv', mime='text/csv', ) with tab4: player_frame, line_frame, pp_frame, timestamp = player_stat_table() dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id'])) fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id'])) if type_var == 'Regular': t_stamp = f"Last Update: " + str(timestamp) + f" CST" elif type_var == 'Showdown': t_stamp = f"Last Update: " + str(timestamp) + f" CST" st.header("Optimals") with st.expander("Info and Filters"): st.info("These filters will display various optimals in the table below to pick from. If you want to export the entire set of 10,000 optimals, hit the 'Prepare full data export' button. If you would like to apply the filters here to the 10,000 optimals before you export, use the 'Prepare full data export (Filter)' button.") prio_col, optimals_site_col, optimals_macro_col, optimals_salary_col, optimals_stacks_col = st.columns(5) with prio_col: prio_var = st.radio("Which priority variable do you want to use?", ('proj', 'Own', 'Mix'), key='prio_var_radio') prio_mix = st.number_input("If Mix, what split of Projection/Ownership to dedicate to Projection?", min_value=0, max_value=100, value=50, step=1) lineup_num = st.number_input("How many lineups do you want to work with?", min_value=1000, max_value=50000, value=25000, step=100, key='lineup_download_var_input') with optimals_site_col: if type_var == 'Regular': if site_var == 'Draftkings': raw_baselines = player_frame[player_frame['Site'] == 'Draftkings'] elif site_var == 'Fanduel': raw_baselines = player_frame[player_frame['Site'] == 'Fanduel'] elif type_var == 'Showdown': if site_var == 'Draftkings': raw_baselines = player_frame[player_frame['Site'] == 'Draftkings'] elif site_var == 'Fanduel': raw_baselines = player_frame[player_frame['Site'] == 'Fanduel'] if site_var == 'Draftkings': slate_var3 = st.radio("Which slate data are you loading?", (['Main Slate', 'Secondary Slate', 'Auxiliary Slate']), key='slate_var3_radio') elif site_var == 'Fanduel': slate_var3 = st.radio("Which slate data are you loading?", (['Main Slate', 'Secondary Slate', 'Auxiliary Slate']), key='slate_var3_radio') with optimals_macro_col: lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1, key='lineup_num_var_input') player_var2 = st.multiselect('Query for lineups including:', options = raw_baselines['Player'].unique(), key='player_var2_multiselect', default=[]) if type_var == 'Regular': if site_var == 'Draftkings': dk_lineups = init_DK_lineups(prio_var, prio_mix, lineup_num, player_var2) elif site_var == 'Fanduel': fd_lineups = init_FD_lineups(prio_var, prio_mix, lineup_num, player_var2) elif type_var == 'Showdown': if site_var == 'Draftkings': dk_lineups = init_DK_lineups(prio_var, prio_mix, lineup_num, player_var2) elif site_var == 'Fanduel': fd_lineups = init_FD_lineups(prio_var, prio_mix, lineup_num, player_var2) with optimals_salary_col: if site_var == 'Draftkings': salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 50000, value = 49000, step = 100, key = 'salary_min_var_dk') salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 50000, value = 50000, step = 100, key = 'salary_max_var_dk') elif site_var == 'Fanduel': salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 55000, value = 54000, step = 100, key = 'salary_min_var_fd') salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 55000, value = 55000, step = 100, key = 'salary_max_var_fd') with optimals_stacks_col: if site_var == 'Draftkings': min_stacks_var = st.number_input("Minimum stacks used", min_value = 0, max_value = 5, value = 1, step = 1, key = 'min_stacks_var_dk') max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 5, value = 5, step = 1, key = 'max_stacks_var_dk') elif site_var == 'Fanduel': min_stacks_var = st.number_input("Minimum stacks used", min_value = 0, max_value = 4, value = 1, step = 1, key = 'min_stacks_var_fd') max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 4, value = 4, step = 1, key = 'max_stacks_var_fd') if site_var == 'Draftkings': if type_var == 'Regular': ROO_slice = raw_baselines player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary'])) column_names = dk_columns elif type_var == 'Showdown': player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary'])) column_names = dk_sd_columns elif site_var == 'Fanduel': if type_var == 'Regular': ROO_slice = raw_baselines player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary'])) column_names = fd_columns elif type_var == 'Showdown': player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary'])) column_names = fd_sd_columns reg_dl_col, filtered_dl_col, blank_dl_col = st.columns([2, 2, 6]) with reg_dl_col: if st.button("Prepare full data export", key='data_export_button'): name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) if site_var == 'Draftkings': if type_var == 'Regular': map_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(dk_id_map) elif type_var == 'Showdown': map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(dk_sd_id_map) elif site_var == 'Fanduel': if type_var == 'Regular': map_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(fd_id_map) elif type_var == 'Showdown': map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(fd_sd_id_map) reg_opt_col, pm_opt_col = st.columns(2) with reg_opt_col: st.download_button( label="Export optimals set (IDs)", data=convert_df(data_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_optimals_ids_button' ) st.download_button( label="Export optimals set (Names)", data=convert_df(name_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_optimals_names_button' ) with pm_opt_col: if site_var == 'Draftkings': if type_var == 'Regular': data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif site_var == 'Fanduel': if type_var == 'Regular': data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) st.download_button( label="Portfolio Manager Export (IDs)", data=convert_pm_df(data_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_pm_ids_button' ) if site_var == 'Draftkings': if type_var == 'Regular': name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif site_var == 'Fanduel': if type_var == 'Regular': name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) st.download_button( label="Portfolio Manager Export (Names)", data=convert_pm_df(name_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_pm_names_button' ) with filtered_dl_col: if st.button("Prepare full data export (Filtered)", key='data_export_filtered_button'): name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) if site_var == 'Draftkings': if type_var == 'Regular': map_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(dk_id_map) elif type_var == 'Showdown': map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(dk_sd_id_map) elif site_var == 'Fanduel': if type_var == 'Regular': map_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(fd_id_map) elif type_var == 'Showdown': map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] for col_idx in map_columns: data_export[col_idx] = data_export[col_idx].map(fd_sd_id_map) data_export = data_export[data_export['salary'] >= salary_min_var] data_export = data_export[data_export['salary'] <= salary_max_var] data_export = data_export[data_export['Team_count'] >= min_stacks_var] data_export = data_export[data_export['Team_count'] <= max_stacks_var] name_export = name_export[name_export['salary'] >= salary_min_var] name_export = name_export[name_export['salary'] <= salary_max_var] name_export = name_export[name_export['Team_count'] >= min_stacks_var] name_export = name_export[name_export['Team_count'] <= max_stacks_var] reg_opt_col, pm_opt_col = st.columns(2) with reg_opt_col: st.download_button( label="Export optimals set (IDs)", data=convert_df(data_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_filtered_optimals_ids_button' ) st.download_button( label="Export optimals set (Names)", data=convert_df(name_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_filtered_optimals_names_button' ) with pm_opt_col: if site_var == 'Draftkings': if type_var == 'Regular': data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif site_var == 'Fanduel': if type_var == 'Regular': data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) st.download_button( label="Portfolio Manager Export (IDs)", data=convert_pm_df(data_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_filtered_pm_ids_button' ) if site_var == 'Draftkings': if type_var == 'Regular': name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif site_var == 'Fanduel': if type_var == 'Regular': name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) elif type_var == 'Showdown': name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1) st.download_button( label="Portfolio Manager Export (Names)", data=convert_pm_df(name_export), file_name='NHL_optimals_export.csv', mime='text/csv', key='export_filtered_pm_names_button' ) if site_var == 'Draftkings': if 'working_seed' in st.session_state: st.session_state.working_seed = st.session_state.working_seed if player_var2 != []: st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var2 == []: st.session_state.working_seed = dk_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) elif 'working_seed' not in st.session_state: st.session_state.working_seed = dk_lineups.copy() st.session_state.working_seed = st.session_state.working_seed if player_var2 != []: st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var2 == []: st.session_state.working_seed = dk_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) elif site_var == 'Fanduel': if 'working_seed' in st.session_state: st.session_state.working_seed = st.session_state.working_seed if player_var2 != []: st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var2 == []: st.session_state.working_seed = fd_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) elif 'working_seed' not in st.session_state: st.session_state.working_seed = fd_lineups.copy() st.session_state.working_seed = st.session_state.working_seed if player_var2 != []: st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var2 == []: st.session_state.working_seed = fd_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] >= salary_min_var] st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] <= salary_max_var] st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] >= min_stacks_var] st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] <= max_stacks_var] export_file = st.session_state.data_export_display.copy() name_export = st.session_state.data_export_display.copy() if site_var == 'Draftkings': if type_var == 'Regular': map_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX'] for col_idx in map_columns: export_file[col_idx] = export_file[col_idx].map(dk_id_map) elif type_var == 'Showdown': map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] for col_idx in map_columns: export_file[col_idx] = export_file[col_idx].map(dk_sd_id_map) elif site_var == 'Fanduel': if type_var == 'Regular': map_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G'] for col_idx in map_columns: export_file[col_idx] = export_file[col_idx].map(fd_id_map) elif type_var == 'Showdown': map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] for col_idx in map_columns: export_file[col_idx] = export_file[col_idx].map(fd_sd_id_map) with st.container(): if st.button("Reset Optimals", key='reset_optimals_button'): for key in st.session_state.keys(): del st.session_state[key] if site_var == 'Draftkings': st.session_state.working_seed = dk_lineups.copy() elif site_var == 'Fanduel': st.session_state.working_seed = fd_lineups.copy() if 'data_export_display' in st.session_state: st.dataframe(st.session_state.data_export_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height=500, use_container_width = True) st.download_button( label="Export display optimals (IDs)", data=convert_df(export_file), file_name='NHL_display_optimals.csv', mime='text/csv', key='export_display_optimals_ids_button' ) st.download_button( label="Export display optimals (Names)", data=convert_df(name_export), file_name='NHL_display_optimals.csv', mime='text/csv', key='export_display_optimals_names_button' ) with st.container(): if type_var == 'Regular': if 'working_seed' in st.session_state: # Create a new dataframe with summary statistics if site_var == 'Draftkings': summary_df = pd.DataFrame({ 'Metric': ['Min', 'Average', 'Max', 'STDdev'], 'Salary': [ np.min(st.session_state.working_seed[:,9]), np.mean(st.session_state.working_seed[:,9]), np.max(st.session_state.working_seed[:,9]), np.std(st.session_state.working_seed[:,9]) ], 'Proj': [ np.min(st.session_state.working_seed[:,10]), np.mean(st.session_state.working_seed[:,10]), np.max(st.session_state.working_seed[:,10]), np.std(st.session_state.working_seed[:,10]) ], 'Own': [ np.min(st.session_state.working_seed[:,15]), np.mean(st.session_state.working_seed[:,15]), np.max(st.session_state.working_seed[:,15]), np.std(st.session_state.working_seed[:,15]) ] }) elif site_var == 'Fanduel': summary_df = pd.DataFrame({ 'Metric': ['Min', 'Average', 'Max', 'STDdev'], 'Salary': [ np.min(st.session_state.working_seed[:,9]), np.mean(st.session_state.working_seed[:,9]), np.max(st.session_state.working_seed[:,9]), np.std(st.session_state.working_seed[:,9]) ], 'Proj': [ np.min(st.session_state.working_seed[:,10]), np.mean(st.session_state.working_seed[:,10]), np.max(st.session_state.working_seed[:,10]), np.std(st.session_state.working_seed[:,10]) ], 'Own': [ np.min(st.session_state.working_seed[:,15]), np.mean(st.session_state.working_seed[:,15]), np.max(st.session_state.working_seed[:,15]), np.std(st.session_state.working_seed[:,15]) ] }) elif type_var == 'Showdown': if 'working_seed' in st.session_state: # Create a new dataframe with summary statistics if site_var == 'Draftkings': summary_df = pd.DataFrame({ 'Metric': ['Min', 'Average', 'Max', 'STDdev'], 'Salary': [ np.min(st.session_state.working_seed[:,6]), np.mean(st.session_state.working_seed[:,6]), np.max(st.session_state.working_seed[:,6]), np.std(st.session_state.working_seed[:,6]) ], 'Proj': [ np.min(st.session_state.working_seed[:,7]), np.mean(st.session_state.working_seed[:,7]), np.max(st.session_state.working_seed[:,7]), np.std(st.session_state.working_seed[:,7]) ], 'Own': [ np.min(st.session_state.working_seed[:,12]), np.mean(st.session_state.working_seed[:,12]), np.max(st.session_state.working_seed[:,12]), np.std(st.session_state.working_seed[:,12]) ] }) elif site_var == 'Fanduel': summary_df = pd.DataFrame({ 'Metric': ['Min', 'Average', 'Max', 'STDdev'], 'Salary': [ np.min(st.session_state.working_seed[:,6]), np.mean(st.session_state.working_seed[:,6]), np.max(st.session_state.working_seed[:,6]), np.std(st.session_state.working_seed[:,6]) ], 'Proj': [ np.min(st.session_state.working_seed[:,7]), np.mean(st.session_state.working_seed[:,7]), np.max(st.session_state.working_seed[:,7]), np.std(st.session_state.working_seed[:,7]) ], 'Own': [ np.min(st.session_state.working_seed[:,12]), np.mean(st.session_state.working_seed[:,12]), np.max(st.session_state.working_seed[:,12]), np.std(st.session_state.working_seed[:,12]) ] }) # Set the index of the summary dataframe as the "Metric" column summary_df = summary_df.set_index('Metric') # Display the summary dataframe st.subheader("Optimal Statistics") st.dataframe(summary_df.style.format({ 'Salary': '{:.2f}', 'Proj': '{:.2f}', 'Own': '{:.2f}' }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True) with st.container(): display_freq_tab, seed_frame_freq_tab = st.tabs(["Display Frequency", "Seed Frame Frequency"]) with display_freq_tab: if 'data_export_display' in st.session_state: if site_var == 'Draftkings': if type_var == 'Regular': player_columns = st.session_state.data_export_display.iloc[:, :9] elif type_var == 'Showdown': player_columns = st.session_state.data_export_display.iloc[:, :6] elif site_var == 'Fanduel': if type_var == 'Regular': player_columns = st.session_state.data_export_display.iloc[:, :9] elif type_var == 'Showdown': player_columns = st.session_state.data_export_display.iloc[:, :6] # Flatten the DataFrame and count unique values value_counts = player_columns.values.flatten().tolist() value_counts = pd.Series(value_counts).value_counts() percentages = (value_counts / lineup_num_var * 100).round(2) # Create a DataFrame with the results summary_df = pd.DataFrame({ 'Player': value_counts.index, 'Frequency': value_counts.values, 'Percentage': percentages.values }) # Sort by frequency in descending order summary_df['Salary'] = summary_df['Player'].map(player_salaries) summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']] summary_df = summary_df.sort_values('Frequency', ascending=False) summary_df = summary_df.set_index('Player') # Display the table st.write("Player Frequency Table:") st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True) st.download_button( label="Export player frequency", data=convert_df_to_csv(summary_df), file_name='NHL_player_frequency.csv', mime='text/csv', key='export_player_frequency_button' ) with seed_frame_freq_tab: if 'working_seed' in st.session_state: if site_var == 'Draftkings': if type_var == 'Regular': player_columns = st.session_state.working_seed[:, :9] elif type_var == 'Showdown': player_columns = st.session_state.working_seed[:, :6] elif site_var == 'Fanduel': if type_var == 'Regular': player_columns = st.session_state.working_seed[:, :9] elif type_var == 'Showdown': player_columns = st.session_state.working_seed[:, :6] # Flatten the DataFrame and count unique values value_counts = player_columns.flatten().tolist() value_counts = pd.Series(value_counts).value_counts() percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2) # Create a DataFrame with the results summary_df = pd.DataFrame({ 'Player': value_counts.index, 'Frequency': value_counts.values, 'Percentage': percentages.values }) # Sort by frequency in descending order summary_df['Salary'] = summary_df['Player'].map(player_salaries) summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']] summary_df = summary_df.sort_values('Frequency', ascending=False) summary_df = summary_df.set_index('Player') # Display the table st.write("Seed Frame Frequency Table:") st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True) st.download_button( label="Export seed frame frequency", data=convert_df_to_csv(summary_df), file_name='NHL_seed_frame_frequency.csv', mime='text/csv', key='export_seed_frame_frequency_button' )