File size: 6,231 Bytes
86f5e84
6492af1
7a18dc2
f18ed57
7a18dc2
8bbcbe6
e80e35a
949a661
7a18dc2
f47916d
f18ed57
949a661
 
 
 
 
 
 
 
 
 
1749eaf
 
 
 
 
 
 
 
 
949a661
f47916d
2e0b4a6
1749eaf
76225a1
1749eaf
76225a1
 
8bbcbe6
6054b1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6492af1
1749eaf
 
 
 
6492af1
 
 
8bbcbe6
f5c14f1
f47916d
f18ed57
e2b52d0
 
7a18dc2
c0c7d17
949a661
 
 
 
 
 
 
1749eaf
8bbcbe6
c0c7d17
7a18dc2
 
5509410
a3ce631
c0c7d17
 
a3ce631
 
 
 
 
 
 
4fbbbf8
 
 
949a661
286c902
949a661
4fbbbf8
 
 
949a661
 
4fbbbf8
 
 
949a661
 
 
 
4fbbbf8
 
 
 
 
 
 
1749eaf
 
4fbbbf8
 
00e2e2c
4fbbbf8
 
 
00e2e2c
a3ce631
 
 
c9e9696
9ca89ad
c9e9696
ed96343
a544bb0
3965984
 
 
 
 
 
 
 
 
f5c14f1
 
3965984
 
 
1749eaf
 
 
3965984
1749eaf
 
 
3965984
 
c9e9696
7a18dc2
 
f18ed57
 
93b83fd
e80e35a
f18ed57
5509410
 
 
 
 
 
b7f4f75
f18ed57
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import os
import numpy as np
import pandas as pd
import streamlit as st

from config import DEFAULT_ICON, LEAGUE_NAME, LEAGUE_NUMBER_TEAMS
from shared_page import common_page_config
from streamlit_filter import filter_dataframe


KEEPER_DATA_URL = "../../tests/mocks/2023_keepers.csv"
HEADSHOT_DATA_URL = "../../tests/mocks/2023_player_headshots.csv"


def load_player_ids() -> pd.DataFrame:
    df = pd.read_csv(r"https://raw.githubusercontent.com/dynastyprocess/data/master/files/db_playerids.csv")
    df["merge_id"] = df["yahoo_id"].combine_first(df["stats_id"])
    return df


def load_adp() -> pd.DataFrame:
    df = pd.read_csv(r"https://raw.githubusercontent.com/dynastyprocess/data/master/files/db_fpecr_latest.csv")
    df = df.loc[
        df.fp_page == "/nfl/rankings/ppr-superflex-cheatsheets.php",
        [
            "yahoo_id",
            "ecr",
            "sd",
        ],
    ]
    return df


def convert_ecr_to_round_val(ecr_float: float, round_offset: float = 1.0, pick_offset: float = -1.0) -> float:
    # As a float, store pick 1 of round 1 as 1.0
    return round_offset + (ecr_float + pick_offset) / LEAGUE_NUMBER_TEAMS


def add_opinionated_keeper_value(df: pd.DataFrame):
    # Manual Hack for overranking of backup QBs
    df.loc[
        df["name"].isin(
            [
                "Teddy Bridgewater",
                "Davis Mills",
                "Andy Dalton",
                "Tyler Huntley",
                "Mike White",
                "Gardner Minshew",
                "Colt McCoy",
                "Sam Darnold",
                "Carson Wentz",
                "Trey Lance",
                "Taylor Heinicke",
            ]
        ),
        ["ecr"],
    ] = np.nan

    df["ecr"] = df["ecr"].apply(convert_ecr_to_round_val)
    # Convert sd without offset to show as pure pick diff
    df["sd"] = df["sd"].apply(lambda x: convert_ecr_to_round_val(x, 0, 0))
    # assumes midround keeper
    # fill -99 for players that are not ranked in ecr
    df["value_keeper"] = (df["keeper_cost"] + 0.5 - df["ecr"]).fillna(-99)


