James McCool commited on
Commit
cd893a3
·
1 Parent(s): 69200bc

visual and optimals update

Browse files
Files changed (1) hide show
  1. app.py +772 -71
app.py CHANGED
@@ -9,8 +9,10 @@ import pulp
9
  import numpy as np
10
  import pandas as pd
11
  import streamlit as st
 
12
  import pymongo
13
  from itertools import combinations
 
14
 
15
  @st.cache_resource
16
  def init_conn():
@@ -25,6 +27,13 @@ db = init_conn()
25
  player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '20+%': '{:.2%}', '2x%': '{:.2%}', '3x%': '{:.2%}',
26
  '4x%': '{:.2%}'}
27
 
 
 
 
 
 
 
 
28
  @st.cache_resource(ttl=200)
29
  def player_stat_table():
30
  collection = db["Player_Level_ROO"]
@@ -47,25 +56,166 @@ def player_stat_table():
47
 
48
  return player_frame, line_frame, pp_frame, timestamp
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  @st.cache_data
51
  def convert_df_to_csv(df):
52
  return df.to_csv().encode('utf-8')
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  player_frame, line_frame, pp_frame, timestamp = player_stat_table()
 
 
 
 
55
  t_stamp = f"Last Update: " + str(timestamp) + f" CST"
56
 
