Spaces:
Sleeping
Sleeping
Jon Solow
commited on
Commit
·
b586854
1
Parent(s):
d27a450
Add MRS Table
Browse files- src/maximum_roster_strategy/__init__.py +0 -0
- src/maximum_roster_strategy/data_loader.py +11 -0
- src/page_selector.py +1 -0
- src/pages/4_Practice_Reports.py +11 -8
- src/pages/80_Maximum_Roster_Strategy.py +85 -0
- src/shared_page.py +8 -0
- src/style.css +14 -0
src/maximum_roster_strategy/__init__.py
ADDED
File without changes
|
src/maximum_roster_strategy/data_loader.py
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
|
5 |
+
MRS_SHEET_ID = os.environ.get("MRS_SHEET_ID")
|
6 |
+
|
7 |
+
|
8 |
+
def get_google_sheet_data() -> pd.DataFrame:
|
9 |
+
sheet_url = f"https://docs.google.com/spreadsheet/ccc?key={MRS_SHEET_ID}&output=csv"
|
10 |
+
df = pd.read_csv(sheet_url)
|
11 |
+
return df
|
src/page_selector.py
CHANGED
@@ -15,6 +15,7 @@ MODE_PAGE_EXCLUSION_MAP = {
|
|
15 |
"Keepers",
|
16 |
"ECR",
|
17 |
"League_Simulation",
|
|
|
18 |
],
|
19 |
OFFSEASON_MODE: [
|
20 |
"Practice_Reports",
|
|
|
15 |
"Keepers",
|
16 |
"ECR",
|
17 |
"League_Simulation",
|
18 |
+
"Keep_Rules",
|
19 |
],
|
20 |
OFFSEASON_MODE: [
|
21 |
"Practice_Reports",
|
src/pages/4_Practice_Reports.py
CHANGED
@@ -5,6 +5,7 @@ from config import DEFAULT_ICON
|
|
5 |
from shared_page import common_page_config
|
6 |
|
7 |
from queries.nfl_teams.practice_reports import scrape_all_team_injury_report, CURRENT_SEASON, CURRENT_WEEK
|
|
|
8 |
|
9 |
|
10 |
@st.cache_data(ttl=60 * 60 * 1)
|
@@ -42,14 +43,16 @@ def get_page():
|
|
42 |
)
|
43 |
|
44 |
with st.container():
|
45 |
-
filtered_data =
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
53 |
st.dataframe(
|
54 |
filtered_data,
|
55 |
hide_index=True,
|
|
|
5 |
from shared_page import common_page_config
|
6 |
|
7 |
from queries.nfl_teams.practice_reports import scrape_all_team_injury_report, CURRENT_SEASON, CURRENT_WEEK
|
8 |
+
from streamlit_filter import filter_dataframe
|
9 |
|
10 |
|
11 |
@st.cache_data(ttl=60 * 60 * 1)
|
|
|
43 |
)
|
44 |
|
45 |
with st.container():
|
46 |
+
filtered_data = filter_dataframe(
|
47 |
+
data[
|
48 |
+
(
|
49 |
+
data.Team.isin(teams_selected)
|
50 |
+
& data.Position.isin(positions_selected)
|
51 |
+
& data.game_status.isin(status_selected)
|
52 |
+
& data["Last Practice Day"].isin(last_practice_day_selected)
|
53 |
+
)
|
54 |
+
]
|
55 |
+
)
|
56 |
st.dataframe(
|
57 |
filtered_data,
|
58 |
hide_index=True,
|
src/pages/80_Maximum_Roster_Strategy.py
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
|
4 |
+
from config import DEFAULT_ICON
|
5 |
+
from shared_page import common_page_config
|
6 |
+
from maximum_roster_strategy import data_loader
|
7 |
+
|
8 |
+
|
9 |
+
MINIMUM_WEEK = 6
|
10 |
+
MAXIMUM_WEEK = 6
|
11 |
+
|
12 |
+
MIN_TIER = 1
|
13 |
+
MAX_TIER = 4
|
14 |
+
|
15 |
+
POSITION_OPTIONS = ["RB", "WR", "TE", "QB"]
|
16 |
+
|
17 |
+
POSITION_ABBR_FULL_NAME_MAP = {
|
18 |
+
"RB": "Running Backs",
|
19 |
+
"WR": "Wide Receivers",
|
20 |
+
"TE": "Tight Ends",
|
21 |
+
"QB": "Quarterbacks (Superflex / 2QB Leagues Only)",
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
@st.cache_data(ttl=60 * 60 * 24)
|
26 |
+
def load_data():
|
27 |
+
return data_loader.get_google_sheet_data()
|
28 |
+
|
29 |
+
|
30 |
+
def get_player_container(player_series: pd.Series):
|
31 |
+
with st.expander(label=player_series["Formatted"]):
|
32 |
+
st.write(player_series["Hold Condition"])
|
33 |
+
if isinstance(notes := player_series["Article Notes"], str):
|
34 |
+
st.write(notes)
|
35 |
+
|
36 |
+
|
37 |
+
# https://github.com/alanjones2/alan-jones-article-code/blob/master/stgrid/app/gridapp.py
|
38 |
+
def make_grid(cols, rows):
|
39 |
+
grid = [0] * cols
|
40 |
+
for i in range(cols):
|
41 |
+
with st.container():
|
42 |
+
grid[i] = st.columns(rows[i])
|
43 |
+
return grid
|
44 |
+
|
45 |
+
|
46 |
+
def get_position_breakdown(df: pd.DataFrame, position_abbr: str, position_full_str: str):
|
47 |
+
with st.container():
|
48 |
+
st.header(position_full_str)
|
49 |
+
df_pos = df[df["Position"] == position_abbr]
|
50 |
+
time_slots = df.sort_values("WeekTimeSlotIndex")["TimeSlotName"].unique().tolist()
|
51 |
+
tier_list = list(range(MIN_TIER, MAX_TIER + 1))
|
52 |
+
num_time_slots = len(time_slots)
|
53 |
+
column_len_list = [num_time_slots] + [1, num_time_slots] * len(tier_list)
|
54 |
+
tier_time_grid = make_grid(len(tier_list) * 2 + 1, column_len_list)
|
55 |
+
|
56 |
+
for time_idx, time_slot in enumerate(time_slots):
|
57 |
+
with tier_time_grid[0][time_idx]:
|
58 |
+
st.markdown(f"<h3 style='text-align: center;'>{time_slot}</h3>", unsafe_allow_html=True)
|
59 |
+
for tier_idx, tier in enumerate(tier_list):
|
60 |
+
if time_idx == 0:
|
61 |
+
with tier_time_grid[(tier_idx + 1) * 2 - 1][0]:
|
62 |
+
st.markdown(f"<h4 style='text-align: center;'>Tier {tier}</h4>", unsafe_allow_html=True)
|
63 |
+
df_tier_slot = df_pos[(df_pos["TimeSlotName"] == time_slot) & (df_pos["Tier"] == tier)]
|
64 |
+
with tier_time_grid[(tier_idx + 1) * 2][time_idx]:
|
65 |
+
df_tier_slot.apply(get_player_container, axis=1)
|
66 |
+
|
67 |
+
|
68 |
+
def get_page():
|
69 |
+
page_title = "Maximum Roster Strategy"
|
70 |
+
st.set_page_config(page_title=page_title, page_icon=DEFAULT_ICON, layout="wide")
|
71 |
+
common_page_config()
|
72 |
+
st.title(page_title)
|
73 |
+
col_select, week_select = st.columns(2, gap="small")
|
74 |
+
with col_select:
|
75 |
+
position = st.selectbox(label="Position", options=POSITION_OPTIONS, index=0)
|
76 |
+
with week_select:
|
77 |
+
week = st.selectbox(label="Week", options=list(range(MAXIMUM_WEEK, MINIMUM_WEEK - 1, -1)), index=0)
|
78 |
+
df_mrs = load_data()
|
79 |
+
df_mrs = df_mrs[df_mrs["Week"] == week]
|
80 |
+
|
81 |
+
get_position_breakdown(df_mrs, position, POSITION_ABBR_FULL_NAME_MAP[position])
|
82 |
+
|
83 |
+
|
84 |
+
if __name__ == "__main__":
|
85 |
+
get_page()
|
src/shared_page.py
CHANGED
@@ -1,7 +1,15 @@
|
|
|
|
|
|
1 |
from page_selector import remove_seasonal_pages
|
2 |
from login_component import get_authorization_button
|
3 |
|
4 |
|
|
|
|
|
|
|
|
|
|
|
5 |
def common_page_config():
|
6 |
get_authorization_button()
|
7 |
remove_seasonal_pages()
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
from page_selector import remove_seasonal_pages
|
4 |
from login_component import get_authorization_button
|
5 |
|
6 |
|
7 |
+
def local_css(file_name):
|
8 |
+
with open(file_name) as f:
|
9 |
+
st.markdown("<style>{}</style>".format(f.read()), unsafe_allow_html=True)
|
10 |
+
|
11 |
+
|
12 |
def common_page_config():
|
13 |
get_authorization_button()
|
14 |
remove_seasonal_pages()
|
15 |
+
local_css("style.css")
|
src/style.css
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
div[data-testid="stVerticalBlock"] > div[data-testid="stHorizontalBlock"] > div[data-testid="column"] {
|
2 |
+
border-style: solid;
|
3 |
+
border-right-style: solid;
|
4 |
+
border-width: 1px;
|
5 |
+
border-color: grey;
|
6 |
+
}
|
7 |
+
|
8 |
+
div[data-testid="stHorizontalBlock"] {
|
9 |
+
gap: 0;
|
10 |
+
}
|
11 |
+
|
12 |
+
div[data-testid="stVerticalBlock"] {
|
13 |
+
gap: 0;
|
14 |
+
}
|