@st.cache_data(ttl=60 * 60 * 24)
def load_data():
    data = pd.read_csv(os.path.join(os.path.dirname(__file__), KEEPER_DATA_URL), index_col=0)
    # Hack to get position, replace with better position from yahoo api in future
    data["position"] = data["eligible_positions"].apply(lambda x: eval(x)[0])
    data.columns = data.columns.str.lower()
    teams_list = sorted(list(data["team_name"].unique()))

    # Merge player ids
    df_player_ids = load_player_ids()
    data = data.merge(df_player_ids, how="left", left_on="player_id", right_on="merge_id", suffixes=("", "_ids"))

    # Merge ADP
    df_adp = load_adp()
    data = data.merge(df_adp, how="left", left_on="player_id", right_on="yahoo_id", suffixes=("", "_adp"))
    add_opinionated_keeper_value(data)
    return data, teams_list


def filtered_keeper_dataframe(data: pd.DataFrame, teams_list: list[str]):
    teams_selected = st.multiselect("Team:", teams_list, placeholder="Select a user team to filter")
    teams_filter = data["team_name"].isin(teams_selected) if teams_selected else data["team_name"].isin(teams_list)

    eligible_options = [True, False]
    is_eligible_selected = st.multiselect(
        "Keeper Eligible:", eligible_options, placeholder="Select True to filter eligible only"
    )
    eligible_filter = (
        data["eligible"].isin(is_eligible_selected) if is_eligible_selected else data["eligible"].isin(eligible_options)
    )
    is_advanced = st.checkbox("Show Advanced View")

    id_cols = [
        "team_name",
        "headshot_url",
        "name",
    ]

    id_cols_advanced = [
        "team",
        "position",
    ]

    cost_cols = [
        "keeper_cost",
        "eligible",
    ]

    cost_cols_advanced = [
        "years_eligible",
    ]

    adp_cols: list[str] = []

    adp_cols_advanced = [
        "ecr",
        "value_keeper",
    ]

    if is_advanced:
        show_columns = id_cols + id_cols_advanced + cost_cols + cost_cols_advanced + adp_cols + adp_cols_advanced
    else:
        show_columns = id_cols + cost_cols + adp_cols

    data_with_filters_applied = data.loc[teams_filter & eligible_filter, show_columns]

    filtered_data = filter_dataframe(data_with_filters_applied)
    st.dataframe(
        filtered_data,
        hide_index=True,
        height=35 * (len(filtered_data) + 1) + 12,
        use_container_width=True,
        column_config={
            "team_name": st.column_config.TextColumn(label="League Team", help="Name of fantasy League team."),
            "headshot_url": st.column_config.ImageColumn(label="", help="Player image"),
            "name": st.column_config.TextColumn(label="Name", help="Player's name"),
            "team": st.column_config.TextColumn(label="NFL Team"),
            "position": st.column_config.TextColumn(label="Position", help="Player's position"),
            "keeper_cost": st.column_config.NumberColumn(
                label="Keeper Cost", help="Draft Round Cost to keep player.  See Rules for details."
            ),
            "eligible": st.column_config.CheckboxColumn(label="Eligible", help="Is player eligible to be keeper?"),
            "years_eligible": st.column_config.NumberColumn(
                label="Years Eligible",
                help="Number of further consecutive seasons player can be kept (subject to maximum of 2)",
            ),
            "ecr": st.column_config.NumberColumn(
                label="ECR",
                help="Player's average draft round.pick Expert Consensus Rank (ECR) for PPR - Superflex League",
            ),
            "value_keeper": st.column_config.NumberColumn(
                label="Value Keeper",
                help="Approx. number of draft rounds of keeper value vs ECR PPR - Superflex League",
            ),
        },
    )


def get_keeper_app():
    keeper_title = f"{LEAGUE_NAME} Keeper Options"
    st.set_page_config(page_title=keeper_title, page_icon=DEFAULT_ICON, layout="wide")
    common_page_config()
    st.title(keeper_title)
    data, teams_list = load_data()

    with st.container():
        filtered_keeper_dataframe(data, teams_list)


if __name__ == "__main__":
    get_keeper_app()