57
- tab1, tab2, tab3 = st.tabs(["Player Range of Outcomes", "Line Combo Range of Outcomes", "Power Play Range of Outcomes"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  with tab1:
60
- col1, col2 = st.columns([1, 7])
61
- with col1:
 
62
  st.info(t_stamp)
63
  if st.button("Load/Reset Data", key='reset1'):
64
- st.cache_data.clear()
65
- player_frame, line_frame, pp_frame, timestamp = player_stat_table()
66
- t_stamp = f"Last Update: " + str(timestamp) + f" CST"
67
- site_var1 = st.radio("What table would you like to display?", ('Draftkings', 'Fanduel'), key='site_var1')
68
- main_var1 = st.radio("Main slate or secondary slate?", ('Main Slate', 'Secondary Slate'), key='main_var1')
 
 
 
 
69
  split_var1 = st.radio("Would you like to view the whole slate or just specific games?", ('Full Slate Run', 'Specific Games'), key='split_var1')
70
  if split_var1 == 'Specific Games':
71
  team_var1 = st.multiselect('Which teams would you like to include in the ROO?', options = player_frame['Team'].unique(), key='team_var1')
@@ -77,79 +227,630 @@ with tab1:
77
  elif pos_split1 == 'All Positions':
78
  pos_var1 = 'All'
79
  sal_var1 = st.slider("Is there a certain price range you want to view?", 2000, 10000, (2000, 20000), key='sal_var1')
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
- with col2:
82
- final_Proj = player_frame[player_frame['Site'] == str(site_var1)]
83
- final_Proj = final_Proj[final_Proj['Type'] == 'Basic']
84
- final_Proj = final_Proj[final_Proj['Slate'] == main_var1]
85
- final_Proj = final_Proj[player_frame['Team'].isin(team_var1)]
86
- final_Proj = final_Proj[final_Proj['Salary'] >= sal_var1[0]]
87
- final_Proj = final_Proj[final_Proj['Salary'] <= sal_var1[1]]
88
- if pos_var1 != 'All':
89
- final_Proj = final_Proj[final_Proj['Position'].str.contains('|'.join(pos_var1))]
90
- final_Proj = final_Proj.sort_values(by='Median', ascending=False)
91
- if pos_var1 == 'All':
92
- final_Proj = final_Proj.sort_values(by='Median', ascending=False)
93
- st.dataframe(final_Proj.iloc[:, :-3].style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), use_container_width = True)
94
- st.download_button(
95
- label="Export Tables",
96
- data=convert_df_to_csv(final_Proj),
97
- file_name='NHL_player_export.csv',
98
- mime='text/csv',
99
- )
100
 
101
  with tab2:
102
- col1, col2 = st.columns([1, 7])
103
- with col1:
 
104
  st.info(t_stamp)
105
  if st.button("Load/Reset Data", key='reset2'):
106
- st.cache_data.clear()
107
- player_frame, line_frame, pp_frame, timestamp = player_stat_table()
108
- t_stamp = f"Last Update: " + str(timestamp) + f" CST"
109
- site_var2 = st.radio("What table would you like to display?", ('Draftkings', 'Fanduel'), key='site_var2')
110
- main_var2 = st.radio("Main slate or secondary slate?", ('Main Slate', 'Secondary Slate'), key='main_var2')
 
 
 
 
111
  sal_var2 = st.slider("Is there a certain price range you want to view?", 5000, 40000, (5000, 40000), key='sal_var2')
112
-
113
- with col2:
114
- final_line_combos = line_frame[line_frame['Site'] == str(site_var2)]
115
- final_line_combos = final_line_combos[final_line_combos['Type'] == 'Basic']
116
- final_line_combos = final_line_combos[final_line_combos['Slate'] == main_var2]
117
- final_line_combos = final_line_combos[final_line_combos['Salary'] >= sal_var2[0]]
118
- final_line_combos = final_line_combos[final_line_combos['Salary'] <= sal_var2[1]]
119
- final_line_combos = final_line_combos.drop_duplicates(subset=['Player'])
120
- final_line_combos = final_line_combos.sort_values(by='Median', ascending=False)
121
- st.dataframe(final_line_combos.iloc[:, :-3].style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
122
- st.download_button(
123
- label="Export Tables",
124
- data=convert_df_to_csv(final_line_combos),
125
- file_name='NHL_linecombos_export.csv',
126
- mime='text/csv',
127
- )
 
 
 
 
 
128
 
129
  with tab3:
130
- col1, col2 = st.columns([1, 7])
131
- with col1:
 
132
  st.info(t_stamp)
133
  if st.button("Load/Reset Data", key='reset3'):
134
- st.cache_data.clear()
135
- player_frame, line_frame, pp_frame, timestamp = player_stat_table()
136
- t_stamp = f"Last Update: " + str(timestamp) + f" CST"
137
- site_var3 = st.radio("What table would you like to display?", ('Draftkings', 'Fanduel'), key='site_var3')
138
- main_var3 = st.radio("Main slate or secondary slate?", ('Main Slate', 'Secondary Slate'), key='main_var3')
 
 
 
 
139
  sal_var3 = st.slider("Is there a certain price range you want to view?", 5000, 40000, (5000, 40000), key='sal_var3')
140
 
141
- with col2:
142
- final_pp_combos = pp_frame[pp_frame['Site'] == str(site_var3)]
143
- final_pp_combos = final_pp_combos[final_pp_combos['Type'] == 'Basic']
144
- final_pp_combos = final_pp_combos[final_pp_combos['Slate'] == main_var3]
145
- final_pp_combos = final_pp_combos[final_pp_combos['Salary'] >= sal_var3[0]]
146
- final_pp_combos = final_pp_combos[final_pp_combos['Salary'] <= sal_var3[1]]
147
- final_pp_combos = final_pp_combos.drop_duplicates(subset=['Player'])
148
- final_pp_combos = final_pp_combos.sort_values(by='Median', ascending=False)
149
- st.dataframe(final_pp_combos.iloc[:, :-3].style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  st.download_button(
151
- label="Export Tables",
152
- data=convert_df_to_csv(final_pp_combos),
153
- file_name='NHL_powerplay_export.csv',
154
- mime='text/csv',
155
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  import numpy as np
10
  import pandas as pd
11
  import streamlit as st
12
+ import gspread
13
  import pymongo
14
  from itertools import combinations
15
+ import math
16
 
17
  @st.cache_resource
18
  def init_conn():
 
27
  player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '20+%': '{:.2%}', '2x%': '{:.2%}', '3x%': '{:.2%}',
28
  '4x%': '{:.2%}'}
29
 
30
+ dk_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
31
+ fd_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
32
+ dk_hb_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX']
33
+ fd_hb_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G']
34
+ dk_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
35
+ fd_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
36
+
37
  @st.cache_resource(ttl=200)
38
  def player_stat_table():
39
  collection = db["Player_Level_ROO"]
 
56
 
57
  return player_frame, line_frame, pp_frame, timestamp
58
 
59
+ @st.cache_resource(ttl = 60)
60
+ def init_DK_lineups(prio_var, prio_mix, lineup_num, player_var2):
61
+
62
+ if prio_var == 'Mix':
63
+ prio_var = None
64
+
65
+ collection = db['DK_NHL_seed_frame']
66
+ if prio_var == None:
67
+ if player_var2 != []:
68
+ player_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX']
69
+ query_conditions = []
70
+
71
+ for player in player_var2:
72
+ # Create a condition for each player to check if they appear in any column
73
+ player_condition = {'$or': [{col: player} for col in player_columns]}
74
+ query_conditions.append(player_condition)
75
+
76
+ # Combine all player conditions with $or
77
+ if query_conditions:
78
+ filter_query = {'$or': query_conditions}
79
+ cursor1 = collection.find(filter_query).limit(math.ceil(lineup_num * (prio_mix / 100)))
80
+ cursor2 = collection.find(filter_query).sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100)))
81
+ else:
82
+ cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100)))
83
+ cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100)))
84
+ raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))])
85
+ else:
86
+ cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100)))
87
+ cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100)))
88
+ raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))])
89
+ else:
90
+ cursor = collection.find().sort(prio_var, -1).limit(lineup_num)
91
+ raw_display = pd.DataFrame(list(cursor))
92
+
93
+ raw_display = raw_display.drop_duplicates(subset=['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX'])
94
+
95
+ raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
96
+
97
+ DK_seed = raw_display.to_numpy()
98
+
99
+ return DK_seed
100
+
101
+ @st.cache_resource(ttl = 60)
102
+ def init_FD_lineups(prio_var, prio_mix, lineup_num, player_var2):
103
+
104
+ if prio_var == 'Mix':
105
+ prio_var = None
106
+
107
+ collection = db['FD_NHL_seed_frame']
108
+ if prio_var == None:
109
+ if player_var2 != []:
110
+ player_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G']
111
+ query_conditions = []
112
+
113
+ for player in player_var2:
114
+ # Create a condition for each player to check if they appear in any column
115
+ player_condition = {'$or': [{col: player} for col in player_columns]}
116
+ query_conditions.append(player_condition)
117
+
118
+ # Combine all player conditions with $or
119
+ if query_conditions:
120
+ filter_query = {'$or': query_conditions}
121
+ cursor1 = collection.find(filter_query).limit(math.ceil(lineup_num * (prio_mix / 100)))
122
+ cursor2 = collection.find(filter_query).sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100)))
123
+ else:
124
+ cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100)))
125
+ cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100)))
126
+ raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))])
127
+ else:
128
+ cursor1 = collection.find().limit(math.ceil(lineup_num * (prio_mix / 100)))
129
+ cursor2 = collection.find().sort('Own', -1).limit(math.ceil(lineup_num * ((100 - prio_mix) / 100)))
130
+ raw_display = pd.concat([pd.DataFrame(list(cursor1)), pd.DataFrame(list(cursor2))])
131
+ else:
132
+ cursor = collection.find().sort(prio_var, -1).limit(lineup_num)
133
+ raw_display = pd.DataFrame(list(cursor))
134
+
135
+ raw_display = raw_display.drop_duplicates(subset=['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G'])
136
+
137
+ raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
138
+
139
+ FD_seed = raw_display.to_numpy()
140
+
141
+ return FD_seed
142
+
143
  @st.cache_data
