James McCool commited on
Commit
a671bf1
·
1 Parent(s): 5fce647

Initial commit for v2 of Streamlit app.

Browse files
Files changed (4) hide show
  1. .streamlit/secrets.toml +1 -0
  2. Dockerfile +12 -0
  3. src/database.py +24 -0
  4. src/streamlit_app.py +344 -36
.streamlit/secrets.toml ADDED
@@ -0,0 +1 @@
 
 
1
+ master_hold = 'https://docs.google.com/spreadsheets/d/1D526UlXmrz-8qxVcUKrA-u7f6FftUiBufxDnzQv980k/edit#gid=791804525'
Dockerfile CHANGED
@@ -5,11 +5,23 @@ WORKDIR /app
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
 
8
  git \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
  COPY requirements.txt ./
12
  COPY src/ ./src/
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  RUN pip3 install -r requirements.txt
15
 
 
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
8
+ software-properties-common \
9
  git \
10
  && rm -rf /var/lib/apt/lists/*
11
 
12
  COPY requirements.txt ./
13
  COPY src/ ./src/
14
+ COPY .streamlit/ ./.streamlit/
15
+
16
+ ENV MONGO_URI="mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
17
+ ENV MASTER_HOLD="https://docs.google.com/spreadsheets/d/1D526UlXmrz-8qxVcUKrA-u7f6FftUiBufxDnzQv980k/edit#gid=791804525"
18
+ RUN useradd -m -u 1000 user
19
+ USER user
20
+ ENV HOME=/home/user\
21
+ PATH=/home/user/.local/bin:$PATH
22
+ WORKDIR $HOME/app
23
+ RUN pip install --no-cache-dir --upgrade pip
24
+ COPY --chown=user . $HOME/app
25
 
26
  RUN pip3 install -r requirements.txt
27
 
src/database.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import gspread
3
+
4
+ @st.cache_resource
5
+ def init_conn():
6
+ scope = ['https://www.googleapis.com/auth/spreadsheets',
7
+ "https://www.googleapis.com/auth/drive"]
8
+
9
+ credentials = {
10
+ "type": "service_account",
11
+ "project_id": "model-sheets-connect",
12
+ "private_key_id": "0e0bc2fdef04e771172fe5807392b9d6639d945e",
13
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDiu1v/e6KBKOcK\ncx0KQ23nZK3ZVvADYy8u/RUn/EDI82QKxTd/DizRLIV81JiNQxDJXSzgkbwKYEDm\n48E8zGvupU8+Nk76xNPakrQKy2Y8+VJlq5psBtGchJTuUSHcXU5Mg2JhQsB376PJ\nsCw552K6Pw8fpeMDJDZuxpKSkaJR6k9G5Dhf5q8HDXnC5Rh/PRFuKJ2GGRpX7n+2\nhT/sCax0J8jfdTy/MDGiDfJqfQrOPrMKELtsGHR9Iv6F4vKiDqXpKfqH+02E9ptz\nBk+MNcbZ3m90M8ShfRu28ebebsASfarNMzc3dk7tb3utHOGXKCf4tF8yYKo7x8BZ\noO9X4gSfAgMBAAECggEAU8ByyMpSKlTCF32TJhXnVJi/kS+IhC/Qn5JUDMuk4LXr\naAEWsWO6kV/ZRVXArjmuSzuUVrXumISapM9Ps5Ytbl95CJmGDiLDwRL815nvv6k3\nUyAS8EGKjz74RpoIoH6E7EWCAzxlnUgTn+5oP9Flije97epYk3H+e2f1f5e1Nn1d\nYNe8U+1HqJgILcxA1TAUsARBfoD7+K3z/8DVPHI8IpzAh6kTHqhqC23Rram4XoQ6\nzj/ZdVBjvnKuazETfsD+Vl3jGLQA8cKQVV70xdz3xwLcNeHsbPbpGBpZUoF73c65\nkAXOrjYl0JD5yAk+hmYhXr6H9c6z5AieuZGDrhmlFQKBgQDzV6LRXmjn4854DP/J\nI82oX2GcI4eioDZPRukhiQLzYerMQBmyqZIRC+/LTCAhYQSjNgMa+ZKyvLqv48M0\n/x398op/+n3xTs+8L49SPI48/iV+mnH7k0WI/ycd4OOKh8rrmhl/0EWb9iitwJYe\nMjTV/QxNEpPBEXfR1/mvrN/lVQKBgQDuhomOxUhWVRVH6x03slmyRBn0Oiw4MW+r\nrt1hlNgtVmTc5Mu+4G0USMZwYuOB7F8xG4Foc7rIlwS7Ic83jMJxemtqAelwOLdV\nXRLrLWJfX8+O1z/UE15l2q3SUEnQ4esPHbQnZowHLm0mdL14qSVMl1mu1XfsoZ3z\nJZTQb48CIwKBgEWbzQRtKD8lKDupJEYqSrseRbK/ax43DDITS77/DWwHl33D3FYC\nMblUm8ygwxQpR4VUfwDpYXBlklWcJovzamXpSnsfcYVkkQH47NuOXPXPkXQsw+w+\nDYcJzeu7F/vZqk9I7oBkWHUrrik9zPNoUzrfPvSRGtkAoTDSwibhoc5dAoGBAMHE\nK0T/ANeZQLNuzQps6S7G4eqjwz5W8qeeYxsdZkvWThOgDd/ewt3ijMnJm5X05hOn\ni4XF1euTuvUl7wbqYx76Wv3/1ZojiNNgy7ie4rYlyB/6vlBS97F4ZxJdxMlabbCW\n6b3EMWa4EVVXKoA1sCY7IVDE+yoQ1JYsZmq45YzPAoGBANWWHuVueFGZRDZlkNlK\nh5OmySmA0NdNug3G1upaTthyaTZ+CxGliwBqMHAwpkIRPwxUJpUwBTSEGztGTAxs\nWsUOVWlD2/1JaKSmHE8JbNg6sxLilcG6WEDzxjC5dLL1OrGOXj9WhC9KX3sq6qb6\nF/j9eUXfXjAlb042MphoF3ZC\n-----END PRIVATE KEY-----\n",
14
+ "client_email": "gspread-connection@model-sheets-connect.iam.gserviceaccount.com",
15
+ "client_id": "100369174533302798535",
16
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
17
+ "token_uri": "https://oauth2.googleapis.com/token",
18
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
19
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40model-sheets-connect.iam.gserviceaccount.com"
20
+ }
21
+
22
+ gc_con = gspread.service_account_from_dict(credentials)
23
+
24
+ return gc_con
src/streamlit_app.py CHANGED
@@ -1,40 +1,348 @@
1
- import altair as alt
 
 
 
 
 
 
2
  import numpy as np
3
  import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
1
+ import streamlit as st
2
+ st.set_page_config(layout="wide")
3
+
4
+ for name in dir():
5
+ if not name.startswith('_'):
6
+ del globals()[name]
7
+
8
  import numpy as np
9
  import pandas as pd
10
  import streamlit as st
11
+ import os
12
+ from database import init_conn
13
+
14
+ gcservice_account = init_conn()
15
+
16
+ master_hold = os.getenv('MASTER_HOLD')
17
+
18
+ sim_format = {'Top_finish': '{:.2%}', 'Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}'}
19
+
20
+ st.markdown("""
21
+ <style>
22
+ /* Tab styling */
23
+ .stElementContainer [data-baseweb="button-group"] {
24
+ gap: 2.000rem;
25
+ padding: 4px;
26
+ }
27
+ .stElementContainer [kind="segmented_control"] {
28
+ height: 2.000rem;
29
+ white-space: pre-wrap;
30
+ background-color: #DAA520;
31
+ color: white;
32
+ border-radius: 20px;
33
+ gap: 1px;
34
+ padding: 10px 20px;
35
+ font-weight: bold;
36
+ transition: all 0.3s ease;
37
+ }
38
+ .stElementContainer [kind="segmented_controlActive"] {
39
+ height: 3.000rem;
40
+ background-color: #DAA520;
41
+ border: 3px solid #FFD700;
42
+ border-radius: 10px;
43
+ color: black;
44
+ }
45
+ .stElementContainer [kind="segmented_control"]:hover {
46
+ background-color: #FFD700;
47
+ cursor: pointer;
48
+ }
49
+
50
+ div[data-baseweb="select"] > div {
51
+ background-color: #DAA520;
52
+ color: white;
53
+ }
54
+
55
+ </style>""", unsafe_allow_html=True)
56
+
57
+ @st.cache_resource(ttl = 600)
58
+ def init_baselines():
59
+ sh = gcservice_account.open_by_url(master_hold)
60
+ worksheet = sh.worksheet('Pitcher_Proj')
61
+ raw_display = pd.DataFrame(worksheet.get_all_records())
62
+ raw_display.replace("", np.nan, inplace=True)
63
+ pitcher_proj = raw_display.dropna()
64
+
65
+ sh = gcservice_account.open_by_url(master_hold)
66
+ worksheet = sh.worksheet('Hitter_Proj')
67
+ raw_display = pd.DataFrame(worksheet.get_all_records())
68
+ raw_display.replace("", np.nan, inplace=True)
69
+ hitter_proj = raw_display.dropna()
70
+
71
+ sh = gcservice_account.open_by_url(master_hold)
72
+ worksheet = sh.worksheet('Display')
73
+ raw_display = pd.DataFrame(worksheet.get_all_records())
74
+ wins_proj = raw_display.dropna()
75
+
76
+ return pitcher_proj, hitter_proj, wins_proj
77
+
78
+ def convert_df_to_csv(df):
79
+ return df.to_csv().encode('utf-8')
80
+
81
+ pitcher_proj, hitter_proj, wins_proj = init_baselines()
82
+ total_teams = pitcher_proj['Team'].values.tolist()
83
+
84
+ selected_tab = st.segmented_control(
85
+ "Select Tab",
86
+ options=["Team Win Projections", "Pitcher Projections", "Hitter Projections", "Pitcher Simulations", "Hitter Simulations"],
87
+ selection_mode='single',
88
+ default='Team Win Projections',
89
+ width='stretch',
90
+ label_visibility='collapsed',
91
+ key='tab_selector'
92
+ )
93
+
94
+ if selected_tab == 'Team Win Projections':
95
+ if st.button("Reset Data", key='reset1'):
96
+ st.cache_data.clear()
97
+ pitcher_proj, hitter_proj, wins_proj = init_baselines()
98
+ total_teams = pitcher_proj['Team'].values.tolist()
99
+ raw_frame = wins_proj.copy()
100
+ export_frame_team = raw_frame[['Team', '2B', 'HR', 'SB', 'P_SO', 'P_H', 'P_R', 'P_HR', 'P_BB', 'LY Added', 'Added', 'LY Adj Wins', 'Adj Wins', 'Vegas', 'Proj wins', 'Diff']]
101
+ export_frame_team = export_frame_team.sort_values(by='Proj wins', ascending=False)
102
+ disp_frame = raw_frame[['Team', '2B', 'HR', 'SB', 'P_SO', 'P_H', 'P_R', 'P_HR', 'P_BB', 'LY Added', 'Added', 'LY Adj Wins', 'Adj Wins', 'Vegas', 'Proj wins', 'Diff']]
103
+ disp_frame = disp_frame.sort_values(by='Proj wins', ascending=False)
104
+
105
+ st.dataframe(disp_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True)
106
+
107
+ st.download_button(
108
+ label="Export Team Win Projections",
109
+ data=convert_df_to_csv(export_frame_team),
110
+ file_name='MLB_team_win_export.csv',
111
+ mime='text/csv',
112
+ key='team_win_export',
113
+ )
114
+
115
+ elif selected_tab == 'Pitcher Projections':
116
+ if st.button("Reset Data", key='reset2'):
117
+ st.cache_data.clear()
118
+ pitcher_proj, hitter_proj, wins_proj = init_baselines()
119
+ total_teams = pitcher_proj['Team'].values.tolist()
120
+ raw_frame = pitcher_proj.copy()
121
+ split_var1 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var1')
122
+ if split_var1 == 'Specific Teams':
123
+ team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = total_teams, key='team_var1')
124
+ elif split_var1 == 'All':
125
+ team_var1 = total_teams
126
+
127
+ working_data = raw_frame[raw_frame['Team'].isin(team_var1)]
128
+ export_frame_sp = raw_frame[['Name', 'Team', 'TBF', 'Ceiling_var', 'True_AVG', 'Hits', 'Singles%', 'Singles', 'Doubles%', 'Doubles', 'xHR%', 'Homeruns', 'Strikeout%', 'Strikeouts',
129
+ 'Walk%', 'Walks', 'Runs%', 'Runs', 'ERA', 'Wins', 'Quality_starts', 'ADP', 'UD_fpts', 'DK_fpts']]
130
+ disp_frame_sp = working_data[['Name', 'Team', 'TBF', 'True_AVG', 'Hits', 'Singles', 'Doubles', 'Homeruns', 'Strikeouts',
131
+ 'Walks', 'Runs', 'ERA', 'Wins', 'Quality_starts', 'ADP', 'UD_fpts', 'DK_fpts']]
132
+ disp_frame_sp = disp_frame_sp.sort_values(by='UD_fpts', ascending=False)
133
+ st.dataframe(disp_frame_sp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn_r').background_gradient(cmap='RdYlGn', subset=['TBF', 'Strikeouts', 'Wins', 'Quality_starts', 'UD_fpts', 'DK_fpts']).format(precision=2), height = 1000, use_container_width = True)
134
+
135
+ st.download_button(
136
+ label="Export Pitcher Projections",
137
+ data=convert_df_to_csv(export_frame_sp),
138
+ file_name='MLB_pitcher_proj_export.csv',
139
+ mime='text/csv',
140
+ key='pitcher_proj_export',
141
+ )
142
+
143
+ elif selected_tab == 'Hitter Projections':
144
+ if st.button("Reset Data", key='reset3'):
145
+ st.cache_data.clear()
146
+ pitcher_proj, hitter_proj, wins_proj = init_baselines()
147
+ total_teams = pitcher_proj['Team'].values.tolist()
148
+ raw_frame = hitter_proj.copy()
149
+ split_var2 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var2')
150
+ if split_var2 == 'Specific Teams':
151
+ team_var2 = st.multiselect('Which teams would you like to include in the tables?', options = total_teams, key='team_var2')
152
+ elif split_var2 == 'All':
153
+ team_var2 = total_teams
154
+
155
+ working_data = raw_frame[raw_frame['Team'].isin(team_var2)]
156
+ export_frame_h = raw_frame[['Name', 'Team', 'PA', 'Ceiling_var', 'Walk%', 'Walks', 'xHits', 'Singles%', 'Singles', 'Doubles%', 'Doubles',
157
+ 'xHR%', 'Homeruns', 'Runs%', 'Runs', 'RBI%', 'RBI', 'Steal%', 'Stolen_bases', 'ADP', 'UD_fpts', 'DK_fpts']]
158
+ disp_frame_h = working_data[['Name', 'Team', 'PA', 'Walks', 'xHits', 'Singles', 'Doubles',
159
+ 'Homeruns', 'Runs', 'RBI', 'Stolen_bases', 'ADP', 'UD_fpts', 'DK_fpts']]
160
+ disp_frame_h = disp_frame_h.sort_values(by='UD_fpts', ascending=False)
161
+ st.dataframe(disp_frame_h.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['ADP']).format(precision=2), height = 1000, use_container_width = True)
162
+
163
+ st.download_button(
164
+ label="Export Hitter Projections",
165
+ data=convert_df_to_csv(export_frame_h),
166
+ file_name='MLB_hitter_proj_export.csv',
167
+ mime='text/csv',
168
+ key='hitter_proj_export',
169
+ )
170
+
171
+ elif selected_tab == 'Pitcher Simulations':
172
+ if st.button("Reset Data", key='reset4'):
173
+ st.cache_data.clear()
174
+ pitcher_proj, hitter_proj, wins_proj = init_baselines()
175
+ total_teams = pitcher_proj['Team'].values.tolist()
176
+ col1, col2 = st.columns([1, 5])
177
+
178
+ with col2:
179
+ df_hold_container = st.empty()
180
+
181
+ with col1:
182
+ prop_type_var_sp = st.selectbox('Select type of prop to simulate', options = ['Strikeouts', 'Wins', 'Quality_starts'], key='prop_type_var_sp')
183
+
184
+ if st.button('Simulate Stat', key='sim_sp'):
185
+ with col2:
186
+
187
+ with df_hold_container.container():
188
+
189
+ df = pitcher_proj.copy()
190
+
191
+ total_sims = 5000
192
+
193
+ df.replace("", 0, inplace=True)
194
+
195
+ if prop_type_var_sp == 'Strikeouts':
196
+ df['Median'] = df['Strikeouts']
197
+ stat_cap = 300
198
+ elif prop_type_var_sp == 'Wins':
199
+ df['Median'] = df['Wins']
200
+ stat_cap = 25
201
+ elif prop_type_var_sp == 'Quality_starts':
202
+ df['Median'] = df['Quality_starts']
203
+ stat_cap = 30
204
+
205
+ flex_file = df.copy()
206
+ flex_file.rename(columns={"Name": "Player"}, inplace = True)
207
+ flex_file['Floor'] = (flex_file['Median'] * .25)
208
+ flex_file['Ceiling'] = np.where((flex_file['Median'] + (flex_file['Median'] * flex_file['Ceiling_var'])) > stat_cap, stat_cap + (flex_file['Median']/10), (flex_file['Median'] + (flex_file['Median'] * flex_file['Ceiling_var'])))
209
+ flex_file['STD'] = (flex_file['Median']/3)
210
+ flex_file = flex_file[['Player', 'Floor', 'Median', 'Ceiling', 'STD']]
211
+
212
+ hold_file = flex_file.copy()
213
+ hold_file = hold_file.sort_values(by='Median', ascending=False)
214
+ overall_file = flex_file.copy()
215
+ overall_file = overall_file.sort_values(by='Median', ascending=False)
216
+
217
+ overall_players = overall_file[['Player']]
218
+
219
+ for x in range(0,total_sims):
220
+ overall_file['g'] = np.random.gumbel(overall_file['Median'] * .75,overall_file['STD'])
221
+ overall_file[x] = np.where((overall_file['g']<=overall_file['Ceiling']),overall_file['g'],overall_file['Ceiling'])
222
+
223
+ check_file = overall_file.copy()
224
+ overall_file=overall_file.drop(['Player', 'Floor', 'Median', 'Ceiling', 'STD', 'g'], axis=1)
225
+ overall_file.astype('int').dtypes
226
+
227
+ players_only = hold_file[['Player']]
228
+ raw_lineups_file = players_only.copy()
229
+
230
+ for x in range(0,total_sims):
231
+ maps_dict = {'proj_map':dict(zip(hold_file.Player,overall_file[x]))}
232
+ raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
233
+ players_only[x] = raw_lineups_file[x].rank(ascending=False)
234
+
235
+ players_only=players_only.drop(['Player'], axis=1)
236
+ players_only.astype('int').dtypes
237
+
238
+ players_only['Average_Rank'] = players_only.mean(axis=1)
239
+ players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
240
+ players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
241
+ players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
242
+ players_only['10%'] = overall_file.quantile(0.1, axis=1)
243
+ players_only['90%'] = overall_file.quantile(0.9, axis=1)
244
+
245
+ players_only['Player'] = hold_file[['Player']]
246
+
247
+ final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '10%', '90%']]
248
+
249
+ final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
250
+ final_Proj = final_Proj[['Player', '10%', 'Median', '90%', 'Top_finish', 'Top_5_finish', 'Top_10_finish']]
251
+ final_Proj.rename(columns={"Median": "Projection"}, inplace = True)
252
+
253
+ with df_hold_container.container():
254
+ df_hold_container = st.empty()
255
+ st.dataframe(final_Proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(sim_format, precision=2), use_container_width = True)
256
+
257
+ elif selected_tab == 'Hitter Simulations':
258
+ if st.button("Reset Data", key='reset5'):
259
+ st.cache_data.clear()
260
+ pitcher_proj, hitter_proj, wins_proj = init_baselines()
261
+ total_teams = pitcher_proj['Team'].values.tolist()
262
+ col1, col2 = st.columns([1, 5])
263
+
264
+ with col2:
265
+ df_hold_container = st.empty()
266
+
267
+ with col1:
268
+ prop_type_var_h = st.selectbox('Select type of prop to simulate', options = ['Hits', 'Doubles', 'Home Runs', 'RBI', 'Stolen Bases'], key='prop_type_var_h')
269
+
270
+
271
+ if st.button('Simulate Stat', key='sim_h'):
272
+ with col2:
273
+
274
+ with df_hold_container.container():
275
+
276
+ df = hitter_proj.copy()
277
+
278
+ total_sims = 5000
279
+
280
+ df.replace("", 0, inplace=True)
281
+
282
+ if prop_type_var_h == 'Hits':
283
+ df['Median'] = df['xHits']
284
+ stat_cap = 250
285
+ elif prop_type_var_h == 'Doubles':
286
+ df['Median'] = df['Doubles']
287
+ stat_cap = 65
288
+ elif prop_type_var_h == 'Home Runs':
289
+ df['Median'] = df['Homeruns']
290
+ stat_cap = 75
291
+ elif prop_type_var_h == 'RBI':
292
+ df['Median'] = df['RBI']
293
+ stat_cap = 150
294
+ elif prop_type_var_h == 'Stolen Bases':
295
+ df['Median'] = df['Stolen_bases']
296
+ stat_cap = 80
297
+
298
+ flex_file = df.copy()
299
+ flex_file.rename(columns={"Name": "Player"}, inplace = True)
300
+ flex_file['Floor'] = (flex_file['Median'] * .15)
301
+ flex_file['Ceiling'] = np.where((flex_file['Median'] + (flex_file['Median'] * flex_file['Ceiling_var'])) > stat_cap, stat_cap + (flex_file['Median']/20), (flex_file['Median'] + (flex_file['Median'] * flex_file['Ceiling_var'])))
302
+ flex_file['STD'] = (flex_file['Median']/2)
303
+ flex_file = flex_file[['Player', 'Floor', 'Median', 'Ceiling', 'STD']]
304
+
305
+ hold_file = flex_file.copy()
306
+ hold_file = hold_file.sort_values(by='Median', ascending=False)
307
+ overall_file = flex_file.copy()
308
+ overall_file = overall_file.sort_values(by='Median', ascending=False)
309
+
310
+ overall_players = overall_file[['Player']]
311
+
312
+ for x in range(0,total_sims):
313
+ overall_file['g'] = np.random.gumbel(overall_file['Median'] * .5,overall_file['STD'])
314
+ overall_file[x] = np.where((overall_file['g']<=overall_file['Ceiling']),overall_file['g'],overall_file['Ceiling'])
315
+
316
+ check_file = overall_file.copy()
317
+ overall_file=overall_file.drop(['Player', 'Floor', 'Median', 'Ceiling', 'STD', 'g'], axis=1)
318
+ overall_file.astype('int').dtypes
319
+
320
+ players_only = hold_file[['Player']]
321
+ raw_lineups_file = players_only.copy()
322
+
323
+ for x in range(0,total_sims):
324
+ maps_dict = {'proj_map':dict(zip(hold_file.Player,overall_file[x]))}
325
+ raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
326
+ players_only[x] = raw_lineups_file[x].rank(ascending=False)
327
+
328
+ players_only=players_only.drop(['Player'], axis=1)
329
+ players_only.astype('int').dtypes
330
+
331
+ players_only['Average_Rank'] = players_only.mean(axis=1)
332
+ players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
333
+ players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
334
+ players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
335
+ players_only['10%'] = overall_file.quantile(0.1, axis=1)
336
+ players_only['90%'] = overall_file.quantile(0.9, axis=1)
337
+
338
+ players_only['Player'] = hold_file[['Player']]
339
+
340
+ final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '10%', '90%']]
341
+
342
+ final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
343
+ final_Proj = final_Proj[['Player', '10%', 'Median', '90%', 'Top_finish', 'Top_5_finish', 'Top_10_finish']]
344
+ final_Proj.rename(columns={"Median": "Projection"}, inplace = True)
345
 
346
+ with df_hold_container.container():
347
+ df_hold_container = st.empty()
348
+ st.dataframe(final_Proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(sim_format, precision=2), use_container_width = True)