James McCool commited on
Commit
7d39b16
Β·
1 Parent(s): 473e375

Adding projections management

Browse files
Files changed (1) hide show
  1. app.py +154 -2
app.py CHANGED
@@ -1266,7 +1266,7 @@ with st.container():
1266
  try:
1267
  selected_tab = st.segmented_control(
1268
  "Select Tab",
1269
- options=["Data Load", "Manage Portfolio"],
1270
  selection_mode='single',
1271
  default='Data Load',
1272
  label_visibility='collapsed',
@@ -1276,7 +1276,7 @@ try:
1276
  except:
1277
  selected_tab = st.segmented_control(
1278
  "Select Tab",
1279
- options=["Data Load", "Manage Portfolio"],
1280
  selection_mode='single',
1281
  default='Data Load',
1282
  label_visibility='collapsed',
@@ -1738,6 +1738,158 @@ if selected_tab == 'Data Load':
1738
 
1739
  del st.session_state['portfolio'], st.session_state['export_portfolio']
1740
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1741
  if selected_tab == 'Manage Portfolio':
1742
  if 'base_frame_names' not in st.session_state:
1743
  st.session_state['base_frame_names'] = {}
 
1266
  try:
1267
  selected_tab = st.segmented_control(
1268
  "Select Tab",
1269
+ options=["Data Load", "Projections Management", "Manage Portfolio"],
1270
  selection_mode='single',
1271
  default='Data Load',
1272
  label_visibility='collapsed',
 
1276
  except:
1277
  selected_tab = st.segmented_control(
1278
  "Select Tab",
1279
+ options=["Data Load", "Projections Management", "Manage Portfolio"],
1280
  selection_mode='single',
1281
  default='Data Load',
1282
  label_visibility='collapsed',
 
1738
 
1739
  del st.session_state['portfolio'], st.session_state['export_portfolio']
1740
 
1741
+
1742
+ if selected_tab == 'Projections Management':
1743
+ if 'projections_df' in st.session_state and st.session_state['projections_df'] is not None:
1744
+ st.subheader("Edit Player Projections")
1745
+ st.caption("Modify median, ownership, or captain ownership values directly in the table below. Changes will update both the projections and all related mappings.")
1746
+
1747
+ # Get the current projections dataframe
1748
+ projections_editor_df = st.session_state['projections_df'].copy()
1749
+
1750
+ # Define column configuration for the data editor
1751
+ column_config = {
1752
+ 'player_names': st.column_config.TextColumn(
1753
+ 'Player',
1754
+ disabled=True,
1755
+ width='medium'
1756
+ ),
1757
+ 'position': st.column_config.TextColumn(
1758
+ 'Position',
1759
+ disabled=True,
1760
+ width='small'
1761
+ ),
1762
+ 'team': st.column_config.TextColumn(
1763
+ 'Team',
1764
+ disabled=True,
1765
+ width='small'
1766
+ ),
1767
+ 'salary': st.column_config.NumberColumn(
1768
+ 'Salary',
1769
+ disabled=True,
1770
+ width='small',
1771
+ format='$%d'
1772
+ ),
1773
+ 'median': st.column_config.NumberColumn(
1774
+ 'Median',
1775
+ min_value=0.0,
1776
+ max_value=100.0,
1777
+ step=0.1,
1778
+ format='%.2f',
1779
+ width='small'
1780
+ ),
1781
+ 'ownership': st.column_config.NumberColumn(
1782
+ 'Ownership %',
1783
+ min_value=0.0,
1784
+ max_value=100.0,
1785
+ step=0.1,
1786
+ format='%.2f',
1787
+ width='small'
1788
+ ),
1789
+ 'captain ownership': st.column_config.NumberColumn(
1790
+ 'Captain Own %',
1791
+ min_value=0.0,
1792
+ max_value=100.0,
1793
+ step=0.1,
1794
+ format='%.2f',
1795
+ width='small'
1796
+ )
1797
+ }
1798
+
1799
+ # Search/filter functionality
1800
+ search_col, team_filter_col, position_filter_col = st.columns([2, 1, 1])
1801
+ with search_col:
1802
+ player_search = st.text_input("πŸ” Search players", placeholder="Type player name...", key='proj_player_search')
1803
+ with team_filter_col:
1804
+ team_options = ['All Teams'] + sorted(projections_editor_df['team'].unique().tolist())
1805
+ team_filter = st.selectbox("Filter by Team", options=team_options, key='proj_team_filter')
1806
+ with position_filter_col:
1807
+ position_options = ['All Positions'] + sorted(projections_editor_df['position'].unique().tolist())
1808
+ position_filter = st.selectbox("Filter by Position", options=position_options, key='proj_position_filter')
1809
+
1810
+ # Apply filters
1811
+ filtered_df = projections_editor_df.copy()
1812
+ if player_search:
1813
+ filtered_df = filtered_df[filtered_df['player_names'].str.contains(player_search, case=False, na=False)]
1814
+ if team_filter != 'All Teams':
1815
+ filtered_df = filtered_df[filtered_df['team'] == team_filter]
1816
+ if position_filter != 'All Positions':
1817
+ filtered_df = filtered_df[filtered_df['position'] == position_filter]
1818
+
1819
+ # Display the editable dataframe
1820
+ edited_df = st.data_editor(
1821
+ filtered_df,
1822
+ column_config=column_config,
1823
+ use_container_width=True,
1824
+ hide_index=True,
1825
+ num_rows='fixed',
1826
+ key='projections_editor'
1827
+ )
1828
+
1829
+ # Check for changes and update
1830
+ if not edited_df.equals(filtered_df):
1831
+ # Find which rows changed
1832
+ changed_mask = ~(edited_df[['median', 'ownership', 'captain ownership']] == filtered_df[['median', 'ownership', 'captain ownership']]).all(axis=1)
1833
+ changed_rows = edited_df[changed_mask]
1834
+
1835
+ if len(changed_rows) > 0:
1836
+ # Update the projections_df in session state
1837
+ for idx, row in changed_rows.iterrows():
1838
+ player_name = row['player_names']
1839
+
1840
+ # Find and update the original projections_df
1841
+ orig_idx = st.session_state['projections_df'][st.session_state['projections_df']['player_names'] == player_name].index
1842
+ if len(orig_idx) > 0:
1843
+ st.session_state['projections_df'].loc[orig_idx[0], 'median'] = row['median']
1844
+ st.session_state['projections_df'].loc[orig_idx[0], 'ownership'] = row['ownership']
1845
+ st.session_state['projections_df'].loc[orig_idx[0], 'captain ownership'] = row['captain ownership']
1846
+
1847
+ # Update map_dict entries
1848
+ if 'map_dict' in st.session_state:
1849
+ st.session_state['map_dict']['proj_map'][player_name] = float(row['median'])
1850
+ st.session_state['map_dict']['own_map'][player_name] = float(row['ownership'])
1851
+
1852
+ # Update ownership percent rank
1853
+ ownership_series = pd.Series(st.session_state['map_dict']['own_map'])
1854
+ st.session_state['map_dict']['own_percent_rank'] = dict(ownership_series.rank(pct=True).astype('float32'))
1855
+
1856
+ # Update captain mappings based on site/type/sport configuration
1857
+ if 'cpt_proj_map' in st.session_state['map_dict']:
1858
+ # Determine the multiplier based on site/type/sport
1859
+ if site_var == 'Draftkings':
1860
+ if type_var == 'Showdown' and sport_var == 'GOLF':
1861
+ st.session_state['map_dict']['cpt_proj_map'][player_name] = float(row['median'])
1862
+ else:
1863
+ st.session_state['map_dict']['cpt_proj_map'][player_name] = float(row['median']) * 1.5
1864
+ elif site_var == 'Fanduel':
1865
+ st.session_state['map_dict']['cpt_proj_map'][player_name] = float(row['median']) * 1.5
1866
+
1867
+ if 'cpt_own_map' in st.session_state['map_dict']:
1868
+ # Captain ownership uses the captain ownership column directly
1869
+ if type_var == 'Showdown' and sport_var == 'GOLF':
1870
+ st.session_state['map_dict']['cpt_own_map'][player_name] = float(row['ownership'])
1871
+ else:
1872
+ st.session_state['map_dict']['cpt_own_map'][player_name] = float(row['captain ownership'])
1873
+
1874
+ # Clear working_frame to force recalculation with new projections
1875
+ if 'working_frame' in st.session_state:
1876
+ del st.session_state['working_frame']
1877
+
1878
+ st.success(f"βœ… Updated {len(changed_rows)} player(s). Portfolio metrics will recalculate on next view.")
1879
+ st.rerun()
1880
+
1881
+ # Display summary statistics
1882
+ st.divider()
1883
+ summary_col1, summary_col2, summary_col3 = st.columns(3)
1884
+ with summary_col1:
1885
+ st.metric("Total Players", len(projections_editor_df))
1886
+ with summary_col2:
1887
+ st.metric("Avg Median", f"{projections_editor_df['median'].mean():.2f}")
1888
+ with summary_col3:
1889
+ st.metric("Avg Ownership", f"{projections_editor_df['ownership'].mean():.2f}%")
1890
+ else:
1891
+ st.info("πŸ“‹ No projections file loaded yet. Please upload projections in the Data Load tab first.")
1892
+
1893
  if selected_tab == 'Manage Portfolio':
1894
  if 'base_frame_names' not in st.session_state:
1895
  st.session_state['base_frame_names'] = {}