144
  def convert_df_to_csv(df):
145
  return df.to_csv().encode('utf-8')
146
 
147
+ @st.cache_data
148
+ def convert_df(array):
149
+ array = pd.DataFrame(array, columns=column_names)
150
+ return array.to_csv().encode('utf-8')
151
+
152
+ @st.cache_data
153
+ def convert_pm_df(array):
154
+ array = pd.DataFrame(array)
155
+ return array.to_csv().encode('utf-8')
156
+
157
+ @st.cache_data
158
+ def convert_hb_df(array, column_names):
159
+ array = pd.DataFrame(array, columns=column_names)
160
+ return array.to_csv().encode('utf-8')
161
+
162
  player_frame, line_frame, pp_frame, timestamp = player_stat_table()
163
+ dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
164
+ fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
165
+ dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
166
+ fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
167
  t_stamp = f"Last Update: " + str(timestamp) + f" CST"
168
 
169
+ app_load_reset_column, app_view_site_column, = st.columns([1, 9])
170
+ with app_load_reset_column:
171
+ if st.button("Load/Reset Data", key='reset_data_button'):
172
+ st.cache_data.clear()
173
+ player_frame, line_frame, pp_frame, timestamp = player_stat_table()
174
+ dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
175
+ fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
176
+ dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
177
+ fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
178
+ dk_lineups = init_DK_lineups('proj', 50, 25000, [])
179
+ fd_lineups = init_FD_lineups('proj', 50, 25000, [])
180
+ for key in st.session_state.keys():
181
+ del st.session_state[key]
182
+ with app_view_site_column:
183
+ with st.container():
184
+ app_view_column, app_site_column, app_type_column = st.columns([3, 3, 3])
185
+ with app_view_column:
186
+ view_var = st.selectbox("Select view", ["Simple", "Advanced"], key='view_selectbox')
187
+ with app_site_column:
188
+ site_var = st.selectbox("What site do you want to view?", ('Draftkings', 'Fanduel'), key='site_selectbox')
189
+ with app_type_column:
190
+ type_var = st.selectbox("What type of data do you want to view?", ('Regular', 'Showdown'), key='type_selectbox')
191
+
192
+ # selected_tab = st.segmented_control(
193
+ # "Select Tab",
194
+ # options=["Player Range of Outcomes", "Line Combo Range of Outcomes", "Power Play Range of Outcomes", "Optimals"],
195
+ # selection_mode='single',
196
+ # default='Player Range of Outcomes',
197
+ # width='stretch',
198
+ # label_visibility='collapsed',
199
+ # key='tab_selector'
200
+ # )
201
+
202
+ tab1, tab2, tab3, tab4 = st.tabs(["Player Range of Outcomes", "Line Combo Range of Outcomes", "Power Play Range of Outcomes", "Optimals"])
203
 
204
  with tab1:
205
+ with st.expander("Info and Filters"):
206
+ with st.container():
207
+ st.info("Advanced view includes all stats and thresholds, simple includes just basic columns for ease of use on mobile")
208
  st.info(t_stamp)
209
  if st.button("Load/Reset Data", key='reset1'):
210
+ st.cache_data.clear()
211
+ player_frame, line_frame, pp_frame, timestamp = player_stat_table()
212
+ dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
213
+ fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
214
+ dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
215
+ fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
216
+ dk_lineups = init_DK_lineups('proj', 50, 25000, [])
217
+ fd_lineups = init_FD_lineups('proj', 50, 25000, [])
218
+ t_stamp = f"Last Update: " + str(timestamp) + f" CST"
219
  split_var1 = st.radio("Would you like to view the whole slate or just specific games?", ('Full Slate Run', 'Specific Games'), key='split_var1')
220
  if split_var1 == 'Specific Games':
221
  team_var1 = st.multiselect('Which teams would you like to include in the ROO?', options = player_frame['Team'].unique(), key='team_var1')
 
227
  elif pos_split1 == 'All Positions':
228
  pos_var1 = 'All'
229
  sal_var1 = st.slider("Is there a certain price range you want to view?", 2000, 10000, (2000, 20000), key='sal_var1')
230
+
231
+ final_Proj = player_frame[player_frame['Site'] == str(site_var)]
232
+ final_Proj = final_Proj[final_Proj['Type'] == 'Basic']
233
+ final_Proj = final_Proj[final_Proj['Slate'] == 'Main Slate']
234
+ final_Proj = final_Proj[player_frame['Team'].isin(team_var1)]
235
+ final_Proj = final_Proj[final_Proj['Salary'] >= sal_var1[0]]
236
+ final_Proj = final_Proj[final_Proj['Salary'] <= sal_var1[1]]
237
+ if pos_var1 != 'All':
238
+ final_Proj = final_Proj[final_Proj['Position'].str.contains('|'.join(pos_var1))]
239
+ final_Proj = final_Proj.sort_values(by='Median', ascending=False)
240
+ if pos_var1 == 'All':
241
+ final_Proj = final_Proj.sort_values(by='Median', ascending=False)
242
 
243
+ if view_var == 'Advanced':
244
+ display_proj = final_Proj[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
245
+ 'Own', 'Small Field Own%', 'Large Field Own%', 'Cash Own%', 'CPT_Own']]
246
+ elif view_var == 'Simple':
247
+ display_proj = final_Proj[['Player', 'Position', 'Salary', 'Median', '3x%', 'Own']]
248
+ st.dataframe(display_proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height = 1000, use_container_width = True, hide_index=True)
249
+ st.download_button(
250
+ label="Export Tables",
251
+ data=convert_df_to_csv(display_proj),
252
+ file_name='NHL_player_export.csv',
253
+ mime='text/csv',
254
+ )
 
 
 
 
 
 
 
255
 
256
  with tab2:
