|
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: |
|
|
|
return round_offset + (ecr_float + pick_offset) / LEAGUE_NUMBER_TEAMS |
|
|
|
|
|
def add_opinionated_keeper_value(df: pd.DataFrame): |
|
|
|
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) |
|
|
|
df["sd"] = df["sd"].apply(lambda x: convert_ecr_to_round_val(x, 0, 0)) |
|
|
|
|
|
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) |
|
|
|
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())) |
|
|
|
|
|
df_player_ids = load_player_ids() |
|
data = data.merge(df_player_ids, how="left", left_on="player_id", right_on="merge_id", suffixes=("", "_ids")) |
|
|
|
|
|
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() |
|
|