CoolFace
Apppublic

TrueDFS/NFL_Betting_Models_Origin

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
streamlit_app.py822 linesDownload Raw Back to src
1import streamlit as st2import numpy as np3from numpy import where as np_where4import pandas as pd5import plotly.express as px6import scipy.stats as stats7st.set_page_config(layout="wide")8 9from database import props_db, dfs_db10 11game_format = {'Win%': '{:.2%}', 'Vegas': '{:.2%}', 'Win% Diff': '{:.2%}'}12american_format = {'First Inning Lead Percentage': '{:.2%}', 'Fifth Inning Lead Percentage': '{:.2%}'}13 14st.markdown("""15<style>16    /* Tab styling */17    .stElementContainer [data-baseweb="button-group"] {18        gap: 2.000rem;19        padding: 4px;20    }21    .stElementContainer [kind="segmented_control"] {22        height: 2.000rem;23        white-space: pre-wrap;24        background-color: #68B1E7;25        color: white;26        border-radius: 20px;27        gap: 1px;28        padding: 10px 20px;29        font-weight: bold;30        transition: all 0.3s ease;31    }32    .stElementContainer [kind="segmented_controlActive"] {33        height: 3.000rem;34        background-color: #68B1E7;35        border: 3px solid #4FB286;36        border-radius: 10px;37        color: black;38    }39    .stElementContainer [kind="segmented_control"]:hover {40        background-color: #4FB286;41        cursor: pointer;42    }43 44    div[data-baseweb="select"] > div {45        background-color: #68B1E7;46        color: white;47    }48 49</style>""", unsafe_allow_html=True)50 51def calculate_poisson(row):52    mean_val = row['Mean_Outcome']53    threshold = row['Prop']54    cdf_value = stats.poisson.cdf(threshold, mean_val)55    probability = 1 - cdf_value56    return probability57 58@st.cache_resource(ttl=600)59def init_baselines():60    collection = dfs_db["Game_Betting_Model"] 61    cursor = collection.find()62    raw_display = pd.DataFrame(list(cursor))63    game_model = raw_display[['Team', 'Opp', 'Win%', 'Vegas', 'Win% Diff', 'Win Line', 'Vegas Line', 'Line Diff', 'PD Spread', 'Vegas Spread', 'Spread Diff']]64    65    collection = dfs_db["Player_Stats"] 66    cursor = collection.find()67    raw_display = pd.DataFrame(list(cursor))68    overall_stats = raw_display[['Player', 'Position', 'Team', 'Opp', 'rush_att', 'rec', 'dropbacks', 'rush_yards', 'rush_tds', 'rec_yards', 'rec_tds', 'pass_att', 'pass_yards', 'pass_tds', 'PPR', 'Half_PPR']]69    70    collection = dfs_db["Prop_Trends"] 71    cursor = collection.find()72    raw_display = pd.DataFrame(list(cursor))73    prop_trends = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L3 Success', 'L6_Success', 'L10_success', 'L6 Avg', 'Projection',74                               'Proj Diff', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge']]75    76    collection = dfs_db["DK_NFL_ROO"] 77    cursor = collection.find()78 79    raw_display = pd.DataFrame(list(cursor))80    raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',81                               'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_ID', 'site']]82    load_display = raw_display[raw_display['Position'] != 'K']83    timestamp = load_display['timestamp'][0]84    85    collection = dfs_db["Prop_Trends"] 86    cursor = collection.find()87    raw_display = pd.DataFrame(list(cursor))88    prop_frame = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L3 Success', 'L6_Success', 'L10_success', 'L6 Avg', 'Projection',89                               'Proj Diff', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge']]90    91    collection = dfs_db['Pick6_Trends']92    cursor = collection.find()93    raw_display = pd.DataFrame(list(cursor))94    pick_frame = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L3 Success', 'L6_Success', 'L10_success', 'L6 Avg', 'Projection',95                               'Proj Diff', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge', 'last_name', 'P6_name', 'Full_name']]96 97    collection = props_db["NFL_Props"] 98    cursor = collection.find()99 100    raw_display = pd.DataFrame(list(cursor))101    market_props = raw_display[['Name', 'Position', 'Projection', 'PropType', 'OddsType', 'over_pay', 'under_pay']]102    market_props['over_prop'] = market_props['Projection']103    market_props['over_line'] = market_props['over_pay'].apply(lambda x: (x - 1) * 100 if x >= 2.0 else -100 / (x - 1))104    market_props['under_prop'] = market_props['Projection']105    market_props['under_line'] = market_props['under_pay'].apply(lambda x: (x - 1) * 100 if x >= 2.0 else -100 / (x - 1))106 107    return game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props108 109def calculate_no_vig(row):110    def implied_probability(american_odds):111        if american_odds < 0:112            return (-american_odds) / ((-american_odds) + 100)113        else:114            return 100 / (american_odds + 100)115 116    over_line = row['over_line']117    under_line = row['under_line']118    over_prop = row['over_prop']119    120    over_prob = implied_probability(over_line)121    under_prob = implied_probability(under_line)122    123    total_prob = over_prob + under_prob124    no_vig_prob = (over_prob / total_prob + 0.5) * over_prop125    126    return no_vig_prob127 128def convert_df_to_csv(df):129    return df.to_csv().encode('utf-8')130 131game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()132qb_stats = overall_stats[overall_stats['Position'] == 'QB']133qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])134non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']135non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])136team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))137t_stamp = f"Last Update: " + str(timestamp) + f" CST"138 139prop_table_options = ['NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_PASSING_COMPLETIONS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',140                      'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']141prop_format = {'L3 Success': '{:.2%}', 'L6_Success': '{:.2%}', 'L10_success': '{:.2%}', 'Trending Over': '{:.2%}', 'Trending Under': '{:.2%}',142               'Implied Over': '{:.2%}', 'Implied Under': '{:.2%}', 'Over Edge': '{:.2%}', 'Under Edge': '{:.2%}'}143all_sim_vars = ['NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_PASSING_COMPLETIONS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',144                      'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']145pick6_sim_vars = ['Rush + Rec Yards', 'Rush + Rec TDs', 'Passing Yards', 'Passing Attempts', 'Passing TDs', 'Completions', 'Rushing Yards', 'Receptions', 'Receiving Yards']146sim_all_hold = pd.DataFrame(columns=['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge'])147 148selected_tab = st.segmented_control(149    "Select Tab",150    options=["Game Betting Model", 'Prop Market', "QB Projections", "RB/WR/TE Projections", "Player Prop Trends", "Player Prop Simulations", "Stat Specific Simulations"],151    selection_mode='single',152    default='Game Betting Model',153    width='stretch',154    label_visibility='collapsed',155    key='tab_selector'156)157 158if selected_tab == 'Game Betting Model':159    st.info(t_stamp)160    if st.button("Reset Data", key='reset1'):161              st.cache_data.clear()162              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()163              qb_stats = overall_stats[overall_stats['Position'] == 'QB']164              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])165              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']166              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])167              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))168              t_stamp = f"Last Update: " + str(timestamp) + f" CST"169    line_var1 = st.radio('How would you like to display odds?', options = ['Percentage', 'American'], key='line_var1')170    team_frame = game_model171    if line_var1 == 'Percentage':172        team_frame = team_frame[['Team', 'Opp', 'Win%', 'Vegas', 'Win% Diff', 'PD Spread', 'Vegas Spread', 'Spread Diff']]173        team_frame = team_frame.set_index('Team')174        try:175            st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Spread Diff']).format(game_format, precision=2), use_container_width = True)176        except:177            st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Spread Diff']).format(precision=2), use_container_width = True)178    if line_var1 == 'American':179        team_frame = team_frame[['Team', 'Opp', 'Win Line', 'Vegas Line', 'Line Diff', 'PD Spread', 'Vegas Spread', 'Spread Diff']]180        team_frame = team_frame.set_index('Team')181        st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Spread Diff']).format(precision=2), height = 1000, use_container_width = True)182    183    st.download_button(184        label="Export Team Model",185        data=convert_df_to_csv(team_frame),186        file_name='NFL_team_betting_export.csv',187        mime='text/csv',188        key='team_export',189    )190 191if selected_tab == 'Prop Market':192    st.info(t_stamp)193    if st.button("Reset Data", key='reset4'):194              st.cache_data.clear()195              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()196              qb_stats = overall_stats[overall_stats['Position'] == 'QB']197              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])198              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']199              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])200              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))201              t_stamp = f"Last Update: " + str(timestamp) + f" CST"202    market_type = st.selectbox('Select type of prop are you wanting to view', options = prop_table_options, key = 'market_type_key')203    disp_market = market_props.copy()204    disp_market = disp_market[disp_market['PropType'] == market_type]205    disp_market['No_Vig_Prop'] = disp_market.apply(calculate_no_vig, axis=1)206    fanduel_frame = disp_market[disp_market['OddsType'] == 'FANDUEL']207    fanduel_dict = dict(zip(fanduel_frame['Name'], fanduel_frame['No_Vig_Prop']))208    draftkings_frame = disp_market[disp_market['OddsType'] == 'DRAFTKINGS']209    draftkings_dict = dict(zip(draftkings_frame['Name'], draftkings_frame['No_Vig_Prop']))210    mgm_frame = disp_market[disp_market['OddsType'] == 'MGM']211    mgm_dict = dict(zip(mgm_frame['Name'], mgm_frame['No_Vig_Prop']))212    bet365_frame = disp_market[disp_market['OddsType'] == 'BET_365']213    bet365_dict = dict(zip(bet365_frame['Name'], bet365_frame['No_Vig_Prop']))214 215    disp_market['FANDUEL'] = disp_market['Name'].map(fanduel_dict)216    disp_market['DRAFTKINGS'] = disp_market['Name'].map(draftkings_dict)217    disp_market['MGM'] = disp_market['Name'].map(mgm_dict)218    disp_market['BET365'] = disp_market['Name'].map(bet365_dict)219 220    disp_market = disp_market[['Name', 'Position','FANDUEL', 'DRAFTKINGS', 'MGM', 'BET365']]221    disp_market = disp_market.drop_duplicates(subset=['Name'], keep='first', ignore_index=True)222 223    st.dataframe(disp_market.style.background_gradient(axis=1, subset=['FANDUEL', 'DRAFTKINGS', 'MGM', 'BET365'], cmap='RdYlGn').format(prop_format, precision=2), height = 1000, use_container_width = True)224    st.download_button(225        label="Export Market Props",226        data=convert_df_to_csv(disp_market),227        file_name='NFL_market_props_export.csv',228        mime='text/csv',229    )230 231if selected_tab == 'QB Projections':232    st.info(t_stamp)233    if st.button("Reset Data", key='reset2'):234              st.cache_data.clear()235              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()236              qb_stats = overall_stats[overall_stats['Position'] == 'QB']237              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])238              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']239              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])240              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))241              t_stamp = f"Last Update: " + str(timestamp) + f" CST"242    split_var1 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var1')243    if split_var1 == 'Specific Teams':244        team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = qb_stats['Team'].unique(), key='team_var1')245    elif split_var1 == 'All':246        team_var1 = qb_stats.Team.values.tolist()247    qb_stats = qb_stats[qb_stats['Team'].isin(team_var1)]248    qb_stats_disp = qb_stats.set_index('Player')249    qb_stats_disp = qb_stats_disp.sort_values(by='PPR', ascending=False)250    st.dataframe(qb_stats_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True)251    st.download_button(252        label="Export Prop Model",253        data=convert_df_to_csv(qb_stats_disp),254        file_name='NFL_qb_stats_export.csv',255        mime='text/csv',256        key='NFL_qb_stats_export',257    )258 259if selected_tab == 'RB/WR/TE Projections':260    st.info(t_stamp)261    if st.button("Reset Data", key='reset3'):262              st.cache_data.clear()263              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()264              qb_stats = overall_stats[overall_stats['Position'] == 'QB']265              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])266              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']267              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])268              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))269              t_stamp = f"Last Update: " + str(timestamp) + f" CST"270    split_var2 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var2')271    if split_var2 == 'Specific Teams':272        team_var2 = st.multiselect('Which teams would you like to include in the tables?', options = non_qb_stats['Team'].unique(), key='team_var2')273    elif split_var2 == 'All':274        team_var2 = non_qb_stats.Team.values.tolist()275    non_qb_stats = non_qb_stats[non_qb_stats['Team'].isin(team_var2)]276    non_qb_stats_disp = non_qb_stats.set_index('Player')277    non_qb_stats_disp = non_qb_stats_disp.sort_values(by='PPR', ascending=False)278    st.dataframe(non_qb_stats_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True)279    st.download_button(280        label="Export Prop Model",281        data=convert_df_to_csv(non_qb_stats_disp),282        file_name='NFL_nonqb_stats_export.csv',283        mime='text/csv',284        key='NFL_nonqb_stats_export',285    )286 287if selected_tab == 'Player Prop Trends':288    st.info(t_stamp)289    if st.button("Reset Data", key='reset5'):290              st.cache_data.clear()291              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()292              qb_stats = overall_stats[overall_stats['Position'] == 'QB']293              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])294              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']295              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])296              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))297              t_stamp = f"Last Update: " + str(timestamp) + f" CST"298    split_var5 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var5')299    if split_var5 == 'Specific Teams':300        team_var5 = st.multiselect('Which teams would you like to include in the tables?', options = prop_trends['Team'].unique(), key='team_var5')301    elif split_var5 == 'All':302        team_var5 = prop_trends.Team.values.tolist()303    prop_type_var2 = st.selectbox('Select type of prop are you wanting to view', options = prop_table_options)304    book_var2 = st.selectbox('Select type of book do you want to view?', options = ['FANDUEL', 'BET365', 'DRAFTKINGS', 'CONSENSUS'])305    prop_frame_disp = prop_trends[prop_trends['Team'].isin(team_var5)]306    prop_frame_disp = prop_frame_disp[prop_frame_disp['book'] == book_var2]307    prop_frame_disp = prop_frame_disp[prop_frame_disp['prop_type'] == prop_type_var2]308    #prop_frame_disp = prop_frame_disp.set_index('Player')309    prop_frame_disp = prop_frame_disp.sort_values(by='Trending Over', ascending=False)310    st.dataframe(prop_frame_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(prop_format, precision=2), height = 1000, use_container_width = True)311    st.download_button(312        label="Export Prop Trends Model",313        data=convert_df_to_csv(prop_frame_disp),314        file_name='NFL_prop_trends_export.csv',315        mime='text/csv',316    )317 318if selected_tab == 'Player Prop Simulations':319    st.info(t_stamp)320    if st.button("Reset Data", key='reset6'):321              st.cache_data.clear()322              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()323              qb_stats = overall_stats[overall_stats['Position'] == 'QB']324              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])325              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']326              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])327              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))328              t_stamp = f"Last Update: " + str(timestamp) + f" CST"329    col1, col2 = st.columns([1, 5])330    331    with col2:332        df_hold_container = st.empty()333        info_hold_container = st.empty()334        plot_hold_container = st.empty()335    336    with col1:337        player_check = st.selectbox('Select player to simulate props', options = overall_stats['Player'].unique())338        prop_type_var = st.selectbox('Select type of prop to simulate', options = ['Pass Yards', 'Pass TDs', 'Rush Yards', 'Rush TDs', 'Receptions', 'Rec Yards', 'Rec TDs', 'Fantasy', 'FD Fantasy', 'PrizePicks'])339 340        ou_var = st.selectbox('Select wether it is an over or under', options = ['Over', 'Under'])341        if prop_type_var == 'Pass Yards':342            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 100.0, max_value = 400.5, value = 250.5, step = .5)343        elif prop_type_var == 'Pass TDs':344            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 5.5, value = 1.5, step = .5)345        elif prop_type_var == 'Rush Yards':346            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 155.5, value = 25.5, step = .5)347        elif prop_type_var == 'Rush TDs':348            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 5.5, value = 1.5, step = .5)349        elif prop_type_var == 'Receptions':350            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 15.5, value = 5.5, step = .5)351        elif prop_type_var == 'Rec Yards':352            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 155.5, value = 25.5, step = .5)353        elif prop_type_var == 'Rec TDs':354            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 5.5, value = 1.5, step = .5)355        elif prop_type_var == 'Fantasy':356            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 10.5, step = .5)357        elif prop_type_var == 'FD Fantasy':358            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 10.5, step = .5)359        elif prop_type_var == 'PrizePicks':360            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 10.5, step = .5)361        line_var = st.number_input('Type in the line on the prop (i.e. -120)', min_value = -1000, max_value = 1000, value = -150, step = 1)362        line_var = line_var + 1363 364        if st.button('Simulate Prop'):365            with col2:366                   367                    with df_hold_container.container():368 369                        df = overall_stats370 371                        total_sims = 5000372 373                        df.replace("", 0, inplace=True)374 375                        player_var = df[df['Player'] == player_check]376                        player_var = player_var.reset_index()377                        378                        if prop_type_var == 'Pass Yards':379                            df['Median'] = df['pass_yards']380                        elif prop_type_var == 'Pass TDs':381                            df['Median'] = df['pass_tds']382                        elif prop_type_var == 'Rush Yards':383                            df['Median'] = df['rush_yards']384                        elif prop_type_var == 'Rush TDs':385                            df['Median'] = df['rush_tds']386                        elif prop_type_var == 'Receptions':387                            df['Median'] = df['rec']388                        elif prop_type_var == 'Rec Yards':389                            df['Median'] = df['rec_yards']390                        elif prop_type_var == 'Rec TDs':391                            df['Median'] = df['rec_tds']392                        elif prop_type_var == 'Fantasy':393                            df['Median'] = df['PPR']394                        elif prop_type_var == 'FD Fantasy':395                            df['Median'] = df['Half_PPF']396                        elif prop_type_var == 'PrizePicks':397                            df['Median'] = df['Half_PPF']398 399                        flex_file = df400                        flex_file['Floor'] = flex_file['Median'] * .25401                        flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)402                        flex_file['STD'] = flex_file['Median'] / 4403                        flex_file = flex_file[['Player', 'Floor', 'Median', 'Ceiling', 'STD']]404 405                        hold_file = flex_file406                        overall_file = flex_file407                        salary_file = flex_file408 409                        overall_players = overall_file[['Player']]410 411                        for x in range(0,total_sims):412                            overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])413 414                        overall_file=overall_file.drop(['Player', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)415                        overall_file.astype('int').dtypes416 417                        players_only = hold_file[['Player']]418 419                        player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)420 421                        players_only['Mean_Outcome'] = overall_file.mean(axis=1)422                        players_only['Prop'] = prop_var423                        players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)424                        players_only['10%'] = overall_file.quantile(0.1, axis=1)425                        players_only['90%'] = overall_file.quantile(0.9, axis=1)426                        if ou_var == 'Over':427                            players_only['beat_prop'] = np.where(players_only['Prop'] <= 3, players_only['poisson_var'], overall_file[overall_file > prop_var].count(axis=1)/float(total_sims))428                        elif ou_var == 'Under':429                            players_only['beat_prop'] = np.where(players_only['Prop'] <= 3, 1 - players_only['poisson_var'], (overall_file[overall_file < prop_var].count(axis=1)/float(total_sims)))430 431                        players_only['implied_odds'] = np.where(line_var <= 0, (-(line_var)/((-(line_var))+100)), 100/(line_var+100))432 433                        players_only['Player'] = hold_file[['Player']]434 435                        final_outcomes = players_only[['Player', '10%', 'Mean_Outcome', '90%', 'implied_odds', 'beat_prop']]436                        final_outcomes['Bet?'] = np.where(final_outcomes['beat_prop'] - final_outcomes['implied_odds'] >= .10, "Bet", "No Bet")437                        final_outcomes = final_outcomes[final_outcomes['Player'] == player_check]438                        player_outcomes = player_outcomes[player_outcomes['Player'] == player_check]439                        player_outcomes = player_outcomes.drop(columns=['Player']).transpose()440                        player_outcomes = player_outcomes.reset_index()441                        player_outcomes.columns = ['Instance', 'Outcome']442 443                        x1 = player_outcomes.Outcome.to_numpy()444 445                        print(x1)446 447                        hist_data = [x1]448 449                        group_labels = ['player outcomes']450 451                        fig = px.histogram(452                                player_outcomes, x='Outcome')453                        fig.add_vline(x=prop_var, line_dash="dash", line_color="green")454 455                        with df_hold_container:456                            df_hold_container = st.empty()457                            format_dict = {'10%': '{:.2f}', 'Mean_Outcome': '{:.2f}','90%': '{:.2f}', 'beat_prop': '{:.2%}','implied_odds': '{:.2%}'}458                            st.dataframe(final_outcomes.style.format(format_dict), use_container_width = True)459 460                        with info_hold_container:461                            st.info('The Y-axis is the percent of times in simulations that the player reaches certain thresholds, while the X-axis is the threshold to be met. The Green dotted line is the prop you entered. You can hover over any spot and see the percent to reach that mark.')462 463                        with plot_hold_container:464                            st.dataframe(player_outcomes, use_container_width = True)465                            plot_hold_container = st.empty()466                            st.plotly_chart(fig, use_container_width=True)467 468if selected_tab == 'Stat Specific Simulations':469    st.info(t_stamp)470    st.info('The Over and Under percentages are a compositve percentage based on simulations, historical performance, and implied probabilities, and may be different than you would expect based purely on the median projection. Likewise, the Edge of a bet is not the only indicator of if you should make the bet or not as the suggestion is using a base acceptable threshold to determine how much edge you should have for each stat category.')471    if st.button("Reset Data/Load Data", key='reset7'):472              st.cache_data.clear()473              game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()474              qb_stats = overall_stats[overall_stats['Position'] == 'QB']475              qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])476              non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']477              non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])478              team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))479              t_stamp = f"Last Update: " + str(timestamp) + f" CST"480        481    settings_container = st.empty()482    df_hold_container = st.empty()483    export_container = st.empty()484 485    with settings_container.container():486        col1, col2, col3, col4 = st.columns([3, 3, 3, 3])487        with col1:488            game_select_var = st.selectbox('Select prop source', options = ['Aggregate', 'Pick6'])489        with col2:490            book_select_var = st.selectbox('Select book', options = ['ALL', 'BET_365', 'DRAFTKINGS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL'])491            if book_select_var == 'ALL':492                book_selections = ['BET_365', 'DRAFTKINGS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL']493            else:494                book_selections = [book_select_var]495            if game_select_var == 'Aggregate':496                prop_df = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]497            elif game_select_var == 'Pick6':498                prop_df = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]499                book_selections = ['Pick6']500        with col3:501            if game_select_var == 'Aggregate':502                prop_type_var = st.selectbox('Select prop category', options = ['All Props', 'NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',503                                                'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS'])504            elif game_select_var == 'Pick6':505                prop_type_var = st.selectbox('Select prop category', options = ['All Props', 'Rush + Rec Yards', 'Rush + Rec TDs', 'Passing Yards', 'Passing Attempts', 'Passing TDs', 'Rushing Attempts', 'Rushing Yards', 'Receptions', 'Receiving Yards', 'Receiving TDs'])506        with col4:507            st.download_button(508                label="Download Prop Source",509                data=convert_df_to_csv(prop_df),510                file_name='NFL_prop_source.csv',511                mime='text/csv',512                key='prop_source',513            )514 515    if st.button('Simulate Prop Category'):516                517        with df_hold_container.container():518            if prop_type_var == 'All Props':519                if game_select_var == 'Aggregate':520                    prop_df_raw = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]521                    sim_vars = ['NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',522                                'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']523                elif game_select_var == 'Pick6':524                    prop_df_raw = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]525                    sim_vars = ['Rush + Rec Yards', 'Rush + Rec TDs', 'Passing Yards', 'Passing Attempts', 'Passing TDs', 'Rushing Attempts', 'Rushing Yards', 'Receptions', 'Receiving Yards', 'Receiving TDs']526                527                player_df = overall_stats.copy()528                529                for prop in sim_vars:530                        531                    for books in book_selections:532                        prop_df = prop_df_raw[prop_df_raw['book'] == books]533                        prop_df = prop_df[prop_df['prop_type'] == prop]534                        prop_df = prop_df[~((prop_df['over_prop'] < 15) & (prop_df['prop_type'] == 'NFL_GAME_PLAYER_RUSHING_YARDS'))]535                        prop_df = prop_df[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]536                        prop_df.rename(columns={"over_prop": "Prop"}, inplace = True)537                        prop_df['Over'] = 1 / prop_df['over_line']538                        prop_df['Under'] = 1 / prop_df['under_line']539 540                        prop_dict = dict(zip(prop_df.Player, prop_df.Prop))541                        prop_type_dict = dict(zip(prop_df.Player, prop_df.prop_type))542                        book_dict = dict(zip(prop_df.Player, prop_df.book))543                        over_dict = dict(zip(prop_df.Player, prop_df.Over))544                        under_dict = dict(zip(prop_df.Player, prop_df.Under))545                        trending_over_dict = dict(zip(prop_df.Player, prop_df['Trending Over']))546                        trending_under_dict = dict(zip(prop_df.Player, prop_df['Trending Under']))547 548                        player_df['book'] = player_df['Player'].map(book_dict)549                        player_df['Prop'] = player_df['Player'].map(prop_dict)550                        player_df['prop_type'] = player_df['Player'].map(prop_type_dict)551                        player_df['Trending Over'] = player_df['Player'].map(trending_over_dict)552                        player_df['Trending Under'] = player_df['Player'].map(trending_under_dict)553 554                        df = player_df.reset_index(drop=True)555 556                        team_dict = dict(zip(df.Player, df.Team))557                        558                        total_sims = 1000559 560                        df.replace("", 0, inplace=True)561                        562                        if prop == "NFL_GAME_PLAYER_PASSING_YARDS" or prop == "Passing Yards":563                            df['Median'] = df['pass_yards']564                        elif prop == "NFL_GAME_PLAYER_RUSHING_YARDS" or prop == "Rushing Yards":565                            df['Median'] = df['rush_yards']566                        elif prop == "NFL_GAME_PLAYER_PASSING_ATTEMPTS" or prop == "Passing Attempts":567                            df['Median'] = df['pass_att']568                        elif prop == "NFL_GAME_PLAYER_PASSING_TOUCHDOWNS" or prop == "Passing TDs":569                            df['Median'] = df['pass_tds']570                        elif prop == "NFL_GAME_PLAYER_RUSHING_ATTEMPTS" or prop == "Rushing Attempts":571                            df['Median'] = df['rush_att']572                        elif prop == "NFL_GAME_PLAYER_RECEIVING_RECEPTIONS" or prop == "Receptions":573                            df['Median'] = df['rec']574                        elif prop == "NFL_GAME_PLAYER_RECEIVING_YARDS" or prop == "Receiving Yards":575                            df['Median'] = df['rec_yards']576                        elif prop == "NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS" or prop == "Receiving TDs":577                            df['Median'] = df['rec_tds']578                        elif prop == "Rush + Rec Yards":579                            df['Median'] = df['rush_yards'] + df['rec_yards']580                        elif prop == "Rush + Rec TDs":581                            df['Median'] = df['rush_tds'] + df['rec_tds']582                            583                        flex_file = df.copy()584                        flex_file['Floor'] = flex_file['Median'] * .25585                        flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)586                        flex_file['STD'] = flex_file['Median'] / 4587                        flex_file['Prop'] = flex_file['Player'].map(prop_dict)588                        flex_file = flex_file[['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD']]589 590                        hold_file = flex_file.copy()591                        overall_file = flex_file.copy()592                        prop_file = flex_file.copy()593                                594                        overall_players = overall_file[['Player']]595 596                        for x in range(0,total_sims):    597                            prop_file[x] = prop_file['Prop']598 599                        prop_file = prop_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)600 601                        for x in range(0,total_sims):602                            overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])603 604                        overall_file=overall_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)605 606                        players_only = hold_file[['Player']]607 608                        player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)609 610                        prop_check = (overall_file - prop_file)611 612                        players_only['Mean_Outcome'] = overall_file.mean(axis=1)613                        players_only['Book'] = players_only['Player'].map(book_dict)614                        players_only['Prop'] = players_only['Player'].map(prop_dict)615                        players_only['Trending Over'] = players_only['Player'].map(trending_over_dict)616                        players_only['Trending Under'] = players_only['Player'].map(trending_under_dict)617                        players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)618                        players_only['10%'] = overall_file.quantile(0.1, axis=1)619                        players_only['90%'] = overall_file.quantile(0.9, axis=1)620                        players_only['Over'] = np_where(players_only['Prop'] <= 3, players_only['poisson_var'], prop_check[prop_check > 0].count(axis=1)/float(total_sims))621                        players_only['Imp Over'] = players_only['Player'].map(over_dict)622                        players_only['Over%'] = players_only[["Over", "Imp Over", "Trending Over"]].mean(axis=1)623                        players_only['Under'] = np_where(players_only['Prop'] <= 3, 1 - players_only['poisson_var'], prop_check[prop_check < 0].count(axis=1)/float(total_sims))624                        players_only['Imp Under'] = players_only['Player'].map(under_dict)625                        players_only['Under%'] = players_only[["Under", "Imp Under", "Trending Under"]].mean(axis=1)626                        players_only['Prop_avg'] = players_only['Prop'].mean() / 100627                        players_only['prop_threshold'] = .10628                        players_only = players_only[players_only['Mean_Outcome'] > 0]629                        players_only['Over_diff'] = players_only['Over%'] - players_only['Imp Over']630                        players_only['Under_diff'] = players_only['Under%'] - players_only['Imp Under']631                        players_only['Bet_check'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], players_only['Over_diff'] , players_only['Under_diff'])632                        players_only['Bet_suggest'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], "Over" , "Under")633                        players_only['Bet?'] = np.where(players_only['Bet_check'] >= players_only['prop_threshold'], players_only['Bet_suggest'], "No Bet")634                        players_only['Edge'] = players_only['Bet_check']635                        players_only['Prop Type'] = prop636 637                        players_only['Player'] = hold_file[['Player']]638                        players_only['Team'] = players_only['Player'].map(team_dict)639 640                        leg_outcomes = players_only[['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge']]641                        sim_all_hold = pd.concat([sim_all_hold, leg_outcomes], ignore_index=True)642                        643                        final_outcomes = sim_all_hold644                        st.write(f'finished {prop} for {books}')645                    646            elif prop_type_var != 'All Props':647 648                player_df = overall_stats.copy()649 650                if game_select_var == 'Aggregate':651                    prop_df_raw = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]652                elif game_select_var == 'Pick6':653                    prop_df_raw = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]654                    655                for books in book_selections:656                    prop_df = prop_df_raw[prop_df_raw['book'] == books]657                    658                    if prop_type_var == "NFL_GAME_PLAYER_PASSING_YARDS":659                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_PASSING_YARDS']660                    elif prop_type_var == "Passing Yards":661                        prop_df = prop_df[prop_df['prop_type'] == 'Passing Yards']662                    elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_YARDS":663                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RUSHING_YARDS']664                    elif prop_type_var == "Rushing Yards":665                        prop_df = prop_df[prop_df['prop_type'] == 'Rushing Yards']666                    elif prop_type_var == "NFL_GAME_PLAYER_PASSING_ATTEMPTS":667                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_PASSING_ATTEMPTS']668                    elif prop_type_var == "Passing Attempts":669                        prop_df = prop_df[prop_df['prop_type'] == 'Passing Attempts']670                    elif prop_type_var == "NFL_GAME_PLAYER_PASSING_TOUCHDOWNS":671                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS']672                    elif prop_type_var == "Passing TDs":673                        prop_df = prop_df[prop_df['prop_type'] == 'Passing TDs']674                    elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_ATTEMPTS":675                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS']676                    elif prop_type_var == "Rushing Attempts":677                        prop_df = prop_df[prop_df['prop_type'] == 'Rushing Attempts']678                    elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_RECEPTIONS":679                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS']680                    elif prop_type_var == "Receptions":681                        prop_df = prop_df[prop_df['prop_type'] == 'Receptions']682                    elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_YARDS":683                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RECEIVING_YARDS']684                    elif prop_type_var == "Receiving Yards":685                        prop_df = prop_df[prop_df['prop_type'] == 'Receiving Yards']686                    elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS":687                        prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']688                    elif prop_type_var == "Receiving TDs":689                        prop_df = prop_df[prop_df['prop_type'] == 'Receiving TDs']690                    elif prop_type_var == "Rush + Rec Yards":691                        prop_df = prop_df[prop_df['prop_type'] == 'Rush + Rec Yards']692                    elif prop_type_var == "Rush + Rec TDs":693                        prop_df = prop_df[prop_df['prop_type'] == 'Rush + Rec TDs']694 695                    prop_df = prop_df[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]696                    prop_df = prop_df.rename(columns={"over_prop": "Prop"})697                    prop_df['Over'] = 1 / prop_df['over_line']698                    prop_df['Under'] = 1 / prop_df['under_line']699 700                    prop_dict = dict(zip(prop_df.Player, prop_df.Prop))701                    prop_type_dict = dict(zip(prop_df.Player, prop_df.prop_type))702                    book_dict = dict(zip(prop_df.Player, prop_df.book))703                    over_dict = dict(zip(prop_df.Player, prop_df.Over))704                    under_dict = dict(zip(prop_df.Player, prop_df.Under))705                    trending_over_dict = dict(zip(prop_df.Player, prop_df['Trending Over']))706                    trending_under_dict = dict(zip(prop_df.Player, prop_df['Trending Under']))707 708                    player_df['book'] = player_df['Player'].map(book_dict)709                    player_df['Prop'] = player_df['Player'].map(prop_dict)710                    player_df['prop_type'] = player_df['Player'].map(prop_type_dict)711                    player_df['Trending Over'] = player_df['Player'].map(trending_over_dict)712                    player_df['Trending Under'] = player_df['Player'].map(trending_under_dict)713 714                    df = player_df.reset_index(drop=True)715 716                    team_dict = dict(zip(df.Player, df.Team))717                    718                    total_sims = 1000719 720                    df.replace("", 0, inplace=True)721                    722                    if prop_type_var == "NFL_GAME_PLAYER_PASSING_YARDS" or prop_type_var == "Passing Yards":723                        df['Median'] = df['pass_yards']724                    elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_YARDS" or prop_type_var == "Rushing Yards":725                        df['Median'] = df['rush_yards']726                    elif prop_type_var == "NFL_GAME_PLAYER_PASSING_ATTEMPTS" or prop_type_var == "Passing Attempts":727                        df['Median'] = df['pass_att']728                    elif prop_type_var == "NFL_GAME_PLAYER_PASSING_TOUCHDOWNS" or prop_type_var == "Passing TDs":729                        df['Median'] = df['pass_tds']730                    elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_ATTEMPTS" or prop_type_var == "Rushing Attempts":731                        df['Median'] = df['rush_att']732                    elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_RECEPTIONS" or prop_type_var == "Receptions":733                        df['Median'] = df['rec']734                    elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_YARDS" or prop_type_var == "Receiving Yards":735                        df['Median'] = df['rec_yards']736                    elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS" or prop_type_var == "Receiving TDs":737                        df['Median'] = df['rec_tds']738                    elif prop_type_var == "Rush + Rec Yards":739                        df['Median'] = df['rush_yards'] + df['rec_yards']740                    elif prop_type_var == "Rush + Rec TDs":741                        df['Median'] = df['rush_tds'] + df['rec_tds']742 743                    flex_file = df.copy()744                    flex_file['Floor'] = flex_file['Median'] * .25745                    flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)746                    flex_file['STD'] = flex_file['Median'] / 4747                    flex_file['Prop'] = flex_file['Player'].map(prop_dict)748                    flex_file = flex_file[['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD']]749 750                    hold_file = flex_file.copy()751                    overall_file = flex_file.copy()752                    prop_file = flex_file.copy()753                            754                    overall_players = overall_file[['Player']]755 756                    for x in range(0,total_sims):    757                        prop_file[x] = prop_file['Prop']758 759                    prop_file = prop_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)760 761                    for x in range(0,total_sims):762                        overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])763 764                    overall_file=overall_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)765 766                    players_only = hold_file[['Player']]767 768                    player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)769 770                    prop_check = (overall_file - prop_file)771 772                    players_only['Mean_Outcome'] = overall_file.mean(axis=1)773                    players_only['Book'] = players_only['Player'].map(book_dict)774                    players_only['Prop'] = players_only['Player'].map(prop_dict)775                    players_only['Trending Over'] = players_only['Player'].map(trending_over_dict)776                    players_only['Trending Under'] = players_only['Player'].map(trending_under_dict)777                    players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)778                    players_only['10%'] = overall_file.quantile(0.1, axis=1)779                    players_only['90%'] = overall_file.quantile(0.9, axis=1)780                    players_only['Over'] = np_where(players_only['Prop'] <= 3, players_only['poisson_var'], prop_check[prop_check > 0].count(axis=1)/float(total_sims))781                    players_only['Imp Over'] = players_only['Player'].map(over_dict)782                    players_only['Over%'] = players_only[["Over", "Imp Over", "Trending Over"]].mean(axis=1)783                    players_only['Under'] = np_where(players_only['Prop'] <= 3, 1 - players_only['poisson_var'], prop_check[prop_check < 0].count(axis=1)/float(total_sims))784                    players_only['Imp Under'] = players_only['Player'].map(under_dict)785                    players_only['Under%'] = players_only[["Under", "Imp Under", "Trending Under"]].mean(axis=1)786                    players_only['Prop_avg'] = players_only['Prop'].mean() / 100787                    players_only['prop_threshold'] = .10788                    players_only = players_only[players_only['Mean_Outcome'] > 0]789                    players_only['Over_diff'] = players_only['Over%'] - players_only['Imp Over']790                    players_only['Under_diff'] = players_only['Under%'] - players_only['Imp Under']791                    players_only['Bet_check'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], players_only['Over_diff'] , players_only['Under_diff'])792                    players_only['Bet_suggest'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], "Over" , "Under")793                    players_only['Bet?'] = np.where(players_only['Bet_check'] >= players_only['prop_threshold'], players_only['Bet_suggest'], "No Bet")794                    players_only['Edge'] = players_only['Bet_check']795                    players_only['Prop Type'] = prop_type_var796 797                    players_only['Player'] = hold_file[['Player']]798                    players_only['Team'] = players_only['Player'].map(team_dict)799 800                    leg_outcomes = players_only[['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge']]801                    sim_all_hold = pd.concat([sim_all_hold, leg_outcomes], ignore_index=True)802                    803                    final_outcomes = sim_all_hold804                    st.write(f'finished {prop_type_var} for {books}')805            806            final_outcomes = final_outcomes.dropna()807            if game_select_var == 'Pick6':808                final_outcomes = final_outcomes.drop_duplicates(subset=['Player', 'Prop Type'])809            final_outcomes = final_outcomes.sort_values(by='Edge', ascending=False)810 811            with df_hold_container:812                df_hold_container = st.empty()813                st.dataframe(final_outcomes.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)814            with export_container:815                export_container = st.empty()816                st.download_button(817                    label="Export Projections",818                    data=convert_df_to_csv(final_outcomes),819                    file_name='NFL_prop_proj.csv',820                    mime='text/csv',821                    key='prop_proj',822                )