File size: 11,974 Bytes
995f524
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84bb751
1679146
 
84bb751
995f524
 
 
88eb52f
 
 
 
 
 
 
 
 
995f524
 
 
 
 
6417509
 
995f524
 
 
 
 
 
 
 
 
6417509
 
995f524
 
 
 
 
 
 
 
 
6417509
 
995f524
 
 
 
 
 
 
 
 
6417509
 
995f524
 
 
 
 
 
 
 
 
6417509
 
995f524
 
 
 
 
f1e043a
995f524
a027402
ee14527
56aba80
a027402
ee14527
f1e043a
ee14527
88aa4bf
 
 
995f524
88aa4bf
995f524
 
 
 
88aa4bf
 
995f524
c6144e0
ead9687
5579016
ead9687
 
88aa4bf
88eb52f
 
 
f1aa9c2
 
 
 
 
 
 
 
 
 
88eb52f
 
 
 
 
 
 
 
 
 
 
ead9687
88eb52f
 
 
 
f1e043a
ee14527
f1aa9c2
 
88eb52f
 
 
 
 
 
 
84bb751
ead9687
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import streamlit as st
st.set_page_config(layout="wide")

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

import numpy as np
import pandas as pd
import streamlit as st
import gspread
import gc

@st.cache_resource
def init_conn():
        scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']

        credentials = {
          "type": "service_account",
          "project_id": "model-sheets-connect",
          "private_key_id": "0e0bc2fdef04e771172fe5807392b9d6639d945e",
          "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",
          "client_email": "gspread-connection@model-sheets-connect.iam.gserviceaccount.com",
          "client_id": "100369174533302798535",
          "auth_uri": "https://accounts.google.com/o/oauth2/auth",
          "token_uri": "https://oauth2.googleapis.com/token",
          "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
          "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40model-sheets-connect.iam.gserviceaccount.com"
        }

        gc_con = gspread.service_account_from_dict(credentials, scope)
      
        return gc_con

gcservice_account = init_conn()

DEM_data = 'https://docs.google.com/spreadsheets/d/1Yq0vGriWK-bS79e-bD6_u9pqrYE6Yrlbb_wEkmH-ot0/edit#gid=1808117109'

percentages_format = {'Pts% Boost': '{:.2%}', 'Reb% Boost': '{:.2%}', 'Ast% Boost': '{:.2%}', '3p% Boost': '{:.2%}',
                      'Stl Boost%': '{:.2%}', 'Blk Boost%': '{:.2%}', 'TOV Boost%': '{:.2%}', 'FPPM Boost': '{:.2%}',
                      'Team FPPM Boost': '{:.2%}'}

@st.cache_resource(ttl = 600)
def init_baselines():
    sh = gcservice_account.open_by_url(DEM_data)
    
    worksheet = sh.worksheet('DEM Matchups')
    raw_display = pd.DataFrame(worksheet.get_values())
    raw_display.columns = raw_display.iloc[0]
    raw_display = raw_display[1:]
    raw_display = raw_display.reset_index(drop=True)
    matchups = raw_display[raw_display['Var'] != ""]
    matchups_dict = dict(zip(matchups['Team'], matchups['Opp']))
    
    worksheet = sh.worksheet('PG_DEM_Calc')
    raw_display = pd.DataFrame(worksheet.get_values())
    raw_display.columns = raw_display.iloc[0]
    raw_display = raw_display[1:]
    raw_display = raw_display.reset_index(drop=True)
    cols_to_check = ['Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost', 'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM Boost']
    raw_display.loc[:, cols_to_check] = raw_display.loc[:, cols_to_check].replace({'%': ''}, regex=True).astype(float) / 100
    raw_display = raw_display.apply(pd.to_numeric, errors='coerce').fillna(raw_display)
    raw_display['position'] = 'Point Guard'
    pg_dem = raw_display[raw_display['Acro'] != ""]

    worksheet = sh.worksheet('SG_DEM_Calc')
    raw_display = pd.DataFrame(worksheet.get_values())
    raw_display.columns = raw_display.iloc[0]
    raw_display = raw_display[1:]
    raw_display = raw_display.reset_index(drop=True)
    cols_to_check = ['Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost', 'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM Boost']
    raw_display.loc[:, cols_to_check] = raw_display.loc[:, cols_to_check].replace({'%': ''}, regex=True).astype(float) / 100
    raw_display = raw_display.apply(pd.to_numeric, errors='coerce').fillna(raw_display)
    raw_display['position'] = 'Shooting Guard'
    sg_dem = raw_display[raw_display['Acro'] != ""]
    
    worksheet = sh.worksheet('SF_DEM_Calc')
    raw_display = pd.DataFrame(worksheet.get_values())
    raw_display.columns = raw_display.iloc[0]
    raw_display = raw_display[1:]
    raw_display = raw_display.reset_index(drop=True)
    cols_to_check = ['Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost', 'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM Boost']
    raw_display.loc[:, cols_to_check] = raw_display.loc[:, cols_to_check].replace({'%': ''}, regex=True).astype(float) / 100
    raw_display = raw_display.apply(pd.to_numeric, errors='coerce').fillna(raw_display)
    raw_display['position'] = 'Small Forward'
    sf_dem = raw_display[raw_display['Acro'] != ""]
    
    worksheet = sh.worksheet('PF_DEM_Calc')
    raw_display = pd.DataFrame(worksheet.get_values())
    raw_display.columns = raw_display.iloc[0]
    raw_display = raw_display[1:]
    raw_display = raw_display.reset_index(drop=True)
    cols_to_check = ['Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost', 'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM Boost']
    raw_display.loc[:, cols_to_check] = raw_display.loc[:, cols_to_check].replace({'%': ''}, regex=True).astype(float) / 100
    raw_display = raw_display.apply(pd.to_numeric, errors='coerce').fillna(raw_display)
    raw_display['position'] = 'Power Forward'
    pf_dem = raw_display[raw_display['Acro'] != ""]
    
    worksheet = sh.worksheet('C_DEM_Calc')
    raw_display = pd.DataFrame(worksheet.get_values())
    raw_display.columns = raw_display.iloc[0]
    raw_display = raw_display[1:]
    raw_display = raw_display.reset_index(drop=True)
    cols_to_check = ['Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost', 'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM Boost']
    raw_display.loc[:, cols_to_check] = raw_display.loc[:, cols_to_check].replace({'%': ''}, regex=True).astype(float) / 100
    raw_display = raw_display.apply(pd.to_numeric, errors='coerce').fillna(raw_display)
    raw_display['position'] = 'Center'
    c_dem = raw_display[raw_display['Acro'] != ""]
    
    overall_dem = pd.concat([pg_dem, sg_dem, sf_dem, pf_dem, c_dem])
    overall_dem = overall_dem[['Acro', 'G', 'Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost',
                               'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM', 'FPPM Boost', 'position']]
    overall_dem['Team'] = overall_dem['Acro'] + '-' + overall_dem['position']
    overall_dem['Team FPPM Boost'] = overall_dem.groupby('Acro', sort=False)['FPPM Boost'].transform('mean')
    overall_dem = overall_dem.reset_index()
    
    
    export_dem = overall_dem[['Team', 'Acro', 'G', 'Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost',
                               'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM', 'FPPM Boost', 'Team FPPM Boost', 'position']]
    
    worksheet = sh.worksheet('DEM Matchups')
    timestamp = worksheet.acell('F1').value

    return export_dem, matchups, matchups_dict, timestamp

