File size: 9,838 Bytes
58cea02
 
 
 
 
 
 
 
 
 
9c7e08b
58cea02
 
 
 
 
 
 
 
d04558f
58cea02
 
 
 
 
 
1689df1
5db8a23
 
 
 
 
 
 
9c7e08b
5db8a23
 
 
 
 
58cea02
1689df1
58cea02
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356c7d4
 
3909ec7
356c7d4
 
 
 
58cea02
356c7d4
29e4551
58cea02
 
 
 
2c44968
2df0c40
 
 
 
 
53f8288
 
2df0c40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53f8288
 
 
 
 
2df0c40
2c44968
 
 
2df0c40
 
2c44968
2df0c40
 
 
 
 
 
2c44968
2df0c40
 
 
 
 
 
2c44968
2df0c40
 
 
 
 
 
94b689a
 
 
 
 
 
 
 
 
 
655c1a7
53f8288
 
655c1a7
94b689a
655c1a7
53f8288
 
655c1a7
94b689a
 
 
 
 
 
 
2df0c40
94b689a
2df0c40
 
 
 
 
 
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
import streamlit as st
st.set_page_config(layout="wide")
import numpy as np
import pandas as pd
import time
from fuzzywuzzy import process
import random

## 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))
            
            # Update projections_df with any new matches
            st.session_state['contest_df'], 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']
        with col1:
            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")


        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']))
        }
        
        if entry_parse_var == 'Specific':
            st.session_state['Contest'] = st.session_state['Contest'][st.session_state['Contest']['BaseName'].isin(entry_names)]
        else:
            st.session_state['Contest'] = st.session_state['Contest']
        
        if type_var == 'Classic':
            st.session_state['Contest']['salary'] = st.session_state['Contest'].apply(lambda row: sum(map_dict['salary_map'].get(player, 0) for player in row), axis=1)
            st.session_state['Contest']['median'] = st.session_state['Contest'].apply(lambda row: sum(map_dict['proj_map'].get(player, 0) for player in row), axis=1)
            st.session_state['Contest']['Own'] = st.session_state['Contest'].apply(lambda row: sum(map_dict['own_map'].get(player, 0) for player in row), axis=1)
        elif type_var == 'Showdown':
            # Calculate salary (CPT uses cpt_salary_map, others use salary_map)
            st.session_state['Contest']['salary'] = st.session_state['Contest'].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
            )
            
            # Calculate median (CPT uses cpt_proj_map, others use proj_map)
            st.session_state['Contest']['median'] = st.session_state['Contest'].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
            )
            
            # Calculate ownership (CPT uses cpt_own_map, others use own_map)
            st.session_state['Contest']['Own'] = st.session_state['Contest'].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
            )

        with col2:
            
            # 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(st.session_state['Contest'])
            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])  # Last column for spacing
            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(
                st.session_state['Contest'].iloc[start_idx:end_idx].style
                .background_gradient(axis=0)
                .background_gradient(cmap='RdYlGn')
                .format(precision=2), 
                height=1000,
                use_container_width=True
            )