257
+ with st.expander("Info and Filters"):
258
+ with st.container():
259
+ st.info("Advanced view includes all stats and thresholds, simple includes just basic columns for ease of use on mobile")
260
  st.info(t_stamp)
261
  if st.button("Load/Reset Data", key='reset2'):
262
+ st.cache_data.clear()
263
+ player_frame, line_frame, pp_frame, timestamp = player_stat_table()
264
+ dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
265
+ fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
266
+ dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
267
+ fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
268
+ dk_lineups = init_DK_lineups('proj', 50, 25000, [])
269
+ fd_lineups = init_FD_lineups('proj', 50, 25000, [])
270
+ t_stamp = f"Last Update: " + str(timestamp) + f" CST"
271
  sal_var2 = st.slider("Is there a certain price range you want to view?", 5000, 40000, (5000, 40000), key='sal_var2')
272
+
273
+ final_line_combos = line_frame[line_frame['Site'] == str(site_var)]
274
+ final_line_combos = final_line_combos[final_line_combos['Type'] == 'Basic']
275
+ final_line_combos = final_line_combos[final_line_combos['Slate'] == 'Main Slate']
276
+ final_line_combos = final_line_combos[final_line_combos['Salary'] >= sal_var2[0]]
277
+ final_line_combos = final_line_combos[final_line_combos['Salary'] <= sal_var2[1]]
278
+ final_line_combos = final_line_combos.drop_duplicates(subset=['Player'])
279
+ final_line_combos = final_line_combos.sort_values(by='Median', ascending=False)
280
+
281
+ if view_var == 'Advanced':
282
+ display_proj_lines = final_line_combos[['Player', 'SK1', 'SK2', 'SK3', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '50+%', '2x%', '3x%', '4x%',
283
+ 'Own']]
284
+ elif view_var == 'Simple':
285
+ display_proj_lines = final_line_combos[['SK1', 'SK2', 'SK3', 'Salary', 'Median', '3x%', 'Own']]
286
+ st.dataframe(display_proj_lines.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height = 1000, use_container_width = True, hide_index=True)
287
+ st.download_button(
288
+ label="Export Tables",
289
+ data=convert_df_to_csv(display_proj_lines),
290
+ file_name='NHL_linecombos_export.csv',
291
+ mime='text/csv',
292
+ )
293
 
294
  with tab3:
295
+ with st.expander("Info and Filters"):
296
+ with st.container():
297
+ st.info("Advanced view includes all stats and thresholds, simple includes just basic columns for ease of use on mobile")
298
  st.info(t_stamp)
299
  if st.button("Load/Reset Data", key='reset3'):
300
+ st.cache_data.clear()
301
+ player_frame, line_frame, pp_frame, timestamp = player_stat_table()
302
+ dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
303
+ fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
304
+ dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
305
+ fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
306
+ dk_lineups = init_DK_lineups('proj', 50, 25000, [])
307
+ fd_lineups = init_FD_lineups('proj', 50, 25000, [])
308
+ t_stamp = f"Last Update: " + str(timestamp) + f" CST"
309
  sal_var3 = st.slider("Is there a certain price range you want to view?", 5000, 40000, (5000, 40000), key='sal_var3')
310
 
