James McCool commited on
Commit
b1f6d22
·
1 Parent(s): 2240edb

Initial commit and dockerization

Browse files
.streamlit/secrets.toml ADDED
@@ -0,0 +1 @@
 
 
1
+ mongo_uri = "mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
Dockerfile CHANGED
@@ -5,11 +5,24 @@ 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
+
17
+
18
+ ENV MONGO_URI="mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
19
+ RUN useradd -m -u 1000 user
20
+ USER user
21
+ ENV HOME=/home/user\
22
+ PATH=/home/user/.local/bin:$PATH
23
+ WORKDIR $HOME/app
24
+ RUN pip install --no-cache-dir --upgrade pip
25
+ COPY --chown=user . $HOME/app
26
 
27
  RUN pip3 install -r requirements.txt
28
 
requirements.txt CHANGED
@@ -1,3 +1,8 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
1
+ streamlit
2
+ openpyxl
3
+ matplotlib
4
+ pulp
5
+ docker
6
+ plotly
7
+ scipy
8
+ pymongo
src/database.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pymongo
3
+ import os
4
+
5
+ @st.cache_resource
6
+ def init_conn():
7
+ uri = os.getenv('MONGO_URI')
8
+ if not uri:
9
+ uri = st.secrets['mongo_uri']
10
+ client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)
11
+ db = client["NFL_Database"]
12
+ return db
13
+
14
+ # Initialize the database connection
15
+ db = init_conn()
src/sim_func_hold/regular_functions.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ from pymongo import MongoClient
5
+ from database import db
6
+
7
+ @st.cache_data(ttl = 600)
8
+ def init_DK_seed_frames(slate_var, sharp_split):
9
+
10
+
11
+ if slate_var == 'Main Slate':
12
+ collection = db['DK_NFL_name_map']
13
+ cursor = collection.find()
14
+ raw_data = pd.DataFrame(list(cursor))
15
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
16
+ collection = db[f"DK_NFL_seed_frame"]
17
+ elif slate_var == 'Secondary Slate':
18
+ collection = db['DK_NFL_Secondary_name_map']
19
+ cursor = collection.find()
20
+ raw_data = pd.DataFrame(list(cursor))
21
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
22
+ collection = db[f"DK_NFL_Secondary_seed_frame"]
23
+ elif slate_var == 'Auxiliary Slate':
24
+ collection = db['DK_NFL_Auxiliary_name_map']
25
+ cursor = collection.find()
26
+ raw_data = pd.DataFrame(list(cursor))
27
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
28
+ collection = db[f"DK_NFL_Auxiliary_seed_frame"]
29
+
30
+ cursor = collection.find().limit(sharp_split)
31
+
32
+ raw_display = pd.DataFrame(list(cursor))
33
+ raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
34
+ dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
35
+ for col in dict_columns:
36
+ raw_display[col] = raw_display[col].map(names_dict)
37
+ DK_seed = raw_display.to_numpy()
38
+
39
+ return DK_seed
40
+
41
+ @st.cache_data(ttl = 599)
42
+ def init_FD_seed_frames(slate_var, sharp_split):
43
+
44
+ if slate_var == 'Main Slate':
45
+ collection = db['FD_NFL_name_map']
46
+ cursor = collection.find()
47
+ raw_data = pd.DataFrame(list(cursor))
48
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
49
+ collection = db[f"FD_NFL_seed_frame"]
50
+ cursor = collection.find().limit(sharp_split)
51
+ elif slate_var == 'Secondary Slate':
52
+ collection = db['FD_NFL_Secondary_name_map']
53
+ cursor = collection.find()
54
+ raw_data = pd.DataFrame(list(cursor))
55
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
56
+ collection = db[f"FD_NFL_Secondary_seed_frame"]
57
+ cursor = collection.find().limit(sharp_split)
58
+ elif slate_var == 'Auxiliary Slate':
59
+ collection = db['FD_NFL_Auxiliary_name_map']
60
+ cursor = collection.find()
61
+ raw_data = pd.DataFrame(list(cursor))
62
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
63
+ collection = db[f"FD_NFL_Auxiliary_seed_frame"]
64
+ cursor = collection.find().limit(sharp_split)
65
+
66
+ raw_display = pd.DataFrame(list(cursor))
67
+ raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
68
+ dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
69
+ for col in dict_columns:
70
+ raw_display[col] = raw_display[col].map(names_dict)
71
+ FD_seed = raw_display.to_numpy()
72
+
73
+ return FD_seed
74
+
75
+ @st.cache_data(ttl = 599)
76
+ def init_baselines(slate_var):
77
+ collection = db["DK_NFL_ROO"]
78
+ cursor = collection.find()
79
+
80
+ raw_display = pd.DataFrame(list(cursor))
81
+ raw_display = raw_display[raw_display['slate'] == slate_var]
82
+ raw_display = raw_display[raw_display['version'] == 'overall']
83
+ dk_raw = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
84
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_ID', 'site']]
85
+ dk_raw['STDev'] = (dk_raw['Ceiling'] - dk_raw['Floor']) / 4
86
+
87
+ collection = db["FD_NFL_ROO"]
88
+ cursor = collection.find()
89
+
90
+ raw_display = pd.DataFrame(list(cursor))
91
+ raw_display = raw_display[raw_display['slate'] == slate_var]
92
+ raw_display = raw_display[raw_display['version'] == 'overall']
93
+ fd_raw = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
94
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_ID', 'site']]
95
+ fd_raw['STDev'] = (fd_raw['Ceiling'] - fd_raw['Floor']) / 4
96
+
97
+ return dk_raw, fd_raw
98
+
99
+ @st.cache_data
100
+ def convert_df(array):
101
+ array = pd.DataFrame(array, columns=column_names)
102
+ return array.to_csv().encode('utf-8')
103
+
104
+ @st.cache_data
105
+ def calculate_DK_value_frequencies(np_array):
106
+ unique, counts = np.unique(np_array[:, :9], return_counts=True)
107
+ frequencies = counts / len(np_array) # Normalize by the number of rows
108
+ combined_array = np.column_stack((unique, frequencies))
109
+ return combined_array
110
+
111
+ @st.cache_data
112
+ def calculate_FD_value_frequencies(np_array):
113
+ unique, counts = np.unique(np_array[:, :9], return_counts=True)
114
+ frequencies = counts / len(np_array) # Normalize by the number of rows
115
+ combined_array = np.column_stack((unique, frequencies))
116
+ return combined_array
117
+
118
+ @st.cache_data
119
+ def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size):
120
+ SimVar = 1
121
+ Sim_Winners = []
122
+ fp_array = seed_frame.copy()
123
+ # Pre-vectorize functions
124
+ vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)
125
+ vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)
126
+
127
+ st.write('Simulating contest on frames')
128
+
129
+ while SimVar <= Sim_size:
130
+ fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)]
131
+
132
+ sample_arrays1 = np.c_[
133
+ fp_random,
134
+ np.sum(np.random.normal(
135
+ loc=vec_projection_map(fp_random[:, :-7]),
136
+ scale=vec_stdev_map(fp_random[:, :-7])),
137
+ axis=1)
138
+ ]
139
+
140
+ sample_arrays = sample_arrays1
141
+
142
+ final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]]
143
+ best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]
144
+ Sim_Winners.append(best_lineup)
145
+ SimVar += 1
146
+
147
+ return Sim_Winners
src/sim_func_hold/showdown_functions.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ from pymongo import MongoClient
5
+ from database import db
6
+
7
+ @st.cache_data(ttl = 599)
8
+ def init_DK_SD_seed_frames(slate, split):
9
+ if slate == 'Showdown #1':
10
+ collection = db["DK_NFL_SD_seed_frame"]
11
+ elif slate == 'Showdown #2':
12
+ collection = db["DK_NFL_Secondary_SD_seed_frame"]
13
+ elif slate == 'Showdown #3':
14
+ collection = db["DK_NFL_Auxiliary_SD_seed_frame"]
15
+
16
+ cursor = collection.find().limit(split)
17
+
18
+ raw_display = pd.DataFrame(list(cursor))
19
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
20
+ DK_seed = raw_display.to_numpy()
21
+
22
+ return DK_seed
23
+
24
+ @st.cache_data(ttl = 599)
25
+ def init_FD_SD_seed_frames(slate, split):
26
+ if slate == 'Showdown #1':
27
+ collection = db[f"FD_NFL_SD_seed_frame"]
28
+ elif slate == 'Showdown #2':
29
+ collection = db[f"FD_NFL_Secondary_SD_seed_frame"]
30
+ elif slate == 'Showdown #3':
31
+ collection = db[f"FD_NFL_Auxiliary_SD_seed_frame"]
32
+
33
+ cursor = collection.find().limit(split)
34
+
35
+ raw_display = pd.DataFrame(list(cursor))
36
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
37
+ FD_seed = raw_display.to_numpy()
38
+
39
+ return FD_seed
40
+
41
+ @st.cache_data(ttl = 599)
42
+ def init_SD_baselines(slate_var):
43
+ collection = db['DK_SD_NFL_ROO']
44
+ cursor = collection.find()
45
+
46
+ raw_display = pd.DataFrame(list(cursor))
47
+ raw_display = raw_display[raw_display['slate'] == slate_var]
48
+ raw_display = raw_display[raw_display['version'] == 'overall']
49
+ raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
50
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
51
+ raw_display = raw_display.rename(columns={'player_id': 'player_ID'})
52
+ raw_display['Small_Field_Own'] = raw_display['Large_Field_Own']
53
+ raw_display['small_CPT_Own_raw'] = (raw_display['Small_Field_Own'] / 2) * ((100 - (100-raw_display['Small_Field_Own']))/100)
54
+ small_cpt_own_var = 300 / raw_display['small_CPT_Own_raw'].sum()
55
+ raw_display['small_CPT_Own'] = raw_display['small_CPT_Own_raw'] * small_cpt_own_var
56
+ raw_display['cpt_Median'] = raw_display['Median'] * 1.25
57
+ raw_display['STDev'] = raw_display['Median'] / 4
58
+ raw_display['CPT_STDev'] = raw_display['cpt_Median'] / 4
59
+
60
+ dk_raw = raw_display.dropna(subset=['Median'])
61
+
62
+ collection = db['FD_SD_NFL_ROO']
63
+ cursor = collection.find()
64
+
65
+ raw_display = pd.DataFrame(list(cursor))
66
+ raw_display = raw_display[raw_display['slate'] == slate_var]
67
+ raw_display = raw_display[raw_display['version'] == 'overall']
68
+ raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
69
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
70
+ raw_display = raw_display.rename(columns={'player_id': 'player_ID'})
71
+ raw_display['Small_Field_Own'] = raw_display['Large_Field_Own']
72
+ raw_display['small_CPT_Own_raw'] = (raw_display['Small_Field_Own'] / 2) * ((100 - (100-raw_display['Small_Field_Own']))/100)
73
+ small_cpt_own_var = 300 / raw_display['small_CPT_Own_raw'].sum()
74
+ raw_display['small_CPT_Own'] = raw_display['small_CPT_Own_raw'] * small_cpt_own_var
75
+ raw_display['cpt_Median'] = raw_display['Median'] * 1.25
76
+ raw_display['STDev'] = raw_display['Median'] / 4
77
+ raw_display['CPT_STDev'] = raw_display['cpt_Median'] / 4
78
+
79
+ fd_raw = raw_display.dropna(subset=['Median'])
80
+
81
+ return dk_raw, fd_raw
82
+
83
+ @st.cache_data
84
+ def convert_df(array):
85
+ array = pd.DataFrame(array, columns=column_names)
86
+ return array.to_csv().encode('utf-8')
87
+
88
+ @st.cache_data
89
+ def calculate_SD_value_frequencies(np_array):
90
+ unique, counts = np.unique(np_array[:, :6], return_counts=True)
91
+ frequencies = counts / len(np_array) # Normalize by the number of rows
92
+ combined_array = np.column_stack((unique, frequencies))
93
+ return combined_array
94
+
95
+ @st.cache_data
96
+ def sim_SD_contest(Sim_size, seed_frame, maps_dict, Contest_Size):
97
+ SimVar = 1
98
+ Sim_Winners = []
99
+
100
+ # Pre-vectorize functions
101
+ vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)
102
+ vec_cpt_projection_map = np.vectorize(maps_dict['cpt_projection_map'].__getitem__)
103
+ vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)
104
+ vec_cpt_stdev_map = np.vectorize(maps_dict['cpt_STDev_map'].__getitem__)
105
+
106
+ st.write('Simulating contest on frames')
107
+
108
+ while SimVar <= Sim_size:
109
+ fp_random = seed_frame[np.random.choice(seed_frame.shape[0], Contest_Size)]
110
+
111
+ sample_arrays1 = np.c_[
112
+ fp_random,
113
+ np.sum(np.random.normal(
114
+ loc=np.concatenate([
115
+ vec_cpt_projection_map(fp_random[:, 0:1]), # Apply cpt_projection_map to first column
116
+ vec_projection_map(fp_random[:, 1:-7]) # Apply original projection to remaining columns
117
+ ], axis=1),
118
+ scale=np.concatenate([
119
+ vec_cpt_stdev_map(fp_random[:, 0:1]), # Apply cpt_projection_map to first column
120
+ vec_stdev_map(fp_random[:, 1:-7]) # Apply original projection to remaining columns
121
+ ], axis=1)),
122
+ axis=1)
123
+ ]
124
+
125
+ sample_arrays = sample_arrays1
126
+
127
+ final_array = sample_arrays[sample_arrays[:, 7].argsort()[::-1]]
128
+ best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]
129
+ Sim_Winners.append(best_lineup)
130
+ SimVar += 1
131
+
132
+ return Sim_Winners
src/streamlit_app.py CHANGED
@@ -1,40 +1,790 @@
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
  import numpy as np
