James McCool commited on
Commit
d69c0ed
·
1 Parent(s): a3a9ac4

Initial Commit

Browse files
Files changed (3) hide show
  1. app.py +589 -0
  2. app.yaml +10 -0
  3. requirements.txt +10 -0
app.py ADDED
@@ -0,0 +1,589 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import numpy as np
3
+ import pandas as pd
4
+ import gspread
5
+ import pymongo
6
+
7
+ st.set_page_config(layout="wide")
8
+
9
+ @st.cache_resource
10
+ def init_conn():
11
+ uri = st.secrets['mongo_uri']
12
+ client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)
13
+ db = client["MLB_Database"]
14
+ db2 = client["MLB_DFS"]
15
+
16
+ return db, db2
17
+
18
+ db, db2 = init_conn()
19
+
20
+ game_format = {'Win Percentage': '{:.2%}','First Inning Lead Percentage': '{:.2%}',
21
+ 'Fifth Inning Lead Percentage': '{:.2%}', '8+ runs': '{:.2%}', 'DK LevX': '{:.2%}', 'FD LevX': '{:.2%}'}
22
+
23
+ player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '20+%': '{:.2%}', '2x%': '{:.2%}', '3x%': '{:.2%}',
24
+ '4x%': '{:.2%}'}
25
+
26
+ dk_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
27
+ fd_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
28
+
29
+ @st.cache_resource(ttl = 60)
30
+ def init_baselines():
31
+ collection = db["Player_Range_Of_Outcomes"]
32
+ cursor = collection.find()
33
+ player_frame = pd.DataFrame(cursor)
34
+
35
+ roo_data = player_frame.drop(columns=['_id'])
36
+ roo_data['Salary'] = roo_data['Salary'].astype(int)
37
+
38
+ dk_roo = roo_data[roo_data['Site'] == 'Draftkings']
39
+ fd_roo = roo_data[roo_data['Site'] == 'Fanduel']
40
+
41
+ collection = db["Player_SD_Range_Of_Outcomes"]
42
+ cursor = collection.find()
43
+ player_frame = pd.DataFrame(cursor)
44
+
45
+ sd_roo_data = player_frame.drop(columns=['_id'])
46
+ sd_roo_data['Salary'] = sd_roo_data['Salary'].astype(int)
47
+ sd_roo_data = sd_roo_data.rename(columns={'Own': 'Own%'})
48
+
49
+ collection = db["Scoring_Percentages"]
50
+ cursor = collection.find()
51
+ team_frame = pd.DataFrame(cursor)
52
+ scoring_percentages = team_frame.drop(columns=['_id'])
53
+ scoring_percentages = scoring_percentages[['Names', 'Avg First Inning', 'First Inning Lead Percentage', 'Avg Fifth Inning', 'Fifth Inning Lead Percentage', 'Avg Score', '8+ runs', 'Win Percentage']]
54
+ scoring_percentages['8+ runs'] = scoring_percentages['8+ runs'].replace('%', '', regex=True).astype(float)
55
+ scoring_percentages['Win Percentage'] = scoring_percentages['Win Percentage'].replace('%', '', regex=True).astype(float)
56
+ dk_hitters_only = dk_roo[dk_roo['pos_group'] != 'Pitchers']
57
+ dk_team_ownership = dk_hitters_only.groupby('Team')['Own%'].sum().reset_index()
58
+ fd_hitters_only = fd_roo[fd_roo['pos_group'] != 'Pitchers']
59
+ fd_team_ownership = fd_hitters_only.groupby('Team')['Own%'].sum().reset_index()
60
+ scoring_percentages = scoring_percentages.merge(dk_team_ownership, left_on='Names', right_on='Team', how='left')
61
+ scoring_percentages.rename(columns={'Own%': 'DK Own%'}, inplace=True)
62
+ scoring_percentages.drop('Team', axis=1, inplace=True)
63
+ scoring_percentages = scoring_percentages.merge(fd_team_ownership, left_on='Names', right_on='Team', how='left')
64
+ scoring_percentages.rename(columns={'Own%': 'FD Own%'}, inplace=True)
65
+ scoring_percentages.drop('Team', axis=1, inplace=True)
66
+
67
+ return roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo
68
+
69
+ @st.cache_data(ttl = 60)
70
+ def init_DK_lineups(type_var, slate_var):
71
+
72
+ if type_var == 'Regular':
73
+ if slate_var == 'Main':
74
+ collection = db['DK_MLB_name_map']
75
+ cursor = collection.find()
76
+ raw_data = pd.DataFrame(list(cursor))
77
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
78
+
79
+ collection = db['DK_MLB_seed_frame']
80
+ cursor = collection.find().limit(10000)
81
+
82
+ raw_display = pd.DataFrame(list(cursor))
83
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
84
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
85
+ # Map names
86
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
87
+ elif slate_var == 'Secondary':
88
+ collection = db['DK_MLB_Secondary_name_map']
89
+ cursor = collection.find()
90
+ raw_data = pd.DataFrame(list(cursor))
91
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
92
+
93
+ collection = db['DK_MLB_Secondary_seed_frame']
94
+ cursor = collection.find().limit(10000)
95
+
96
+ raw_display = pd.DataFrame(list(cursor))
97
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
98
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
99
+ # Map names
100
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
101
+ elif slate_var == 'Auxiliary':
102
+ collection = db['DK_MLB_Turbo_name_map']
103
+ cursor = collection.find()
104
+ raw_data = pd.DataFrame(list(cursor))
105
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
106
+
107
+ collection = db['DK_MLB_Turbo_seed_frame']
108
+ cursor = collection.find().limit(10000)
109
+
110
+ raw_display = pd.DataFrame(list(cursor))
111
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
112
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
113
+ # Map names
114
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
115
+ elif type_var == 'Showdown':
116
+ if slate_var == 'Main':
117
+ collection = db2['DK_MLB_SD1_seed_frame']
118
+ cursor = collection.find().limit(10000)
119
+
120
+ raw_display = pd.DataFrame(list(cursor))
121
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Own']]
122
+ elif slate_var == 'Secondary':
123
+ collection = db2['DK_MLB_SD2_seed_frame']
124
+ cursor = collection.find().limit(10000)
125
+
126
+ raw_display = pd.DataFrame(list(cursor))
127
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Own']]
128
+ elif slate_var == 'Auxiliary':
129
+ collection = db2['DK_MLB_SD3_seed_frame']
130
+ cursor = collection.find().limit(10000)
131
+
132
+ raw_display = pd.DataFrame(list(cursor))
133
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Own']]
134
+
135
+ DK_seed = raw_display.to_numpy()
136
+
137
+ return DK_seed
138
+
139
+ @st.cache_data(ttl = 60)
140
+ def init_FD_lineups(type_var,slate_var):
141
+
142
+ if type_var == 'Regular':
143
+ if slate_var == 'Main':
144
+ collection = db['FD_MLB_name_map']
145
+ cursor = collection.find()
146
+ raw_data = pd.DataFrame(list(cursor))
147
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
148
+
149
+ collection = db['FD_MLB_seed_frame']
150
+ cursor = collection.find().limit(10000)
151
+
152
+ raw_display = pd.DataFrame(list(cursor))
153
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
154
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
155
+ # Map names
156
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
157
+ elif slate_var == 'Secondary':
158
+ collection = db['FD_MLB_Secondary_name_map']
159
+ cursor = collection.find()
160
+ raw_data = pd.DataFrame(list(cursor))
161
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
162
+
163
+ collection = db['FD_MLB_Secondary_seed_frame']
164
+ cursor = collection.find().limit(10000)
165
+
166
+ raw_display = pd.DataFrame(list(cursor))
167
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
168
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
169
+ # Map names
170
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
171
+ elif slate_var == 'Auxiliary':
172
+ collection = db['FD_MLB_Turbo_name_map']
173
+ cursor = collection.find()
174
+ raw_data = pd.DataFrame(list(cursor))
175
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
176
+
177
+ collection = db['FD_MLB_Turbo_seed_frame']
178
+ cursor = collection.find().limit(10000)
179
+
180
+ raw_display = pd.DataFrame(list(cursor))
181
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
182
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
183
+ # Map names
184
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
185
+
186
+ elif type_var == 'Showdown':
187
+ if slate_var == 'Main':
188
+ collection = db2['FD_MLB_SD1_seed_frame']
189
+ cursor = collection.find().limit(10000)
190
+
191
+ raw_display = pd.DataFrame(list(cursor))
192
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Own']]
193
+ elif slate_var == 'Secondary':
194
+ collection = db2['FD_MLB_SD2_seed_frame']
195
+ cursor = collection.find().limit(10000)
196
+
197
+ raw_display = pd.DataFrame(list(cursor))
198
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Own']]
199
+ elif slate_var == 'Auxiliary':
200
+ collection = db2['FD_MLB_SD3_seed_frame']
201
+ cursor = collection.find().limit(10000)
202
+
203
+ raw_display = pd.DataFrame(list(cursor))
204
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Own']]
205
+
206
+ FD_seed = raw_display.to_numpy()
207
+
208
+ return FD_seed
209
+
210
+ @st.cache_data
211
+ def convert_df_to_csv(df):
212
+ return df.to_csv().encode('utf-8')
213
+
214
+ @st.cache_data
215
+ def convert_df(array):
216
+ array = pd.DataFrame(array, columns=column_names)
217
+ return array.to_csv().encode('utf-8')
218
+
219
+ col1, col2 = st.columns([1, 9])
220
+ with col1:
221
+ if st.button("Load/Reset Data", key='reset'):
222
+ st.cache_data.clear()
223
+ roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo = init_baselines()
224
+ hold_display = roo_data
225
+ dk_lineups = init_DK_lineups('Regular', 'Main')
226
+ fd_lineups = init_FD_lineups('Regular', 'Main')
227
+ for key in st.session_state.keys():
228
+ del st.session_state[key]
229
+ with col2:
230
+ with st.container():
231
+ col1, col2 = st.columns([3, 3])
232
+ with col1:
233
+ view_var = st.selectbox("Select view", ["Simple", "Advanced"], key='view_var')
234
+ with col2:
235
+ site_var = st.selectbox("What site do you want to view?", ('Draftkings', 'Fanduel'), key='site_var')
236
+
237
+
238
+ tab1, tab2, tab3 = st.tabs(["Scoring Percentages", "Player ROO", "Optimals"])
239
+
240
+ roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo = init_baselines()
241
+ hold_display = roo_data
242
+
243
+ with tab1:
244
+ st.header("Scoring Percentages")
245
+ with st.expander("Info and Filters"):
246
+ with st.container():
247
+ slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'All Games'), key='slate_var1')
248
+ own_var1 = st.radio("How would you like to display team ownership?", ('Sum', 'Average'), key='own_var1')
249
+ if view_var == "Simple":
250
+ scoring_percentages = scoring_percentages[['Names', 'Avg Score', '8+ runs', 'Win Percentage']]
251
+ st.dataframe(scoring_percentages.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(game_format, precision=2), height=750, use_container_width = True, hide_index=True)
252
+ elif view_var == "Advanced":
253
+ st.dataframe(scoring_percentages.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(game_format, precision=2), height=750, use_container_width = True, hide_index=True)
254
+
255
+ with tab2:
256
+ st.header("Player ROO")
257
+ with st.expander("Info and Filters"):
258
+ with st.container():
259
+ slate_type_var2 = st.radio("Which slate type are you loading?", ('Regular', 'Showdown'), key='slate_type_var2')
260
+ slate_var2 = st.radio("Which slate data are you loading?", ('Main', 'Secondary', 'Auxiliary'), key='slate_var2')
261
+ pos_var2 = st.radio("Which position group would you like to view?", ('All', 'Pitchers', 'Hitters'), key='pos_var2')
262
+ team_var2 = st.selectbox("Which team would you like to view?", ['All', 'Specific'], key='team_var2')
263
+ if team_var2 == 'Specific':
264
+ team_select2 = st.multiselect("Which team would you like to view?", roo_data['Team'].unique(), key='team_select2')
265
+ else:
266
+ team_select2 = None
267
+ if slate_type_var2 == 'Regular':
268
+ if site_var == 'Draftkings':
269
+
270
+ player_roo_raw = dk_roo.copy()
271
+
272
+ if pos_var2 == 'All':
273
+ pass
274
+ elif pos_var2 == 'Pitchers':
275
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Pitchers']
276
+ elif pos_var2 == 'Hitters':
277
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Hitters']
278
+
279
+ elif site_var == 'Fanduel':
280
+
281
+ player_roo_raw = fd_roo.copy()
282
+
283
+ if pos_var2 == 'All':
284
+ pass
285
+ elif pos_var2 == 'Pitchers':
286
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Pitchers']
287
+ elif pos_var2 == 'Hitters':
288
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Hitters']
289
+
290
+ if slate_var2 == 'Main':
291
+ player_roo_raw = player_roo_raw[player_roo_raw['Slate'] == 'main_slate']
292
+ elif slate_var2 == 'Secondary':
293
+ player_roo_raw = player_roo_raw[player_roo_raw['Slate'] == 'secondary_slate']
294
+ elif slate_var2 == 'Auxiliary':
295
+ player_roo_raw = player_roo_raw[player_roo_raw['Slate'] == 'turbo_slate']
296
+
297
+ elif slate_type_var2 == 'Showdown':
298
+ player_roo_raw = sd_roo_data.copy()
299
+ if site_var == 'Draftkings':
300
+ player_roo_raw['Site'] = 'Draftkings'
301
+ elif site_var == 'Fanduel':
302
+ player_roo_raw['Site'] = 'Fanduel'
303
+
304
+ if team_select2:
305
+ player_roo_raw = player_roo_raw[player_roo_raw['Team'].isin(team_select2)]
306
+
307
+ player_roo_disp = player_roo_raw
308
+
309
+ if slate_type_var2 == 'Regular':
310
+ player_roo_disp = player_roo_disp.drop(columns=['Site', 'Slate', 'pos_group', 'timestamp', 'player_ID'])
311
+ elif slate_type_var2 == 'Showdown':
312
+ player_roo_disp = player_roo_disp.drop(columns=['site', 'slate', 'version', 'timestamp'])
313
+
314
+ if view_var == "Simple":
315
+ try:
316
+ player_roo_disp = player_roo_disp[['Player', 'Position', 'Salary', 'Median', 'Ceiling', 'Own%']]
317
+ st.dataframe(player_roo_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, hide_index=True)
318
+ except:
319
+ st.dataframe(player_roo_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, hide_index=True)
320
+ elif view_var == "Advanced":
321
+ try:
322
+ st.dataframe(player_roo_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, hide_index=True)
323
+ except:
324
+ st.dataframe(player_roo_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True, hide_index=True)
325
+
326
+ with tab3:
327
+ st.header("Optimals")
328
+ with st.expander("Info and Filters"):
329
+ with st.container():
330
+ slate_type_var3 = st.radio("Which slate type are you loading?", ('Regular', 'Showdown'), key='slate_type_var3')
331
+ slate_var3 = st.radio("Which slate data are you loading?", ('Main', 'Secondary', 'Auxiliary'), key='slate_var3')
332
+
333
+ if slate_type_var3 == 'Regular':
334
+ if site_var == 'Draftkings':
335
+ dk_lineups = init_DK_lineups(slate_type_var3, slate_var3)
336
+ elif site_var == 'Fanduel':
337
+ fd_lineups = init_FD_lineups(slate_type_var3, slate_var3)
338
+ elif slate_type_var3 == 'Showdown':
339
+ if site_var == 'Draftkings':
340
+ dk_lineups = init_DK_lineups(slate_type_var3, slate_var3)
341
+ elif site_var == 'Fanduel':
342
+ fd_lineups = init_FD_lineups(slate_type_var3, slate_var3)
343
+ lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1)
344
+
345
+ if slate_type_var3 == 'Regular':
346
+ raw_baselines = roo_data
347
+ elif slate_type_var3 == 'Showdown':
348
+ raw_baselines = sd_roo_data
349
+
350
+ if site_var == 'Draftkings':
351
+ if slate_type_var3 == 'Regular':
352
+ ROO_slice = raw_baselines[raw_baselines['Site'] == 'Draftkings']
353
+ player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
354
+ elif slate_type_var3 == 'Showdown':
355
+ player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
356
+ # Get the minimum and maximum ownership values from dk_lineups
357
+ min_own = np.min(dk_lineups[:,8])
358
+ max_own = np.max(dk_lineups[:,8])
359
+ column_names = dk_columns
360
+
361
+ player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1')
362
+ if player_var1 == 'Specific Players':
363
+ player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique())
364
+ elif player_var1 == 'Full Slate':
365
+ player_var2 = raw_baselines.Player.values.tolist()
366
+
367
+ elif site_var == 'Fanduel':
368
+ raw_baselines = hold_display
369
+ if slate_type_var3 == 'Regular':
370
+ ROO_slice = raw_baselines[raw_baselines['Site'] == 'Fanduel']
371
+ player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
372
+ elif slate_type_var3 == 'Showdown':
373
+ player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
374
+ min_own = np.min(fd_lineups[:,8])
375
+ max_own = np.max(fd_lineups[:,8])
376
+ column_names = fd_columns
377
+
378
+ player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1')
379
+ if player_var1 == 'Specific Players':
380
+ player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique())
381
+ elif player_var1 == 'Full Slate':
382
+ player_var2 = raw_baselines.Player.values.tolist()
383
+
384
+ if st.button("Prepare data export", key='data_export'):
385
+ data_export = st.session_state.working_seed.copy()
386
+ # if site_var == 'Draftkings':
387
+ # for col_idx in range(6):
388
+ # data_export[:, col_idx] = np.array([id_dict.get(player, player) for player in data_export[:, col_idx]])
389
+ # elif site_var == 'Fanduel':
390
+ # for col_idx in range(6):
391
+ # data_export[:, col_idx] = np.array([id_dict.get(player, player) for player in data_export[:, col_idx]])
392
+ st.download_button(
393
+ label="Export optimals set",
394
+ data=convert_df(data_export),
395
+ file_name='MLB_optimals_export.csv',
396
+ mime='text/csv',
397
+ )
398
+
399
+ if site_var == 'Draftkings':
400
+ if 'working_seed' in st.session_state:
401
+ st.session_state.working_seed = st.session_state.working_seed
402
+ if player_var1 == 'Specific Players':
403
+ 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)]
404
+ elif player_var1 == 'Full Slate':
405
+ st.session_state.working_seed = dk_lineups.copy()
406
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
407
+ elif 'working_seed' not in st.session_state:
408
+ st.session_state.working_seed = dk_lineups.copy()
409
+ st.session_state.working_seed = st.session_state.working_seed
410
+ if player_var1 == 'Specific Players':
411
+ 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)]
412
+ elif player_var1 == 'Full Slate':
413
+ st.session_state.working_seed = dk_lineups.copy()
414
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
415
+
416
+ elif site_var == 'Fanduel':
417
+ if 'working_seed' in st.session_state:
418
+ st.session_state.working_seed = st.session_state.working_seed
419
+ if player_var1 == 'Specific Players':
420
+ 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)]
421
+ elif player_var1 == 'Full Slate':
422
+ st.session_state.working_seed = fd_lineups.copy()
423
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
424
+ elif 'working_seed' not in st.session_state:
425
+ st.session_state.working_seed = fd_lineups.copy()
426
+ st.session_state.working_seed = st.session_state.working_seed
427
+ if player_var1 == 'Specific Players':
428
+ 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)]
429
+ elif player_var1 == 'Full Slate':
430
+ st.session_state.working_seed = fd_lineups.copy()
431
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
432
+
433
+ export_file = st.session_state.data_export_display.copy()
434
+ # if site_var == 'Draftkings':
435
+ # for col_idx in range(6):
436
+ # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict)
437
+ # elif site_var == 'Fanduel':
438
+ # for col_idx in range(6):
439
+ # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict)
440
+
441
+ with st.container():
442
+ if st.button("Reset Optimals", key='reset3'):
443
+ for key in st.session_state.keys():
444
+ del st.session_state[key]
445
+ if site_var == 'Draftkings':
446
+ st.session_state.working_seed = dk_lineups.copy()
447
+ elif site_var == 'Fanduel':
448
+ st.session_state.working_seed = fd_lineups.copy()
449
+ if 'data_export_display' in st.session_state:
450
+ 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)
451
+ st.download_button(
452
+ label="Export display optimals",
453
+ data=convert_df(export_file),
454
+ file_name='MLB_display_optimals.csv',
455
+ mime='text/csv',
456
+ )
457
+
458
+ with st.container():
459
+ if 'working_seed' in st.session_state:
460
+ # Create a new dataframe with summary statistics
461
+ if site_var == 'Draftkings':
462
+ summary_df = pd.DataFrame({
463
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
464
+ 'Salary': [
465
+ np.min(st.session_state.working_seed[:,10]),
466
+ np.mean(st.session_state.working_seed[:,10]),
467
+ np.max(st.session_state.working_seed[:,10]),
468
+ np.std(st.session_state.working_seed[:,10])
469
+ ],
470
+ 'Proj': [
471
+ np.min(st.session_state.working_seed[:,11]),
472
+ np.mean(st.session_state.working_seed[:,11]),
473
+ np.max(st.session_state.working_seed[:,11]),
474
+ np.std(st.session_state.working_seed[:,11])
475
+ ],
476
+ 'Own': [
477
+ np.min(st.session_state.working_seed[:,16]),
478
+ np.mean(st.session_state.working_seed[:,16]),
479
+ np.max(st.session_state.working_seed[:,16]),
480
+ np.std(st.session_state.working_seed[:,16])
481
+ ]
482
+ })
483
+ elif site_var == 'Fanduel':
484
+ summary_df = pd.DataFrame({
485
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
486
+ 'Salary': [
487
+ np.min(st.session_state.working_seed[:,9]),
488
+ np.mean(st.session_state.working_seed[:,9]),
489
+ np.max(st.session_state.working_seed[:,9]),
490
+ np.std(st.session_state.working_seed[:,9])
491
+ ],
492
+ 'Proj': [
493
+ np.min(st.session_state.working_seed[:,10]),
494
+ np.mean(st.session_state.working_seed[:,10]),
495
+ np.max(st.session_state.working_seed[:,10]),
496
+ np.std(st.session_state.working_seed[:,10])
497
+ ],
498
+ 'Own': [
499
+ np.min(st.session_state.working_seed[:,15]),
500
+ np.mean(st.session_state.working_seed[:,15]),
501
+ np.max(st.session_state.working_seed[:,15]),
502
+ np.std(st.session_state.working_seed[:,15])
503
+ ]
504
+ })
505
+
506
+ # Set the index of the summary dataframe as the "Metric" column
507
+ summary_df = summary_df.set_index('Metric')
508
+
509
+ # Display the summary dataframe
510
+ st.subheader("Optimal Statistics")
511
+ st.dataframe(summary_df.style.format({
512
+ 'Salary': '{:.2f}',
513
+ 'Proj': '{:.2f}',
514
+ 'Own': '{:.2f}'
515
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True)
516
+
517
+ with st.container():
518
+ tab1, tab2 = st.tabs(["Display Frequency", "Seed Frame Frequency"])
519
+ with tab1:
520
+ if 'data_export_display' in st.session_state:
521
+ if site_var == 'Draftkings':
522
+ player_columns = st.session_state.data_export_display.iloc[:, :10]
523
+ elif site_var == 'Fanduel':
524
+ player_columns = st.session_state.data_export_display.iloc[:, :9]
525
+
526
+ # Flatten the DataFrame and count unique values
527
+ value_counts = player_columns.values.flatten().tolist()
528
+ value_counts = pd.Series(value_counts).value_counts()
529
+
530
+ percentages = (value_counts / lineup_num_var * 100).round(2)
531
+
532
+ # Create a DataFrame with the results
533
+ summary_df = pd.DataFrame({
534
+ 'Player': value_counts.index,
535
+ 'Frequency': value_counts.values,
536
+ 'Percentage': percentages.values
537
+ })
538
+
539
+ # Sort by frequency in descending order
540
+ summary_df['Salary'] = summary_df['Player'].map(player_salaries)
541
+ summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
542
+ summary_df = summary_df.sort_values('Frequency', ascending=False)
543
+ summary_df = summary_df.set_index('Player')
544
+
545
+ # Display the table
546
+ st.write("Player Frequency Table:")
547
+ st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
548
+
549
+ st.download_button(
550
+ label="Export player frequency",
551
+ data=convert_df_to_csv(summary_df),
552
+ file_name='MLB_player_frequency.csv',
553
+ mime='text/csv',
554
+ )
555
+ with tab2:
556
+ if 'working_seed' in st.session_state:
557
+ if site_var == 'Draftkings':
558
+ player_columns = st.session_state.working_seed[:, :10]
559
+ elif site_var == 'Fanduel':
560
+ player_columns = st.session_state.working_seed[:, :9]
561
+
562
+ # Flatten the DataFrame and count unique values
563
+ value_counts = player_columns.flatten().tolist()
564
+ value_counts = pd.Series(value_counts).value_counts()
565
+
566
+ percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
567
+ # Create a DataFrame with the results
568
+ summary_df = pd.DataFrame({
569
+ 'Player': value_counts.index,
570
+ 'Frequency': value_counts.values,
571
+ 'Percentage': percentages.values
572
+ })
573
+
574
+ # Sort by frequency in descending order
575
+ summary_df['Salary'] = summary_df['Player'].map(player_salaries)
576
+ summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
577
+ summary_df = summary_df.sort_values('Frequency', ascending=False)
578
+ summary_df = summary_df.set_index('Player')
579
+
580
+ # Display the table
581
+ st.write("Seed Frame Frequency Table:")
582
+ st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
583
+
584
+ st.download_button(
585
+ label="Export seed frame frequency",
586
+ data=convert_df_to_csv(summary_df),
587
+ file_name='MLB_seed_frame_frequency.csv',
588
+ mime='text/csv',
589
+ )
app.yaml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ runtime: python
2
+ env: flex
3
+
4
+ runtime_config:
5
+ python_version: 3
6
+
7
+ entrypoint: streamlit run streamlit-app.py --server.port $PORT
8
+
9
+ automatic_scaling:
10
+ max_num_instances: 200
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ gspread
3
+ openpyxl
4
+ matplotlib
5
+ streamlit-aggrid
6
+ pulp
7
+ docker
8
+ plotly
9
+ scipy
10
+ pymongo