311
+ final_pp_combos = pp_frame[pp_frame['Site'] == str(site_var)]
312
+ final_pp_combos = final_pp_combos[final_pp_combos['Type'] == 'Basic']
313
+ final_pp_combos = final_pp_combos[final_pp_combos['Slate'] == 'Main Slate']
314
+ final_pp_combos = final_pp_combos[final_pp_combos['Salary'] >= sal_var3[0]]
315
+ final_pp_combos = final_pp_combos[final_pp_combos['Salary'] <= sal_var3[1]]
316
+ final_pp_combos = final_pp_combos.drop_duplicates(subset=['Player'])
317
+ final_pp_combos = final_pp_combos.sort_values(by='Median', ascending=False)
318
+
319
+ if view_var == 'Advanced':
320
+ display_proj_pp = final_pp_combos[['Player', 'SK1', 'SK2', 'SK3', 'SK4', 'SK5', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '75+%', '2x%', '3x%', '4x%',
321
+ 'Own']]
322
+ elif view_var == 'Simple':
323
+ display_proj_pp = final_pp_combos[['SK1', 'SK2', 'SK3', 'SK4', 'SK5', 'Salary', 'Median', '3x%', 'Own']]
324
+ st.dataframe(display_proj_pp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True, hide_index=True)
325
+ st.download_button(
326
+ label="Export Tables",
327
+ data=convert_df_to_csv(display_proj_pp),
328
+ file_name='NHL_powerplay_export.csv',
329
+ mime='text/csv',
330
+ )
331
+
332
+ with tab4:
333
+ player_frame, line_frame, pp_frame, timestamp = player_stat_table()
334
+ dk_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
335
+ fd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
336
+ dk_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Draftkings']['Player'], player_frame[player_frame['Site'] == 'Draftkings']['player_id']))
337
+ fd_sd_id_map = dict(zip(player_frame[player_frame['Site'] == 'Fanduel']['Player'], player_frame[player_frame['Site'] == 'Fanduel']['player_id']))
338
+ if type_var == 'Regular':
339
+ t_stamp = f"Last Update: " + str(timestamp) + f" CST"
340
+ elif type_var == 'Showdown':
341
+ t_stamp = f"Last Update: " + str(timestamp) + f" CST"
342
+ st.header("Optimals")
343
+ with st.expander("Info and Filters"):
344
+ st.info("These filters will display various optimals in the table below to pick from. If you want to export the entire set of 10,000 optimals, hit the 'Prepare full data export' button. If you would like to apply the filters here to the 10,000 optimals before you export, use the 'Prepare full data export (Filter)' button.")
345
+ prio_col, optimals_site_col, optimals_macro_col, optimals_salary_col, optimals_stacks_col = st.columns(5)
346
+
347
+ with prio_col:
348
+ prio_var = st.radio("Which priority variable do you want to use?", ('proj', 'Own', 'Mix'), key='prio_var_radio')
349
+ prio_mix = st.number_input("If Mix, what split of Projection/Ownership to dedicate to Projection?", min_value=0, max_value=100, value=50, step=1)
350
+ lineup_num = st.number_input("How many lineups do you want to work with?", min_value=1000, max_value=50000, value=25000, step=100, key='lineup_download_var_input')
351
+
352
+ with optimals_site_col:
353
+ if type_var == 'Regular':
354
+ if site_var == 'Draftkings':
355
+ raw_baselines = player_frame[player_frame['Site'] == 'Draftkings']
356
+ elif site_var == 'Fanduel':
357
+ raw_baselines = player_frame[player_frame['Site'] == 'Fanduel']
358
+ elif type_var == 'Showdown':
359
+ if site_var == 'Draftkings':
360
+ raw_baselines = player_frame[player_frame['Site'] == 'Draftkings']
361
+ elif site_var == 'Fanduel':
362
+ raw_baselines = player_frame[player_frame['Site'] == 'Fanduel']
363
+ if site_var == 'Draftkings':
364
+ slate_var3 = st.radio("Which slate data are you loading?", (['Main Slate', 'Secondary Slate', 'Auxiliary Slate']), key='slate_var3_radio')
365
+ elif site_var == 'Fanduel':
366
+ slate_var3 = st.radio("Which slate data are you loading?", (['Main Slate', 'Secondary Slate', 'Auxiliary Slate']), key='slate_var3_radio')
367
+
368
+ with optimals_macro_col:
369
+ lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1, key='lineup_num_var_input')
370
+ player_var2 = st.multiselect('Query for lineups including:', options = raw_baselines['Player'].unique(), key='player_var2_multiselect', default=[])
371
+
372
+ if type_var == 'Regular':
373
+ if site_var == 'Draftkings':
374
+ dk_lineups = init_DK_lineups(prio_var, prio_mix, lineup_num, player_var2)
375
+ elif site_var == 'Fanduel':
376
+ fd_lineups = init_FD_lineups(prio_var, prio_mix, lineup_num, player_var2)
377
+ elif type_var == 'Showdown':
378
+ if site_var == 'Draftkings':
379
+ dk_lineups = init_DK_lineups(prio_var, prio_mix, lineup_num, player_var2)
380
+ elif site_var == 'Fanduel':
381
+ fd_lineups = init_FD_lineups(prio_var, prio_mix, lineup_num, player_var2)
382
+
383
+ with optimals_salary_col:
384
+ if site_var == 'Draftkings':
385
+ salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 50000, value = 49000, step = 100, key = 'salary_min_var_dk')
386
+ salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 50000, value = 50000, step = 100, key = 'salary_max_var_dk')
387
+ elif site_var == 'Fanduel':
388
+ salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 60000, value = 59000, step = 100, key = 'salary_min_var_fd')
389
+ salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 60000, value = 60000, step = 100, key = 'salary_max_var_fd')
390
+ with optimals_stacks_col:
391
+ if site_var == 'Draftkings':
392
+ min_stacks_var = st.number_input("Minimum stacks used", min_value = 0, max_value = 5, value = 1, step = 1, key = 'min_stacks_var_dk')
393
+ max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 5, value = 5, step = 1, key = 'max_stacks_var_dk')
394
+ elif site_var == 'Fanduel':
395
+ min_stacks_var = st.number_input("Minimum stacks used", min_value = 0, max_value = 4, value = 1, step = 1, key = 'min_stacks_var_fd')
396
+ max_stacks_var = st.number_input("Maximum stacks used", min_value = 0, max_value = 4, value = 4, step = 1, key = 'max_stacks_var_fd')
397
+
398
+
399
+ if site_var == 'Draftkings':
400
+ if type_var == 'Regular':
401
+ ROO_slice = raw_baselines
402
+ player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
403
+ column_names = dk_columns
404
+ elif type_var == 'Showdown':
405
+ player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
406
+ column_names = dk_sd_columns
407
+
408
+
409
+ elif site_var == 'Fanduel':
410
+ if type_var == 'Regular':
411
+ ROO_slice = raw_baselines
412
+ player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
413
+ column_names = fd_columns
414
+ elif type_var == 'Showdown':
415
+ player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
416
+ column_names = fd_sd_columns
417
+
418
+ reg_dl_col, filtered_dl_col, blank_dl_col = st.columns([2, 2, 6])
419
+ with reg_dl_col:
420
+ if st.button("Prepare full data export", key='data_export_button'):
421
+ name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
422
+ data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
423
+ if site_var == 'Draftkings':
424
+ if type_var == 'Regular':
425
+ map_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX']
426
+ for col_idx in map_columns:
427
+ data_export[col_idx] = data_export[col_idx].map(dk_id_map)
428
+ elif type_var == 'Showdown':
429
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
430
+ for col_idx in map_columns:
431
+ data_export[col_idx] = data_export[col_idx].map(dk_sd_id_map)
432
+ elif site_var == 'Fanduel':
433
+ if type_var == 'Regular':
434
+ map_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G']
435
+ for col_idx in map_columns:
436
+ data_export[col_idx] = data_export[col_idx].map(fd_id_map)
437
+ elif type_var == 'Showdown':
438
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
439
+ for col_idx in map_columns:
440
+ data_export[col_idx] = data_export[col_idx].map(fd_sd_id_map)
441
+ reg_opt_col, pm_opt_col = st.columns(2)
442
+ with reg_opt_col:
443
+ st.download_button(
444
+ label="Export optimals set (IDs)",
445
+ data=convert_df(data_export),
446
+ file_name='NHL_optimals_export.csv',
447
+ mime='text/csv',
448
+ key='export_optimals_ids_button'
449
+ )
450
+ st.download_button(
451
+ label="Export optimals set (Names)",
452
+ data=convert_df(name_export),
453
+ file_name='NHL_optimals_export.csv',
454
+ mime='text/csv',
455
+ key='export_optimals_names_button'
456
+ )
457
+ with pm_opt_col:
458
+ if site_var == 'Draftkings':
459
+ if type_var == 'Regular':
460
+ data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
461
+ elif type_var == 'Showdown':
462
+ data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
463
+ elif site_var == 'Fanduel':
464
+ if type_var == 'Regular':
465
+ data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
466
+ elif type_var == 'Showdown':
467
+ data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
468
+ st.download_button(
469
+ label="Portfolio Manager Export (IDs)",
470
+ data=convert_pm_df(data_export),
471
+ file_name='NHL_optimals_export.csv',
472
+ mime='text/csv',
473
+ key='export_pm_ids_button'
474
+ )
475
+
476
+ if site_var == 'Draftkings':
477
+ if type_var == 'Regular':
478
+ name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
479
+ elif type_var == 'Showdown':
480
+ name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
481
+ elif site_var == 'Fanduel':
482
+ if type_var == 'Regular':
483
+ name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
484
+ elif type_var == 'Showdown':
485
+ name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
486
+ st.download_button(
487
+ label="Portfolio Manager Export (Names)",
488
+ data=convert_pm_df(name_export),
489
+ file_name='NHL_optimals_export.csv',
490
+ mime='text/csv',
491
+ key='export_pm_names_button'
492
+ )
493
+ with filtered_dl_col:
494
+ if st.button("Prepare full data export (Filtered)", key='data_export_filtered_button'):
495
+ name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
496
+ data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
497
+ if site_var == 'Draftkings':
498
+ if type_var == 'Regular':
499
+ map_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX']
500
+ for col_idx in map_columns:
501
+ data_export[col_idx] = data_export[col_idx].map(dk_id_map)
502
+ elif type_var == 'Showdown':
503
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
504
+ for col_idx in map_columns:
505
+ data_export[col_idx] = data_export[col_idx].map(dk_sd_id_map)
506
+
507
+ elif site_var == 'Fanduel':
508
+ if type_var == 'Regular':
509
+ map_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G']
510
+ for col_idx in map_columns:
511
+ data_export[col_idx] = data_export[col_idx].map(fd_id_map)
512
+ elif type_var == 'Showdown':
513
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
514
+ for col_idx in map_columns:
515
+ data_export[col_idx] = data_export[col_idx].map(fd_sd_id_map)
516
+
517
+ data_export = data_export[data_export['salary'] >= salary_min_var]
518
+ data_export = data_export[data_export['salary'] <= salary_max_var]
519
+ data_export = data_export[data_export['Team_count'] >= min_stacks_var]
520
+ data_export = data_export[data_export['Team_count'] <= max_stacks_var]
521
+
522
+ name_export = name_export[name_export['salary'] >= salary_min_var]
523
+ name_export = name_export[name_export['salary'] <= salary_max_var]
524
+ name_export = name_export[name_export['Team_count'] >= min_stacks_var]
525
+ name_export = name_export[name_export['Team_count'] <= max_stacks_var]
526
+
527
+ reg_opt_col, pm_opt_col = st.columns(2)
528
+ with reg_opt_col:
529
+ st.download_button(
530
+ label="Export optimals set (IDs)",
531
+ data=convert_df(data_export),
532
+ file_name='NHL_optimals_export.csv',
533
+ mime='text/csv',
534
+ key='export_filtered_optimals_ids_button'
535
+ )
536
+ st.download_button(
537
+ label="Export optimals set (Names)",
538
+ data=convert_df(name_export),
539
+ file_name='NHL_optimals_export.csv',
540
+ mime='text/csv',
541
+ key='export_filtered_optimals_names_button'
542
+ )
543
+ with pm_opt_col:
544
+ if site_var == 'Draftkings':
545
+ if type_var == 'Regular':
546
+ data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
547
+ elif type_var == 'Showdown':
548
+ data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
549
+ elif site_var == 'Fanduel':
550
+ if type_var == 'Regular':
551
+ data_export = data_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
552
+ elif type_var == 'Showdown':
553
+ data_export = data_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
554
+ st.download_button(
555
+ label="Portfolio Manager Export (IDs)",
556
+ data=convert_pm_df(data_export),
557
+ file_name='NHL_optimals_export.csv',
558
+ mime='text/csv',
559
+ key='export_filtered_pm_ids_button'
560
+ )
561
+
562
+ if site_var == 'Draftkings':
563
+ if type_var == 'Regular':
564
+ name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
565
+ elif type_var == 'Showdown':
566
+ name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
567
+ elif site_var == 'Fanduel':
568
+ if type_var == 'Regular':
569
+ name_export = name_export.set_index('C1').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
570
+ elif type_var == 'Showdown':
571
+ name_export = name_export.set_index('CPT').drop(columns=['salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'], axis=1)
572
+ st.download_button(
573
+ label="Portfolio Manager Export (Names)",
574
+ data=convert_pm_df(name_export),
575
+ file_name='NHL_optimals_export.csv',
576
+ mime='text/csv',
577
+ key='export_filtered_pm_names_button'
578
+ )
579
+
580
+ if site_var == 'Draftkings':
581
+ if 'working_seed' in st.session_state:
582
+ st.session_state.working_seed = st.session_state.working_seed
583
+ if player_var2 != []:
584
+ st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
585
+ elif player_var2 == []:
586
+ st.session_state.working_seed = dk_lineups.copy()
587
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
588
+ elif 'working_seed' not in st.session_state:
589
+ st.session_state.working_seed = dk_lineups.copy()
590
+ st.session_state.working_seed = st.session_state.working_seed
591
+ if player_var2 != []:
592
+ st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
593
+ elif player_var2 == []:
594
+ st.session_state.working_seed = dk_lineups.copy()
595
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
596
+
597
+ elif site_var == 'Fanduel':
598
+ if 'working_seed' in st.session_state:
599
+ st.session_state.working_seed = st.session_state.working_seed
600
+ if player_var2 != []:
601
+ st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
602
+ elif player_var2 == []:
603
+ st.session_state.working_seed = fd_lineups.copy()
604
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
605
+ elif 'working_seed' not in st.session_state:
606
+ st.session_state.working_seed = fd_lineups.copy()
607
+ st.session_state.working_seed = st.session_state.working_seed
608
+ if player_var2 != []:
609
+ st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)]
610
+ elif player_var2 == []:
611
+ st.session_state.working_seed = fd_lineups.copy()
612
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
613
+ st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] >= salary_min_var]
614
+ st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] <= salary_max_var]
615
+ st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] >= min_stacks_var]
616
+ st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['Team_count'] <= max_stacks_var]
617
+ export_file = st.session_state.data_export_display.copy()
618
+ name_export = st.session_state.data_export_display.copy()
619
+ if site_var == 'Draftkings':
620
+ if type_var == 'Regular':
621
+ map_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX']
622
+ for col_idx in map_columns:
623
+ export_file[col_idx] = export_file[col_idx].map(dk_id_map)
624
+ elif type_var == 'Showdown':
625
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
626
+ for col_idx in map_columns:
627
+ export_file[col_idx] = export_file[col_idx].map(dk_sd_id_map)
628
+ elif site_var == 'Fanduel':
629
+ if type_var == 'Regular':
630
+ map_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G']
631
+ for col_idx in map_columns:
632
+ export_file[col_idx] = export_file[col_idx].map(fd_id_map)
633
+ elif type_var == 'Showdown':
634
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
635
+ for col_idx in map_columns:
636
+ export_file[col_idx] = export_file[col_idx].map(fd_sd_id_map)
637
+
638
+ with st.container():
639
+ if st.button("Reset Optimals", key='reset_optimals_button'):
640
+ for key in st.session_state.keys():
641
+ del st.session_state[key]
642
+ if site_var == 'Draftkings':
643
+ st.session_state.working_seed = dk_lineups.copy()
644
+ elif site_var == 'Fanduel':
645
+ st.session_state.working_seed = fd_lineups.copy()
646
+ if 'data_export_display' in st.session_state:
647
+ st.dataframe(st.session_state.data_export_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height=500, use_container_width = True)
648
+ st.download_button(
649
+ label="Export display optimals (IDs)",
650
+ data=convert_df(export_file),
651
+ file_name='NHL_display_optimals.csv',
652
+ mime='text/csv',
653
+ key='export_display_optimals_ids_button'
654
+ )
655
  st.download_button(
656
+ label="Export display optimals (Names)",
657
+ data=convert_df(name_export),
658
+ file_name='NHL_display_optimals.csv',
659
+ mime='text/csv',
660
+ key='export_display_optimals_names_button'
661
+ )
662
+
663
+ with st.container():
664
+ if type_var == 'Regular':
665
+ if 'working_seed' in st.session_state:
666
+ # Create a new dataframe with summary statistics
667
+ if site_var == 'Draftkings':
668
+ summary_df = pd.DataFrame({
669
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
670
+ 'Salary': [
671
+ np.min(st.session_state.working_seed[:,9]),
672
+ np.mean(st.session_state.working_seed[:,9]),
673
+ np.max(st.session_state.working_seed[:,9]),
674
+ np.std(st.session_state.working_seed[:,9])
675
+ ],
676
+ 'Proj': [
677
+ np.min(st.session_state.working_seed[:,10]),
678
+ np.mean(st.session_state.working_seed[:,10]),
679
+ np.max(st.session_state.working_seed[:,10]),
680
+ np.std(st.session_state.working_seed[:,10])
681
+ ],
682
+ 'Own': [
683
+ np.min(st.session_state.working_seed[:,15]),
684
+ np.mean(st.session_state.working_seed[:,15]),
685
+ np.max(st.session_state.working_seed[:,15]),
686
+ np.std(st.session_state.working_seed[:,15])
687
+ ]
688
+ })
689
+ elif site_var == 'Fanduel':
690
+ summary_df = pd.DataFrame({
691
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
692
+ 'Salary': [
693
+ np.min(st.session_state.working_seed[:,9]),
694
+ np.mean(st.session_state.working_seed[:,9]),
695
+ np.max(st.session_state.working_seed[:,9]),
696
+ np.std(st.session_state.working_seed[:,9])
697
+ ],
698
+ 'Proj': [
699
+ np.min(st.session_state.working_seed[:,10]),
700
+ np.mean(st.session_state.working_seed[:,10]),
701
+ np.max(st.session_state.working_seed[:,10]),
702
+ np.std(st.session_state.working_seed[:,10])
703
+ ],
704
+ 'Own': [
705
+ np.min(st.session_state.working_seed[:,15]),
706
+ np.mean(st.session_state.working_seed[:,15]),
707
+ np.max(st.session_state.working_seed[:,15]),
708
+ np.std(st.session_state.working_seed[:,15])
709
+ ]
710
+ })
711
+ elif type_var == 'Showdown':
712
+ if 'working_seed' in st.session_state:
713
+ # Create a new dataframe with summary statistics
714
+ if site_var == 'Draftkings':
715
+ summary_df = pd.DataFrame({
716
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
717
+ 'Salary': [
718
+ np.min(st.session_state.working_seed[:,6]),
719
+ np.mean(st.session_state.working_seed[:,6]),
720
+ np.max(st.session_state.working_seed[:,6]),
721
+ np.std(st.session_state.working_seed[:,6])
722
+ ],
723
+ 'Proj': [
724
+ np.min(st.session_state.working_seed[:,7]),
725
+ np.mean(st.session_state.working_seed[:,7]),
726
+ np.max(st.session_state.working_seed[:,7]),
727
+ np.std(st.session_state.working_seed[:,7])
728
+ ],
729
+ 'Own': [
730
+ np.min(st.session_state.working_seed[:,12]),
731
+ np.mean(st.session_state.working_seed[:,12]),
732
+ np.max(st.session_state.working_seed[:,12]),
733
+ np.std(st.session_state.working_seed[:,12])
734
+ ]
735
+ })
736
+ elif site_var == 'Fanduel':
737
+ summary_df = pd.DataFrame({
738
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
739
+ 'Salary': [
740
+ np.min(st.session_state.working_seed[:,6]),
741
+ np.mean(st.session_state.working_seed[:,6]),
742
+ np.max(st.session_state.working_seed[:,6]),
743
+ np.std(st.session_state.working_seed[:,6])
744
+ ],
745
+ 'Proj': [
746
+ np.min(st.session_state.working_seed[:,7]),
747
+ np.mean(st.session_state.working_seed[:,7]),
748
+ np.max(st.session_state.working_seed[:,7]),
749
+ np.std(st.session_state.working_seed[:,7])
750
+ ],
751
+ 'Own': [
752
+ np.min(st.session_state.working_seed[:,12]),
753
+ np.mean(st.session_state.working_seed[:,12]),
754
+ np.max(st.session_state.working_seed[:,12]),
755
+ np.std(st.session_state.working_seed[:,12])
756
+ ]
757
+ })
758
+
759
+ # Set the index of the summary dataframe as the "Metric" column
760
+ summary_df = summary_df.set_index('Metric')
761
+
762
+ # Display the summary dataframe
763
+ st.subheader("Optimal Statistics")
764
+ st.dataframe(summary_df.style.format({
765
+ 'Salary': '{:.2f}',
766
+ 'Proj': '{:.2f}',
767
+ 'Own': '{:.2f}'
768
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True)
769
+
770
+ with st.container():
771
+ display_freq_tab, seed_frame_freq_tab = st.tabs(["Display Frequency", "Seed Frame Frequency"])
772
+ with display_freq_tab:
773
+ if 'data_export_display' in st.session_state:
774
+ if site_var == 'Draftkings':
775
+ if type_var == 'Regular':
776
+ player_columns = st.session_state.data_export_display.iloc[:, :9]
777
+ elif type_var == 'Showdown':
778
+ player_columns = st.session_state.data_export_display.iloc[:, :6]
779
+ elif site_var == 'Fanduel':
780
+ if type_var == 'Regular':
781
+ player_columns = st.session_state.data_export_display.iloc[:, :9]
782
+ elif type_var == 'Showdown':
783
+ player_columns = st.session_state.data_export_display.iloc[:, :6]
784
+
785
+ # Flatten the DataFrame and count unique values
786
+ value_counts = player_columns.values.flatten().tolist()
787
+ value_counts = pd.Series(value_counts).value_counts()
788
+
789
+ percentages = (value_counts / lineup_num_var * 100).round(2)
790
+
791
+ # Create a DataFrame with the results
792
+ summary_df = pd.DataFrame({
793
+ 'Player': value_counts.index,
794
+ 'Frequency': value_counts.values,
795
+ 'Percentage': percentages.values
796
+ })
797
+
798
+ # Sort by frequency in descending order
799
+ summary_df['Salary'] = summary_df['Player'].map(player_salaries)
800
+ summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
801
+ summary_df = summary_df.sort_values('Frequency', ascending=False)
802
+ summary_df = summary_df.set_index('Player')
803
+
804
+ # Display the table
805
+ st.write("Player Frequency Table:")
806
+ st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
807
+
808
+ st.download_button(
809
+ label="Export player frequency",
810
+ data=convert_df_to_csv(summary_df),
811
+ file_name='NHL_player_frequency.csv',
812
+ mime='text/csv',
813
+ key='export_player_frequency_button'
814
+ )
815
+ with seed_frame_freq_tab:
816
+ if 'working_seed' in st.session_state:
817
+ if site_var == 'Draftkings':
818
+ if type_var == 'Regular':
819
+ player_columns = st.session_state.working_seed[:, :9]
820
+ elif type_var == 'Showdown':
821
+ player_columns = st.session_state.working_seed[:, :6]
822
+ elif site_var == 'Fanduel':
823
+ if type_var == 'Regular':
824
+ player_columns = st.session_state.working_seed[:, :9]
825
+ elif type_var == 'Showdown':
826
+ player_columns = st.session_state.working_seed[:, :6]
827
+
828
+ # Flatten the DataFrame and count unique values
829
+ value_counts = player_columns.flatten().tolist()
830
+ value_counts = pd.Series(value_counts).value_counts()
831
+
832
+ percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
833
+ # Create a DataFrame with the results
834
+ summary_df = pd.DataFrame({
835
+ 'Player': value_counts.index,
836
+ 'Frequency': value_counts.values,
837
+ 'Percentage': percentages.values
838
+ })
839
+
840
+ # Sort by frequency in descending order
841
+ summary_df['Salary'] = summary_df['Player'].map(player_salaries)
842
+ summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
843
+ summary_df = summary_df.sort_values('Frequency', ascending=False)
844
+ summary_df = summary_df.set_index('Player')
845
+
846
+ # Display the table
847
+ st.write("Seed Frame Frequency Table:")
848
+ st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
849
+
850
+ st.download_button(
851
+ label="Export seed frame frequency",
852
+ data=convert_df_to_csv(summary_df),
853
+ file_name='NHL_seed_frame_frequency.csv',
854
+ mime='text/csv',
855
+ key='export_seed_frame_frequency_button'
856
+ )