def convert_df_to_csv(df):
    return df.to_csv().encode('utf-8')

overall_dem, matchups, matchups_dict, timestamp = init_baselines()
t_stamp = f"Updated through: " + str(timestamp) + f" CST"

col1, col2 = st.columns([1, 9])
with col1:
    st.info(t_stamp)
    if st.button("Reset Data", key='reset1'):
              st.cache_data.clear()
              overall_dem, matchups, matchups_dict, t_stamp = init_baselines()
    split_var1 = st.radio("View all teams or just this main slate's matchups?", ('Slate Matchups', 'All'), key='split_var1')
    if split_var1 == 'Slate Matchups':
        view_var1 = matchups.Opp.values.tolist()
        split_var2 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var2')
        if split_var2 == 'Specific Teams':
            team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = view_var1, key='team_var1')
        elif split_var2 == 'All':
            team_var1 = view_var1
        split_var3 = st.radio("Would you like to view all positions or specific ones?", ('All', 'Specific Positions'), key='split_var3')
        if split_var3 == 'Specific Positions':
            pos_var1 = st.multiselect('Which teams would you like to include in the tables?', options = overall_dem['position'].unique(), key='pos_var1')
        elif split_var3 == 'All':
            pos_var1 = overall_dem.position.values.tolist()
    if split_var1 == 'All':
        split_var2 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var2')
        if split_var2 == 'Specific Teams':
            team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = overall_dem['Acro'].unique(), key='team_var1')
        elif split_var2 == 'All':
            team_var1 = overall_dem.Acro.values.tolist()
        split_var3 = st.radio("Would you like to view all positions or specific ones?", ('All', 'Specific Positions'), key='split_var3')
        if split_var3 == 'Specific Positions':
            pos_var1 = st.multiselect('Which teams would you like to include in the tables?', options = overall_dem['position'].unique(), key='pos_var1')
        elif split_var3 == 'All':
            pos_var1 = overall_dem.position.values.tolist()
with col2:
    if split_var1 == 'Slate Matchups':
        dem_display = overall_dem[overall_dem['Acro'].isin(view_var1)]
        dem_display['Team (Getting Boost)'] = dem_display['Acro'].map(matchups_dict)
        dem_display.rename(columns={"Acro": "Opp (Giving Boost)"}, inplace = True)
        dem_display = dem_display[['Team (Getting Boost)', 'Opp (Giving Boost)', 'G', 'Pts% Boost', 'Reb% Boost', 'Ast% Boost', '3p% Boost',
                                   'Stl Boost%', 'Blk Boost%', 'TOV Boost%', 'FPPM', 'FPPM Boost', 'Team FPPM Boost', 'position']]
        dem_display = dem_display[dem_display['Team (Getting Boost)'].isin(team_var1)]
        dem_display = dem_display[dem_display['position'].isin(pos_var1)]
        dem_display = dem_display.sort_values(by='FPPM Boost', ascending=False)
    elif split_var1 == 'All':
        dem_display = overall_dem[overall_dem['Acro'].isin(team_var1)]
        dem_display = dem_display[dem_display['position'].isin(pos_var1)]
        dem_display = dem_display.sort_values(by='FPPM Boost', ascending=False)
        dem_display.rename(columns={"Team": "Team (Giving Boost)"}, inplace = True)
        dem_display = dem_display.set_index('Team (Giving Boost)')
    st.dataframe(dem_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
    st.download_button(
        label="Export DEM Numbers",
        data=convert_df_to_csv(overall_dem),
        file_name='DEM_export.csv',
        mime='text/csv',
    )