3
  import pandas as pd
4
+ import pymongo
5
+ import re
6
+ import os
7
+ from itertools import combinations
8
+
9
+
10
+ st.set_page_config(layout="wide")
11
+
12
+ from database import db
13
+ from sim_func_hold.regular_functions import *
14
+ from sim_func_hold.showdown_functions import *
15
+
16
+ percentages_format = {'Exposure': '{:.2%}'}
17
+ freq_format = {'Exposure': '{:.2%}', 'Proj Own': '{:.2%}', 'Edge': '{:.2%}'}
18
+ dk_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
19
+ fd_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
20
+ dk_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
21
+ fd_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
22
+
23
+ st.markdown("""
24
+ <style>
25
+ /* Tab styling */
26
+ .stElementContainer [data-baseweb="button-group"] {
27
+ gap: 2.000rem;
28
+ padding: 4px;
29
+ }
30
+ .stElementContainer [kind="segmented_control"] {
31
+ height: 2.000rem;
32
+ white-space: pre-wrap;
33
+ background-color: #68B1E7;
34
+ color: white;
35
+ border-radius: 20px;
36
+ gap: 1px;
37
+ padding: 10px 20px;
38
+ font-weight: bold;
39
+ transition: all 0.3s ease;
40
+ }
41
+ .stElementContainer [kind="segmented_controlActive"] {
42
+ height: 3.000rem;
43
+ background-color: #68B1E7;
44
+ border: 3px solid #4FB286;
45
+ border-radius: 10px;
46
+ color: black;
47
+ }
48
+ .stElementContainer [kind="segmented_control"]:hover {
49
+ background-color: #4FB286;
50
+ cursor: pointer;
51
+ }
52
+
53
+ div[data-baseweb="select"] > div {
54
+ background-color: #68B1E7;
55
+ color: white;
56
+ }
57
+
58
+ </style>""", unsafe_allow_html=True)
59
+
60
+ if st.button("Load/Reset Data", key='reset2'):
61
+ st.cache_data.clear()
62
+ for key in st.session_state.keys():
63
+ del st.session_state[key]
64
+ DK_seed = init_DK_seed_frames('Main Slate', 10000)
65
+ DK_sd_seed = init_DK_SD_seed_frames('Main Slate', 10000)
66
+ FD_seed = init_FD_seed_frames('Main Slate', 10000)
67
+ FD_sd_seed = init_FD_SD_seed_frames('Main Slate', 10000)
68
+ dk_raw, fd_raw = init_baselines('Main Slate')
69
+ dk_sd_raw, fd_sd_raw = init_SD_baselines('Main Slate')
70
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
71
+ dk_sd_id_dict = dict(zip(dk_sd_raw.Player, dk_sd_raw.player_ID))
72
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
73
+ fd_sd_id_dict = dict(zip(fd_sd_raw.Player, fd_sd_raw.player_ID))
74
+
75
+ selected_tab = st.segmented_control(
76
+ "Select Tab",
77
+ options=["Regular Slate Contest Sims", "Showdown Contest Sims"],
78
+ selection_mode='single',
79
+ default='Regular Slate Contest Sims',
80
+ width='stretch',
81
+ label_visibility='collapsed',
82
+ key='tab_selector'
83
+ )
84
+
85
+ if selected_tab == "Regular Slate Contest Sims":
86
+ dk_raw, fd_raw = init_baselines('Main Slate')
87
+ raw_baselines = dk_raw
88
+ column_names = dk_columns
89
+ with st.expander("Info and Filters"):
90
+ site_data_col, slate_data_col, contest_size_col, contest_sharpness_col = st.columns([1, 1, 1, 1])
91
+ with site_data_col:
92
+ sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
93
+
94
+ with slate_data_col:
95
+ sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Late Slate'), key='sim_slate_var1')
96
+
97
+ with contest_size_col:
98
+ contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large'))
99
+ if contest_var1 == 'Small':
100
+ Contest_Size = 1000
101
+ elif contest_var1 == 'Medium':
102
+ Contest_Size = 5000
103
+ elif contest_var1 == 'Large':
104
+ Contest_Size = 10000
105
+ elif contest_var1 == 'Custom':
106
+ Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
107
+ with contest_sharpness_col:
108
+ strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
109
+ if strength_var1 == 'Not Very':
110
+ sharp_split = 500000
111
+ elif strength_var1 == 'Below Average':
112
+ sharp_split = 250000
113
+ elif strength_var1 == 'Average':
114
+ sharp_split = 100000
115
+ elif strength_var1 == 'Above Average':
116
+ sharp_split = 50000
117
+ elif strength_var1 == 'Very':
118
+ sharp_split = 10000
119
+
120
+ if st.button("Run Contest Sim"):
121
+
122
+ if 'working_seed' not in st.session_state:
123
+ if sim_site_var1 == 'Draftkings':
124
+ st.session_state.working_seed = init_DK_seed_frames(sim_slate_var1, sharp_split)
125
+ dk_raw, fd_raw = init_baselines(sim_slate_var1)
126
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
127
+
128
+ raw_baselines = dk_raw
129
+ column_names = dk_columns
130
+ elif sim_site_var1 == 'Fanduel':
131
+ st.session_state.working_seed = init_FD_seed_frames(sim_slate_var1, sharp_split)
132
+ dk_raw, fd_raw = init_baselines(sim_slate_var1)
133
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
134
+
135
+ raw_baselines = fd_raw
136
+ column_names = fd_columns
137
+ st.session_state.maps_dict = {
138
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
139
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
140
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
141
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
142
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
143
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
144
+ }
145
+
146
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
147
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
148
+
149
+ #st.table(Sim_Winner_Frame)
150
+
151
+ # Initial setup
152
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
153
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
154
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
155
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
156
+
157
+ # Type Casting
158
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
159
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
160
+
161
+ # Sorting
162
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
163
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
164
+
165
+ # Data Copying
166
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
167
+ if sim_site_var1 == 'Draftkings':
168
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
169
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)
170
+ elif sim_site_var1 == 'Fanduel':
171
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
172
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(fd_id_dict)
173
+
174
+ # Data Copying
175
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
176
+ st.session_state.freq_copy = st.session_state.Sim_Winner_Display
177
+ else:
178
+ st.session_state.maps_dict = {
179
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
180
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
181
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
182
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
183
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
184
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
185
+ }
186
+
187
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
188
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
189
+
190
+ # Initial setup
191
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
192
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
193
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
194
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
195
+
196
+ # Type Casting
197
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
198
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
199
+
200
+ # Sorting
201
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
202
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
203
+
204
+ # Data Copying
205
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
206
+
207
+ # Data Copying
208
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
209
+
210
+ if sim_site_var1 == 'Draftkings':
211
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
212
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
213
+ elif sim_site_var1 == 'Fanduel':
214
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
215
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
216
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
217
+ freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])
218
+ freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])
219
+ freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
220
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
221
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
222
+ freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])
223
+ st.session_state.player_freq = freq_working.copy()
224
+
225
+ if sim_site_var1 == 'Draftkings':
226
+ qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
227
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
228
+ elif sim_site_var1 == 'Fanduel':
229
+ qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
230
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
231
+ qb_working['Freq'] = qb_working['Freq'].astype(int)
232
+ qb_working['Position'] = qb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
233
+ qb_working['Salary'] = qb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
234
+ qb_working['Proj Own'] = qb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
235
+ qb_working['Exposure'] = qb_working['Freq']/(1000)
236
+ qb_working['Edge'] = qb_working['Exposure'] - qb_working['Proj Own']
237
+ qb_working['Team'] = qb_working['Player'].map(st.session_state.maps_dict['Team_map'])
238
+ st.session_state.qb_freq = qb_working.copy()
239
+
240
+ if sim_site_var1 == 'Draftkings':
241
+ rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
242
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
243
+ elif sim_site_var1 == 'Fanduel':
244
+ rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
245
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
246
+ rbwrte_working['Freq'] = rbwrte_working['Freq'].astype(int)
247
+ rbwrte_working['Position'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Pos_map'])
248
+ rbwrte_working['Salary'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Salary_map'])
249
+ rbwrte_working['Proj Own'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
250
+ rbwrte_working['Exposure'] = rbwrte_working['Freq']/(1000)
251
+ rbwrte_working['Edge'] = rbwrte_working['Exposure'] - rbwrte_working['Proj Own']
252
+ rbwrte_working['Team'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Team_map'])
253
+ st.session_state.rbwrte_freq = rbwrte_working.copy()
254
+
255
+ if sim_site_var1 == 'Draftkings':
256
+ rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
257
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
258
+ elif sim_site_var1 == 'Fanduel':
259
+ rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
260
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
261
+ rb_working['Freq'] = rb_working['Freq'].astype(int)
262
+ rb_working['Position'] = rb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
263
+ rb_working['Salary'] = rb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
264
+ rb_working['Proj Own'] = rb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
265
+ rb_working['Exposure'] = rb_working['Freq']/(1000)
266
+ rb_working['Edge'] = rb_working['Exposure'] - rb_working['Proj Own']
267
+ rb_working['Team'] = rb_working['Player'].map(st.session_state.maps_dict['Team_map'])
268
+ st.session_state.rb_freq = rb_working.copy()
269
+
270
+ if sim_site_var1 == 'Draftkings':
271
+ wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
272
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
273
+ elif sim_site_var1 == 'Fanduel':
274
+ wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
275
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
276
+ wr_working['Freq'] = wr_working['Freq'].astype(int)
277
+ wr_working['Position'] = wr_working['Player'].map(st.session_state.maps_dict['Pos_map'])
278
+ wr_working['Salary'] = wr_working['Player'].map(st.session_state.maps_dict['Salary_map'])
279
+ wr_working['Proj Own'] = wr_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
280
+ wr_working['Exposure'] = wr_working['Freq']/(1000)
281
+ wr_working['Edge'] = wr_working['Exposure'] - wr_working['Proj Own']
282
+ wr_working['Team'] = wr_working['Player'].map(st.session_state.maps_dict['Team_map'])
283
+ st.session_state.wr_freq = wr_working.copy()
284
+
285
+ if sim_site_var1 == 'Draftkings':
286
+ te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
287
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
288
+ elif sim_site_var1 == 'Fanduel':
289
+ te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
290
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
291
+ te_working['Freq'] = te_working['Freq'].astype(int)
292
+ te_working['Position'] = te_working['Player'].map(st.session_state.maps_dict['Pos_map'])
293
+ te_working['Salary'] = te_working['Player'].map(st.session_state.maps_dict['Salary_map'])
294
+ te_working['Proj Own'] = te_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
295
+ te_working['Exposure'] = te_working['Freq']/(1000)
296
+ te_working['Edge'] = te_working['Exposure'] - te_working['Proj Own']
297
+ te_working['Team'] = te_working['Player'].map(st.session_state.maps_dict['Team_map'])
298
+ st.session_state.te_freq = te_working.copy()
299
+
300
+ if sim_site_var1 == 'Draftkings':
301
+ flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
302
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
303
+ elif sim_site_var1 == 'Fanduel':
304
+ flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
305
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
306
+ flex_working['Freq'] = flex_working['Freq'].astype(int)
307
+ flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map'])
308
+ flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map'])
309
+ flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
310
+ flex_working['Exposure'] = flex_working['Freq']/(1000)
311
+ flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
312
+ flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map'])
313
+ st.session_state.flex_freq = flex_working.copy()
314
+
315
+ if sim_site_var1 == 'Draftkings':
316
+ dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
317
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
318
+ elif sim_site_var1 == 'Fanduel':
319
+ dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
320
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
321
+ dst_working['Freq'] = dst_working['Freq'].astype(int)
322
+ dst_working['Position'] = dst_working['Player'].map(st.session_state.maps_dict['Pos_map'])
323
+ dst_working['Salary'] = dst_working['Player'].map(st.session_state.maps_dict['Salary_map'])
324
+ dst_working['Proj Own'] = dst_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
325
+ dst_working['Exposure'] = dst_working['Freq']/(1000)
326
+ dst_working['Edge'] = dst_working['Exposure'] - dst_working['Proj Own']
327
+ dst_working['Team'] = dst_working['Player'].map(st.session_state.maps_dict['Team_map'])
328
+ st.session_state.dst_freq = dst_working.copy()
329
+
330
+ if sim_site_var1 == 'Draftkings':
331
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
332
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
333
+ elif sim_site_var1 == 'Fanduel':
334
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
335
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
336
+ team_working['Freq'] = team_working['Freq'].astype(int)
337
+ team_working['Exposure'] = team_working['Freq']/(1000)
338
+ st.session_state.team_freq = team_working.copy()
339
+
340
+ with st.container():
341
+ if st.button("Reset Sim", key='reset_sim'):
342
+ for key in st.session_state.keys():
343
+ del st.session_state[key]
344
+ if 'player_freq' in st.session_state:
345
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
346
+ if player_split_var2 == 'Specific Players':
347
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
348
+ elif player_split_var2 == 'Full Players':
349
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
350
+
351
+ if player_split_var2 == 'Specific Players':
352
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]
353
+ if player_split_var2 == 'Full Players':
354
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
355
+ if 'Sim_Winner_Display' in st.session_state:
356
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
357
+ if 'Sim_Winner_Export' in st.session_state:
358
+ st.download_button(
359
+ label="Export Full Frame",
360
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
361
+ file_name='MLB_consim_export.csv',
362
+ mime='text/csv',
363
+ )
364
+ tab1, tab2 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics'])
365
+
366
+ with tab1:
367
+ if 'Sim_Winner_Display' in st.session_state:
368
+ # Create a new dataframe with summary statistics
369
+ summary_df = pd.DataFrame({
370
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
371
+ 'Salary': [
372
+ st.session_state.Sim_Winner_Display['salary'].min(),
373
+ st.session_state.Sim_Winner_Display['salary'].mean(),
374
+ st.session_state.Sim_Winner_Display['salary'].max(),
375
+ st.session_state.Sim_Winner_Display['salary'].std()
376
+ ],
377
+ 'Proj': [
378
+ st.session_state.Sim_Winner_Display['proj'].min(),
379
+ st.session_state.Sim_Winner_Display['proj'].mean(),
380
+ st.session_state.Sim_Winner_Display['proj'].max(),
381
+ st.session_state.Sim_Winner_Display['proj'].std()
382
+ ],
383
+ 'Own': [
384
+ st.session_state.Sim_Winner_Display['Own'].min(),
385
+ st.session_state.Sim_Winner_Display['Own'].mean(),
386
+ st.session_state.Sim_Winner_Display['Own'].max(),
387
+ st.session_state.Sim_Winner_Display['Own'].std()
388
+ ],
389
+ 'Fantasy': [
390
+ st.session_state.Sim_Winner_Display['Fantasy'].min(),
391
+ st.session_state.Sim_Winner_Display['Fantasy'].mean(),
392
+ st.session_state.Sim_Winner_Display['Fantasy'].max(),
393
+ st.session_state.Sim_Winner_Display['Fantasy'].std()
394
+ ],
395
+ 'GPP_Proj': [
396
+ st.session_state.Sim_Winner_Display['GPP_Proj'].min(),
397
+ st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),
398
+ st.session_state.Sim_Winner_Display['GPP_Proj'].max(),
399
+ st.session_state.Sim_Winner_Display['GPP_Proj'].std()
400
+ ]
401
+ })
402
+
403
+ # Set the index of the summary dataframe as the "Metric" column
404
+ summary_df = summary_df.set_index('Metric')
405
+
406
+ # Display the summary dataframe
407
+ st.subheader("Winning Frame Statistics")
408
+ st.dataframe(summary_df.style.format({
409
+ 'Salary': '{:.2f}',
410
+ 'Proj': '{:.2f}',
411
+ 'Fantasy': '{:.2f}',
412
+ 'GPP_Proj': '{:.2f}'
413
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)
414
+
415
+ with tab2:
416
+ if 'Sim_Winner_Display' in st.session_state:
417
+ # Apply position mapping to FLEX column
418
+ flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map'])
419
+
420
+ # Count occurrences of each position in FLEX
421
+ flex_counts = flex_positions.value_counts()
422
+
423
+ # Calculate average statistics for each FLEX position
424
+ flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({
425
+ 'proj': 'mean',
426
+ 'Own': 'mean',
427
+ 'Fantasy': 'mean',
428
+ 'GPP_Proj': 'mean'
429
+ })
430
+
431
+ # Combine counts and average statistics
432
+ flex_summary = pd.concat([flex_counts, flex_stats], axis=1)
433
+ flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
434
+ flex_summary = flex_summary.reset_index()
435
+ flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
436
+
437
+ # Display the summary dataframe
438
+ st.subheader("FLEX Position Statistics")
439
+ st.dataframe(flex_summary.style.format({
440
+ 'Count': '{:.0f}',
441
+ 'Avg Proj': '{:.2f}',
442
+ 'Avg Fantasy': '{:.2f}',
443
+ 'Avg GPP_Proj': '{:.2f}'
444
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)
445
+
446
+ else:
447
+ st.write("Simulation data or position mapping not available.")
448
+ with st.container():
449
+ tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9 = st.tabs(['Overall Exposures', 'QB Exposures', 'RB-WR-TE Exposures', 'RB Exposures', 'WR Exposures', 'TE Exposures', 'FLEX Exposures', 'DST Exposures', 'Team Exposures'])
450
+ with tab1:
451
+ if 'player_freq' in st.session_state:
452
+
453
+ st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
454
+ st.download_button(
455
+ label="Export Exposures",
456
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
457
+ file_name='player_freq_export.csv',
458
+ mime='text/csv',
459
+ key='overall'
460
+ )
461
+ with tab2:
462
+ if 'qb_freq' in st.session_state:
463
+
464
+ st.dataframe(st.session_state.qb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
465
+ st.download_button(
466
+ label="Export Exposures",
467
+ data=st.session_state.qb_freq.to_csv().encode('utf-8'),
468
+ file_name='qb_freq.csv',
469
+ mime='text/csv',
470
+ key='qb'
471
+ )
472
+ with tab3:
473
+ if 'rbwrte_freq' in st.session_state:
474
+
475
+ st.dataframe(st.session_state.rbwrte_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
476
+ st.download_button(
477
+ label="Export Exposures",
478
+ data=st.session_state.rbwrte_freq.to_csv().encode('utf-8'),
479
+ file_name='rbwrte_freq.csv',
480
+ mime='text/csv',
481
+ key='rbwrte'
482
+ )
483
+ with tab4:
484
+ if 'rb_freq' in st.session_state:
485
+
486
+ st.dataframe(st.session_state.rb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
487
+ st.download_button(
488
+ label="Export Exposures",
489
+ data=st.session_state.rb_freq.to_csv().encode('utf-8'),
490
+ file_name='rb_freq.csv',
491
+ mime='text/csv',
492
+ key='rb'
493
+ )
494
+ with tab5:
495
+ if 'wr_freq' in st.session_state:
496
+
497
+ st.dataframe(st.session_state.wr_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
498
+ st.download_button(
499
+ label="Export Exposures",
500
+ data=st.session_state.wr_freq.to_csv().encode('utf-8'),
501
+ file_name='wr_freq.csv',
502
+ mime='text/csv',
503
+ key='wr'
504
+ )
505
+ with tab6:
506
+ if 'te_freq' in st.session_state:
507
+
508
+ st.dataframe(st.session_state.te_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
509
+ st.download_button(
510
+ label="Export Exposures",
511
+ data=st.session_state.te_freq.to_csv().encode('utf-8'),
512
+ file_name='te_freq.csv',
513
+ mime='text/csv',
514
+ key='te'
515
+ )
516
+ with tab7:
517
+ if 'flex_freq' in st.session_state:
518
+
519
+ st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
520
+ st.download_button(
521
+ label="Export Exposures",
522
+ data=st.session_state.flex_freq.to_csv().encode('utf-8'),
523
+ file_name='flex_freq.csv',
524
+ mime='text/csv',
525
+ key='flex'
526
+ )
527
+ with tab8:
528
+ if 'dst_freq' in st.session_state:
529
+
530
+ st.dataframe(st.session_state.dst_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
531
+ st.download_button(
532
+ label="Export Exposures",
533
+ data=st.session_state.dst_freq.to_csv().encode('utf-8'),
534
+ file_name='dst_freq.csv',
535
+ mime='text/csv',
536
+ key='dst'
537
+ )
538
+ with tab9:
539
+ if 'team_freq' in st.session_state:
540
+
541
+ st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
542
+ st.download_button(
543
+ label="Export Exposures",
544
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
545
+ file_name='team_freq.csv',
546
+ mime='text/csv',
547
+ key='team'
548
+ )
549
+
550
+ if selected_tab == "Showdown Contest Sims":
551
+ dk_raw, fd_raw = init_SD_baselines('Showdown #1')
552
+ raw_baselines = dk_raw
553
+ column_names = dk_sd_columns
554
+ with st.expander("Info and Filters"):
555
+ site_data_col, slate_data_col, contest_size_col, contest_sharpness_col = st.columns([1, 1, 1, 1])
556
+ with site_data_col:
557
+ sim_site_var2 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var2')
558
+
559
+ with slate_data_col:
560
+ sim_slate_var2 = st.radio("Which data are you loading?", ('Showdown #1', 'Showdown #2', 'Showdown #3'), key='sim_slate_var2')
561
+
562
+ with contest_size_col:
563
+ contest_var2 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large'), key='contest_var2')
564
+ if contest_var2 == 'Small':
565
+ Contest_Size = 1000
566
+ elif contest_var2 == 'Medium':
567
+ Contest_Size = 5000
568
+ elif contest_var2 == 'Large':
569
+ Contest_Size = 10000
570
+ elif contest_var2 == 'Custom':
571
+ Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
572
+ with contest_sharpness_col:
573
+ strength_var2 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'), key='strength_var2')
574
+ if strength_var2 == 'Not Very':
575
+ sharp_split = 500000
576
+ elif strength_var2 == 'Below Average':
577
+ sharp_split = 250000
578
+ elif strength_var2 == 'Average':
579
+ sharp_split = 100000
580
+ elif strength_var2 == 'Above Average':
581
+ sharp_split = 50000
582
+ elif strength_var2 == 'Very':
583
+ sharp_split = 10000
584
+
585
+ if st.button("Run Contest Sim"):
586
+
587
+ if 'sd_working_seed' not in st.session_state:
588
+ if sim_site_var2 == 'Draftkings':
589
+ st.session_state.sd_working_seed = init_DK_SD_seed_frames(sim_slate_var2, sharp_split)
590
+ export_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
591
+ raw_baselines = dk_raw
592
+ column_names = dk_sd_columns
593
+ elif sim_site_var2 == 'Fanduel':
594
+ st.session_state.sd_working_seed = init_FD_SD_seed_frames(sim_slate_var2, sharp_split)
595
+ export_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
596
+ raw_baselines = fd_raw
597
+ column_names = fd_sd_columns
598
+ maps_dict = {
599
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
600
+ 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
601
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
602
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
603
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
604
+ 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
605
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
606
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
607
+ 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
608
+ }
609
+ Sim_Winners = sim_SD_contest(1000, st.session_state.sd_working_seed, maps_dict, Contest_Size)
610
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
611
+
612
+ #st.table(Sim_Winner_Frame)
613
+
614
+ # Initial setup
615
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
616
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
617
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
618
+
619
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
620
+
621
+ # Type Casting
622
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
623
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
624
+
625
+ # Sorting
626
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
627
+ st.session_state.Sim_Winner_Frame = st.session_state.Sim_Winner_Frame.drop(columns=['unique_id', 'win_count'])
628
+
629
+ # Data Copying
630
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
631
+ st.session_state.Sim_Winner_Export.iloc[:, 0:6] = st.session_state.Sim_Winner_Export.iloc[:, 0:6].apply(lambda x: x.map(export_id_dict))
632
+
633
+ # Data Copying
634
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
635
+ freq_copy = st.session_state.Sim_Winner_Display
636
+
637
+ else:
638
+ maps_dict = {
639
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
640
+ 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
641
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
642
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
643
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
644
+ 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
645
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
646
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
647
+ 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
648
+ }
649
+ Sim_Winners = sim_SD_contest(1000, st.session_state.working_seed, maps_dict, Contest_Size)
650
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
651
+
652
+ #st.table(Sim_Winner_Frame)
653
+
654
+ # Initial setup
655
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
656
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
657
+ Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)
658
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
659
+
660
+ # Type Casting
661
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
662
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
663
+
664
+ # Sorting
665
+ st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)
666
+ st.session_state.Sim_Winner_Frame = st.session_state.Sim_Winner_Frame.drop(columns=['unique_id', 'win_count'])
667
+
668
+ # Data Copying
669
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
670
+ st.session_state.Sim_Winner_Export.iloc[:, 0:6] = st.session_state.Sim_Winner_Export.iloc[:, 0:6].apply(lambda x: x.map(export_id_dict))
671
+
672
+ # Data Copying
673
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
674
+ freq_copy = st.session_state.Sim_Winner_Display
675
+
676
+ if sim_site_var2 == 'Draftkings':
677
+ freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:6].values, return_counts=True)),
678
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
679
+ elif sim_site_var2 == 'Fanduel':
680
+ freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:5].values, return_counts=True)),
681
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
682
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
683
+ freq_working['Position'] = freq_working['Player'].map(maps_dict['Pos_map'])
684
+ freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map']) / 1.5
685
+ freq_working['Proj Own'] = freq_working['Player'].map(maps_dict['Own_map']) / 100
686
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
687
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
688
+ freq_working['Team'] = freq_working['Player'].map(maps_dict['Team_map'])
689
+ st.session_state.player_freq = freq_working.copy()
690
+
691
+ cpt_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:1].values, return_counts=True)),
692
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
693
+ cpt_working['Freq'] = cpt_working['Freq'].astype(int)
694
+ cpt_working['Position'] = cpt_working['Player'].map(maps_dict['Pos_map'])
695
+ cpt_working['Salary'] = cpt_working['Player'].map(maps_dict['Salary_map'])
696
+ cpt_working['Proj Own'] = cpt_working['Player'].map(maps_dict['cpt_Own_map']) / 100
697
+ cpt_working['Exposure'] = cpt_working['Freq']/(1000)
698
+ cpt_working['Edge'] = cpt_working['Exposure'] - cpt_working['Proj Own']
699
+ cpt_working['Team'] = cpt_working['Player'].map(maps_dict['Team_map'])
700
+ st.session_state.sp_freq = cpt_working.copy()
701
+
702
+ flex_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,1:6].values, return_counts=True)),
703
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
704
+ cpt_own_div = 600
705
+ flex_working['Freq'] = flex_working['Freq'].astype(int)
706
+ flex_working['Position'] = flex_working['Player'].map(maps_dict['Pos_map'])
707
+ flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map']) / 1.5
708
+ flex_working['Proj Own'] = (flex_working['Player'].map(maps_dict['Own_map']) / 100) - (flex_working['Player'].map(maps_dict['cpt_Own_map']) / 100)
709
+ flex_working['Exposure'] = flex_working['Freq']/(1000)
710
+ flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
711
+ flex_working['Team'] = flex_working['Player'].map(maps_dict['Team_map'])
712
+ st.session_state.flex_freq = flex_working.copy()
713
 
