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()