James McCool commited on
Commit
9157685
·
1 Parent(s): 11b3ab5

Initial Commit

Browse files
Files changed (3) hide show
  1. app.py +762 -0
  2. app.yaml +10 -0
  3. requirements.txt +10 -0
app.py ADDED
@@ -0,0 +1,762 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ st.set_page_config(layout="wide")
3
+ import numpy as np
4
+ import pandas as pd
5
+ import pymongo
6
+
7
+ @st.cache_resource
8
+ def init_conn():
9
+
10
+ uri = st.secrets['mongo_uri']
11
+ client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)
12
+ db = client["MLB_Database"]
13
+
14
+ return db
15
+
16
+ db = init_conn()
17
+
18
+ percentages_format = {'Exposure': '{:.2%}'}
19
+ freq_format = {'Exposure': '{:.2%}', 'Proj Own': '{:.2%}', 'Edge': '{:.2%}'}
20
+ dk_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
21
+ fd_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
22
+
23
+ st.markdown("""
24
+ <style>
25
+ /* Tab styling */
26
+ .stTabs [data-baseweb="tab-list"] {
27
+ gap: 8px;
28
+ padding: 4px;
29
+ }
30
+ .stTabs [data-baseweb="tab"] {
31
+ height: 50px;
32
+ white-space: pre-wrap;
33
+ background-color: #FFD700;
34
+ color: white;
35
+ border-radius: 10px;
36
+ gap: 1px;
37
+ padding: 10px 20px;
38
+ font-weight: bold;
39
+ transition: all 0.3s ease;
40
+ }
41
+ .stTabs [aria-selected="true"] {
42
+ background-color: #DAA520;
43
+ color: white;
44
+ }
45
+ .stTabs [data-baseweb="tab"]:hover {
46
+ background-color: #DAA520;
47
+ cursor: pointer;
48
+ }
49
+ </style>""", unsafe_allow_html=True)
50
+
51
+ @st.cache_data(ttl = 60)
52
+ def init_DK_seed_frames(sharp_split):
53
+
54
+ collection = db['DK_MLB_name_map']
55
+ cursor = collection.find()
56
+ raw_data = pd.DataFrame(list(cursor))
57
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
58
+
59
+ # Get the valid players from the Range of Outcomes collection
60
+ collection = db["Player_Range_Of_Outcomes"]
61
+ cursor = collection.find({"site": "Draftkings", "slate": "Main Slate"})
62
+ valid_players = set(pd.DataFrame(list(cursor))['Player'].unique())
63
+
64
+ collection = db["DK_MLB_seed_frame"]
65
+ cursor = collection.find().limit(sharp_split)
66
+
67
+ raw_display = pd.DataFrame(list(cursor))
68
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
69
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
70
+ # Map names
71
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
72
+
73
+ # Validate lineups against valid players
74
+ raw_display = validate_lineup_players(raw_display, valid_players, dict_columns)
75
+
76
+ # Remove any remaining NaN values
77
+ raw_display = raw_display.dropna()
78
+ DK_seed = raw_display.to_numpy()
79
+
80
+ return DK_seed
81
+
82
+ @st.cache_data(ttl = 60)
83
+ def init_DK_secondary_seed_frames(sharp_split):
84
+
85
+ collection = db['DK_MLB_secondary_name_map']
86
+ cursor = collection.find()
87
+ raw_data = pd.DataFrame(list(cursor))
88
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
89
+
90
+ # Get the valid players from the Range of Outcomes collection
91
+ collection = db["Player_Range_Of_Outcomes"]
92
+ cursor = collection.find({"site": "Draftkings", "slate": "Secondary Slate"})
93
+ valid_players = set(pd.DataFrame(list(cursor))['Player'].unique())
94
+
95
+ collection = db["DK_MLB_secondary_seed_frame"]
96
+ cursor = collection.find().limit(sharp_split)
97
+
98
+ raw_display = pd.DataFrame(list(cursor))
99
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
100
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
101
+ # Map names
102
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
103
+
104
+ # Validate lineups against valid players
105
+ raw_display = validate_lineup_players(raw_display, valid_players, dict_columns)
106
+
107
+ # Remove any remaining NaN values
108
+ raw_display = raw_display.dropna()
109
+ DK_seed = raw_display.to_numpy()
110
+
111
+ return DK_seed
112
+
113
+ @st.cache_data(ttl = 60)
114
+ def init_FD_seed_frames(sharp_split):
115
+
116
+ collection = db['FD_MLB_name_map']
117
+ cursor = collection.find()
118
+ raw_data = pd.DataFrame(list(cursor))
119
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
120
+
121
+ # Get the valid players from the Range of Outcomes collection
122
+ collection = db["Player_Range_Of_Outcomes"]
123
+ cursor = collection.find({"site": "Fanduel", "slate": "Main Slate"})
124
+ valid_players = set(pd.DataFrame(list(cursor))['Player'].unique())
125
+
126
+ collection = db["FD_MLB_seed_frame"]
127
+ cursor = collection.find().limit(sharp_split)
128
+
129
+ raw_display = pd.DataFrame(list(cursor))
130
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
131
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
132
+ # Map names
133
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
134
+
135
+ # Validate lineups against valid players
136
+ raw_display = validate_lineup_players(raw_display, valid_players, dict_columns)
137
+
138
+ # Remove any remaining NaN values
139
+ raw_display = raw_display.dropna()
140
+ FD_seed = raw_display.to_numpy()
141
+
142
+ return FD_seed
143
+
144
+ @st.cache_data(ttl = 60)
145
+ def init_FD_secondary_seed_frames(sharp_split):
146
+
147
+ collection = db['FD_MLB_secondary_name_map']
148
+ cursor = collection.find()
149
+ raw_data = pd.DataFrame(list(cursor))
150
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
151
+
152
+ # Get the valid players from the Range of Outcomes collection
153
+ collection = db["Player_Range_Of_Outcomes"]
154
+ cursor = collection.find({"site": "Fanduel", "slate": "Secondary Slate"})
155
+ valid_players = set(pd.DataFrame(list(cursor))['Player'].unique())
156
+
157
+ collection = db["FD_MLB_secondary_seed_frame"]
158
+ cursor = collection.find().limit(sharp_split)
159
+
160
+ raw_display = pd.DataFrame(list(cursor))
161
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
162
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
163
+ # Map names
164
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
165
+
166
+ # Validate lineups against valid players
167
+ raw_display = validate_lineup_players(raw_display, valid_players, dict_columns)
168
+
169
+ # Remove any remaining NaN values
170
+ raw_display = raw_display.dropna()
171
+ FD_seed = raw_display.to_numpy()
172
+
173
+ return FD_seed
174
+
175
+ @st.cache_data(ttl = 599)
176
+ def init_baselines():
177
+ collection = db["Player_Range_Of_Outcomes"]
178
+ cursor = collection.find()
179
+
180
+ load_display = pd.DataFrame(list(cursor))
181
+
182
+ load_display.replace('', np.nan, inplace=True)
183
+ load_display.rename(columns={"Fantasy": "Median", 'Name': 'Player', 'player_ID': 'player_id'}, inplace = True)
184
+ load_display = load_display[load_display['Median'] > 0]
185
+
186
+ dk_roo_raw = load_display[load_display['site'] == 'Draftkings']
187
+ dk_roo_raw = dk_roo_raw[dk_roo_raw['slate'] == 'Main Slate']
188
+ dk_roo_raw['STDev'] = dk_roo_raw['Median'] / 3
189
+ dk_raw = dk_roo_raw.dropna(subset=['Median'])
190
+
191
+ fd_roo_raw = load_display[load_display['site'] == 'Fanduel']
192
+ fd_roo_raw = fd_roo_raw[fd_roo_raw['slate'] == 'Main Slate']
193
+ fd_roo_raw['STDev'] = fd_roo_raw['Median'] / 3
194
+ fd_raw = fd_roo_raw.dropna(subset=['Median'])
195
+
196
+ dk_secondary_roo_raw = load_display[load_display['site'] == 'Draftkings']
197
+ dk_secondary_roo_raw = dk_secondary_roo_raw[dk_secondary_roo_raw['slate'] == 'Secondary Slate']
198
+ dk_secondary_roo_raw['STDev'] = dk_secondary_roo_raw['Median'] / 3
199
+ dk_secondary = dk_secondary_roo_raw.dropna(subset=['Median'])
200
+
201
+ fd_secondary_roo_raw = load_display[load_display['site'] == 'Fanduel']
202
+ fd_secondary_roo_raw = fd_secondary_roo_raw[fd_secondary_roo_raw['slate'] == 'Secondary Slate']
203
+ fd_secondary_roo_raw['STDev'] = fd_secondary_roo_raw['Median'] / 3
204
+ fd_secondary = fd_secondary_roo_raw.dropna(subset=['Median'])
205
+
206
+ teams_playing_count = len(dk_raw.Team.unique())
207
+
208
+ return dk_raw, fd_raw, dk_secondary, fd_secondary, teams_playing_count
209
+
210
+ @st.cache_data
211
+ def validate_lineup_players(df, valid_players, player_columns):
212
+ """
213
+ Validates that all players in specified columns exist in valid_players set
214
+
215
+ Args:
216
+ df: DataFrame containing lineups
217
+ valid_players: Set of valid player names
218
+ player_columns: List of columns containing player names
219
+
220
+ Returns:
221
+ DataFrame with only valid lineups
222
+ """
223
+ valid_rows = df[player_columns].apply(lambda x: x.isin(valid_players)).all(axis=1)
224
+ return df[valid_rows]
225
+
226
+ @st.cache_data
227
+ def convert_df(array):
228
+ array = pd.DataFrame(array, columns=column_names)
229
+ return array.to_csv().encode('utf-8')
230
+
231
+ @st.cache_data
232
+ def calculate_DK_value_frequencies(np_array):
233
+ unique, counts = np.unique(np_array[:, :9], return_counts=True)
234
+ frequencies = counts / len(np_array) # Normalize by the number of rows
235
+ combined_array = np.column_stack((unique, frequencies))
236
+ return combined_array
237
+
238
+ @st.cache_data
239
+ def calculate_FD_value_frequencies(np_array):
240
+ unique, counts = np.unique(np_array[:, :8], return_counts=True)
241
+ frequencies = counts / len(np_array) # Normalize by the number of rows
242
+ combined_array = np.column_stack((unique, frequencies))
243
+ return combined_array
244
+
245
+ @st.cache_data
246
+ def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size, teams_playing_count, site):
247
+ SimVar = 1
248
+ Sim_Winners = []
249
+ fp_array = seed_frame.copy()
250
+ # Pre-vectorize functions
251
+ vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)
252
+ vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)
253
+
254
+ st.write('Simulating contest on frames')
255
+
256
+ while SimVar <= Sim_size:
257
+ fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)]
258
+
259
+ if site == 'Draftkings':
260
+ # Calculate stack multipliers first
261
+ stack_multiplier = np.ones(fp_random.shape[0]) # Start with no bonus
262
+ stack_multiplier += np.minimum(0.10, np.where(fp_random[:, 12] == 4, 0.025 * (teams_playing_count - 8), 0))
263
+ stack_multiplier += np.minimum(0.15, np.where(fp_random[:, 12] >= 5, 0.025 * (teams_playing_count - 12), 0))
264
+ elif site == 'Fanduel':
265
+ # Calculate stack multipliers first
266
+ stack_multiplier = np.ones(fp_random.shape[0]) # Start with no bonus
267
+ stack_multiplier += np.minimum(0.10, np.where(fp_random[:, 11] == 4, 0.025 * (teams_playing_count - 8), 0))
268
+ stack_multiplier += np.minimum(0.15, np.where(fp_random[:, 11] >= 5, 0.025 * (teams_playing_count - 12), 0))
269
+
270
+ # Apply multipliers to both loc and scale in the normal distribution
271
+ base_projections = np.sum(np.random.normal(
272
+ loc=vec_projection_map(fp_random[:, :-7]) * stack_multiplier[:, np.newaxis],
273
+ scale=vec_stdev_map(fp_random[:, :-7]) * stack_multiplier[:, np.newaxis]),
274
+ axis=1)
275
+
276
+ final_projections = base_projections
277
+
278
+ sample_arrays = np.c_[fp_random, final_projections]
279
+ if site == 'Draftkings':
280
+ final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]]
281
+ elif site == 'Fanduel':
282
+ final_array = sample_arrays[sample_arrays[:, 9].argsort()[::-1]]
283
+ best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]
284
+ Sim_Winners.append(best_lineup)
285
+ SimVar += 1
286
+
287
+ return Sim_Winners
288
+
289
+ dk_raw, fd_raw, teams_playing_count = init_baselines()
290
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
291
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
292
+
293
+ tab1, tab2 = st.tabs(['Contest Sims', 'Data Export'])
294
+
295
+ with tab1:
296
+ with st.expander("Info and Filters"):
297
+ if st.button("Load/Reset Data", key='reset2'):
298
+ st.cache_data.clear()
299
+ for key in st.session_state.keys():
300
+ del st.session_state[key]
301
+ DK_seed = init_DK_seed_frames(10000)
302
+ FD_seed = init_FD_seed_frames(10000)
303
+ dk_raw, fd_raw, teams_playing_count = init_baselines()
304
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
305
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
306
+
307
+ sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Other Main Slate'), key='sim_slate_var1')
308
+ sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
309
+
310
+ contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom'))
311
+ if contest_var1 == 'Small':
312
+ Contest_Size = 1000
313
+ elif contest_var1 == 'Medium':
314
+ Contest_Size = 5000
315
+ elif contest_var1 == 'Large':
316
+ Contest_Size = 10000
317
+ elif contest_var1 == 'Custom':
318
+ Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
319
+ strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
320
+ if strength_var1 == 'Not Very':
321
+ sharp_split = 500000
322
+ elif strength_var1 == 'Below Average':
323
+ sharp_split = 250000
324
+ elif strength_var1 == 'Average':
325
+ sharp_split = 100000
326
+ elif strength_var1 == 'Above Average':
327
+ sharp_split = 50000
328
+ elif strength_var1 == 'Very':
329
+ sharp_split = 10000
330
+
331
+ if st.button("Run Contest Sim"):
332
+ if 'working_seed' in st.session_state:
333
+ st.session_state.maps_dict = {
334
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
335
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
336
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
337
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
338
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
339
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
340
+ }
341
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size, teams_playing_count, sim_site_var1)
342
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
343
+
344
+ #st.table(Sim_Winner_Frame)
345
+
346
+ # Initial setup
347
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
348
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
349
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
350
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
351
+
352
+ # Type Casting
353
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
354
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
355
+
356
+ # Sorting
357
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
358
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
359
+
360
+ # Data Copying
361
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
362
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
363
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)
364
+ st.session_state.Sim_Winner_Export = st.session_state.Sim_Winner_Export.drop_duplicates(subset=['Team', 'Secondary', 'salary', 'unique_id'])
365
+
366
+ # Data Copying
367
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
368
+
369
+ else:
370
+ if sim_site_var1 == 'Draftkings':
371
+ if sim_slate_var1 == 'Main Slate':
372
+ st.session_state.working_seed = init_DK_seed_frames(sharp_split)
373
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
374
+ raw_baselines = dk_raw
375
+ column_names = dk_columns
376
+ elif sim_site_var1 == 'Fanduel':
377
+ if sim_slate_var1 == 'Main Slate':
378
+ st.session_state.working_seed = init_FD_seed_frames(sharp_split)
379
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
380
+ raw_baselines = fd_raw
381
+ column_names = fd_columns
382
+
383
+ st.session_state.maps_dict = {
384
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
385
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
386
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
387
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
388
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
389
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
390
+ }
391
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size, teams_playing_count, sim_site_var1)
392
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
393
+
394
+ #st.table(Sim_Winner_Frame)
395
+
396
+ # Initial setup
397
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
398
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
399
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
400
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
401
+
402
+ # Type Casting
403
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
404
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
405
+
406
+ # Sorting
407
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
408
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
409
+
410
+ # Data Copying
411
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
412
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
413
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)
414
+ st.session_state.Sim_Winner_Export = st.session_state.Sim_Winner_Export.drop_duplicates(subset=['Team', 'Secondary', 'salary', 'unique_id'])
415
+
416
+ # Data Copying
417
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
418
+ st.session_state.freq_copy = st.session_state.Sim_Winner_Display
419
+
420
+ if sim_site_var1 == 'Draftkings':
421
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:10].values, return_counts=True)),
422
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
423
+ elif sim_site_var1 == 'Fanduel':
424
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
425
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
426
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
427
+ freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])
428
+ freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])
429
+ freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
430
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
431
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
432
+ freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])
433
+ st.session_state.player_freq = freq_working.copy()
434
+
435
+ if sim_site_var1 == 'Draftkings':
436
+ sp_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:2].values, return_counts=True)),
437
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
438
+ elif sim_site_var1 == 'Fanduel':
439
+ sp_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
440
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
441
+ sp_working['Freq'] = sp_working['Freq'].astype(int)
442
+ sp_working['Position'] = sp_working['Player'].map(st.session_state.maps_dict['Pos_map'])
443
+ sp_working['Salary'] = sp_working['Player'].map(st.session_state.maps_dict['Salary_map'])
444
+ sp_working['Proj Own'] = sp_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
445
+ sp_working['Exposure'] = sp_working['Freq']/(1000)
446
+ sp_working['Edge'] = sp_working['Exposure'] - sp_working['Proj Own']
447
+ sp_working['Team'] = sp_working['Player'].map(st.session_state.maps_dict['Team_map'])
448
+ st.session_state.sp_freq = sp_working.copy()
449
+
450
+ if sim_site_var1 == 'Draftkings':
451
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,12:13].values, return_counts=True)),
452
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
453
+ elif sim_site_var1 == 'Fanduel':
454
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
455
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
456
+ team_working['Freq'] = team_working['Freq'].astype(int)
457
+ team_working['Exposure'] = team_working['Freq']/(1000)
458
+ st.session_state.team_freq = team_working.copy()
459
+
460
+ if sim_site_var1 == 'Draftkings':
461
+ stack_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,13:14].values, return_counts=True)),
462
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
463
+ elif sim_site_var1 == 'Fanduel':
464
+ stack_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,12:13].values, return_counts=True)),
465
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
466
+ stack_working['Freq'] = stack_working['Freq'].astype(int)
467
+ stack_working['Exposure'] = stack_working['Freq']/(1000)
468
+ st.session_state.stack_freq = stack_working.copy()
469
+
470
+ with st.container():
471
+ if st.button("Reset Sim", key='reset_sim'):
472
+ for key in st.session_state.keys():
473
+ del st.session_state[key]
474
+ if 'player_freq' in st.session_state:
475
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
476
+ if player_split_var2 == 'Specific Players':
477
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
478
+ elif player_split_var2 == 'Full Players':
479
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
480
+
481
+ if player_split_var2 == 'Specific Players':
482
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]
483
+ if player_split_var2 == 'Full Players':
484
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
485
+ if 'Sim_Winner_Display' in st.session_state:
486
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
487
+ if 'Sim_Winner_Export' in st.session_state:
488
+ st.download_button(
489
+
490
+ label="Export Full Frame",
491
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
492
+ file_name='MLB_consim_export.csv',
493
+ mime='text/csv',
494
+ )
495
+ tab1, tab2 = st.tabs(['Winning Frame Statistics', 'Stack Type Statistics'])
496
+
497
+ with tab1:
498
+ if 'Sim_Winner_Display' in st.session_state:
499
+ # Create a new dataframe with summary statistics
500
+ summary_df = pd.DataFrame({
501
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
502
+ 'Salary': [
503
+ st.session_state.Sim_Winner_Display['salary'].min(),
504
+ st.session_state.Sim_Winner_Display['salary'].mean(),
505
+ st.session_state.Sim_Winner_Display['salary'].max(),
506
+ st.session_state.Sim_Winner_Display['salary'].std()
507
+ ],
508
+ 'Proj': [
509
+ st.session_state.Sim_Winner_Display['proj'].min(),
510
+ st.session_state.Sim_Winner_Display['proj'].mean(),
511
+ st.session_state.Sim_Winner_Display['proj'].max(),
512
+ st.session_state.Sim_Winner_Display['proj'].std()
513
+ ],
514
+ 'Own': [
515
+ st.session_state.Sim_Winner_Display['Own'].min(),
516
+ st.session_state.Sim_Winner_Display['Own'].mean(),
517
+ st.session_state.Sim_Winner_Display['Own'].max(),
518
+ st.session_state.Sim_Winner_Display['Own'].std()
519
+ ],
520
+ 'Fantasy': [
521
+ st.session_state.Sim_Winner_Display['Fantasy'].min(),
522
+ st.session_state.Sim_Winner_Display['Fantasy'].mean(),
523
+ st.session_state.Sim_Winner_Display['Fantasy'].max(),
524
+ st.session_state.Sim_Winner_Display['Fantasy'].std()
525
+ ],
526
+ 'GPP_Proj': [
527
+ st.session_state.Sim_Winner_Display['GPP_Proj'].min(),
528
+ st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),
529
+ st.session_state.Sim_Winner_Display['GPP_Proj'].max(),
530
+ st.session_state.Sim_Winner_Display['GPP_Proj'].std()
531
+ ]
532
+ })
533
+
534
+ # Set the index of the summary dataframe as the "Metric" column
535
+ summary_df = summary_df.set_index('Metric')
536
+
537
+ # Display the summary dataframe
538
+ st.subheader("Winning Frame Statistics")
539
+ st.dataframe(summary_df.style.format({
540
+ 'Salary': '{:.2f}',
541
+ 'Proj': '{:.2f}',
542
+ 'Own': '{:.2f}',
543
+ 'Fantasy': '{:.2f}',
544
+ 'GPP_Proj': '{:.2f}'
545
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)
546
+
547
+ with tab2:
548
+ if 'Sim_Winner_Display' in st.session_state:
549
+ # Apply position mapping to FLEX column
550
+ stack_counts = st.session_state.freq_copy['Team_count'].value_counts()
551
+
552
+ # Calculate average statistics for each stack size
553
+ stack_stats = st.session_state.freq_copy.groupby('Team_count').agg({
554
+ 'proj': 'mean',
555
+ 'Own': 'mean',
556
+ 'Fantasy': 'mean',
557
+ 'GPP_Proj': 'mean'
558
+ })
559
+
560
+ # Combine counts and average statistics
561
+ stack_summary = pd.concat([stack_counts, stack_stats], axis=1)
562
+ stack_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
563
+ stack_summary = stack_summary.reset_index()
564
+ stack_summary.columns = ['Stack Size', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
565
+ stack_summary = stack_summary.sort_values(by='Stack Size', ascending=True)
566
+ stack_summary = stack_summary.set_index('Stack Size')
567
+
568
+ # Display the summary dataframe
569
+ st.subheader("Stack Type Statistics")
570
+ st.dataframe(stack_summary.style.format({
571
+ 'Count': '{:.0f}',
572
+ 'Avg Proj': '{:.2f}',
573
+ 'Avg Own': '{:.2f}',
574
+ 'Avg Fantasy': '{:.2f}',
575
+ 'Avg GPP_Proj': '{:.2f}'
576
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)
577
+ else:
578
+ st.write("Simulation data or position mapping not available.")
579
+
580
+
581
+ with st.container():
582
+ tab1, tab2, tab3, tab4 = st.tabs(['Overall Exposures', 'SP Exposures', 'Team Exposures', 'Stack Size Exposures'])
583
+ with tab1:
584
+ if 'player_freq' in st.session_state:
585
+
586
+ st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
587
+ st.download_button(
588
+ label="Export Exposures",
589
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
590
+ file_name='player_freq_export.csv',
591
+ mime='text/csv',
592
+ key='overall'
593
+ )
594
+ with tab2:
595
+ if 'sp_freq' in st.session_state:
596
+
597
+ st.dataframe(st.session_state.sp_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
598
+ st.download_button(
599
+ label="Export Exposures",
600
+ data=st.session_state.sp_freq.to_csv().encode('utf-8'),
601
+ file_name='sp_freq.csv',
602
+ mime='text/csv',
603
+ key='sp'
604
+ )
605
+ with tab3:
606
+ if 'team_freq' in st.session_state:
607
+
608
+ st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
609
+ st.download_button(
610
+ label="Export Exposures",
611
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
612
+ file_name='team_freq.csv',
613
+ mime='text/csv',
614
+ key='team'
615
+ )
616
+ with tab4:
617
+ if 'stack_freq' in st.session_state:
618
+
619
+ st.dataframe(st.session_state.stack_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
620
+ st.download_button(
621
+ label="Export Exposures",
622
+ data=st.session_state.stack_freq.to_csv().encode('utf-8'),
623
+ file_name='stack_freq.csv',
624
+ mime='text/csv',
625
+ key='stack'
626
+ )
627
+
628
+ with tab2:
629
+ with st.expander("Info and Filters"):
630
+ if st.button("Load/Reset Data", key='reset1'):
631
+ st.cache_data.clear()
632
+ for key in st.session_state.keys():
633
+ del st.session_state[key]
634
+ DK_seed = init_DK_seed_frames(10000)
635
+ FD_seed = init_FD_seed_frames(10000)
636
+ dk_raw, fd_raw, teams_playing_count = init_baselines()
637
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
638
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
639
+
640
+ slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate'))
641
+ site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'))
642
+ sharp_split_var = st.number_input("How many lineups do you want?", value=10000, max_value=500000, min_value=10000, step=10000)
643
+ lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=500, value=10, step=1)
644
+
645
+ if site_var1 == 'Draftkings':
646
+
647
+ team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1')
648
+ if team_var1 == 'Specific Teams':
649
+ team_var2 = st.multiselect('Which teams do you want?', options = dk_raw['Team'].unique())
650
+ elif team_var1 == 'Full Slate':
651
+ team_var2 = dk_raw.Team.values.tolist()
652
+
653
+ stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1')
654
+ if stack_var1 == 'Specific Stack Sizes':
655
+ stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0])
656
+ elif stack_var1 == 'Full Slate':
657
+ stack_var2 = [5, 4, 3, 2, 1, 0]
658
+
659
+ raw_baselines = dk_raw
660
+ column_names = dk_columns
661
+
662
+ elif site_var1 == 'Fanduel':
663
+
664
+ team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1')
665
+ if team_var1 == 'Specific Teams':
666
+ team_var2 = st.multiselect('Which teams do you want?', options = fd_raw['Team'].unique())
667
+ elif team_var1 == 'Full Slate':
668
+ team_var2 = fd_raw.Team.values.tolist()
669
+
670
+ stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1')
671
+ if stack_var1 == 'Specific Stack Sizes':
672
+ stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0])
673
+ elif stack_var1 == 'Full Slate':
674
+ stack_var2 = [5, 4, 3, 2, 1, 0]
675
+
676
+ raw_baselines = fd_raw
677
+ column_names = fd_columns
678
+
679
+
680
+ if st.button("Prepare data export", key='data_export'):
681
+ if 'working_seed' in st.session_state:
682
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]
683
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 10], stack_var2)]
684
+ st.session_state.data_export_display = st.session_state.working_seed[0:lineup_num_var]
685
+ elif 'working_seed' not in st.session_state:
686
+ if site_var1 == 'Draftkings':
687
+ if slate_var1 == 'Main Slate':
688
+ st.session_state.working_seed = init_DK_seed_frames(sharp_split_var)
689
+
690
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
691
+ raw_baselines = dk_raw
692
+ column_names = dk_columns
693
+ elif slate_var1 == 'Secondary Slate':
694
+ st.session_state.working_seed = init_DK_secondary_seed_frames(sharp_split_var)
695
+
696
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
697
+ raw_baselines = dk_raw
698
+ column_names = dk_columns
699
+
700
+ elif site_var1 == 'Fanduel':
701
+ if slate_var1 == 'Main Slate':
702
+ st.session_state.working_seed = init_FD_seed_frames(sharp_split_var)
703
+
704
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
705
+ raw_baselines = fd_raw
706
+ column_names = fd_columns
707
+ elif slate_var1 == 'Secondary Slate':
708
+ st.session_state.working_seed = init_FD_secondary_seed_frames(sharp_split_var)
709
+
710
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
711
+ raw_baselines = fd_raw
712
+ column_names = fd_columns
713
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]
714
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 10], stack_var2)]
715
+ st.session_state.data_export_display = st.session_state.working_seed[0:lineup_num_var]
716
+ data_export = st.session_state.working_seed.copy()
717
+ st.download_button(
718
+ label="Export optimals set",
719
+ data=convert_df(data_export),
720
+ file_name='MLB_optimals_export.csv',
721
+ mime='text/csv',
722
+ )
723
+ for key in st.session_state.keys():
724
+ del st.session_state[key]
725
+
726
+ if st.button("Load Data", key='load_data'):
727
+ if site_var1 == 'Draftkings':
728
+ if 'working_seed' in st.session_state:
729
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]
730
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 10], stack_var2)]
731
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
732
+ elif 'working_seed' not in st.session_state:
733
+ if slate_var1 == 'Main Slate':
734
+ st.session_state.working_seed = init_DK_seed_frames(sharp_split_var)
735
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))
736
+
737
+ raw_baselines = dk_raw
738
+ column_names = dk_columns
739
+
740
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]
741
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 10], stack_var2)]
742
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
743
+
744
+ elif site_var1 == 'Fanduel':
745
+ if 'working_seed' in st.session_state:
746
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]
747
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 10], stack_var2)]
748
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
749
+ elif 'working_seed' not in st.session_state:
750
+ if slate_var1 == 'Main Slate':
751
+ st.session_state.working_seed = init_FD_seed_frames(sharp_split_var)
752
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))
753
+
754
+ raw_baselines = fd_raw
755
+ column_names = fd_columns
756
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]
757
+ st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 10], stack_var2)]
758
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
759
+
760
+ with st.container():
761
+ if 'data_export_display' in st.session_state:
762
+ st.dataframe(st.session_state.data_export_display.style.format(freq_format, precision=2), use_container_width = True)
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: 1000
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ gspread
3
+ openpyxl
4
+ matplotlib
5
+ pymongo
6
+ pulp
7
+ docker
8
+ plotly
9
+ scipy
10
+ polars