File size: 5,309 Bytes
6d2d129
 
 
 
 
 
 
 
 
 
 
 
42841bf
6d2d129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
01d0fea
 
6d2d129
4bfd7b8
01d0fea
 
 
 
4bfd7b8
 
6d2d129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80cfc94
 
 
 
 
6d2d129
 
 
 
31e15be
 
 
 
 
 
 
6d2d129
 
 
42841bf
6d2d129
 
dc974d8
6d2d129
 
 
 
 
dc974d8
 
 
 
6d2d129
 
 
 
42841bf
459585e
42841bf
6d2d129
 
 
 
 
 
 
31e15be
4bfd7b8
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from dataclasses import dataclass
import pandas as pd
import streamlit as st

from domain.constants import SEASON
from domain.playoffs import (
    PLAYOFF_WEEK_TO_NAME,
    ROSTER_WEEK_TO_PLAYOFF_WEEK,
    PLAYOFFS_TEAMS,
    PLAYOFF_TEAM_DEF_PLAYER,
)
from queries.nflverse.github_data import get_weekly_rosters
from queries.pfr.league_schedule import get_season_game_map


@dataclass
class PlayerOption:
    full_name: str
    gsis_id: str
    headshot_url: str
    position: str
    team: str
    gametime: pd.Timestamp | None
    week: int | 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,
            week=int(input_series.week),
        )

    @classmethod
    def empty_player(cls, week: int | None = None, position: str = ""):
        return cls(full_name="", gsis_id="", headshot_url="", position=position, team="", gametime=None, week=week)

    @classmethod
    def hidden_player(cls, week: int | None = None, position: str = ""):
        return cls(
            full_name="Hidden", gsis_id="", headshot_url="", position=position, team="", gametime=None, week=week
        )

    def is_locked(self) -> bool:
        if not self.gametime:
            return False
        else:
            date_compare = (pd.Timestamp.now(tz="America/New_York")) + pd.Timedelta(days=0, hours=0)
            return self.gametime < date_compare


def initialize_empty_options_map() -> dict[str, dict[int, list[PlayerOption]]]:
    options_map: dict[str, dict[int, list[PlayerOption]]] = {}
    for pos in ["QB", "RB", "WR", "TE", "K", "DEF"]:
        options_map[pos] = {}
        for week in PLAYOFF_WEEK_TO_NAME.keys():
            options_map[pos][int(week)] = [PlayerOption.empty_player(week=week)]
    return options_map


def player_options_from_df(df_options) -> dict[str, dict[int, list[PlayerOption]]]:
    options_map = initialize_empty_options_map()
    for pos, pos_week_map in options_map.items():
        for week in pos_week_map.keys():
            df_pos_week = df_options[((df_options.week == week) & (df_options.position == pos))]
            if len(df_pos_week) > 0:
                player_options_list = df_pos_week.apply(PlayerOption.from_series, axis=1).tolist()
                options_map[pos][int(week)].extend(player_options_list)
    return options_map


def modify_defensive_players_to_be_team_defense(df_options):
    for team, player_id in PLAYOFF_TEAM_DEF_PLAYER:
        if player_id in df_options.gsis_id.values:
            df_options.loc[df_options.gsis_id == player_id, "position"] = "DEF"
            df_options.loc[df_options.gsis_id == player_id, "full_name"] = team.team_name


def display_player(player_opt: PlayerOption | None):
    if player_opt:
        if player_opt.headshot_url:
            st.image(player_opt.headshot_url)
        if player_opt.full_name:
            st.write(player_opt.full_name)
            if player_opt.gametime:
                gametime_str = player_opt.gametime.strftime("%-m/%-d %-I:%M %p")
            else:
                gametime_str = ""
            st.write(f"{player_opt.team} - {gametime_str}")


@st.cache_data(ttl=60 * 60 * 24)
def load_options():
    df_rosters = load_options_df()
    player_options = player_options_from_df(df_rosters)
    return player_options


@st.cache_data(ttl=60 * 60 * 24)
def load_options_df():
    df_rosters = get_weekly_rosters()

    # get game schedules
    week_game_times, latest_game_time_defaults = get_season_game_map(SEASON)

    # sort
    sort_by_cols = ["position", "fantasy_points", "week"]
    df_rosters.sort_values(sort_by_cols, ascending=False, inplace=True)

    # filter data from non-playoffs
    df_rosters = df_rosters[df_rosters.week.isin(ROSTER_WEEK_TO_PLAYOFF_WEEK.keys())]
    df_rosters["week"] = df_rosters["week"].map(ROSTER_WEEK_TO_PLAYOFF_WEEK)

    # Filter out duplicates which occur for week 1 (bye players come from week 18)
    df_rosters = df_rosters.drop_duplicates(subset=["gsis_id", "week"])

    # set gametime
    if len(df_rosters) == 0:
        return initialize_empty_options_map()
    df_rosters["gametime"] = df_rosters.apply(
        lambda x: week_game_times.get(x.week, {})
        .get(x.team, {})
        .get("gametime", latest_game_time_defaults.get(x.week, None)),
        axis=1,
    )

    df_rosters["in_playoffs"] = df_rosters.apply(lambda x: x.team in PLAYOFFS_TEAMS[x.week], axis=1)

    df_rosters = df_rosters[df_rosters.in_playoffs]
    modify_defensive_players_to_be_team_defense(df_rosters)
    return df_rosters


@st.cache_data(ttl=60 * 60 * 24)
def get_map_week_player_id_option() -> dict[int, dict[str, PlayerOption]]:
    options_pos_week_map = load_options()
    options_week_id_map: dict[int, dict[str, PlayerOption]] = {k: {} for k in PLAYOFF_WEEK_TO_NAME.keys()}

    for _, pos_map in options_pos_week_map.items():
        for week, pos_week_opt_list in pos_map.items():
            for player_opt in pos_week_opt_list:
                options_week_id_map[week][player_opt.gsis_id] = player_opt
    return options_week_id_map