import streamlit as st st.set_page_config(layout="wide") for name in dir(): if not name.startswith('_'): del globals()[name] import numpy as np import pandas as pd import streamlit as st import gc import pymongo @st.cache_resource def init_conn(): uri = st.secrets['mongo_uri'] client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000) db = client["PGA_Database"] return db db = init_conn() dk_player_url = 'https://docs.google.com/spreadsheets/d/1lMLxWdvCnOFBtG9dhM0zv2USuxZbkogI_2jnxFfQVVs/edit#gid=1828092624' CSV_URL = 'https://docs.google.com/spreadsheets/d/1lMLxWdvCnOFBtG9dhM0zv2USuxZbkogI_2jnxFfQVVs/edit#gid=1828092624' player_roo_format = {'Cut_Odds': '{:.2%}', 'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '100+%': '{:.2%}', '5x%': '{:.2%}', '6x%': '{:.2%}', '7x%': '{:.2%}', '10x%': '{:.2%}', '11x%': '{:.2%}', '12x%': '{:.2%}','LevX': '{:.2%}'} dk_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own'] fd_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own'] st.markdown(""" """, unsafe_allow_html=True) @st.cache_resource(ttl = 60) def init_baselines(): collection = db["PGA_Placement_Rates"] cursor = collection.find() placement_frame = pd.DataFrame(cursor) collection = db["PGA_Range_of_Outcomes"] cursor = collection.find() player_frame = pd.DataFrame(cursor) player_frame['Cut_Odds'] = player_frame['Player'].map(placement_frame.set_index('Player')['Cut_Odds']) player_frame = player_frame[['Player', 'Cut_Odds'] + [col for col in player_frame.columns if col not in ['Player', 'Cut_Odds']]] timestamp = player_frame['Timestamp'][0] roo_data = player_frame.drop(columns=['_id', 'index', 'Timestamp']) roo_data['Salary'] = roo_data['Salary'].astype(int) collection = db["PGA_SD_ROO"] cursor = collection.find() player_frame = pd.DataFrame(cursor) sd_roo_data = player_frame.drop(columns=['_id', 'index']) sd_roo_data['Salary'] = sd_roo_data['Salary'].astype(int) sd_roo_data = player_frame.drop(columns=['_id', 'index']) sd_roo_data['Salary'] = sd_roo_data['Salary'].astype(int) return roo_data, sd_roo_data, timestamp @st.cache_data(ttl = 60) def init_DK_lineups(type): if type == 'Regular': collection = db['PGA_DK_Seed_Frame_Name_Map'] elif type == 'Showdown': collection = db['PGA_DK_SD_Seed_Frame_Name_Map'] cursor = collection.find() raw_data = pd.DataFrame(list(cursor)) names_dict = dict(zip(raw_data['key'], raw_data['value'])) if type == 'Regular': collection = db["PGA_DK_Seed_Frame"] elif type == 'Showdown': collection = db["PGA_DK_SD_Seed_Frame"] cursor = collection.find().limit(10000) raw_display = pd.DataFrame(list(cursor)) raw_display = raw_display[['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']] dict_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] for col in dict_columns: raw_display[col] = raw_display[col].map(names_dict) DK_seed = raw_display.to_numpy() return DK_seed @st.cache_data(ttl = 60) def init_FD_lineups(type): if type == 'Regular': collection = db['PGA_FD_Seed_Frame_Name_Map'] elif type == 'Showdown': collection = db['PGA_DK_SD_Seed_Frame_Name_Map'] cursor = collection.find() raw_data = pd.DataFrame(list(cursor)) names_dict = dict(zip(raw_data['key'], raw_data['value'])) if type == 'Regular': collection = db["PGA_FD_Seed_Frame"] elif type == 'Showdown': collection = db["PGA_DK_SD_Seed_Frame"] cursor = collection.find().limit(10000) raw_display = pd.DataFrame(list(cursor)) raw_display = raw_display[['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']] dict_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] for col in dict_columns: raw_display[col] = raw_display[col].map(names_dict) FD_seed = raw_display.to_numpy() return FD_seed 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') roo_data, sd_roo_data, timestamp = init_baselines() hold_display = roo_data lineup_display = [] check_list = [] rand_player = 0 boost_player = 0 salaryCut = 0 tab1, tab2 = st.tabs(["Player Overall Projections", "Optimals and Exposures"]) with tab1: with st.expander("Info and Filters"): if st.button("Reset Data", key='reset1'): # Clear values from *all* all in-memory and on-disk data caches: # i.e. clear values from both square and cube st.cache_data.clear() roo_data, sd_roo_data, timestamp = init_baselines() dk_lineups = init_DK_lineups('Regular') fd_lineups = init_FD_lineups('Regular') hold_display = roo_data for key in st.session_state.keys(): del st.session_state[key] st.write(timestamp) col1, col2, col3 = st.columns(3) with col1: view_var = st.radio("Select a View", ["Simple", "Advanced"]) with col2: site_var = st.radio("Select a Site", ["Draftkings", "FanDuel"]) with col3: type_var = st.radio("Select a Type", ["Full Slate", "Showdown"]) with st.container(): if type_var == "Full Slate": display = hold_display[hold_display['Site'] == site_var] display = display.drop_duplicates(subset=['Player']) elif type_var == "Showdown": display = sd_roo_data display = display.drop_duplicates(subset=['Player']) if view_var == "Simple": if type_var == "Full Slate": display = display[['Player', 'Cut_Odds', 'Salary', 'Median', '10x%', 'Own']] display = display.set_index('Player') elif type_var == "Showdown": display = display[['Player', 'Salary', 'Median', '5x%', 'Own']] display = display.set_index('Player') st.dataframe(display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True) elif view_var == "Advanced": display = display display = display.set_index('Player') st.dataframe(display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True) st.download_button( label="Export Projections", data=convert_df_to_csv(display), file_name='PGA_DFS_export.csv', mime='text/csv', ) with tab2: with st.expander("Info and Filters"): if st.button("Load/Reset Data", key='reset2'): st.cache_data.clear() roo_data, sd_roo_data, timestamp = init_baselines() hold_display = roo_data dk_lineups = init_DK_lineups('Regular') fd_lineups = init_FD_lineups('Regular') t_stamp = f"Last Update: " + str(timestamp) + f" CST" for key in st.session_state.keys(): del st.session_state[key] slate_var1 = st.radio("Which data are you loading?", ('Regular', 'Showdown')) site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel')) if slate_var1 == 'Regular': if site_var1 == 'Draftkings': dk_lineups = init_DK_lineups('Regular') elif site_var1 == 'Fanduel': fd_lineups = init_FD_lineups('Regular') elif slate_var1 == 'Showdown': if site_var1 == 'Draftkings': dk_lineups = init_DK_lineups('Showdown') elif site_var1 == 'Fanduel': fd_lineups = init_FD_lineups('Showdown') lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1) if slate_var1 == 'Regular': raw_baselines = roo_data elif slate_var1 == 'Showdown': raw_baselines = sd_roo_data if site_var1 == 'Draftkings': if slate_var1 == 'Regular': ROO_slice = raw_baselines[raw_baselines['Site'] == 'Draftkings'] player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary'])) elif slate_var1 == 'Showdown': player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary'])) # Get the minimum and maximum ownership values from dk_lineups min_own = np.min(dk_lineups[:,8]) max_own = np.max(dk_lineups[:,8]) column_names = dk_columns player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1') if player_var1 == 'Specific Players': player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique()) elif player_var1 == 'Full Slate': player_var2 = raw_baselines.Player.values.tolist() elif site_var1 == 'Fanduel': raw_baselines = hold_display if slate_var1 == 'Regular': ROO_slice = raw_baselines[raw_baselines['Site'] == 'Fanduel'] player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary'])) elif slate_var1 == 'Showdown': player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary'])) min_own = np.min(fd_lineups[:,8]) max_own = np.max(fd_lineups[:,8]) column_names = fd_columns player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1') if player_var1 == 'Specific Players': player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique()) elif player_var1 == 'Full Slate': player_var2 = raw_baselines.Player.values.tolist() if st.button("Prepare data export", key='data_export'): data_export = st.session_state.working_seed.copy() # if site_var1 == 'Draftkings': # for col_idx in range(6): # data_export[:, col_idx] = np.array([id_dict.get(player, player) for player in data_export[:, col_idx]]) # elif site_var1 == 'Fanduel': # for col_idx in range(6): # data_export[:, col_idx] = np.array([id_dict.get(player, player) for player in data_export[:, col_idx]]) st.download_button( label="Export optimals set", data=convert_df(data_export), file_name='NBA_optimals_export.csv', mime='text/csv', ) if site_var1 == 'Draftkings': if 'working_seed' in st.session_state: st.session_state.working_seed = st.session_state.working_seed if player_var1 == 'Specific Players': 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_var1 == 'Full Slate': 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_var1 == 'Specific Players': 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_var1 == 'Full Slate': 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_var1 == 'Fanduel': if 'working_seed' in st.session_state: st.session_state.working_seed = st.session_state.working_seed if player_var1 == 'Specific Players': 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_var1 == 'Full Slate': 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_var1 == 'Specific Players': 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_var1 == 'Full Slate': 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) export_file = st.session_state.data_export_display.copy() # if site_var1 == 'Draftkings': # for col_idx in range(6): # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict) # elif site_var1 == 'Fanduel': # for col_idx in range(6): # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict) with st.container(): if st.button("Reset Optimals", key='reset3'): for key in st.session_state.keys(): del st.session_state[key] if site_var1 == 'Draftkings': st.session_state.working_seed = dk_lineups.copy() elif site_var1 == '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", data=convert_df(export_file), file_name='NBA_display_optimals.csv', mime='text/csv', ) with st.container(): if 'working_seed' in st.session_state: # Create a new dataframe with summary statistics if site_var1 == '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[:,8]), np.mean(st.session_state.working_seed[:,8]), np.max(st.session_state.working_seed[:,8]), np.std(st.session_state.working_seed[:,8]) ] }) elif site_var1 == '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[:,8]), np.mean(st.session_state.working_seed[:,8]), np.max(st.session_state.working_seed[:,8]), np.std(st.session_state.working_seed[:,8]) ] }) # 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(): tab1, tab2 = st.tabs(["Display Frequency", "Seed Frame Frequency"]) with tab1: if 'data_export_display' in st.session_state: if site_var1 == 'Draftkings': player_columns = st.session_state.data_export_display.iloc[:, :6] elif site_var1 == 'Fanduel': 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='PGA_player_frequency.csv', mime='text/csv', ) with tab2: if 'working_seed' in st.session_state: if site_var1 == 'Draftkings': player_columns = st.session_state.working_seed[:, :6] elif site_var1 == 'Fanduel': 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='PGA_seed_frame_frequency.csv', mime='text/csv', )