CoolFace
Apppublic

TrueDFS/NHL_DFS_Contest_Sims_Origin

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py718 linesDownload Raw Back to root
1import streamlit as st2st.set_page_config(layout="wide")3import numpy as np4import pandas as pd5import pymongo6 7@st.cache_resource8def init_conn():9        10        uri = st.secrets['mongo_uri']11        client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)12        db = client["NHL_Database"]13 14        return db15    16db = init_conn()17 18percentages_format = {'Exposure': '{:.2%}'}19freq_format = {'Exposure': '{:.2%}', 'Proj Own': '{:.2%}', 'Edge': '{:.2%}'}20dk_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']21fd_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']22 23@st.cache_data(ttl = 600)24def init_DK_seed_frames(sharp_split, slate_var):  25 26    if slate_var == 'Main Slate':27        collection = db['DK_NHL_seed_frame_Main Slate']28    elif slate_var == 'Secondary Slate':29        collection = db['DK_NHL_seed_frame_Secondary Slate']30    elif slate_var == 'Auxiliary Slate':31        collection = db['DK_NHL_seed_frame_Auxiliary Slate']32 33    cursor = collection.find().limit(sharp_split)34 35    raw_display = pd.DataFrame(list(cursor))36    raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]37    DK_seed = raw_display.to_numpy()38 39    return DK_seed40 41@st.cache_data(ttl = 599)42def init_FD_seed_frames(sharp_split, slate_var):  43    44    if slate_var == 'Main Slate':45        collection = db['FD_NHL_seed_frame_Main Slate']46    elif slate_var == 'Secondary Slate':47        collection = db['FD_NHL_seed_frame_Secondary Slate']48    elif slate_var == 'Auxiliary Slate':49        collection = db['FD_NHL_seed_frame_Auxiliary Slate']50 51    cursor = collection.find().limit(sharp_split)52 53    raw_display = pd.DataFrame(list(cursor))54    raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]55    FD_seed = raw_display.to_numpy()56 57    return FD_seed58 59@st.cache_data(ttl = 599)60def init_baselines():61    collection = db["Player_Level_ROO"] 62    cursor = collection.find()63    64    raw_display = pd.DataFrame(list(cursor))65    load_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own',66                               'Small Field Own%', 'Large Field Own%', 'Cash Own%', 'CPT_Own', 'Site', 'Type', 'Slate', 'player_id', 'timestamp']]67    load_display['STDev'] = load_display['Median'] / 368    DK_load_display = load_display[load_display['Site'] == 'Draftkings']69    DK_load_display = DK_load_display.drop_duplicates(subset=['Player'], keep='first')70    71    dk_raw = DK_load_display.dropna(subset=['Median'])72    dk_raw['Team'] = dk_raw['Team'].replace(['TB', 'SJ', 'LA'], ['TBL', 'SJS', 'LAK'])73 74    FD_load_display = load_display[load_display['Site'] == 'Fanduel']75    FD_load_display = FD_load_display.drop_duplicates(subset=['Player'], keep='first')76    77    fd_raw = FD_load_display.dropna(subset=['Median'])78    fd_raw['Team'] = fd_raw['Team'].replace(['TB', 'SJ', 'LA'], ['TBL', 'SJS', 'LAK'])79 80    teams_playing_count = len(dk_raw.Team.unique())81 82    return dk_raw, fd_raw, teams_playing_count83 84@st.cache_data85def convert_df(array):86    array = pd.DataFrame(array, columns=column_names)87    return array.to_csv().encode('utf-8')88 89@st.cache_data90def calculate_DK_value_frequencies(np_array):91    unique, counts = np.unique(np_array[:, :9], return_counts=True)92    frequencies = counts / len(np_array)  # Normalize by the number of rows 93    combined_array = np.column_stack((unique, frequencies))  94    return combined_array 95 96@st.cache_data97def calculate_FD_value_frequencies(np_array):98    unique, counts = np.unique(np_array[:, :9], return_counts=True)99    frequencies = counts / len(np_array)  # Normalize by the number of rows 100    combined_array = np.column_stack((unique, frequencies))  101    return combined_array102 103@st.cache_data104def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size, teams_playing_count):105    SimVar = 1106    Sim_Winners = []107    fp_array = seed_frame.copy()108    # Pre-vectorize functions109    vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)110    vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)111    112    st.write('Simulating contest on frames')113    114    while SimVar <= Sim_size:115        fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)]116            117        # Calculate stack multipliers first118        stack_multiplier = np.ones(fp_random.shape[0])  # Start with no bonus119        stack_multiplier += np.minimum(0.10, np.where(fp_random[:, 12] == 4, 0.025 * (teams_playing_count - 8), 0))120        stack_multiplier += np.minimum(0.15, np.where(fp_random[:, 12] >= 5, 0.025 * (teams_playing_count - 12), 0))121        122        # Apply multipliers to both loc and scale in the normal distribution123        base_projections = np.sum(np.random.normal(124            loc=vec_projection_map(fp_random[:, :-7]) * stack_multiplier[:, np.newaxis],125            scale=vec_stdev_map(fp_random[:, :-7]) * stack_multiplier[:, np.newaxis]),126        axis=1)127        128        final_projections = base_projections129 130        sample_arrays = np.c_[fp_random, final_projections]131 132        final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]]133        best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]134        Sim_Winners.append(best_lineup)135        SimVar += 1136        137    return Sim_Winners138 139dk_raw, fd_raw, teams_playing_count = init_baselines()140dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))141fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))142 143tab1, tab2 = st.tabs(['Contest Sims', 'Data Export'])144            145with tab1:146    with st.expander("Info and Filters"):147        if st.button("Load/Reset Data", key='reset2'):148              st.cache_data.clear()149              for key in st.session_state.keys():150                  del st.session_state[key]151              DK_seed = init_DK_seed_frames(10000, 'Main Slate')152              FD_seed = init_FD_seed_frames(10000, 'Main Slate')153              dk_raw, fd_raw, teams_playing_count = init_baselines()154              dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))155              fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))156 157        sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Auxiliary Slate'), key='sim_slate_var1')158        sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')159            160        contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom'))161        if contest_var1 == 'Small':162            Contest_Size = 1000163        elif contest_var1 == 'Medium':164            Contest_Size = 5000165        elif contest_var1 == 'Large':166            Contest_Size = 10000167        elif contest_var1 == 'Custom':168            Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")169        strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))170        if strength_var1 == 'Not Very':171            sharp_split = 500000172        elif strength_var1 == 'Below Average':173            sharp_split = 250000174        elif strength_var1 == 'Average':175            sharp_split = 100000176        elif strength_var1 == 'Above Average':177            sharp_split = 50000178        elif strength_var1 == 'Very':179            sharp_split = 10000180 181    if st.button("Run Contest Sim"):182        if 'working_seed' in st.session_state:183            st.session_state.maps_dict = {184                    'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),185                    'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),186                    'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),187                    'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),188                    'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),189                    'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))190                    }191            Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size, teams_playing_count)192            Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))193            194            #st.table(Sim_Winner_Frame)195                        196            # Initial setup197            Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])198            Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2199            Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)200            Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))201            202            # Type Casting203            type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}204            Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)205            206            # Sorting207            st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)208            st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)209            210            # Data Copying211            st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()212            for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:213                st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)214            st.session_state.Sim_Winner_Export = st.session_state.Sim_Winner_Export.drop_duplicates(subset=['Team', 'Secondary', 'salary', 'unique_id'])215            216            # Data Copying217            st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()218            219        else:220            if sim_site_var1 == 'Draftkings':221                st.session_state.working_seed = init_DK_seed_frames(sharp_split, sim_slate_var1)222                dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))223                raw_baselines = dk_raw224                column_names = dk_columns225            elif sim_site_var1 == 'Fanduel':226                st.session_state.working_seed = init_FD_seed_frames(sharp_split, sim_slate_var1)227                fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))228                raw_baselines = fd_raw229                column_names = fd_columns230 231            st.session_state.maps_dict = {232                    'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),233                    'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),234                    'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),235                    'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),236                    'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),237                    'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))238                    }239            Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size, teams_playing_count)240            Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))241            242            #st.table(Sim_Winner_Frame)243                        244            # Initial setup245            Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])246            Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2247            Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)248            Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))249            250            # Type Casting251            type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}252            Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)253            254            # Sorting255            st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)256            st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)257            258            # Data Copying259            st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()260            for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:261                st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)262            st.session_state.Sim_Winner_Export = st.session_state.Sim_Winner_Export.drop_duplicates(subset=['Team', 'Secondary', 'salary', 'unique_id'])263            264            # Data Copying265            st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()266            st.session_state.freq_copy = st.session_state.Sim_Winner_Display267            268        if sim_site_var1 == 'Draftkings':269            freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),270                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)271        elif sim_site_var1 == 'Fanduel':272            freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),273                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)274        freq_working['Freq'] = freq_working['Freq'].astype(int)275        freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])276        freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])277        freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100278        freq_working['Exposure'] = freq_working['Freq']/(1000)279        freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']280        freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])281        st.session_state.player_freq = freq_working.copy()282 283        if sim_site_var1 == 'Draftkings':284            center_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:2].values, return_counts=True)),285                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)286        elif sim_site_var1 == 'Fanduel':287            center_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:2].values, return_counts=True)),288                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)289        center_working['Freq'] = center_working['Freq'].astype(int)290        center_working['Position'] = center_working['Player'].map(st.session_state.maps_dict['Pos_map'])291        center_working['Salary'] = center_working['Player'].map(st.session_state.maps_dict['Salary_map'])292        center_working['Proj Own'] = center_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100293        center_working['Exposure'] = center_working['Freq']/(1000)294        center_working['Edge'] = center_working['Exposure'] - center_working['Proj Own']295        center_working['Team'] = center_working['Player'].map(st.session_state.maps_dict['Team_map'])296        st.session_state.center_freq = center_working.copy()297        298        if sim_site_var1 == 'Draftkings':299            wing_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,2:5].values, return_counts=True)),300                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)301        elif sim_site_var1 == 'Fanduel':302            wing_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,2:4].values, return_counts=True)),303                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)304        wing_working['Freq'] = wing_working['Freq'].astype(int)305        wing_working['Position'] = wing_working['Player'].map(st.session_state.maps_dict['Pos_map'])306        wing_working['Salary'] = wing_working['Player'].map(st.session_state.maps_dict['Salary_map'])307        wing_working['Proj Own'] = wing_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100308        wing_working['Exposure'] = wing_working['Freq']/(1000)309        wing_working['Edge'] = wing_working['Exposure'] - wing_working['Proj Own']310        wing_working['Team'] = wing_working['Player'].map(st.session_state.maps_dict['Team_map'])311        st.session_state.wing_freq = wing_working.copy()312        313        if sim_site_var1 == 'Draftkings':314            dmen_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,5:7].values, return_counts=True)),315                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)316        elif sim_site_var1 == 'Fanduel':317            dmen_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,4:6].values, return_counts=True)),318                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)319        dmen_working['Freq'] = dmen_working['Freq'].astype(int)320        dmen_working['Position'] = dmen_working['Player'].map(st.session_state.maps_dict['Pos_map'])321        dmen_working['Salary'] = dmen_working['Player'].map(st.session_state.maps_dict['Salary_map'])322        dmen_working['Proj Own'] = dmen_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100323        dmen_working['Exposure'] = dmen_working['Freq']/(1000)324        dmen_working['Edge'] = dmen_working['Exposure'] - dmen_working['Proj Own']325        dmen_working['Team'] = dmen_working['Player'].map(st.session_state.maps_dict['Team_map'])326        st.session_state.dmen_freq = dmen_working.copy()327        328        if sim_site_var1 == 'Draftkings':329            flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),330                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)331        elif sim_site_var1 == 'Fanduel':332            flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:8].values, return_counts=True)),333                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)334        flex_working['Freq'] = flex_working['Freq'].astype(int)335        flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map'])336        flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map'])337        flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100338        flex_working['Exposure'] = flex_working['Freq']/(1000)339        flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']340        flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map'])341        st.session_state.flex_freq = flex_working.copy()342        343        if sim_site_var1 == 'Draftkings':344            goalie_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),345                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)346        elif sim_site_var1 == 'Fanduel':347            goalie_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),348                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)349        goalie_working['Freq'] = goalie_working['Freq'].astype(int)350        goalie_working['Position'] = goalie_working['Player'].map(st.session_state.maps_dict['Pos_map'])351        goalie_working['Salary'] = goalie_working['Player'].map(st.session_state.maps_dict['Salary_map'])352        goalie_working['Proj Own'] = goalie_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100353        goalie_working['Exposure'] = goalie_working['Freq']/(1000)354        goalie_working['Edge'] = goalie_working['Exposure'] - goalie_working['Proj Own']355        goalie_working['Team'] = goalie_working['Player'].map(st.session_state.maps_dict['Team_map'])356        st.session_state.goalie_freq = goalie_working.copy()357 358        if sim_site_var1 == 'Draftkings':359            team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),360                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)361        elif sim_site_var1 == 'Fanduel':362            team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),363                                            columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)364        team_working['Freq'] = team_working['Freq'].astype(int)365        team_working['Exposure'] = team_working['Freq']/(1000)366        st.session_state.team_freq = team_working.copy()367            368        with st.container():369            if st.button("Reset Sim", key='reset_sim'):370                for key in st.session_state.keys():371                    del st.session_state[key]372            if 'player_freq' in st.session_state: 373                player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')374                if player_split_var2 == 'Specific Players':375                          find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())376                elif player_split_var2 == 'Full Players':377                          find_var2 = st.session_state.player_freq.Player.values.tolist()378    379                if player_split_var2 == 'Specific Players':380                          st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]381                if player_split_var2 == 'Full Players':382                          st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame383            if 'Sim_Winner_Display' in st.session_state:384                st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)385            if 'Sim_Winner_Export' in st.session_state:386                st.download_button(387                     388                    label="Export Full Frame",389                    data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),390                    file_name='MLB_consim_export.csv',391                    mime='text/csv',392                )  393        tab1, tab2, tab3 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics', 'Stack Type Statistics'])394        395        with tab1:396            if 'Sim_Winner_Display' in st.session_state:397                # Create a new dataframe with summary statistics398                summary_df = pd.DataFrame({399                    'Metric': ['Min', 'Average', 'Max', 'STDdev'],400                    'Salary': [401                        st.session_state.Sim_Winner_Display['salary'].min(),402                        st.session_state.Sim_Winner_Display['salary'].mean(),403                        st.session_state.Sim_Winner_Display['salary'].max(),404                        st.session_state.Sim_Winner_Display['salary'].std()405                    ],406                    'Proj': [407                        st.session_state.Sim_Winner_Display['proj'].min(),408                        st.session_state.Sim_Winner_Display['proj'].mean(),409                        st.session_state.Sim_Winner_Display['proj'].max(),410                        st.session_state.Sim_Winner_Display['proj'].std()411                    ],412                    'Own': [413                        st.session_state.Sim_Winner_Display['Own'].min(),414                        st.session_state.Sim_Winner_Display['Own'].mean(),415                        st.session_state.Sim_Winner_Display['Own'].max(),416                        st.session_state.Sim_Winner_Display['Own'].std()417                    ],418                    'Fantasy': [419                        st.session_state.Sim_Winner_Display['Fantasy'].min(),420                        st.session_state.Sim_Winner_Display['Fantasy'].mean(),421                        st.session_state.Sim_Winner_Display['Fantasy'].max(),422                        st.session_state.Sim_Winner_Display['Fantasy'].std()423                    ],424                    'GPP_Proj': [425                        st.session_state.Sim_Winner_Display['GPP_Proj'].min(),426                        st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),427                        st.session_state.Sim_Winner_Display['GPP_Proj'].max(),428                        st.session_state.Sim_Winner_Display['GPP_Proj'].std()429                    ]430                })431 432                # Set the index of the summary dataframe as the "Metric" column433                summary_df = summary_df.set_index('Metric')434 435                # Display the summary dataframe436                st.subheader("Winning Frame Statistics")437                st.dataframe(summary_df.style.format({438                    'Salary': '{:.2f}',439                    'Proj': '{:.2f}',440                    'Own': '{:.2f}',441                    'Fantasy': '{:.2f}',442                    'GPP_Proj': '{:.2f}'443                }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)444 445        with tab2:446            if 'Sim_Winner_Display' in st.session_state:447                # Apply position mapping to FLEX column448                if sim_site_var1 == 'Draftkings':449                    flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map'])450                elif sim_site_var1 == 'Fanduel':451                    flex1_positions = st.session_state.freq_copy['FLEX1'].map(st.session_state.maps_dict['Pos_map'])452                    flex2_positions = st.session_state.freq_copy['FLEX2'].map(st.session_state.maps_dict['Pos_map'])453                    flex_positions = pd.concat([flex1_positions, flex2_positions])454                455                # Count occurrences of each position in FLEX456                flex_counts = flex_positions.value_counts()457                458                # Calculate average statistics for each FLEX position459                flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({460                    'proj': 'mean',461                    'Own': 'mean',462                    'Fantasy': 'mean',463                    'GPP_Proj': 'mean'464                })465                466                # Combine counts and average statistics467                flex_summary = pd.concat([flex_counts, flex_stats], axis=1)468                flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']469                flex_summary = flex_summary.reset_index()470                flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']471                472                # Display the summary dataframe473                st.subheader("FLEX Position Statistics")474                st.dataframe(flex_summary.style.format({475                    'Count': '{:.0f}',476                    'Avg Proj': '{:.2f}',477                    'Avg Own': '{:.2f}',478                    'Avg Fantasy': '{:.2f}',479                    'Avg GPP_Proj': '{:.2f}'480                }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)481            else:482                st.write("Simulation data or position mapping not available.")483 484        with tab3:485            if 'Sim_Winner_Display' in st.session_state:486                # Apply position mapping to FLEX column487                stack_counts = st.session_state.freq_copy['Team_count'].value_counts()488                489                # Calculate average statistics for each stack size490                stack_stats = st.session_state.freq_copy.groupby('Team_count').agg({491                    'proj': 'mean',492                    'Own': 'mean',493                    'Fantasy': 'mean',494                    'GPP_Proj': 'mean'495                })496                497                # Combine counts and average statistics498                stack_summary = pd.concat([stack_counts, stack_stats], axis=1)499                stack_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']500                stack_summary = stack_summary.reset_index()501                stack_summary.columns = ['Stack Size', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']502                stack_summary = stack_summary.sort_values(by='Stack Size', ascending=True)503                stack_summary = stack_summary.set_index('Stack Size')504                505                # Display the summary dataframe506                st.subheader("Stack Type Statistics")507                st.dataframe(stack_summary.style.format({508                    'Count': '{:.0f}',509                    'Avg Proj': '{:.2f}',510                    'Avg Own': '{:.2f}',511                    'Avg Fantasy': '{:.2f}',512                    'Avg GPP_Proj': '{:.2f}'513                }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)514            else:515                st.write("Simulation data or position mapping not available.")516                517            518        with st.container():519            tab1, tab2, tab3, tab4, tab5, tab6, tab7 = st.tabs(['Overall Exposures', 'Center Exposures', 'Wing Exposures', 'Defense Exposures', 'Flex Exposures', 'Goalie Exposures', 'Team Exposures'])520            with tab1:521                if 'player_freq' in st.session_state:522                    523                    st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)524                    st.download_button(525                        label="Export Exposures",526                        data=st.session_state.player_freq.to_csv().encode('utf-8'),527                        file_name='player_freq_export.csv',528                        mime='text/csv',529                        key='overall'530                    )531            with tab2:532                if 'center_freq' in st.session_state:533                    534                    st.dataframe(st.session_state.center_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)535                    st.download_button(536                        label="Export Exposures",537                        data=st.session_state.center_freq.to_csv().encode('utf-8'),538                        file_name='center_freq.csv',539                        mime='text/csv',540                        key='center'541                    )542            with tab3:543                if 'wing_freq' in st.session_state:544                    545                    st.dataframe(st.session_state.wing_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)546                    st.download_button(547                        label="Export Exposures",548                        data=st.session_state.wing_freq.to_csv().encode('utf-8'),549                        file_name='wing_freq.csv',550                        mime='text/csv',551                        key='wing'552                    )553            with tab4:554                if 'dmen_freq' in st.session_state:555                    556                    st.dataframe(st.session_state.dmen_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)557                    st.download_button(558                        label="Export Exposures",559                        data=st.session_state.dmen_freq.to_csv().encode('utf-8'),560                        file_name='dmen_freq.csv',561                        mime='text/csv',562                        key='dmen'563                    )564            with tab5:565                if 'flex_freq' in st.session_state:566                    567                    st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)568                    st.download_button(569                        label="Export Exposures",570                        data=st.session_state.flex_freq.to_csv().encode('utf-8'),571                        file_name='flex_freq.csv',572                        mime='text/csv',573                        key='flex'574                    )575            with tab6:576                if 'goalie_freq' in st.session_state:577                    578                    st.dataframe(st.session_state.goalie_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)579                    st.download_button(580                        label="Export Exposures",581                        data=st.session_state.goalie_freq.to_csv().encode('utf-8'),582                        file_name='goalie_freq.csv',583                        mime='text/csv',584                        key='goalie'585                    )586            with tab7:587                if 'team_freq' in st.session_state:588                    589                    st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)590                    st.download_button(591                        label="Export Exposures",592                        data=st.session_state.team_freq.to_csv().encode('utf-8'),593                        file_name='team_freq.csv',594                        mime='text/csv',595                        key='team'596                    )597 598with tab2:599    with st.expander("Info and Filters"):600        if st.button("Load/Reset Data", key='reset1'):601                st.cache_data.clear()602                for key in st.session_state.keys():603                    del st.session_state[key]604                DK_seed = init_DK_seed_frames(10000)605                FD_seed = init_FD_seed_frames(10000)606                dk_raw, fd_raw, teams_playing_count = init_baselines()607                dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))608                fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))609                610        slate_var2 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Auxiliary Slate'))611        site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'))612        sharp_split_var = st.number_input("How many lineups do you want?", value=10000, max_value=500000, min_value=10000, step=10000)613        lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=500, value=10, step=1)614 615        if site_var1 == 'Draftkings':616            617            team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1')618            if team_var1 == 'Specific Teams':619                    team_var2 = st.multiselect('Which teams do you want?', options = dk_raw['Team'].unique())620            elif team_var1 == 'Full Slate':621                    team_var2 = dk_raw.Team.values.tolist()622            623            stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1')624            if stack_var1 == 'Specific Stack Sizes':625                    stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0])626            elif stack_var1 == 'Full Slate':627                    stack_var2 = [5, 4, 3, 2, 1, 0]628            629            raw_baselines = dk_raw630            column_names = dk_columns631                    632        elif site_var1 == 'Fanduel':633            634            team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1')635            if team_var1 == 'Specific Teams':636                    team_var2 = st.multiselect('Which teams do you want?', options = fd_raw['Team'].unique())637            elif team_var1 == 'Full Slate':638                    team_var2 = fd_raw.Team.values.tolist()639            640            stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1')641            if stack_var1 == 'Specific Stack Sizes':642                    stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0])643            elif stack_var1 == 'Full Slate':644                    stack_var2 = [5, 4, 3, 2, 1, 0]645            646            raw_baselines = fd_raw647            column_names = fd_columns648        649 650        if st.button("Prepare data export", key='data_export'):651                if 'working_seed' in st.session_state:652                    st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]653                    st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]654                    st.session_state.data_export_display = st.session_state.working_seed[0:lineup_num_var]655                elif 'working_seed' not in st.session_state:656                    if site_var1 == 'Draftkings':657                        st.session_state.working_seed = init_DK_seed_frames(sharp_split_var, slate_var2)658 659                        dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))660                        raw_baselines = dk_raw661                        column_names = dk_columns662                663                    elif site_var1 == 'Fanduel':664                        st.session_state.working_seed = init_FD_seed_frames(sharp_split_var, slate_var2)665 666                        fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))667                        raw_baselines = fd_raw668                        column_names = fd_columns669                    st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]670                    st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]671                    st.session_state.data_export_display = st.session_state.working_seed[0:lineup_num_var]672                data_export = st.session_state.working_seed.copy()673                st.download_button(674                    label="Export optimals set",675                    data=convert_df(data_export),676                    file_name='NHL_optimals_export.csv',677                    mime='text/csv',678                )679                for key in st.session_state.keys():680                    del st.session_state[key]681            682    if st.button("Load Data", key='load_data'):683        if site_var1 == 'Draftkings':684            if 'working_seed' in st.session_state:685                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]686                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]687                st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)688            elif 'working_seed' not in st.session_state:689                if slate_var2 == 'Main Slate':690                    st.session_state.working_seed = init_DK_seed_frames(sharp_split_var)691                    dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))692 693                    raw_baselines = dk_raw694                    column_names = dk_columns695            696                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]697                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]698                st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)699            700        elif site_var1 == 'Fanduel':701            if 'working_seed' in st.session_state:702                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]703                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]704                st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)705            elif 'working_seed' not in st.session_state:706                if slate_var2 == 'Main Slate':707                    st.session_state.working_seed = init_FD_seed_frames(sharp_split_var)708                    fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))709                    710                    raw_baselines = fd_raw711                    column_names = fd_columns712                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]713                st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]714                st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)715            716    with st.container():717        if 'data_export_display' in st.session_state:718            st.dataframe(st.session_state.data_export_display.style.format(freq_format, precision=2), use_container_width = True)