James McCool commited on
Commit
9961eef
·
1 Parent(s): 31e0d08

Initial commit for modernization

Browse files
.streamlit/secrets.toml ADDED
@@ -0,0 +1 @@
 
 
1
+ NHL_Data = "https://docs.google.com/spreadsheets/d/1NmKa-b-2D3w7rRxwMPSchh31GKfJ1XcDI2GU8rXWnHI/edit?gid=1951430245#gid=1951430245"
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 NHL_Data="https://docs.google.com/spreadsheets/d/1NmKa-b-2D3w7rRxwMPSchh31GKfJ1XcDI2GU8rXWnHI/edit?gid=1951430245#gid=1951430245"
17
+ ENV MONGO_URI="mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
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
 
requirements.txt CHANGED
@@ -1,3 +1,9 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
 
1
+ streamlit
2
+ gspread
3
+ openpyxl
4
+ matplotlib
5
+ streamlit-aggrid
6
+ pulp
7
+ docker
8
+ plotly
9
+ scipy
src/database.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import gspread
3
+ import os
4
+
5
+ @st.cache_resource
6
+ def init_conn():
7
+ scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
8
+
9
+ credentials = {
10
+ "type": "service_account",
11
+ "project_id": "model-sheets-connect",
12
+ "private_key_id": st.secrets['model_sheets_connect_pk'],
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
+ credentials2 = {
23
+ "type": "service_account",
24
+ "project_id": "sheets-api-connect-378620",
25
+ "private_key_id": st.secrets['sheets_api_connect_pk'],
26
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtKa01beXwc88R\nnPZVQTNPVQuBnbwoOfc66gW3547ja/UEyIGAF112dt/VqHprRafkKGmlg55jqJNt\na4zceLKV+wTm7vBu7lDISTJfGzCf2TrxQYNqwMKE2LOjI69dBM8u4Dcb4k0wcp9v\ntW1ZzLVVuwTvmrg7JBHjiSaB+x5wxm/r3FOiJDXdlAgFlytzqgcyeZMJVKKBQHyJ\njEGg/1720A0numuOCt71w/2G0bDmijuj1e6tH32MwRWcvRNZ19K9ssyDz2S9p68s\nYDhIxX69OWxwScTIHLY6J2t8txf/XMivL/636fPlDADvBEVTdlT606n8CcKUVQeq\npUVdG+lfAgMBAAECggEAP38SUA7B69eTfRpo658ycOs3Amr0JW4H/bb1rNeAul0K\nZhwd/HnU4E07y81xQmey5kN5ZeNrD5EvqkZvSyMJHV0EEahZStwhjCfnDB/cxyix\nZ+kFhv4y9eK+kFpUAhBy5nX6T0O+2T6WvzAwbmbVsZ+X8kJyPuF9m8ldcPlD0sce\ntj8NwVq1ys52eosqs7zi2vjt+eMcaY393l4ls+vNq8Yf27cfyFw45W45CH/97/Nu\n5AmuzlCOAfFF+z4OC5g4rei4E/Qgpxa7/uom+BVfv9G0DIGW/tU6Sne0+37uoGKt\nW6DzhgtebUtoYkG7ZJ05BTXGp2lwgVcNRoPwnKJDxQKBgQDT5wYPUBDW+FHbvZSp\nd1m1UQuXyerqOTA9smFaM8sr/UraeH85DJPEIEk8qsntMBVMhvD3Pw8uIUeFNMYj\naLmZFObsL+WctepXrVo5NB6RtLB/jZYxiKMatMLUJIYtcKIp+2z/YtKiWcLnwotB\nWdCjVnPTxpkurmF2fWP/eewZ+wKBgQDRMtJg7etjvKyjYNQ5fARnCc+XsI3gkBe1\nX9oeXfhyfZFeBXWnZzN1ITgFHplDznmBdxAyYGiQdbbkdKQSghviUQ0igBvoDMYy\n1rWcy+a17Mj98uyNEfmb3X2cC6WpvOZaGHwg9+GY67BThwI3FqHIbyk6Ko09WlTX\nQpRQjMzU7QKBgAfi1iflu+q0LR+3a3vvFCiaToskmZiD7latd9AKk2ocsBd3Woy9\n+hXXecJHPOKV4oUJlJgvAZqe5HGBqEoTEK0wyPNLSQlO/9ypd+0fEnArwFHO7CMF\nycQprAKHJXM1eOOFFuZeQCaInqdPZy1UcV5Szla4UmUZWkk1m24blHzXAoGBAMcA\nyH4qdbxX9AYrC1dvsSRvgcnzytMvX05LU0uF6tzGtG0zVlub4ahvpEHCfNuy44UT\nxRWW/oFFaWjjyFxO5sWggpUqNuHEnRopg3QXx22SRRTGbN45li/+QAocTkgsiRh1\nqEcYZsO4mPCsQqAy6E2p6RcK+Xa+omxvSnVhq0x1AoGAKr8GdkCl4CF6rieLMAQ7\nLNBuuoYGaHoh8l5E2uOQpzwxVy/nMBcAv+2+KqHEzHryUv1owOi6pMLv7A9mTFoS\n18B0QRLuz5fSOsVnmldfC9fpUc6H8cH1SINZpzajqQA74bPwELJjnzrCnH79TnHG\nJuElxA33rFEjbgbzdyrE768=\n-----END PRIVATE KEY-----\n",
27
+ "client_email": "gspread-connection@sheets-api-connect-378620.iam.gserviceaccount.com",
28
+ "client_id": "106625872877651920064",
29
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
30
+ "token_uri": "https://oauth2.googleapis.com/token",
31
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
32
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40sheets-api-connect-378620.iam.gserviceaccount.com"
33
+ }
34
+
35
+ NHL_Data = os.getenv('NHL_Data')
36
+
37
+ gc = gspread.service_account_from_dict(credentials)
38
+ gc2 = gspread.service_account_from_dict(credentials2)
39
+
40
+ return gc, gc2, NHL_Data
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
+ from database import init_conn
12
+
13
+ gcservice_account, gcservice_account2, NHL_Data = init_conn()
14
+
15
+ @st.cache_resource(ttl = 600)
16
+ def init_baselines():
17
+ sh = gcservice_account.open_by_url(NHL_Data)
18
+
19
+ worksheet = sh.worksheet('Gamelog')
20
+ raw_display = pd.DataFrame(worksheet.get_values())
21
+ raw_display.columns = raw_display.iloc[0]
22
+ raw_display = raw_display[1:]
23
+ raw_display = raw_display.reset_index(drop=True)
24
+ gamelog_table = raw_display[raw_display['Player'] != ""]
25
+ gamelog_table = gamelog_table[['Player', 'Team', 'Position', 'Date', 'TOI', 'Goals', 'TotalAssists', 'FirstAssists', 'SecondAssists', 'TotalPoints', 'IPP',
26
+ 'Shots', 'SH%', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'RushAttempts', 'ReboundsCreated', 'PIM', 'TotalPenalties', 'Minor',
27
+ 'Major', 'PenaltiesDrawn', 'Giveaways', 'Takeaways', 'Hits', 'HitsTaken', 'ShotsBlocked', 'FaceoffsWon',
28
+ 'FaceoffsLost', 'Faceoffs%']]
29
+ gamelog_table = gamelog_table.set_axis(['Player', 'Team', 'Position', 'Date', 'TOI', 'Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points', 'IPP',
30
+ 'Shots', 'SH%', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties', 'Minor',
31
+ 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
32
+ 'Faceoffs Lost', 'Faceoffs %'], axis=1)
33
+ data_cols = gamelog_table.columns.drop(['Player', 'Team', 'Position', 'Date'])
34
+ gamelog_table[data_cols] = gamelog_table[data_cols].apply(pd.to_numeric, errors='coerce')
35
+ gamelog_table['Date'] = pd.to_datetime(gamelog_table['Date']).dt.date
36
+ gamelog_table['dk_shots_bonus'] = np.where((gamelog_table['Shots'] >= 5), 1, 0)
37
+ gamelog_table['dk_blocks_bonus'] = np.where((gamelog_table['Shots Blocked'] >= 3), 1, 0)
38
+ gamelog_table['dk_goals_bonus'] = np.where((gamelog_table['Goals'] >= 3), 1, 0)
39
+ gamelog_table['dk_points_bonus'] = np.where((gamelog_table['Total Points'] >= 3), 1, 0)
40
+ gamelog_table['dk_fantasy'] = sum([(gamelog_table['Goals'] * 8.5), (gamelog_table['Total Assists'] * 5), (gamelog_table['Shots'] * 1.5),
41
+ (gamelog_table['Shots Blocked'] * 1.3), (gamelog_table['dk_shots_bonus'] * 3), (gamelog_table['dk_blocks_bonus'] * 3),
42
+ (gamelog_table['dk_goals_bonus'] * 3), (gamelog_table['dk_points_bonus'] * 3)]).astype(float).round(2)
43
+ gamelog_table['fd_fantasy'] = sum([(gamelog_table['Goals'] * 12), (gamelog_table['Total Assists'] * 8), (gamelog_table['Shots'] * 1.6),
44
+ (gamelog_table['Shots Blocked'] * 1.6)]).astype(float).round(2)
45
+
46
+
47
+
48
+ gamelog_table = gamelog_table.set_axis(['Player', 'Team', 'Position', 'Date', 'TOI', 'Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points', 'IPP',
49
+ 'Shots', 'Shots%', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties', 'Minor',
50
+ 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
51
+ 'Faceoffs Lost', 'Faceoffs%', 'dk_shots_bonus', 'dk_blocks_bonus', 'dk_goals_bonus', 'dk_points_bonus',
52
+ 'dk_fantasy', 'fd_fantasy'], axis=1)
53
+
54
+ return gamelog_table
55
+
56
+ @st.cache_data(show_spinner=False)
57
+ def seasonlong_build(data_sample):
58
+ season_long_table = data_sample[['Player', 'Team', 'Position']]
59
+ season_long_table['TOI'] = data_sample.groupby(['Player', 'Team'], sort=False)['TOI'].transform('mean').astype(float)
60
+ season_long_table['Goals'] = data_sample.groupby(['Player', 'Team'], sort=False)['Goals'].transform('mean').astype(float)
61
+ season_long_table['Total Assists'] = data_sample.groupby(['Player', 'Team'], sort=False)['Total Assists'].transform('mean').astype(float)
62
+ season_long_table['First Assists'] = data_sample.groupby(['Player', 'Team'], sort=False)['First Assists'].transform('mean').astype(float)
63
+ season_long_table['Second Assists'] = data_sample.groupby(['Player', 'Team'], sort=False)['Second Assists'].transform('mean').astype(float)
64
+ season_long_table['Total Points'] = data_sample.groupby(['Player', 'Team'], sort=False)['Total Points'].transform('mean').astype(float)
65
+ season_long_table['IPP'] = data_sample.groupby(['Player', 'Team'], sort=False)['IPP'].transform('mean').astype(float)
66
+ season_long_table['Shots'] = data_sample.groupby(['Player', 'Team'], sort=False)['Shots'].transform('mean').astype(float)
67
+ season_long_table['ixG'] = data_sample.groupby(['Player', 'Team'], sort=False)['ixG'].transform('mean').astype(float)
68
+ season_long_table['iCF'] = data_sample.groupby(['Player', 'Team'], sort=False)['iCF'].transform('mean').astype(float)
69
+ season_long_table['iFF'] = data_sample.groupby(['Player', 'Team'], sort=False)['iFF'].transform('mean').astype(float)
70
+ season_long_table['iSCF'] = data_sample.groupby(['Player', 'Team'], sort=False)['iSCF'].transform('mean').astype(float)
71
+ season_long_table['iHDCF'] = data_sample.groupby(['Player', 'Team'], sort=False)['iHDCF'].transform('mean').astype(float)
72
+ season_long_table['Rush Attempts'] = data_sample.groupby(['Player', 'Team'], sort=False)['Rush Attempts'].transform('mean').astype(float)
73
+ season_long_table['Rebounds Created'] = data_sample.groupby(['Player', 'Team'], sort=False)['Rebounds Created'].transform('mean').astype(float)
74
+ season_long_table['PIM'] = data_sample.groupby(['Player', 'Team'], sort=False)['PIM'].transform('mean').astype(float)
75
+ season_long_table['Total Penalties'] = data_sample.groupby(['Player', 'Team'], sort=False)['Total Penalties'].transform('mean').astype(float)
76
+ season_long_table['Minor'] = data_sample.groupby(['Player', 'Team'], sort=False)['Minor'].transform('mean').astype(float)
77
+ season_long_table['Major'] = data_sample.groupby(['Player', 'Team'], sort=False)['Major'].transform('mean').astype(float)
78
+ season_long_table['Penalties Drawn'] = data_sample.groupby(['Player', 'Team'], sort=False)['Penalties Drawn'].transform('mean').astype(float)
79
+ season_long_table['Giveaways'] = data_sample.groupby(['Player', 'Team'], sort=False)['Giveaways'].transform('mean').astype(float)
80
+ season_long_table['Takeaways'] = data_sample.groupby(['Player', 'Team'], sort=False)['Takeaways'].transform('mean').astype(float)
81
+ season_long_table['Hits'] = data_sample.groupby(['Player', 'Team'], sort=False)['Hits'].transform('mean').astype(float)
82
+ season_long_table['Hits Taken'] = data_sample.groupby(['Player', 'Team'], sort=False)['Hits Taken'].transform('mean').astype(float)
83
+ season_long_table['Shots Blocked'] = data_sample.groupby(['Player', 'Team'], sort=False)['Shots Blocked'].transform('mean').astype(float)
84
+ season_long_table['Faceoffs Won'] = data_sample.groupby(['Player', 'Team'], sort=False)['Faceoffs Won'].transform('mean').astype(float)
85
+ season_long_table['Faceoffs Lost'] = data_sample.groupby(['Player', 'Team'], sort=False)['Faceoffs Lost'].transform('mean').astype(float)
86
+ season_long_table['dk_shots_bonus'] = data_sample.groupby(['Player', 'Team'], sort=False)['dk_shots_bonus'].transform('mean').astype(float)
87
+ season_long_table['dk_blocks_bonus'] = data_sample.groupby(['Player', 'Team'], sort=False)['dk_blocks_bonus'].transform('mean').astype(float)
88
+ season_long_table['dk_goals_bonus'] = data_sample.groupby(['Player', 'Team'], sort=False)['dk_goals_bonus'].transform('mean').astype(float)
89
+ season_long_table['dk_points_bonus'] = data_sample.groupby(['Player', 'Team'], sort=False)['dk_points_bonus'].transform('mean').astype(float)
90
+ season_long_table['dk_fantasy'] = data_sample.groupby(['Player', 'Team'], sort=False)['dk_fantasy'].transform('mean').astype(float)
91
+ season_long_table['fd_fantasy'] = data_sample.groupby(['Player', 'Team'], sort=False)['fd_fantasy'].transform('mean').astype(float)
92
+ season_long_table = season_long_table.drop_duplicates(subset='Player')
93
+
94
+ season_long_table = season_long_table.sort_values(by='dk_fantasy', ascending=False)
95
+
96
+
97
+ season_long_table = season_long_table.set_axis(['Player', 'Team', 'Position', 'TOI', 'Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points',
98
+ 'IPP', 'Shots', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties',
99
+ 'Minor', 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
100
+ 'Faceoffs Lost', 'dk_shots_bonus', 'dk_blocks_bonus', 'dk_goals_bonus', 'dk_points_bonus',
101
+ 'dk_fantasy', 'fd_fantasy'], axis=1)
102
+
103
+ return season_long_table
104
+
105
+ @st.cache_data(show_spinner=False)
106
+ def run_fantasy_corr(data_sample):
107
+ cor_testing = data_sample
108
+ date_list = cor_testing['Date'].unique().tolist()
109
+ player_list = cor_testing['Player'].unique().tolist()
110
+ corr_frame = pd.DataFrame()
111
+ corr_frame['DATE'] = date_list
112
+ for player in player_list:
113
+ player_testing = cor_testing[cor_testing['Player'] == player]
114
+ fantasy_map = dict(zip(player_testing['Date'], player_testing['dk_fantasy']))
115
+ corr_frame[player] = corr_frame['DATE'].map(fantasy_map)
116
+ players_fantasy = corr_frame.drop('DATE', axis=1)
117
+ corrM = players_fantasy.corr()
118
+
119
+ return corrM
120
+
121
+ @st.cache_data(show_spinner=False)
122
+ def run_min_corr(data_sample):
123
+ cor_testing = data_sample
124
+ date_list = cor_testing['Date'].unique().tolist()
125
+ player_list = cor_testing['Player'].unique().tolist()
126
+ corr_frame = pd.DataFrame()
127
+ corr_frame['DATE'] = date_list
128
+ for player in player_list:
129
+ player_testing = cor_testing[cor_testing['Player'] == player]
130
+ fantasy_map = dict(zip(player_testing['Date'], player_testing['TOI']))
131
+ corr_frame[player] = corr_frame['DATE'].map(fantasy_map)
132
+ players_fantasy = corr_frame.drop('DATE', axis=1)
133
+ corrM = players_fantasy.corr()
134
+
135
+ return corrM
136
+
137
+ @st.cache_data(show_spinner=False)
138
+ def split_frame(input_df, rows):
139
+ df = [input_df.loc[i : i + rows - 1, :] for i in range(0, len(input_df), rows)]
140
+ return df
141
+
142
+ def convert_df_to_csv(df):
143
+ return df.to_csv().encode('utf-8')
144
+
145
+ gamelog_table = init_baselines()
146
+ basic_cols = ['Player', 'Team', 'Position', 'Date', 'TOI']
147
+ basic_season_cols = ['Player', 'Team', 'Position', 'TOI']
148
+ data_cols = ['Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points', 'IPP',
149
+ 'Shots', 'Shots%', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties', 'Minor',
150
+ 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
151
+ 'Faceoffs Lost', 'Faceoffs%', 'dk_shots_bonus', 'dk_blocks_bonus', 'dk_goals_bonus', 'dk_points_bonus',
152
+ 'dk_fantasy', 'fd_fantasy']
153
+ season_data_cols = ['Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points',
154
+ 'IPP', 'Shots', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties',
155
+ 'Minor', 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
156
+ 'Faceoffs Lost', 'dk_shots_bonus', 'dk_blocks_bonus', 'dk_goals_bonus', 'dk_points_bonus',
157
+ 'dk_fantasy', 'fd_fantasy']
158
+ indv_teams = gamelog_table.drop_duplicates(subset='Team')
159
+ total_teams = indv_teams.Team.values.tolist()
160
+ indv_players = gamelog_table.drop_duplicates(subset='Player')
161
+ total_players = indv_players.Player.values.tolist()
162
+ total_dates = gamelog_table.Date.values.tolist()
163
+
164
+ tab1, tab2 = st.tabs(['Gamelogs', 'Correlation Matrix'])
165
 
166
+ with tab1:
167
+ col1, col2 = st.columns([1, 9])
168
+ with col1:
169
+ if st.button("Reset Data", key='reset1'):
170
+ st.cache_data.clear()
171
+ gamelog_table = init_baselines()
172
+ basic_cols = ['Player', 'Team', 'Position', 'Date', 'TOI']
173
+ basic_season_cols = ['Player', 'Team', 'Position', 'TOI']
174
+ data_cols = ['Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points', 'IPP',
175
+ 'Shots', 'Shots%', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties', 'Minor',
176
+ 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
177
+ 'Faceoffs Lost', 'Faceoffs%', 'dk_shots_bonus', 'dk_blocks_bonus', 'dk_goals_bonus', 'dk_points_bonus',
178
+ 'dk_fantasy', 'fd_fantasy']
179
+ season_data_cols = ['Goals', 'Total Assists', 'First Assists', 'Second Assists', 'Total Points',
180
+ 'IPP', 'Shots', 'ixG', 'iCF', 'iFF', 'iSCF', 'iHDCF', 'Rush Attempts', 'Rebounds Created', 'PIM', 'Total Penalties',
181
+ 'Minor', 'Major', 'Penalties Drawn', 'Giveaways', 'Takeaways', 'Hits', 'Hits Taken', 'Shots Blocked', 'Faceoffs Won',
182
+ 'Faceoffs Lost', 'dk_shots_bonus', 'dk_blocks_bonus', 'dk_goals_bonus', 'dk_points_bonus',
183
+ 'dk_fantasy', 'fd_fantasy']
184
+ indv_teams = gamelog_table.drop_duplicates(subset='Team')
185
+ total_teams = indv_teams.Team.values.tolist()
186
+ indv_players = gamelog_table.drop_duplicates(subset='Player')
187
+ total_players = indv_players.Player.values.tolist()
188
+ total_dates = gamelog_table.Date.values.tolist()
189
+
190
+ split_var1 = st.radio("What table would you like to view?", ('Season Logs', 'Gamelogs'), key='split_var1')
191
+ split_var2 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var2')
192
+
193
+ if split_var2 == 'Specific Teams':
194
+ team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = total_teams, key='team_var1')
195
+ elif split_var2 == 'All':
196
+ team_var1 = total_teams
197
+
198
+ split_var3 = st.radio("Would you like to view all dates or specific ones?", ('All', 'Specific Dates'), key='split_var3')
199
+
200
+ if split_var3 == 'Specific Dates':
201
+ low_date = st.date_input('Min Date:', value=None, format="MM/DD/YYYY", key='low_date')
202
+ if low_date is not None:
203
+ low_date = pd.to_datetime(low_date).date()
204
+ high_date = st.date_input('Max Date:', value=None, format="MM/DD/YYYY", key='high_date')
205
+ if high_date is not None:
206
+ high_date = pd.to_datetime(high_date).date()
207
+ elif split_var3 == 'All':
208
+ low_date = gamelog_table['Date'].min()
209
+ high_date = gamelog_table['Date'].max()
210
+
211
+ split_var4 = st.radio("Would you like to view all players or specific ones?", ('All', 'Specific Players'), key='split_var4')
212
+
213
+ if split_var4 == 'Specific Players':
214
+ player_var1 = st.multiselect('Which players would you like to include in the tables?', options = total_players, key='player_var1')
215
+ elif split_var4 == 'All':
216
+ player_var1 = total_players
217
+
218
+ min_var1 = st.slider("Is there a certain TOI range you want to view?", 0, 50, (0, 50), key='min_var1')
219
+
220
+ with col2:
221
+ working_data = gamelog_table
222
+ if split_var1 == 'Season Logs':
223
+ choose_cols = st.container()
224
+ with choose_cols:
225
+ choose_disp = st.multiselect('Which stats would you like to view?', options = season_data_cols, default = season_data_cols, key='col_display')
226
+ disp_stats = basic_season_cols + choose_disp
227
+ display = st.container()
228
+ working_data = working_data[working_data['Date'] >= low_date]
229
+ working_data = working_data[working_data['Date'] <= high_date]
230
+ working_data = working_data[working_data['TOI'] >= min_var1[0]]
231
+ working_data = working_data[working_data['TOI'] <= min_var1[1]]
232
+ working_data = working_data[working_data['Team'].isin(team_var1)]
233
+ working_data = working_data[working_data['Player'].isin(player_var1)]
234
+ season_long_table = seasonlong_build(working_data)
235
+ season_long_table = season_long_table.set_index('Player')
236
+ season_long_table_disp = season_long_table.reindex(disp_stats,axis="columns")
237
+ display.dataframe(season_long_table_disp.style.format(precision=2), height=750, use_container_width = True)
238
+ st.download_button(
239
+ label="Export seasonlogs Model",
240
+ data=convert_df_to_csv(season_long_table),
241
+ file_name='Seasonlogs_NHL_View.csv',
242
+ mime='text/csv',
243
+ )
244
+
245
+ elif split_var1 == 'Gamelogs':
246
+ choose_cols = st.container()
247
+ with choose_cols:
248
+ choose_disp = st.multiselect('Which stats would you like to view?', options = data_cols, default = data_cols, key='col_display')
249
+ gamelog_disp_stats = basic_cols + choose_disp
250
+ working_data = working_data[working_data['Date'] >= low_date]
251
+ working_data = working_data[working_data['Date'] <= high_date]
252
+ working_data = working_data[working_data['TOI'] >= min_var1[0]]
253
+ working_data = working_data[working_data['TOI'] <= min_var1[1]]
254
+ working_data = working_data[working_data['Team'].isin(team_var1)]
255
+ working_data = working_data[working_data['Player'].isin(player_var1)]
256
+ working_data = working_data.sort_values(by='Date', ascending=False)
257
+ working_data = working_data.reset_index(drop=True)
258
+ gamelog_data = working_data.reindex(gamelog_disp_stats,axis="columns")
259
+ display = st.container()
260
+
261
+ bottom_menu = st.columns((4, 1, 1))
262
+ with bottom_menu[2]:
263
+ batch_size = st.selectbox("Page Size", options=[25, 50, 100])
264
+ with bottom_menu[1]:
265
+ total_pages = (
266
+ int(len(gamelog_data) / batch_size) if int(len(gamelog_data) / batch_size) > 0 else 1
267
+ )
268
+ current_page = st.number_input(
269
+ "Page", min_value=1, max_value=total_pages, step=1
270
+ )
271
+ with bottom_menu[0]:
272
+ st.markdown(f"Page **{current_page}** of **{total_pages}** ")
273
+
274
+
275
+ pages = split_frame(gamelog_data, batch_size)
276
+ # pages = pages.set_index('Player')
277
+ display.dataframe(data=pages[current_page - 1].style.format(precision=2), height=500, use_container_width=True)
278
+ st.download_button(
279
+ label="Export gamelogs Model",
280
+ data=convert_df_to_csv(gamelog_data),
281
+ file_name='Gamelogs_NBA_View.csv',
282
+ mime='text/csv',
283
+ )
284
+
285
+ with tab2:
286
+ col1, col2 = st.columns([1, 9])
287
+ with col1:
288
+ if st.button("Reset Data", key='reset2'):
289
+ st.cache_data.clear()
290
+ gamelog_table = init_baselines()
291
+ indv_teams = gamelog_table.drop_duplicates(subset='Team')
292
+ total_teams = indv_teams.Team.values.tolist()
293
+ indv_players = gamelog_table.drop_duplicates(subset='Player')
294
+ total_players = indv_players.Player.values.tolist()
295
+ total_dates = gamelog_table.Date.values.tolist()
296
+
297
+ corr_var = st.radio("Are you correlating fantasy or TOI?", ('Fantasy', 'TOI'), key='corr_var')
298
+
299
+ split_var1_t2 = st.radio("Would you like to view specific teams or specific players?", ('Specific Teams', 'Specific Players'), key='split_var1_t2')
300
+
301
+ if split_var1_t2 == 'Specific Teams':
302
+ corr_var1_t2 = st.multiselect('Which teams would you like to include in the correlation?', options = total_teams, key='corr_var1_t2')
303
+ elif split_var1_t2 == 'Specific Players':
304
+ corr_var1_t2 = st.multiselect('Which players would you like to include in the correlation?', options = total_players, key='corr_var1_t2')
305
+
306
+ split_var2_t2 = st.radio("Would you like to view all dates or specific ones?", ('All', 'Specific Dates'), key='split_var3_t2')
307
+
308
+ if split_var2_t2 == 'Specific Dates':
309
+ low_date_t2 = st.date_input('Min Date:', value=None, format="MM/DD/YYYY", key='low_date_t2')
310
+ if low_date_t2 is not None:
311
+ low_date_t2 = pd.to_datetime(low_date_t2).date()
312
+ high_date_t2 = st.date_input('Max Date:', value=None, format="MM/DD/YYYY", key='high_date_t2')
313
+ if high_date_t2 is not None:
314
+ high_date_t2 = pd.to_datetime(high_date_t2).date()
315
+ elif split_var2_t2 == 'All':
316
+ low_date_t2 = gamelog_table['Date'].min()
317
+ high_date_t2 = gamelog_table['Date'].max()
318
+
319
+ min_var1_t2 = st.slider("Is there a certain minutes range you want to view?", 0, 50, (0, 50), key='min_var1_t2')
320
+
321
+ with col2:
322
+ if split_var1_t2 == 'Specific Teams':
323
+ display = st.container()
324
+ gamelog_table = gamelog_table.sort_values(by='dk_fantasy', ascending=False)
325
+ gamelog_table = gamelog_table[gamelog_table['Date'] >= low_date_t2]
326
+ gamelog_table = gamelog_table[gamelog_table['Date'] <= high_date_t2]
327
+ gamelog_table = gamelog_table[gamelog_table['TOI'] >= min_var1_t2[0]]
328
+ gamelog_table = gamelog_table[gamelog_table['TOI'] <= min_var1_t2[1]]
329
+ gamelog_table = gamelog_table[gamelog_table['Team'].isin(corr_var1_t2)]
330
+ if corr_var == 'Fantasy':
331
+ corr_display = run_fantasy_corr(gamelog_table)
332
+ elif corr_var == 'TOI':
333
+ corr_display = run_min_corr(gamelog_table)
334
+ display.dataframe(corr_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height=1000, use_container_width = True)
335
+
336
+ elif split_var1_t2 == 'Specific Players':
337
+ display = st.container()
338
+ gamelog_table = gamelog_table.sort_values(by='dk_fantasy', ascending=False)
339
+ gamelog_table = gamelog_table[gamelog_table['Date'] >= low_date_t2]
340
+ gamelog_table = gamelog_table[gamelog_table['Date'] <= high_date_t2]
341
+ gamelog_table = gamelog_table[gamelog_table['TOI'] >= min_var1_t2[0]]
342
+ gamelog_table = gamelog_table[gamelog_table['TOI'] <= min_var1_t2[1]]
343
+ gamelog_table = gamelog_table[gamelog_table['Player'].isin(corr_var1_t2)]
344
+ if corr_var == 'Fantasy':
345
+ corr_display = run_fantasy_corr(gamelog_table)
346
+ elif corr_var == 'TOI':
347
+ corr_display = run_min_corr(gamelog_table)
348
+ display.dataframe(corr_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)