James McCool commited on
Commit
a293e56
·
1 Parent(s): 1d5de76

Implement initial project structure and setup

Browse files
Files changed (3) hide show
  1. app.py +770 -0
  2. app.yaml +10 -0
  3. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,770 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ return db
16
+
17
+ db = init_conn()
18
+
19
+ game_format = {'Win%': '{:.2%}','First Inning Lead Percentage': '{:.2%}', 'Top Score': '{:.2%}',
20
+ 'Fifth Inning Lead Percentage': '{:.2%}', '8+ Runs': '{:.2%}', 'LevX': '{:.2%}'}
21
+
22
+ player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '20+%': '{:.2%}', '2x%': '{:.2%}', '3x%': '{:.2%}',
23
+ '4x%': '{:.2%}'}
24
+
25
+ dk_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
26
+ fd_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
27
+ dk_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
28
+ fd_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
29
+
30
+ st.markdown("""
31
+ <style>
32
+ /* Tab styling */
33
+ .stTabs [data-baseweb="tab-list"] {
34
+ gap: 8px;
35
+ padding: 4px;
36
+ }
37
+ .stTabs [data-baseweb="tab"] {
38
+ height: 50px;
39
+ white-space: pre-wrap;
40
+ background-color: #DAA520;
41
+ color: white;
42
+ border-radius: 10px;
43
+ gap: 1px;
44
+ padding: 10px 20px;
45
+ font-weight: bold;
46
+ transition: all 0.3s ease;
47
+ }
48
+ .stTabs [aria-selected="true"] {
49
+ background-color: #DAA520;
50
+ border: 3px solid #FFD700;
51
+ color: white;
52
+ }
53
+ .stTabs [data-baseweb="tab"]:hover {
54
+ background-color: #FFD700;
55
+ cursor: pointer;
56
+ }
57
+ div[data-baseweb="select"] > div {
58
+ background-color: #DAA520;
59
+ color: white;
60
+ }
61
+ </style>""", unsafe_allow_html=True)
62
+
63
+ @st.cache_resource(ttl = 60)
64
+ def init_baselines():
65
+ collection = db["Player_Range_Of_Outcomes"]
66
+ cursor = collection.find()
67
+ player_frame = pd.DataFrame(cursor)
68
+
69
+ roo_data = player_frame.drop(columns=['_id'])
70
+ roo_data['Salary'] = roo_data['Salary'].astype(int)
71
+
72
+ dk_roo = roo_data[roo_data['Site'] == 'Draftkings']
73
+ dk_id_map = dict(zip(dk_roo['Player'], dk_roo['player_ID']))
74
+ fd_roo = roo_data[roo_data['Site'] == 'Fanduel']
75
+ fd_id_map = dict(zip(fd_roo['Player'], fd_roo['player_ID']))
76
+
77
+ collection = db["Player_SD_Range_Of_Outcomes"]
78
+ cursor = collection.find()
79
+ player_frame = pd.DataFrame(cursor)
80
+
81
+ sd_roo_data = player_frame.drop(columns=['_id'])
82
+ sd_roo_data['Salary'] = sd_roo_data['Salary'].astype(int)
83
+ sd_roo_data = sd_roo_data.rename(columns={'Own': 'Own%'})
84
+
85
+ collection = db["Scoring_Percentages"]
86
+ cursor = collection.find()
87
+ team_frame = pd.DataFrame(cursor)
88
+ scoring_percentages = team_frame.drop(columns=['_id'])
89
+ 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',
90
+ 'DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'DK Main Top Score', 'FD Main Top Score', 'DK Secondary Top Score', 'FD Secondary Top Score',
91
+ 'DK Turbo Top Score', 'FD Turbo Top Score']]
92
+ scoring_percentages['8+ runs'] = scoring_percentages['8+ runs'].replace('%', '', regex=True).astype(float)
93
+ scoring_percentages['Win Percentage'] = scoring_percentages['Win Percentage'].replace('%', '', regex=True).astype(float)
94
+ scoring_percentages['DK Main Top Score'] = scoring_percentages['DK Main Top Score'].replace('', np.nan).astype(float)
95
+ scoring_percentages['FD Main Top Score'] = scoring_percentages['FD Main Top Score'].replace('', np.nan).astype(float)
96
+ scoring_percentages['DK Secondary Top Score'] = scoring_percentages['DK Secondary Top Score'].replace('', np.nan).astype(float)
97
+ scoring_percentages['FD Secondary Top Score'] = scoring_percentages['FD Secondary Top Score'].replace('', np.nan).astype(float)
98
+ scoring_percentages['DK Turbo Top Score'] = scoring_percentages['DK Turbo Top Score'].replace('', np.nan).astype(float)
99
+ scoring_percentages['FD Turbo Top Score'] = scoring_percentages['FD Turbo Top Score'].replace('', np.nan).astype(float)
100
+
101
+ return roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo, dk_id_map, fd_id_map
102
+
103
+ @st.cache_data(ttl = 60)
104
+ def init_DK_lineups(type_var, slate_var):
105
+
106
+ if type_var == 'Regular':
107
+ if slate_var == 'Main':
108
+ collection = db['DK_MLB_name_map']
109
+ cursor = collection.find()
110
+ raw_data = pd.DataFrame(list(cursor))
111
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
112
+
113
+ collection = db['DK_MLB_seed_frame']
114
+ cursor = collection.find().limit(10000)
115
+
116
+ raw_display = pd.DataFrame(list(cursor))
117
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
118
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
119
+ # Map names
120
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
121
+ elif slate_var == 'Secondary':
122
+ collection = db['DK_MLB_Secondary_name_map']
123
+ cursor = collection.find()
124
+ raw_data = pd.DataFrame(list(cursor))
125
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
126
+
127
+ collection = db['DK_MLB_Secondary_seed_frame']
128
+ cursor = collection.find().limit(10000)
129
+
130
+ raw_display = pd.DataFrame(list(cursor))
131
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
132
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
133
+ # Map names
134
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
135
+ elif slate_var == 'Auxiliary':
136
+ collection = db['DK_MLB_Turbo_name_map']
137
+ cursor = collection.find()
138
+ raw_data = pd.DataFrame(list(cursor))
139
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
140
+
141
+ collection = db['DK_MLB_Turbo_seed_frame']
142
+ cursor = collection.find().limit(10000)
143
+
144
+ raw_display = pd.DataFrame(list(cursor))
145
+ raw_display = raw_display[['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
146
+ dict_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
147
+ # Map names
148
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
149
+ elif type_var == 'Showdown':
150
+ if slate_var == 'Main':
151
+ collection = db['DK_MLB_SD1_seed_frame']
152
+ cursor = collection.find().limit(10000)
153
+
154
+ raw_display = pd.DataFrame(list(cursor))
155
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
156
+ elif slate_var == 'Secondary':
157
+ collection = db['DK_MLB_SD2_seed_frame']
158
+ cursor = collection.find().limit(10000)
159
+
160
+ raw_display = pd.DataFrame(list(cursor))
161
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
162
+ elif slate_var == 'Auxiliary':
163
+ collection = db['DK_MLB_SD3_seed_frame']
164
+ cursor = collection.find().limit(10000)
165
+
166
+ raw_display = pd.DataFrame(list(cursor))
167
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
168
+
169
+ DK_seed = raw_display.to_numpy()
170
+
171
+ return DK_seed
172
+
173
+ @st.cache_data(ttl = 60)
174
+ def init_FD_lineups(type_var,slate_var):
175
+
176
+ if type_var == 'Regular':
177
+ if slate_var == 'Main':
178
+ collection = db['FD_MLB_name_map']
179
+ cursor = collection.find()
180
+ raw_data = pd.DataFrame(list(cursor))
181
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
182
+
183
+ collection = db['FD_MLB_seed_frame']
184
+ cursor = collection.find().limit(10000)
185
+
186
+ raw_display = pd.DataFrame(list(cursor))
187
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
188
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
189
+ # Map names
190
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
191
+ elif slate_var == 'Secondary':
192
+ collection = db['FD_MLB_Secondary_name_map']
193
+ cursor = collection.find()
194
+ raw_data = pd.DataFrame(list(cursor))
195
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
196
+
197
+ collection = db['FD_MLB_Secondary_seed_frame']
198
+ cursor = collection.find().limit(10000)
199
+
200
+ raw_display = pd.DataFrame(list(cursor))
201
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
202
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
203
+ # Map names
204
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
205
+ elif slate_var == 'Auxiliary':
206
+ collection = db['FD_MLB_Turbo_name_map']
207
+ cursor = collection.find()
208
+ raw_data = pd.DataFrame(list(cursor))
209
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
210
+
211
+ collection = db['FD_MLB_Turbo_seed_frame']
212
+ cursor = collection.find().limit(10000)
213
+
214
+ raw_display = pd.DataFrame(list(cursor))
215
+ raw_display = raw_display[['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
216
+ dict_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
217
+ # Map names
218
+ raw_display[dict_columns] = raw_display[dict_columns].apply(lambda x: x.map(names_dict))
219
+
220
+ elif type_var == 'Showdown':
221
+ if slate_var == 'Main':
222
+ collection = db['FD_MLB_SD1_seed_frame']
223
+ cursor = collection.find().limit(10000)
224
+
225
+ raw_display = pd.DataFrame(list(cursor))
226
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
227
+ elif slate_var == 'Secondary':
228
+ collection = db['FD_MLB_SD2_seed_frame']
229
+ cursor = collection.find().limit(10000)
230
+
231
+ raw_display = pd.DataFrame(list(cursor))
232
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
233
+ elif slate_var == 'Auxiliary':
234
+ collection = db['FD_MLB_SD3_seed_frame']
235
+ cursor = collection.find().limit(10000)
236
+
237
+ raw_display = pd.DataFrame(list(cursor))
238
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
239
+
240
+ FD_seed = raw_display.to_numpy()
241
+
242
+ return FD_seed
243
+
244
+ @st.cache_data
245
+ def convert_df_to_csv(df):
246
+ return df.to_csv().encode('utf-8')
247
+
248
+ @st.cache_data
249
+ def convert_df(array):
250
+ array = pd.DataFrame(array, columns=column_names)
251
+ return array.to_csv().encode('utf-8')
252
+
253
+ col1, col2 = st.columns([1, 9])
254
+ with col1:
255
+ if st.button("Load/Reset Data", key='reset'):
256
+ st.cache_data.clear()
257
+ roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo, dk_id_map, fd_id_map = init_baselines()
258
+ hold_display = roo_data
259
+ dk_lineups = init_DK_lineups('Regular', 'Main')
260
+ fd_lineups = init_FD_lineups('Regular', 'Main')
261
+ for key in st.session_state.keys():
262
+ del st.session_state[key]
263
+ with col2:
264
+ with st.container():
265
+ col1, col2 = st.columns([3, 3])
266
+ with col1:
267
+ view_var = st.selectbox("Select view", ["Simple", "Advanced"], key='view_var')
268
+ with col2:
269
+ site_var = st.selectbox("What site do you want to view?", ('Draftkings', 'Fanduel'), key='site_var')
270
+
271
+
272
+ tab1, tab2, tab3 = st.tabs(["Scoring Percentages", "Player ROO", "Optimals"])
273
+
274
+ roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo, dk_id_map, fd_id_map = init_baselines()
275
+ hold_display = roo_data
276
+
277
+ with tab1:
278
+ st.header("Scoring Percentages")
279
+ with st.expander("Info and Filters"):
280
+ with st.container():
281
+ slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Turbo Slate'), key='slate_var1')
282
+ own_var1 = st.radio("How would you like to display team ownership?", ('Sum', 'Average'), key='own_var1')
283
+
284
+ if site_var == 'Draftkings':
285
+ if slate_var1 == 'Main Slate':
286
+ scoring_percentages = scoring_percentages[scoring_percentages['DK Main Slate'] == 1]
287
+ elif slate_var1 == 'Secondary Slate':
288
+ scoring_percentages = scoring_percentages[scoring_percentages['DK Secondary Slate'] == 1]
289
+ elif slate_var1 == 'Turbo Slate':
290
+ scoring_percentages = scoring_percentages[scoring_percentages['DK Turbo Slate'] == 1]
291
+ elif site_var == 'Fanduel':
292
+ if slate_var1 == 'Main Slate':
293
+ scoring_percentages = scoring_percentages[scoring_percentages['FD Main Slate'] == 1]
294
+ elif slate_var1 == 'Secondary Slate':
295
+ scoring_percentages = scoring_percentages[scoring_percentages['FD Secondary Slate'] == 1]
296
+ elif slate_var1 == 'Turbo Slate':
297
+ scoring_percentages = scoring_percentages[scoring_percentages['FD Turbo Slate'] == 1]
298
+
299
+ dk_hitters_only = dk_roo[dk_roo['pos_group'] != 'Pitchers']
300
+ if slate_var1 == 'Main Slate':
301
+ dk_hitters_only = dk_hitters_only[dk_hitters_only['Slate'] == 'main_slate']
302
+ elif slate_var1 == 'Secondary Slate':
303
+ dk_hitters_only = dk_hitters_only[dk_hitters_only['Slate'] == 'secondary_slate']
304
+ elif slate_var1 == 'Turbo Slate':
305
+ dk_hitters_only = dk_hitters_only[dk_hitters_only['Slate'] == 'turbo_slate']
306
+ dk_hitters_only = dk_hitters_only.replace('CWS', 'CHW')
307
+ dk_team_ownership = dk_hitters_only.groupby('Team')['Own%'].sum().reset_index()
308
+ fd_hitters_only = fd_roo[fd_roo['pos_group'] != 'Pitchers']
309
+ if slate_var1 == 'Main Slate':
310
+ fd_hitters_only = fd_hitters_only[fd_hitters_only['Slate'] == 'main_slate']
311
+ elif slate_var1 == 'Secondary Slate':
312
+ fd_hitters_only = fd_hitters_only[fd_hitters_only['Slate'] == 'secondary_slate']
313
+ elif slate_var1 == 'Turbo Slate':
314
+ fd_hitters_only = fd_hitters_only[fd_hitters_only['Slate'] == 'turbo_slate']
315
+ fd_hitters_only = fd_hitters_only.replace('CWS', 'CHW')
316
+ fd_team_ownership = fd_hitters_only.groupby('Team')['Own%'].sum().reset_index()
317
+ scoring_percentages = scoring_percentages.merge(dk_team_ownership, left_on='Names', right_on='Team', how='left')
318
+ scoring_percentages.rename(columns={'Own%': 'DK Own%'}, inplace=True)
319
+ scoring_percentages.drop('Team', axis=1, inplace=True)
320
+ scoring_percentages = scoring_percentages.merge(fd_team_ownership, left_on='Names', right_on='Team', how='left')
321
+ scoring_percentages.rename(columns={'Own%': 'FD Own%'}, inplace=True)
322
+ scoring_percentages.drop('Team', axis=1, inplace=True)
323
+ if site_var == 'Draftkings':
324
+ if slate_var1 == 'Main Slate':
325
+ scoring_percentages['DK LevX'] = scoring_percentages['DK Main Top Score'].rank(pct=True).astype(float) - scoring_percentages['DK Own%'].rank(pct=True).astype(float)
326
+ scoring_percentages = scoring_percentages.rename(columns={'DK Main Top Score': 'Top Score'})
327
+ scoring_percentages = scoring_percentages.drop(['DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'FD Main Top Score', 'DK Secondary Top Score', 'FD Secondary Top Score', 'DK Turbo Top Score', 'FD Turbo Top Score'], axis=1)
328
+ elif slate_var1 == 'Secondary Slate':
329
+ scoring_percentages['DK LevX'] = scoring_percentages['DK Secondary Top Score'].rank(pct=True).astype(float) - scoring_percentages['DK Own%'].rank(pct=True).astype(float)
330
+ scoring_percentages = scoring_percentages.rename(columns={'DK Secondary Top Score': 'Top Score'})
331
+ scoring_percentages = scoring_percentages.drop(['DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'FD Main Top Score', 'DK Main Top Score', 'FD Secondary Top Score', 'DK Turbo Top Score', 'FD Turbo Top Score'], axis=1)
332
+ elif slate_var1 == 'Turbo Slate':
333
+ scoring_percentages['DK LevX'] = scoring_percentages['DK Turbo Top Score'].rank(pct=True).astype(float) - scoring_percentages['DK Own%'].rank(pct=True).astype(float)
334
+ scoring_percentages = scoring_percentages.rename(columns={'DK Turbo Top Score': 'Top Score'})
335
+ scoring_percentages = scoring_percentages.drop(['DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'FD Main Top Score', 'DK Main Top Score', 'FD Secondary Top Score', 'DK Secondary Top Score', 'FD Turbo Top Score'], axis=1)
336
+ elif site_var == 'Fanduel':
337
+ if slate_var1 == 'Main Slate':
338
+ scoring_percentages['FD LevX'] = scoring_percentages['FD Main Top Score'].rank(pct=True).astype(float) - scoring_percentages['FD Own%'].rank(pct=True).astype(float)
339
+ scoring_percentages = scoring_percentages.rename(columns={'FD Main Top Score': 'Top Score'})
340
+ scoring_percentages = scoring_percentages.drop(['DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'DK Main Top Score', 'DK Secondary Top Score', 'FD Secondary Top Score', 'DK Turbo Top Score', 'FD Turbo Top Score'], axis=1)
341
+ elif slate_var1 == 'Secondary Slate':
342
+ scoring_percentages['FD LevX'] = scoring_percentages['FD Secondary Top Score'].rank(pct=True).astype(float) - scoring_percentages['FD Own%'].rank(pct=True).astype(float)
343
+ scoring_percentages = scoring_percentages.rename(columns={'FD Secondary Top Score': 'Top Score'})
344
+ scoring_percentages = scoring_percentages.drop(['DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'FD Main Top Score', 'DK Main Top Score', 'DK Secondary Top Score', 'DK Turbo Top Score', 'FD Turbo Top Score'], axis=1)
345
+ elif slate_var1 == 'Turbo Slate':
346
+ scoring_percentages['FD LevX'] = scoring_percentages['FD Turbo Top Score'].rank(pct=True).astype(float) - scoring_percentages['FD Own%'].rank(pct=True).astype(float)
347
+ scoring_percentages = scoring_percentages.rename(columns={'FD Turbo Top Score': 'Top Score'})
348
+ scoring_percentages = scoring_percentages.drop(['DK Main Slate', 'DK Secondary Slate', 'DK Turbo Slate', 'FD Main Slate', 'FD Secondary Slate', 'FD Turbo Slate', 'FD Main Top Score', 'DK Main Top Score', 'FD Secondary Top Score', 'DK Secondary Top Score', 'DK Turbo Top Score'], axis=1)
349
+ scoring_percentages = scoring_percentages.sort_values(by='8+ runs', ascending=False)
350
+ if site_var == 'Draftkings':
351
+ scoring_percentages = scoring_percentages.rename(columns={'DK LevX': 'LevX', 'DK Own%': 'Own%', 'Avg Score': 'Runs', 'Win Percentage': 'Win%', '8+ runs': '8+ Runs'})
352
+ scoring_percentages = scoring_percentages.drop(['FD Own%'], axis=1)
353
+ elif site_var == 'Fanduel':
354
+ scoring_percentages = scoring_percentages.rename(columns={'FD LevX': 'LevX', 'FD Own%': 'Own%', 'Avg Score': 'Runs', 'Win Percentage': 'Win%', '8+ runs': '8+ Runs'})
355
+ scoring_percentages = scoring_percentages.drop(['DK Own%'], axis=1)
356
+
357
+ if view_var == "Simple":
358
+ scoring_percentages = scoring_percentages[['Names', 'Runs', '8+ Runs', 'Win%', 'LevX', 'Own%']]
359
+ scoring_percentages = scoring_percentages.set_index('Names', drop=True)
360
+ st.dataframe(scoring_percentages.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(game_format, precision=2), height=750, use_container_width = True)
361
+ elif view_var == "Advanced":
362
+ scoring_percentages = scoring_percentages.set_index('Names', drop=True)
363
+ st.dataframe(scoring_percentages.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(game_format, precision=2), height=750, use_container_width = True)
364
+
365
+ with tab2:
366
+ st.header("Player ROO")
367
+ with st.expander("Info and Filters"):
368
+ with st.container():
369
+ slate_type_var2 = st.radio("Which slate type are you loading?", ('Regular', 'Showdown'), key='slate_type_var2')
370
+ slate_var2 = st.radio("Which slate data are you loading?", ('Main', 'Secondary', 'Auxiliary'), key='slate_var2')
371
+ group_var2 = st.radio("Which position group would you like to view?", ('All', 'Pitchers', 'Hitters'), key='group_var2')
372
+ team_var2 = st.selectbox("Which team would you like to view?", ['All', 'Specific'], key='team_var2')
373
+ if team_var2 == 'Specific':
374
+ team_select2 = st.multiselect("Select your team(s)", roo_data['Team'].unique(), key='team_select2')
375
+ else:
376
+ team_select2 = None
377
+ pos_var2 = st.selectbox("Which position(s) would you like to view?", ['All', 'Specific'], key='pos_var2')
378
+ if pos_var2 == 'Specific':
379
+ pos_select2 = st.multiselect("Select your position(s)", roo_data['Position'].unique(), key='pos_select2')
380
+ else:
381
+ pos_select2 = None
382
+ if slate_type_var2 == 'Regular':
383
+ if site_var == 'Draftkings':
384
+
385
+ player_roo_raw = dk_roo.copy()
386
+
387
+ if group_var2 == 'All':
388
+ pass
389
+ elif group_var2 == 'Pitchers':
390
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Pitchers']
391
+ elif group_var2 == 'Hitters':
392
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Hitters']
393
+
394
+ elif site_var == 'Fanduel':
395
+
396
+ player_roo_raw = fd_roo.copy()
397
+
398
+ if group_var2 == 'All':
399
+ pass
400
+ elif group_var2 == 'Pitchers':
401
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Pitchers']
402
+ elif group_var2 == 'Hitters':
403
+ player_roo_raw = player_roo_raw[player_roo_raw['pos_group'] == 'Hitters']
404
+
405
+ if slate_var2 == 'Main':
406
+ player_roo_raw = player_roo_raw[player_roo_raw['Slate'] == 'main_slate']
407
+ elif slate_var2 == 'Secondary':
408
+ player_roo_raw = player_roo_raw[player_roo_raw['Slate'] == 'secondary_slate']
409
+ elif slate_var2 == 'Auxiliary':
410
+ player_roo_raw = player_roo_raw[player_roo_raw['Slate'] == 'turbo_slate']
411
+
412
+ elif slate_type_var2 == 'Showdown':
413
+ player_roo_raw = sd_roo_data.copy()
414
+ if site_var == 'Draftkings':
415
+ player_roo_raw['site'] = 'Draftkings'
416
+ elif site_var == 'Fanduel':
417
+ player_roo_raw['site'] = 'Fanduel'
418
+
419
+ if slate_var2 == 'Main':
420
+ player_roo_raw = player_roo_raw[player_roo_raw['slate'] == 'DK SD1']
421
+ elif slate_var2 == 'Secondary':
422
+ player_roo_raw = player_roo_raw[player_roo_raw['slate'] == 'DK SD2']
423
+ elif slate_var2 == 'Auxiliary':
424
+ player_roo_raw = player_roo_raw[player_roo_raw['slate'] == 'DK SD3']
425
+
426
+ if team_select2:
427
+ player_roo_raw = player_roo_raw[player_roo_raw['Team'].isin(team_select2)]
428
+ if pos_select2:
429
+ position_mask = player_roo_raw['Position'].apply(lambda x: any(pos in x for pos in pos_select2))
430
+ player_roo_raw = player_roo_raw[position_mask]
431
+
432
+ player_roo_disp = player_roo_raw
433
+
434
+ if slate_type_var2 == 'Regular':
435
+ player_roo_disp = player_roo_disp.drop(columns=['Site', 'Slate', 'pos_group', 'timestamp', 'player_ID'])
436
+ elif slate_type_var2 == 'Showdown':
437
+ player_roo_disp = player_roo_disp.drop(columns=['site', 'slate', 'version', 'timestamp'])
438
+
439
+ player_roo_disp = player_roo_disp.drop_duplicates(subset=['Player'])
440
+
441
+ if view_var == "Simple":
442
+ try:
443
+ player_roo_disp = player_roo_disp[['Player', 'Position', 'Team', 'Salary', 'Median', 'Ceiling', 'Own%']]
444
+ player_roo_disp = player_roo_disp.set_index('Player', drop=True)
445
+ 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)
446
+ except:
447
+ player_roo_disp = player_roo_disp.set_index('Player', drop=True)
448
+ 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)
449
+
450
+ elif view_var == "Advanced":
451
+ try:
452
+ player_roo_disp = player_roo_disp.set_index('Player', drop=True)
453
+ 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)
454
+ except:
455
+ player_roo_disp = player_roo_disp.set_index('Player', drop=True)
456
+ 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)
457
+
458
+ with tab3:
459
+ st.header("Optimals")
460
+ with st.expander("Info and Filters"):
461
+ col1, col2, col3 = st.columns(3)
462
+ with col1:
463
+ slate_type_var3 = st.radio("Which slate type are you loading?", ('Regular', 'Showdown'), key='slate_type_var3')
464
+ if slate_type_var3 == 'Regular':
465
+ raw_baselines = roo_data
466
+ elif slate_type_var3 == 'Showdown':
467
+ raw_baselines = sd_roo_data
468
+ slate_var3 = st.radio("Which slate data are you loading?", ('Main', 'Secondary', 'Auxiliary'), key='slate_var3')
469
+ if slate_type_var3 == 'Regular':
470
+ if site_var == 'Draftkings':
471
+ dk_lineups = init_DK_lineups(slate_type_var3, slate_var3)
472
+ elif site_var == 'Fanduel':
473
+ fd_lineups = init_FD_lineups(slate_type_var3, slate_var3)
474
+ elif slate_type_var3 == 'Showdown':
475
+ if site_var == 'Draftkings':
476
+ dk_lineups = init_DK_lineups(slate_type_var3, slate_var3)
477
+ elif site_var == 'Fanduel':
478
+ fd_lineups = init_FD_lineups(slate_type_var3, slate_var3)
479
+ with col2:
480
+ lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1)
481
+ player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1')
482
+ if player_var1 == 'Specific Players':
483
+ player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique())
484
+ elif player_var1 == 'Full Slate':
485
+ player_var2 = raw_baselines.Player.values.tolist()
486
+ with col3:
487
+ if site_var == 'Draftkings':
488
+ salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 50000, value = 49000, step = 100, key = 'salary_min_var')
489
+ salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 50000, value = 50000, step = 100, key = 'salary_max_var')
490
+ elif site_var == 'Fanduel':
491
+ salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 35000, value = 34000, step = 100, key = 'salary_min_var')
492
+ salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 35000, value = 35000, step = 100, key = 'salary_max_var')
493
+
494
+
495
+ if site_var == 'Draftkings':
496
+ if slate_type_var3 == 'Regular':
497
+ ROO_slice = raw_baselines[raw_baselines['Site'] == 'Draftkings']
498
+ player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
499
+ column_names = dk_columns
500
+ elif slate_type_var3 == 'Showdown':
501
+ player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
502
+ column_names = dk_sd_columns
503
+ # Get the minimum and maximum ownership values from dk_lineups
504
+ min_own = np.min(dk_lineups[:,12])
505
+ max_own = np.max(dk_lineups[:,12])
506
+
507
+
508
+ elif site_var == 'Fanduel':
509
+ raw_baselines = hold_display
510
+ if slate_type_var3 == 'Regular':
511
+ ROO_slice = raw_baselines[raw_baselines['Site'] == 'Fanduel']
512
+ player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary']))
513
+ column_names = fd_columns
514
+ elif slate_type_var3 == 'Showdown':
515
+ player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary']))
516
+ column_names = fd_sd_columns
517
+ # Get the minimum and maximum ownership values from dk_lineups
518
+ min_own = np.min(fd_lineups[:,11])
519
+ max_own = np.max(fd_lineups[:,11])
520
+
521
+ if st.button("Prepare full data export", key='data_export'):
522
+ name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
523
+ data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
524
+ if site_var == 'Draftkings':
525
+ if slate_type_var3 == 'Regular':
526
+ map_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
527
+ elif slate_type_var3 == 'Showdown':
528
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
529
+ for col_idx in map_columns:
530
+ data_export[col_idx] = data_export[col_idx].map(dk_id_map)
531
+ elif site_var == 'Fanduel':
532
+ if slate_type_var3 == 'Regular':
533
+ map_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
534
+ elif slate_type_var3 == 'Showdown':
535
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4']
536
+ for col_idx in map_columns:
537
+ data_export[col_idx] = data_export[col_idx].map(fd_id_map)
538
+ st.download_button(
539
+ label="Export optimals set (IDs)",
540
+ data=convert_df(data_export),
541
+ file_name='MLB_optimals_export.csv',
542
+ mime='text/csv',
543
+ )
544
+ st.download_button(
545
+ label="Export optimals set (Names)",
546
+ data=convert_df(name_export),
547
+ file_name='MLB_optimals_export.csv',
548
+ mime='text/csv',
549
+ )
550
+
551
+ if site_var == 'Draftkings':
552
+ if 'working_seed' in st.session_state:
553
+ st.session_state.working_seed = st.session_state.working_seed
554
+ if player_var1 == 'Specific Players':
555
+ 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)]
556
+ elif player_var1 == 'Full Slate':
557
+ st.session_state.working_seed = dk_lineups.copy()
558
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
559
+ elif 'working_seed' not in st.session_state:
560
+ st.session_state.working_seed = dk_lineups.copy()
561
+ st.session_state.working_seed = st.session_state.working_seed
562
+ if player_var1 == 'Specific Players':
563
+ 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)]
564
+ elif player_var1 == 'Full Slate':
565
+ st.session_state.working_seed = dk_lineups.copy()
566
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
567
+
568
+ elif site_var == 'Fanduel':
569
+ if 'working_seed' in st.session_state:
570
+ st.session_state.working_seed = st.session_state.working_seed
571
+ if player_var1 == 'Specific Players':
572
+ 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)]
573
+ elif player_var1 == 'Full Slate':
574
+ st.session_state.working_seed = fd_lineups.copy()
575
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
576
+ elif 'working_seed' not in st.session_state:
577
+ st.session_state.working_seed = fd_lineups.copy()
578
+ st.session_state.working_seed = st.session_state.working_seed
579
+ if player_var1 == 'Specific Players':
580
+ 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)]
581
+ elif player_var1 == 'Full Slate':
582
+ st.session_state.working_seed = fd_lineups.copy()
583
+ st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
584
+ st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] >= salary_min_var]
585
+ st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'] <= salary_max_var]
586
+ export_file = st.session_state.data_export_display.copy()
587
+ name_export = st.session_state.data_export_display.copy()
588
+ if site_var == 'Draftkings':
589
+ if slate_type_var3 == 'Regular':
590
+ map_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
591
+ elif slate_type_var3 == 'Showdown':
592
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']
593
+ for col_idx in map_columns:
594
+ export_file[col_idx] = export_file[col_idx].map(dk_id_map)
595
+ elif site_var == 'Fanduel':
596
+ if slate_type_var3 == 'Regular':
597
+ map_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
598
+ elif slate_type_var3 == 'Showdown':
599
+ map_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4']
600
+ for col_idx in map_columns:
601
+ export_file[col_idx] = export_file[col_idx].map(fd_id_map)
602
+
603
+ with st.container():
604
+ if st.button("Reset Optimals", key='reset3'):
605
+ for key in st.session_state.keys():
606
+ del st.session_state[key]
607
+ if site_var == 'Draftkings':
608
+ st.session_state.working_seed = dk_lineups.copy()
609
+ elif site_var == 'Fanduel':
610
+ st.session_state.working_seed = fd_lineups.copy()
611
+ if 'data_export_display' in st.session_state:
612
+ 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)
613
+ st.download_button(
614
+ label="Export display optimals (IDs)",
615
+ data=convert_df(export_file),
616
+ file_name='MLB_display_optimals.csv',
617
+ mime='text/csv',
618
+ )
619
+ st.download_button(
620
+ label="Export display optimals (Names)",
621
+ data=convert_df(name_export),
622
+ file_name='MLB_display_optimals.csv',
623
+ mime='text/csv',
624
+ )
625
+
626
+ with st.container():
627
+ if slate_type_var3 == 'Regular':
628
+ if 'working_seed' in st.session_state:
629
+ # Create a new dataframe with summary statistics
630
+ if site_var == 'Draftkings':
631
+ summary_df = pd.DataFrame({
632
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
633
+ 'Salary': [
634
+ np.min(st.session_state.working_seed[:,10]),
635
+ np.mean(st.session_state.working_seed[:,10]),
636
+ np.max(st.session_state.working_seed[:,10]),
637
+ np.std(st.session_state.working_seed[:,10])
638
+ ],
639
+ 'Proj': [
640
+ np.min(st.session_state.working_seed[:,11]),
641
+ np.mean(st.session_state.working_seed[:,11]),
642
+ np.max(st.session_state.working_seed[:,11]),
643
+ np.std(st.session_state.working_seed[:,11])
644
+ ],
645
+ 'Own': [
646
+ np.min(st.session_state.working_seed[:,16]),
647
+ np.mean(st.session_state.working_seed[:,16]),
648
+ np.max(st.session_state.working_seed[:,16]),
649
+ np.std(st.session_state.working_seed[:,16])
650
+ ]
651
+ })
652
+ elif site_var == 'Fanduel':
653
+ summary_df = pd.DataFrame({
654
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
655
+ 'Salary': [
656
+ np.min(st.session_state.working_seed[:,9]),
657
+ np.mean(st.session_state.working_seed[:,9]),
658
+ np.max(st.session_state.working_seed[:,9]),
659
+ np.std(st.session_state.working_seed[:,9])
660
+ ],
661
+ 'Proj': [
662
+ np.min(st.session_state.working_seed[:,10]),
663
+ np.mean(st.session_state.working_seed[:,10]),
664
+ np.max(st.session_state.working_seed[:,10]),
665
+ np.std(st.session_state.working_seed[:,10])
666
+ ],
667
+ 'Own': [
668
+ np.min(st.session_state.working_seed[:,15]),
669
+ np.mean(st.session_state.working_seed[:,15]),
670
+ np.max(st.session_state.working_seed[:,15]),
671
+ np.std(st.session_state.working_seed[:,15])
672
+ ]
673
+ })
674
+
675
+ # Set the index of the summary dataframe as the "Metric" column
676
+ summary_df = summary_df.set_index('Metric')
677
+
678
+ # Display the summary dataframe
679
+ st.subheader("Optimal Statistics")
680
+ st.dataframe(summary_df.style.format({
681
+ 'Salary': '{:.2f}',
682
+ 'Proj': '{:.2f}',
683
+ 'Own': '{:.2f}'
684
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True)
685
+
686
+ with st.container():
687
+ tab1, tab2 = st.tabs(["Display Frequency", "Seed Frame Frequency"])
688
+ with tab1:
689
+ if 'data_export_display' in st.session_state:
690
+ if site_var == 'Draftkings':
691
+ if slate_type_var3 == 'Regular':
692
+ player_columns = st.session_state.data_export_display.iloc[:, :10]
693
+ elif slate_type_var3 == 'Showdown':
694
+ player_columns = st.session_state.data_export_display.iloc[:, :6]
695
+ elif site_var == 'Fanduel':
696
+ if slate_type_var3 == 'Regular':
697
+ player_columns = st.session_state.data_export_display.iloc[:, :9]
698
+ elif slate_type_var3 == 'Showdown':
699
+ player_columns = st.session_state.data_export_display.iloc[:, :5]
700
+
701
+ # Flatten the DataFrame and count unique values
702
+ value_counts = player_columns.values.flatten().tolist()
703
+ value_counts = pd.Series(value_counts).value_counts()
704
+
705
+ percentages = (value_counts / lineup_num_var * 100).round(2)
706
+
707
+ # Create a DataFrame with the results
708
+ summary_df = pd.DataFrame({
709
+ 'Player': value_counts.index,
710
+ 'Frequency': value_counts.values,
711
+ 'Percentage': percentages.values
712
+ })
713
+
714
+ # Sort by frequency in descending order
715
+ summary_df['Salary'] = summary_df['Player'].map(player_salaries)
716
+ summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
717
+ summary_df = summary_df.sort_values('Frequency', ascending=False)
718
+ summary_df = summary_df.set_index('Player')
719
+
720
+ # Display the table
721
+ st.write("Player Frequency Table:")
722
+ st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
723
+
724
+ st.download_button(
725
+ label="Export player frequency",
726
+ data=convert_df_to_csv(summary_df),
727
+ file_name='MLB_player_frequency.csv',
728
+ mime='text/csv',
729
+ )
730
+ with tab2:
731
+ if 'working_seed' in st.session_state:
732
+ if site_var == 'Draftkings':
733
+ if slate_type_var3 == 'Regular':
734
+ player_columns = st.session_state.working_seed[:, :10]
735
+ elif slate_type_var3 == 'Showdown':
736
+ player_columns = st.session_state.working_seed[:, :7]
737
+ elif site_var == 'Fanduel':
738
+ if slate_type_var3 == 'Regular':
739
+ player_columns = st.session_state.working_seed[:, :9]
740
+ elif slate_type_var3 == 'Showdown':
741
+ player_columns = st.session_state.working_seed[:, :6]
742
+
743
+ # Flatten the DataFrame and count unique values
744
+ value_counts = player_columns.flatten().tolist()
745
+ value_counts = pd.Series(value_counts).value_counts()
746
+
747
+ percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
748
+ # Create a DataFrame with the results
749
+ summary_df = pd.DataFrame({
750
+ 'Player': value_counts.index,
751
+ 'Frequency': value_counts.values,
752
+ 'Percentage': percentages.values
753
+ })
754
+
755
+ # Sort by frequency in descending order
756
+ summary_df['Salary'] = summary_df['Player'].map(player_salaries)
757
+ summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
758
+ summary_df = summary_df.sort_values('Frequency', ascending=False)
759
+ summary_df = summary_df.set_index('Player')
760
+
761
+ # Display the table
762
+ st.write("Seed Frame Frequency Table:")
763
+ st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
764
+
765
+ st.download_button(
766
+ label="Export seed frame frequency",
767
+ data=convert_df_to_csv(summary_df),
768
+ file_name='MLB_seed_frame_frequency.csv',
769
+ mime='text/csv',
770
+ )
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,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ gspread
3
+ openpyxl
4
+ matplotlib
5
+ pulp
6
+ docker
7
+ plotly
8
+ scipy
9
+ pymongo