Jon Solow
Implement game time in options
4393241
raw
history blame
5.91 kB
from dataclasses import dataclass
import pandas as pd
import streamlit as st
from config import DEFAULT_ICON
from shared_page import common_page_config
from domain.constants import SEASON
from domain.playoffs import PLAYOFF_WEEK_TO_NAME, CURRENT_PLAYOFF_WEEK, PLAYOFF_WEEK_TO_SCHEDULE_WEEK
from domain.teams import SCHEDULE_NAME_TO_PFR_NAME_MAP
from queries.nflverse.github_data import get_weekly_rosters
from queries.pfr.league_schedule import get_season_time_map
from login import check_password, get_user_team, save_user_team
@dataclass
class PlayerOption:
full_name: str
gsis_id: str
headshot_url: str
position: str
team: str
gametime: pd.Timestamp | None
@classmethod
def from_series(cls, input_series):
return cls(
full_name=input_series.full_name,
gsis_id=input_series.gsis_id,
headshot_url=input_series.headshot_url,
position=input_series.position,
team=input_series.team,
gametime=input_series.gametime,
)
@classmethod
def empty_player(cls):
return cls(
full_name="",
gsis_id="",
headshot_url="",
position="",
team="",
gametime=None,
)
def player_options_from_df(df_options, position_filter: str) -> list[PlayerOption]:
empty_first_option_list = [PlayerOption.empty_player()]
return (
empty_first_option_list
+ df_options[df_options.position == position_filter].apply(PlayerOption.from_series, axis=1).tolist()
)
@st.cache_data(ttl=60 * 60 * 24)
def load_options():
# filter active only
df_rosters = get_weekly_rosters()
df_rosters = df_rosters[df_rosters.status == "ACT"]
# get current week games
schedule_week = PLAYOFF_WEEK_TO_SCHEDULE_WEEK[CURRENT_PLAYOFF_WEEK]
current_week_game_times = get_season_time_map(SEASON)[schedule_week]
latest_game_time = max(current_week_game_times.values())
# select latest
sort_by_cols = ["position", "week", "fantasy_points"]
df_rosters = df_rosters.sort_values(sort_by_cols, ascending=False).drop_duplicates(subset="gsis_id")
# set gametime
df_rosters["gametime"] = df_rosters.apply(
lambda x: current_week_game_times.get(SCHEDULE_NAME_TO_PFR_NAME_MAP[x.team], latest_game_time), axis=1
)
qb_options = player_options_from_df(df_rosters, "QB")
wr_options = player_options_from_df(df_rosters, "WR")
rb_options = player_options_from_df(df_rosters, "RB")
te_options = player_options_from_df(df_rosters, "TE")
k_options = player_options_from_df(df_rosters, "K")
return qb_options, wr_options, rb_options, te_options, k_options
def format_player_option(player_opt: PlayerOption) -> str:
return f"{player_opt.team} - {player_opt.full_name}"
def display_player(player_opt: PlayerOption | None):
if player_opt:
if player_opt.headshot_url:
st.image(player_opt.headshot_url, caption=player_opt.full_name)
def position_cell(week: str, pos_str: str, options_list: list[PlayerOption], existing_selection_map):
pos_label = f"{week}-{pos_str}"
selected_id = existing_selection_map.get(pos_label)
if isinstance(selected_id, str):
selected_option_idx, selected_player = next(
(i, v) for i, v in enumerate(options_list) if str(selected_id) == str(v.gsis_id)
)
else:
selected_player = PlayerOption.empty_player()
selected_option_idx = 0
if int(week) > CURRENT_PLAYOFF_WEEK:
options = []
selected_option_idx = 0
elif int(week) < CURRENT_PLAYOFF_WEEK:
options = [selected_player]
selected_option_idx = 0
else:
options = options_list
selected_player_from_box = st.selectbox(
pos_str,
options=options,
format_func=format_player_option,
index=selected_option_idx,
key=pos_label,
)
if selected_player_from_box and int(week) == CURRENT_PLAYOFF_WEEK:
if selected_player_from_box.gsis_id and selected_player_from_box.gsis_id != selected_id:
update_and_save_selection(pos_label, selected_player_from_box.gsis_id, existing_selection_map),
display_player(selected_player_from_box)
def update_and_save_selection(pos_label: str, selection_id: str, existing_selection_map):
existing_selection_map[pos_label] = selection_id
save_user_team(existing_selection_map)
def get_page():
page_title = "Select Your Team"
st.set_page_config(page_title=page_title, page_icon=DEFAULT_ICON, layout="wide")
common_page_config()
if not check_password():
st.write("Sorry, you must be logged in first to play")
st.stop()
st.title(page_title)
if st.button("Refresh Data"):
st.rerun()
existing_selections = get_user_team()
qb_options, wr_options, rb_options, te_options, k_options = load_options()
for week in range(1, 5):
st.header(PLAYOFF_WEEK_TO_NAME[week])
selection_cols = st.columns(8)
with selection_cols[0]:
position_cell(week, "QB-1", qb_options, existing_selections)
with selection_cols[1]:
position_cell(week, "RB-1", rb_options, existing_selections)
with selection_cols[2]:
position_cell(week, "RB-2", rb_options, existing_selections)
with selection_cols[3]:
position_cell(week, "WR-1", wr_options, existing_selections)
with selection_cols[4]:
position_cell(week, "WR-2", wr_options, existing_selections)
with selection_cols[5]:
position_cell(week, "TE-1", te_options, existing_selections)
with selection_cols[6]:
position_cell(week, "K-1", k_options, existing_selections)
with selection_cols[7]:
position_cell(week, "DEF-1", [], existing_selections)
if __name__ == "__main__":
get_page()