File size: 10,237 Bytes
58cea02 d765ee8 58cea02 9c7e08b 58cea02 d04558f 58cea02 1689df1 5db8a23 9c7e08b 5db8a23 58cea02 1689df1 58cea02 356c7d4 3909ec7 356c7d4 e24862c 6d04e58 58cea02 6d04e58 2df0c40 2c57866 e24862c 2df0c40 e24862c 2df0c40 6d04e58 e24862c 2c57866 d765ee8 2c57866 6d04e58 d765ee8 6d04e58 2df0c40 e24862c |
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 180 181 182 183 184 185 |
import streamlit as st
st.set_page_config(layout="wide")
import numpy as np
import pandas as pd
import time
from fuzzywuzzy import process
from collections import Counter
## import global functions
from global_func.clean_player_name import clean_player_name
from global_func.load_contest_file import load_contest_file
from global_func.load_file import load_file
from global_func.load_ss_file import load_ss_file
from global_func.find_name_mismatches import find_name_mismatches
from global_func.predict_dupes import predict_dupes
from global_func.highlight_rows import highlight_changes, highlight_changes_winners, highlight_changes_losers
from global_func.load_csv import load_csv
from global_func.find_csv_mismatches import find_csv_mismatches
tab1, tab2 = st.tabs(["Data Load", "Contest Analysis"])
with tab1:
if st.button('Clear data', key='reset1'):
st.session_state.clear()
# Add file uploaders to your app
col1, col2, col3 = st.columns(3)
with col1:
st.subheader("Contest File")
st.info("Go ahead and upload a Contest file here. Only include player columns and an optional 'Stack' column if you are playing MLB.")
Contest_file = st.file_uploader("Upload Contest File (CSV or Excel)", type=['csv', 'xlsx', 'xls'])
if 'Contest' in st.session_state:
del st.session_state['Contest']
if Contest_file:
st.session_state['Contest'], st.session_state['ownership_dict'], st.session_state['entry_list'] = load_contest_file(Contest_file)
st.session_state['Contest'] = st.session_state['Contest'].dropna(how='all')
st.session_state['Contest'] = st.session_state['Contest'].reset_index(drop=True)
if st.session_state['Contest'] is not None:
st.success('Contest file loaded successfully!')
st.dataframe(st.session_state['Contest'].head(10))
with col2:
st.subheader("Projections File")
st.info("upload a projections file that has 'player_names', 'salary', 'median', 'ownership', and 'captain ownership' (Needed for Showdown) columns. Note that the salary for showdown needs to be the FLEX salary, not the captain salary.")
# Create two columns for the uploader and template button
upload_col, template_col = st.columns([3, 1])
with upload_col:
projections_file = st.file_uploader("Upload Projections File (CSV or Excel)", type=['csv', 'xlsx', 'xls'])
if 'projections_df' in st.session_state:
del st.session_state['projections_df']
with template_col:
# Create empty DataFrame with required columns
template_df = pd.DataFrame(columns=['player_names', 'position', 'team', 'salary', 'median', 'ownership', 'captain ownership'])
# Add download button for template
st.download_button(
label="Template",
data=template_df.to_csv(index=False),
file_name="projections_template.csv",
mime="text/csv"
)
if projections_file:
export_projections, projections = load_file(projections_file)
if projections is not None:
st.success('Projections file loaded successfully!')
st.dataframe(projections.head(10))
if Contest_file and projections_file:
if st.session_state['Contest'] is not None and projections is not None:
st.subheader("Name Matching functions")
# Initialize projections_df in session state if it doesn't exist
if 'projections_df' not in st.session_state:
st.session_state['projections_df'] = projections.copy()
st.session_state['projections_df']['salary'] = (st.session_state['projections_df']['salary'].astype(str).str.replace(',', '').astype(float).astype(int))
# Run name matching only once when first loading the files
st.session_state['Contest'], st.session_state['projections_df'] = find_name_mismatches(st.session_state['Contest'], st.session_state['projections_df'])
with tab2:
if st.button('Clear data', key='reset3'):
st.session_state.clear()
if 'Contest' in st.session_state and 'projections_df' in st.session_state:
col1, col2 = st.columns([1, 8])
excluded_cols = ['BaseName', 'EntryCount']
# Create mapping dictionaries
map_dict = {
'pos_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['position'])),
'team_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['team'])),
'salary_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['salary'])),
'proj_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['median'])),
'own_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['ownership'])),
'own_percent_rank': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['ownership'].rank(pct=True))),
'cpt_salary_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['salary'])),
'cpt_proj_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['median'] * 1.5)),
'cpt_own_map': dict(zip(st.session_state['projections_df']['player_names'], st.session_state['projections_df']['captain ownership']))
}
# Create a copy of the dataframe for calculations
working_df = st.session_state['Contest'].copy()
with col1:
with st.expander("Info and filters"):
with st.form(key='filter_form'):
type_var = st.selectbox("Select Game Type", ['Classic', 'Showdown'])
entry_parse_var = st.selectbox("Do you want to view a specific player(s) or a group of players?", ['All', 'Specific'])
entry_names = st.multiselect("Select players", options=st.session_state['entry_list'], default=[])
submitted = st.form_submit_button("Submit")
if submitted:
# Apply entry name filter if specific entries are selected
if entry_parse_var == 'Specific' and entry_names:
working_df = working_df[working_df['BaseName'].isin(entry_names)]
# Calculate metrics based on game type
if type_var == 'Classic':
working_df['stack'] = working_df.apply(
lambda row: Counter(
map_dict['team_map'].get(player, '') for player in row
if map_dict['team_map'].get(player, '') != ''
).most_common(1)[0][0] if any(map_dict['team_map'].get(player, '') for player in row) else '',
axis=1
)
working_df['stack_size'] = working_df.apply(
lambda row: Counter(
map_dict['team_map'].get(player, '') for player in row
if map_dict['team_map'].get(player, '') != ''
).most_common(1)[0][1] if any(map_dict['team_map'].get(player, '') for player in row) else '',
axis=1
)
working_df['salary'] = working_df.apply(lambda row: sum(map_dict['salary_map'].get(player, 0) for player in row), axis=1)
working_df['median'] = working_df.apply(lambda row: sum(map_dict['proj_map'].get(player, 0) for player in row), axis=1)
working_df['Own'] = working_df.apply(lambda row: sum(map_dict['own_map'].get(player, 0) for player in row), axis=1)
elif type_var == 'Showdown':
working_df['salary'] = working_df.apply(
lambda row: map_dict['cpt_salary_map'].get(row.iloc[0], 0) +
sum(map_dict['salary_map'].get(player, 0) for player in row.iloc[1:]),
axis=1
)
working_df['median'] = working_df.apply(
lambda row: map_dict['cpt_proj_map'].get(row.iloc[0], 0) +
sum(map_dict['proj_map'].get(player, 0) for player in row.iloc[1:]),
axis=1
)
working_df['Own'] = working_df.apply(
lambda row: map_dict['cpt_own_map'].get(row.iloc[0], 0) +
sum(map_dict['own_map'].get(player, 0) for player in row.iloc[1:]),
axis=1
)
# Initialize pagination in session state if not exists
if 'current_page' not in st.session_state:
st.session_state.current_page = 0
# Calculate total pages
rows_per_page = 500
total_rows = len(working_df)
total_pages = (total_rows + rows_per_page - 1) // rows_per_page
# Create pagination controls in a single row
pagination_cols = st.columns([4, 1, 1, 1, 4])
with pagination_cols[1]:
if st.button("β Previous", disabled=st.session_state.current_page == 0):
st.session_state.current_page -= 1
with pagination_cols[2]:
st.markdown(f"**Page {st.session_state.current_page + 1} of {total_pages}**", unsafe_allow_html=True)
with pagination_cols[3]:
if st.button("Next β", disabled=st.session_state.current_page == total_pages - 1):
st.session_state.current_page += 1
# Calculate start and end indices for current page
start_idx = st.session_state.current_page * rows_per_page
end_idx = min((st.session_state.current_page + 1) * rows_per_page, total_rows)
# Display the paginated dataframe
st.dataframe(
working_df.iloc[start_idx:end_idx].style
.background_gradient(axis=0)
.background_gradient(cmap='RdYlGn')
.format(precision=2),
height=1000,
use_container_width=True,
hide_index=True
)
|