File size: 10,550 Bytes
be4a56a
 
 
 
 
 
 
 
 
 
 
d581c52
 
 
 
be4a56a
 
 
 
 
 
 
 
3421080
be4a56a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3421080
be4a56a
1e9c6b7
fb77958
 
be4a56a
eed2a00
 
2218cec
be4a56a
ddd4ee7
 
 
1e9c6b7
be4a56a
ed7d6a0
 
 
 
 
 
 
 
 
 
1e9c6b7
be4a56a
 
 
 
107d40e
 
f53ed74
1e9c6b7
be3ac19
bc28625
49e84d7
be4a56a
1e9c6b7
be4a56a
 
 
 
86c06f6
1e9c6b7
 
701b56f
 
 
fb77958
7da07a1
7cab575
 
7da07a1
 
898fd7b
 
7cab575
488c0d1
8751601
be4a56a
 
 
 
4d6e5f5
51316bf
d581c52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51316bf
d581c52
 
 
51316bf
4d6e5f5
8751601
be4a56a
 
 
 
 
8751601
1e9c6b7
ed7d6a0
 
 
8751601
ed7d6a0
8751601
1e9c6b7
be4a56a
 
1e9c6b7
def2aed
 
1e9c6b7
 
64fa655
def2aed
 
4d6e5f5
 
 
 
 
 
 
 
 
 
1e9c6b7
4d6e5f5
 
 
 
1e9c6b7
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
186
187
188
189
190
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
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, landscape
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
from io import BytesIO

@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": st.secrets['model_sheets_connect_pk'],
          "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": "[email protected]",
          "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()

NHL_data = st.secrets['NHL_Data']

percentages_format = {'Shots': '{:.2%}', 'HDCF': '{:.2%}', 'Goals': '{:.2%}', 'Assists': '{:.2%}', 'Blocks': '{:.2%}',
                      'L14_Shots': '{:.2%}', 'L14_HDCF': '{:.2%}', 'L14_Goals': '{:.2%}', 'L14_Assists': '{:.2%}',
                      'L14_Blocks': '{:.2%}', 'Max Goal%': '{:.2%}', 'L14 Max Goal%': '{:.2%}'}

matchups_format = {'HDCF%': '{:.2%}', 'o_HDCA%': '{:.2%}', 'HDCF_m%': '{:.2%}'}

@st.cache_resource(ttl = 599)
def init_baselines():
    parse_hold = pd.DataFrame(columns=['Line', 'SK1', 'SK2', 'SK3', 'Cost', 'Team Total', 'Shots', 'HDCF', 'Goals', 'Assists', 'Blocks',
                              'L14_Shots', 'L14_HDCF', 'L14_Goals', 'L14_Assists', 'L14_Blocks', 'Max Goal%'])
    
    sh = gcservice_account.open_by_url(NHL_data)
    
    worksheet = sh.worksheet('Player_Level_ROO')
    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)
    raw_display = raw_display[raw_display['Opp'] != ""]
    team_frame = raw_display[['Team', 'Opp']]
    team_list = team_frame['Team'].unique()
    team_dict = dict(zip(team_frame['Team'], team_frame['Opp']))
    
    worksheet = sh.worksheet('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)
    raw_display = raw_display[raw_display['Opp'] != ""]
    matchups = raw_display[['Team', 'Opp', 'FL1$', 'FL2$', 'FL3$', 'Team Total', 'Game Pace', 'SF', 'o_SA', 'SF_m', 'HDCF',
                              'o_HDCA', 'HDCF_m', 'HDCF%', 'o_HDCA%', 'HDCF_m%', 'HDSF+']]
    data_cols = matchups.columns.drop(['Team', 'Opp'])
    matchups[data_cols] = matchups[data_cols].apply(pd.to_numeric, errors='coerce')
    matchups = matchups.dropna(subset='FL1$')
    matchups = matchups.sort_values(by='HDCF_m', ascending=False)
    
    worksheet = sh.worksheet('Marketshares')
    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)
    # raw_display = raw_display[raw_display['Line'] != ""]
    overall_ms = raw_display[['Line', 'SK1', 'SK2', 'SK3', 'Cost', 'Team Total', 'Shots', 'HDCF', 'Goals', 'Assists', 'Blocks',
                              'L14_Shots', 'L14_HDCF', 'L14_Goals', 'L14_Assists', 'L14_Blocks']]
    pat = '|'.join(team_list)
    s = overall_ms['Line'].str.extract('('+ pat + ')', expand=False)
    overall_ms['Max Goal%'] = overall_ms.groupby(s)['Goals'].transform('max')
    overall_ms['L14 Max Goal%'] = overall_ms.groupby(s)['L14_Goals'].transform('max')
    
    data_cols = overall_ms.columns.drop(['Line', 'SK1', 'SK2', 'SK3'])
    overall_ms[data_cols] = overall_ms[data_cols].apply(pd.to_numeric, errors='coerce')
    overall_ms['Proj Goal'] = overall_ms['Goals'] * overall_ms['Team Total']
    overall_ms['L14 Proj Goal'] = overall_ms['L14_Goals'] * overall_ms['Team Total']
    overall_ms = overall_ms[['Line', 'SK1', 'SK2', 'SK3', 'Cost', 'Team Total', 'Shots', 'HDCF', 'Goals', 'Max Goal%', 'Proj Goal',
                             'Assists', 'Blocks', 'L14_Shots', 'L14_HDCF', 'L14_Goals', 'L14 Max Goal%', 'L14 Proj Goal', 'L14_Assists', 'L14_Blocks']]
    overall_ms = overall_ms.sort_values(by='Shots', ascending=False)
        
    return matchups, overall_ms, team_frame, team_list, team_dict

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