714
+ team_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,8:9].values, return_counts=True)),
715
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
716
+ team_working['Freq'] = team_working['Freq'].astype(int)
717
+ team_working['Exposure'] = team_working['Freq']/(1000)
718
+ st.session_state.team_freq = team_working.copy()
719
+
720
+ with st.container():
721
+ if st.button("Reset Sim", key='reset_sim'):
722
+ for key in st.session_state.keys():
723
+ del st.session_state[key]
724
+ if 'player_freq' in st.session_state:
725
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
726
+ if player_split_var2 == 'Specific Players':
727
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
728
+ elif player_split_var2 == 'Full Players':
729
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
730
+
731
+ if player_split_var2 == 'Specific Players':
732
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]
733
+ if player_split_var2 == 'Full Players':
734
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
735
+ if 'Sim_Winner_Display' in st.session_state:
736
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
737
+ if 'Sim_Winner_Export' in st.session_state:
738
+ st.download_button(
739
+ label="Export Full Frame",
740
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
741
+ file_name='NFL_SD_consim_export.csv',
742
+ mime='text/csv',
743
+ )
744
+
745
+ with st.container():
746
+ tab1, tab2, tab3, tab4 = st.tabs(['Overall Exposures', 'CPT Exposures', 'FLEX Exposures', 'Team Exposures'])
747
+ with tab1:
748
+ if 'player_freq' in st.session_state:
749
+
750
+ st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
751
+ st.download_button(
752
+ label="Export Exposures",
753
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
754
+ file_name='player_freq_export.csv',
755
+ mime='text/csv',
756
+ key='overall'
757
+ )
758
+ with tab2:
759
+ if 'sp_freq' in st.session_state:
760
+
761
+ st.dataframe(st.session_state.sp_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
762
+ st.download_button(
763
+ label="Export Exposures",
764
+ data=st.session_state.sp_freq.to_csv().encode('utf-8'),
765
+ file_name='cpt_freq.csv',
766
+ mime='text/csv',
767
+ key='sp'
768
+ )
769
+ with tab3:
770
+ if 'flex_freq' in st.session_state:
771
+
772
+ st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
773
+ st.download_button(
774
+ label="Export Exposures",
775
+ data=st.session_state.flex_freq.to_csv().encode('utf-8'),
776
+ file_name='flex_freq.csv',
777
+ mime='text/csv',
778
+ key='flex'
779
+ )
780
+ with tab4:
781
+ if 'team_freq' in st.session_state:
782
+
783
+ st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)
784
+ st.download_button(
785
+ label="Export Exposures",
786
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
787
+ file_name='team_freq.csv',
788
+ mime='text/csv',
789
+ key='team'
790
+ )