def convert_df_to_pdf(df):
    try:
        # Create a buffer to receive PDF data
        buffer = BytesIO()
        
        # Create the PDF object using the buffer as its "file"
        doc = SimpleDocTemplate(buffer, pagesize=landscape(letter))
        
        # Convert DataFrame to a list of lists for the table
        data = [df.columns.tolist()] + df.values.tolist()
        
        # Create the table
        table = Table(data)
        
        # Add style to the table
        style = TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.white),
            ('TEXTCOLOR', (0, 1), (-1, -1), colors.black),
            ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 1), (-1, -1), 8),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ])
        table.setStyle(style)
        
        # Build the PDF
        elements = [table]
        doc.build(elements)
        
        # Get the value of the BytesIO buffer
        pdf = buffer.getvalue()
        buffer.close()
        
        return pdf
        
    except Exception as e:
        st.error(f"Error generating PDF: {str(e)}")
        return None

matchups, overall_ms, team_frame, team_list, team_dict = init_baselines()

col1, col2 = st.columns([1, 9])
with col1:
    if st.button("Reset Data", key='reset1'):
              st.cache_data.clear()
              matchups, overall_ms, team_frame, team_list, team_dict = init_baselines()
    split_var1 = st.radio("View matchups or line marketshares?", ('Slate Matchups', 'Line Marketshares'), key='split_var1')
    if split_var1 == "Line Marketshares":
        team_var = st.radio("View all teams or specific teams?", ('All Teams', 'Specific Teams'), key='team_var')
        if team_var == "All Teams":
            team_split = team_frame.Team.values.tolist()
        elif team_var == "Specific Teams":
            team_split = st.multiselect('Which teams would you like to include in the tables?', options = team_frame['Team'].unique(), key='team_var1')
    
with col2:
    if split_var1 == 'Slate Matchups':
        display_table = matchups
        display_table = display_table.set_index('Team')
        st.dataframe(display_table.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(matchups_format, precision=2), height=500, use_container_width = True)
    elif split_var1 == 'Line Marketshares':
        display_table = overall_ms
        display_parsed = display_table[display_table['Line'].str.contains('|'.join(team_split))]
        display_parsed = display_parsed.set_index('Line')
        st.dataframe(display_parsed.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), height=500, use_container_width = True)
download_var = st.selectbox('What download would you like?', options = ['CSV', 'PDF'], key='download_var')
if st.button('Download'):
    if download_var == 'CSV':
        st.download_button(
            label="Export Marketshares (CSV)",
    data=convert_df_to_csv(display_table),
    file_name='Marketshares_export.csv',
    mime='text/csv',
        )
    elif download_var == 'PDF':
        st.download_button(
            label="Export Marketshares (PDF)",
            data=convert_df_to_pdf(display_table),
            file_name='Marketshares_export.pdf',
            mime='application/pdf',
        )