rairo commited on
Commit
6ab8cdb
·
verified ·
1 Parent(s): 1188007

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +698 -57
src/streamlit_app.py CHANGED
@@ -1,68 +1,709 @@
1
-
2
  import streamlit as st
3
  import pandas as pd
4
- from nba_data import get_player_id, get_player_stats
5
- import altair as alt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- st.set_page_config(page_title="NBA Head-to-Head", page_icon="🏀")
8
- st.title("🏀 NBA Head-to-Head Player Comparison")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
- # --- Player 1 ---
11
- player_1 = st.text_input("🔎 Player 1 Full Name", key="player_1")
12
- player_2 = st.text_input("🆚 Player 2 Full Name", key="player_2")
 
13
 
14
- stats_1 = None
15
- stats_2 = None
16
- season_selected = None
 
17
 
18
- if player_1 and player_2:
19
- player_1_id = get_player_id(player_1)
20
- player_2_id = get_player_id(player_2)
 
 
 
 
 
 
21
 
22
- if player_1_id and player_2_id:
23
- stats_1 = get_player_stats(player_1_id)
24
- stats_2 = get_player_stats(player_2_id)
 
 
 
 
 
 
25
 
26
- common_seasons = sorted(
27
- list(set(stats_1["SEASON_ID"]).intersection(set(stats_2["SEASON_ID"]))), reverse=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- if common_seasons:
31
- season_selected = st.selectbox("📅 Select Season", common_seasons)
32
-
33
- df_1 = stats_1[stats_1["SEASON_ID"] == season_selected]
34
- df_2 = stats_2[stats_2["SEASON_ID"] == season_selected]
35
-
36
- st.subheader(f"📊 {player_1} vs {player_2} - {season_selected}")
37
- combined = pd.DataFrame({
38
- "Stat": ["PTS", "AST", "REB", "STL", "BLK"],
39
- player_1: [
40
- float(df_1["PTS"].values[0]),
41
- float(df_1["AST"].values[0]),
42
- float(df_1["REB"].values[0]),
43
- float(df_1["STL"].values[0]),
44
- float(df_1["BLK"].values[0]),
45
- ],
46
- player_2: [
47
- float(df_2["PTS"].values[0]),
48
- float(df_2["AST"].values[0]),
49
- float(df_2["REB"].values[0]),
50
- float(df_2["STL"].values[0]),
51
- float(df_2["BLK"].values[0]),
52
- ],
53
- })
54
-
55
- chart_data = combined.melt("Stat", var_name="Player", value_name="Value")
56
-
57
- chart = alt.Chart(chart_data).mark_bar().encode(
58
- x="Stat:N",
59
- y="Value:Q",
60
- color="Player:N",
61
- tooltip=["Player", "Stat", "Value"]
62
- ).properties(width=600, height=400)
63
-
64
- st.altair_chart(chart, use_container_width=True)
65
- else:
66
- st.warning("These players do not have overlapping seasons.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  else:
68
- st.error("One or both players not found.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import pandas as pd
3
+ import numpy as np
4
+ import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ from plotly.subplots import make_subplots
7
+ import requests
8
+ from nba_api.stats.endpoints import (
9
+ playercareerstats, playercompare, teamdetails, teamgamelog,
10
+ leaguegamelog, playergamelog, commonplayerinfo, teamplayerdashboard,
11
+ leagueleaders, playerestimatedmetrics, teamestimatedmetrics
12
+ )
13
+ from nba_api.stats.static import players, teams
14
+ import time
15
+ from datetime import datetime
16
+ import json
17
+
18
+ # Page configuration
19
+ st.set_page_config(
20
+ page_title="NBA Analytics Hub",
21
+ page_icon="🏀",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # Custom CSS
27
+ st.markdown("""
28
+ <style>
29
+ .main-header {
30
+ font-size: 3rem;
31
+ font-weight: bold;
32
+ text-align: center;
33
+ color: #1f77b4;
34
+ margin-bottom: 2rem;
35
+ }
36
+ .section-header {
37
+ font-size: 1.5rem;
38
+ font-weight: bold;
39
+ color: #2e8b57;
40
+ margin: 1rem 0;
41
+ }
42
+ .metric-card {
43
+ background-color: #f0f2f6;
44
+ padding: 1rem;
45
+ border-radius: 10px;
46
+ margin: 0.5rem 0;
47
+ }
48
+ </style>
49
+ """, unsafe_allow_html=True)
50
+
51
+ # Initialize session state
52
+ if 'chat_history' not in st.session_state:
53
+ st.session_state.chat_history = []
54
+
55
+ # Perplexity API configuration
56
+ PERPLEXITY_API_KEY = st.secrets.get("PERPLEXITY_API_KEY", "")
57
 
58
+ def query_perplexity(prompt, max_tokens=500):
59
+ """Query Perplexity Sonar API"""
60
+ if not PERPLEXITY_API_KEY:
61
+ return "Please configure your Perplexity API key in Streamlit secrets."
62
+
63
+ url = "https://api.perplexity.ai/chat/completions"
64
+ headers = {
65
+ "Authorization": f"Bearer {PERPLEXITY_API_KEY}",
66
+ "Content-Type": "application/json"
67
+ }
68
+
69
+ data = {
70
+ "model": "llama-3.1-sonar-small-128k-online",
71
+ "messages": [{"role": "user", "content": prompt}],
72
+ "max_tokens": max_tokens,
73
+ "temperature": 0.2
74
+ }
75
+
76
+ try:
77
+ response = requests.post(url, json=data, headers=headers)
78
+ response.raise_for_status()
79
+ return response.json()["choices"][0]["message"]["content"]
80
+ except Exception as e:
81
+ return f"Error querying Perplexity API: {str(e)}"
82
 
83
+ @st.cache_data(ttl=3600)
84
+ def get_all_players():
85
+ """Get all NBA players"""
86
+ return players.get_players()
87
 
88
+ @st.cache_data(ttl=3600)
89
+ def get_all_teams():
90
+ """Get all NBA teams"""
91
+ return teams.get_teams()
92
 
93
+ @st.cache_data(ttl=300)
94
+ def get_player_stats(player_id, season_type="Regular Season"):
95
+ """Get player career stats"""
96
+ try:
97
+ career_stats = playercareerstats.PlayerCareerStats(player_id=player_id)
98
+ return career_stats.get_data_frames()[0]
99
+ except Exception as e:
100
+ st.error(f"Error fetching player stats: {str(e)}")
101
+ return pd.DataFrame()
102
 
103
+ @st.cache_data(ttl=300)
104
+ def get_team_stats(team_id, season="2023-24"):
105
+ """Get team stats"""
106
+ try:
107
+ team_dashboard = teamplayerdashboard.TeamPlayerDashboard(team_id=team_id, season=season)
108
+ return team_dashboard.get_data_frames()[1] # Team stats
109
+ except Exception as e:
110
+ st.error(f"Error fetching team stats: {str(e)}")
111
+ return pd.DataFrame()
112
 
113
+ def create_comparison_chart(data, players_names, metric):
114
+ """Create comparison chart for players"""
115
+ fig = go.Figure()
116
+
117
+ for i, player in enumerate(players_names):
118
+ if player in data['PLAYER_NAME'].values:
119
+ player_data = data[data['PLAYER_NAME'] == player]
120
+ fig.add_trace(go.Scatter(
121
+ x=player_data['SEASON_ID'],
122
+ y=player_data[metric],
123
+ mode='lines+markers',
124
+ name=player,
125
+ line=dict(width=3)
126
+ ))
127
+
128
+ fig.update_layout(
129
+ title=f"{metric} Comparison",
130
+ xaxis_title="Season",
131
+ yaxis_title=metric,
132
+ hovermode='x unified',
133
+ height=500
134
+ )
135
+
136
+ return fig
137
+
138
+ def create_radar_chart(player_stats, categories):
139
+ """Create radar chart for player comparison"""
140
+ fig = go.Figure()
141
+
142
+ for player_name, stats in player_stats.items():
143
+ fig.add_trace(go.Scatterpolar(
144
+ r=[stats.get(cat, 0) for cat in categories],
145
+ theta=categories,
146
+ fill='toself',
147
+ name=player_name,
148
+ opacity=0.7
149
+ ))
150
+
151
+ fig.update_layout(
152
+ polar=dict(
153
+ radialaxis=dict(
154
+ visible=True,
155
+ range=[0, 100]
156
+ )),
157
+ showlegend=True,
158
+ title="Player Comparison Radar Chart"
159
+ )
160
+
161
+ return fig
162
+
163
+ # Main app
164
+ def main():
165
+ st.markdown('<h1 class="main-header">🏀 NBA Analytics Hub</h1>', unsafe_allow_html=True)
166
+
167
+ # Sidebar navigation
168
+ st.sidebar.title("Navigation")
169
+ page = st.sidebar.selectbox(
170
+ "Choose Analysis Type",
171
+ [
172
+ "Player vs Player Comparison",
173
+ "Team vs Team Analysis",
174
+ "NBA Awards Predictor",
175
+ "AI Chat & Insights",
176
+ "Young Player Projections",
177
+ "Similar Players Finder",
178
+ "Roster Builder"
179
+ ]
180
+ )
181
+
182
+ if page == "Player vs Player Comparison":
183
+ player_comparison_page()
184
+ elif page == "Team vs Team Analysis":
185
+ team_comparison_page()
186
+ elif page == "NBA Awards Predictor":
187
+ awards_predictor_page()
188
+ elif page == "AI Chat & Insights":
189
+ ai_chat_page()
190
+ elif page == "Young Player Projections":
191
+ young_player_projections_page()
192
+ elif page == "Similar Players Finder":
193
+ similar_players_page()
194
+ elif page == "Roster Builder":
195
+ roster_builder_page()
196
+
197
+ def player_comparison_page():
198
+ st.markdown('<h2 class="section-header">Player vs Player Comparison</h2>', unsafe_allow_html=True)
199
+
200
+ # Get all players
201
+ all_players = get_all_players()
202
+ player_names = [player['full_name'] for player in all_players]
203
+
204
+ col1, col2 = st.columns(2)
205
+
206
+ with col1:
207
+ selected_players = st.multiselect(
208
+ "Select Players to Compare (up to 4)",
209
+ player_names,
210
+ max_selections=4
211
  )
212
+
213
+ with col2:
214
+ seasons = st.multiselect(
215
+ "Select Seasons",
216
+ ["2023-24", "2022-23", "2021-22", "2020-21", "2019-20"],
217
+ default=["2023-24"]
218
+ )
219
+
220
+ if selected_players:
221
+ # Get player IDs
222
+ player_ids = []
223
+ for name in selected_players:
224
+ player_id = next((p['id'] for p in all_players if p['full_name'] == name), None)
225
+ if player_id:
226
+ player_ids.append(player_id)
227
+
228
+ # Fetch and display stats
229
+ stats_tabs = st.tabs(["Basic Stats", "Advanced Stats", "Visualizations"])
230
+
231
+ with stats_tabs[0]:
232
+ st.subheader("Basic Statistics")
233
+ basic_stats_data = []
234
+
235
+ for i, player_id in enumerate(player_ids):
236
+ stats_df = get_player_stats(player_id)
237
+ if not stats_df.empty:
238
+ # Filter by selected seasons
239
+ filtered_stats = stats_df[stats_df['SEASON_ID'].isin(seasons)]
240
+ if not filtered_stats.empty:
241
+ avg_stats = filtered_stats.mean(numeric_only=True)
242
+ avg_stats['PLAYER_NAME'] = selected_players[i]
243
+ basic_stats_data.append(avg_stats)
244
+
245
+ if basic_stats_data:
246
+ comparison_df = pd.DataFrame(basic_stats_data)
247
+ basic_cols = ['PLAYER_NAME', 'GP', 'MIN', 'PTS', 'REB', 'AST', 'STL', 'BLK', 'FG_PCT', 'FT_PCT', 'FG3_PCT']
248
+ display_cols = [col for col in basic_cols if col in comparison_df.columns]
249
+ st.dataframe(comparison_df[display_cols].round(2), use_container_width=True)
250
+
251
+ with stats_tabs[1]:
252
+ st.subheader("Advanced Statistics")
253
+ # Display advanced metrics like PER, TS%, etc.
254
+ if basic_stats_data:
255
+ advanced_df = comparison_df.copy()
256
+ # Calculate some advanced stats
257
+ if all(col in advanced_df.columns for col in ['PTS', 'FGA', 'FTA']):
258
+ advanced_df['TS%'] = advanced_df['PTS'] / (2 * (advanced_df['FGA'] + 0.44 * advanced_df['FTA']))
259
+
260
+ advanced_cols = ['PLAYER_NAME', 'PTS', 'REB', 'AST', 'FG_PCT', 'TS%'] if 'TS%' in advanced_df.columns else ['PLAYER_NAME', 'PTS', 'REB', 'AST', 'FG_PCT']
261
+ display_cols = [col for col in advanced_cols if col in advanced_df.columns]
262
+ st.dataframe(advanced_df[display_cols].round(3), use_container_width=True)
263
+
264
+ with stats_tabs[2]:
265
+ st.subheader("Player Comparison Charts")
266
+
267
+ if basic_stats_data:
268
+ # Create comparison charts
269
+ metrics = ['PTS', 'REB', 'AST', 'FG_PCT']
270
+ available_metrics = [m for m in metrics if m in comparison_df.columns]
271
+
272
+ selected_metric = st.selectbox("Select Metric to Visualize", available_metrics)
273
+
274
+ if selected_metric:
275
+ # Bar chart comparison
276
+ fig = px.bar(
277
+ comparison_df,
278
+ x='PLAYER_NAME',
279
+ y=selected_metric,
280
+ title=f"{selected_metric} Comparison",
281
+ color='PLAYER_NAME'
282
+ )
283
+ st.plotly_chart(fig, use_container_width=True)
284
+
285
+ # Radar chart for multi-metric comparison
286
+ if len(available_metrics) >= 3:
287
+ radar_data = {}
288
+ for _, row in comparison_df.iterrows():
289
+ radar_data[row['PLAYER_NAME']] = {
290
+ metric: row[metric] for metric in available_metrics[:5]
291
+ }
292
+
293
+ if radar_data:
294
+ radar_fig = create_radar_chart(radar_data, available_metrics[:5])
295
+ st.plotly_chart(radar_fig, use_container_width=True)
296
 
297
+ def team_comparison_page():
298
+ st.markdown('<h2 class="section-header">Team vs Team Analysis</h2>', unsafe_allow_html=True)
299
+
300
+ all_teams = get_all_teams()
301
+ team_names = [team['full_name'] for team in all_teams]
302
+
303
+ col1, col2 = st.columns(2)
304
+
305
+ with col1:
306
+ selected_teams = st.multiselect(
307
+ "Select Teams to Compare",
308
+ team_names,
309
+ max_selections=4
310
+ )
311
+
312
+ with col2:
313
+ seasons = st.multiselect(
314
+ "Select Seasons",
315
+ ["2023-24", "2022-23", "2021-22", "2020-21"],
316
+ default=["2023-24"]
317
+ )
318
+
319
+ if selected_teams:
320
+ team_stats_data = []
321
+
322
+ for team_name in selected_teams:
323
+ team_id = next((t['id'] for t in all_teams if t['full_name'] == team_name), None)
324
+ if team_id:
325
+ for season in seasons:
326
+ stats_df = get_team_stats(team_id, season)
327
+ if not stats_df.empty:
328
+ team_avg = stats_df.mean(numeric_only=True)
329
+ team_avg['TEAM_NAME'] = team_name
330
+ team_avg['SEASON'] = season
331
+ team_stats_data.append(team_avg)
332
+
333
+ if team_stats_data:
334
+ team_df = pd.DataFrame(team_stats_data)
335
+
336
+ # Display team comparison
337
+ st.subheader("Team Statistics Comparison")
338
+ team_cols = ['TEAM_NAME', 'SEASON', 'PTS', 'REB', 'AST', 'FG_PCT', 'FG3_PCT', 'FT_PCT']
339
+ display_cols = [col for col in team_cols if col in team_df.columns]
340
+ st.dataframe(team_df[display_cols].round(2), use_container_width=True)
341
+
342
+ # Visualization
343
+ st.subheader("Team Performance Visualization")
344
+ metric_options = ['PTS', 'REB', 'AST', 'FG_PCT']
345
+ available_metrics = [m for m in metric_options if m in team_df.columns]
346
+
347
+ if available_metrics:
348
+ selected_metric = st.selectbox("Select Metric", available_metrics)
349
+
350
+ fig = px.bar(
351
+ team_df,
352
+ x='TEAM_NAME',
353
+ y=selected_metric,
354
+ color='SEASON',
355
+ title=f"Team {selected_metric} Comparison",
356
+ barmode='group'
357
+ )
358
+ st.plotly_chart(fig, use_container_width=True)
359
+
360
+ def awards_predictor_page():
361
+ st.markdown('<h2 class="section-header">NBA Awards Predictor</h2>', unsafe_allow_html=True)
362
+
363
+ award_type = st.selectbox(
364
+ "Select Award Type",
365
+ ["MVP", "Defensive Player of the Year", "Rookie of the Year", "6th Man of the Year", "All-NBA First Team"]
366
+ )
367
+
368
+ st.subheader(f"{award_type} Prediction Criteria")
369
+
370
+ # Define criteria for different awards
371
+ if award_type == "MVP":
372
+ criteria = {
373
+ "Points Per Game": st.slider("Minimum PPG", 15.0, 35.0, 25.0),
374
+ "Team Wins": st.slider("Minimum Team Wins", 35, 70, 50),
375
+ "Player Efficiency Rating": st.slider("Minimum PER", 15.0, 35.0, 25.0),
376
+ "Win Shares": st.slider("Minimum Win Shares", 5.0, 20.0, 10.0)
377
+ }
378
+ elif award_type == "Defensive Player of the Year":
379
+ criteria = {
380
+ "Blocks Per Game": st.slider("Minimum BPG", 0.0, 4.0, 1.5),
381
+ "Steals Per Game": st.slider("Minimum SPG", 0.0, 3.0, 1.0),
382
+ "Defensive Rating": st.slider("Maximum Defensive Rating", 90.0, 120.0, 105.0),
383
+ "Team Defensive Ranking": st.slider("Maximum Team Def Rank", 1, 30, 10)
384
+ }
385
  else:
386
+ criteria = {
387
+ "Points Per Game": st.slider("Minimum PPG", 10.0, 30.0, 15.0),
388
+ "Games Played": st.slider("Minimum Games", 50, 82, 65),
389
+ "Shooting Efficiency": st.slider("Minimum FG%", 0.35, 0.65, 0.45)
390
+ }
391
+
392
+ if st.button("Generate Predictions"):
393
+ # Use AI to analyze and predict
394
+ prompt = f"""
395
+ Based on the following criteria for {award_type}, analyze current NBA players and provide predictions:
396
+
397
+ Criteria: {criteria}
398
+
399
+ Please provide:
400
+ 1. Top 5 candidates with their stats
401
+ 2. Analysis of why each candidate fits the criteria
402
+ 3. Your prediction for the winner with reasoning
403
+
404
+ Focus on current 2023-24 season performance and recent trends.
405
+ """
406
+
407
+ with st.spinner("Analyzing candidates..."):
408
+ prediction = query_perplexity(prompt, max_tokens=800)
409
+ st.markdown("### AI Prediction Analysis")
410
+ st.write(prediction)
411
+
412
+ def ai_chat_page():
413
+ st.markdown('<h2 class="section-header">AI NBA Chat & Insights</h2>', unsafe_allow_html=True)
414
+
415
+ # Chat interface
416
+ st.subheader("Ask AI About NBA Stats and Insights")
417
+
418
+ # Display chat history
419
+ for message in st.session_state.chat_history:
420
+ with st.chat_message(message["role"]):
421
+ st.write(message["content"])
422
+
423
+ # Chat input
424
+ if prompt := st.chat_input("Ask about NBA players, teams, stats, or strategies..."):
425
+ # Add user message to chat history
426
+ st.session_state.chat_history.append({"role": "user", "content": prompt})
427
+
428
+ # Display user message
429
+ with st.chat_message("user"):
430
+ st.write(prompt)
431
+
432
+ # Generate AI response
433
+ with st.chat_message("assistant"):
434
+ with st.spinner("Thinking..."):
435
+ # Enhance prompt with NBA context
436
+ enhanced_prompt = f"""
437
+ As an NBA expert analyst, please answer this question about basketball:
438
+
439
+ {prompt}
440
+
441
+ Please provide detailed analysis with current stats, trends, and insights when relevant.
442
+ If specific player or team stats are mentioned, include recent performance data.
443
+ """
444
+
445
+ response = query_perplexity(enhanced_prompt, max_tokens=700)
446
+ st.write(response)
447
+
448
+ # Add assistant response to chat history
449
+ st.session_state.chat_history.append({"role": "assistant", "content": response})
450
+
451
+ # Quick action buttons
452
+ st.subheader("Quick Insights")
453
+ col1, col2, col3 = st.columns(3)
454
+
455
+ with col1:
456
+ if st.button("🏆 Championship Contenders"):
457
+ prompt = "Analyze the current NBA championship contenders for 2024. Who are the top 5 teams and why?"
458
+ response = query_perplexity(prompt)
459
+ st.write(response)
460
+
461
+ with col2:
462
+ if st.button("⭐ Rising Stars"):
463
+ prompt = "Who are the most promising young NBA players to watch in 2024? Focus on players 23 and under."
464
+ response = query_perplexity(prompt)
465
+ st.write(response)
466
+
467
+ with col3:
468
+ if st.button("📊 Trade Analysis"):
469
+ prompt = "What are some potential NBA trades that could happen this season? Analyze team needs and available players."
470
+ response = query_perplexity(prompt)
471
+ st.write(response)
472
+
473
+ def young_player_projections_page():
474
+ st.markdown('<h2 class="section-header">Young Player Projections</h2>', unsafe_allow_html=True)
475
+
476
+ # Player selection
477
+ all_players = get_all_players()
478
+ player_names = [player['full_name'] for player in all_players]
479
+
480
+ selected_player = st.selectbox("Select Young Player (or enter manually)", [""] + player_names)
481
+
482
+ if not selected_player:
483
+ manual_player = st.text_input("Enter Player Name Manually")
484
+ if manual_player:
485
+ selected_player = manual_player
486
+
487
+ if selected_player:
488
+ col1, col2 = st.columns(2)
489
+
490
+ with col1:
491
+ current_age = st.number_input("Current Age", min_value=18, max_value=25, value=21)
492
+ years_in_league = st.number_input("Years in NBA", min_value=0, max_value=7, value=2)
493
+
494
+ with col2:
495
+ current_ppg = st.number_input("Current PPG", min_value=0.0, max_value=40.0, value=15.0)
496
+ current_rpg = st.number_input("Current RPG", min_value=0.0, max_value=20.0, value=5.0)
497
+ current_apg = st.number_input("Current APG", min_value=0.0, max_value=15.0, value=3.0)
498
+
499
+ if st.button("Generate AI Projection"):
500
+ prompt = f"""
501
+ Analyze and project the future potential of NBA player {selected_player}:
502
+
503
+ Current Stats:
504
+ - Age: {current_age}
505
+ - Years in NBA: {years_in_league}
506
+ - PPG: {current_ppg}
507
+ - RPG: {current_rpg}
508
+ - APG: {current_apg}
509
+
510
+ Please provide:
511
+ 1. 3-year projection of their stats
512
+ 2. Peak potential analysis
513
+ 3. Areas for improvement
514
+ 4. Comparison to similar players at the same age
515
+ 5. Career trajectory prediction
516
+
517
+ Base your analysis on historical player development patterns and current NBA trends.
518
+ """
519
+
520
+ with st.spinner("Generating projection..."):
521
+ projection = query_perplexity(prompt, max_tokens=800)
522
+ st.markdown("### AI Player Projection")
523
+ st.write(projection)
524
+
525
+ # Create a simple projection visualization
526
+ years = [f"Year {i+1}" for i in range(5)]
527
+ projected_ppg = [current_ppg * (1 + 0.1 * i) for i in range(5)] # Simple growth model
528
+
529
+ fig = go.Figure()
530
+ fig.add_trace(go.Scatter(
531
+ x=years,
532
+ y=projected_ppg,
533
+ mode='lines+markers',
534
+ name='Projected PPG',
535
+ line=dict(width=3, color='blue')
536
+ ))
537
+
538
+ fig.update_layout(
539
+ title=f"{selected_player} - PPG Projection",
540
+ xaxis_title="Years",
541
+ yaxis_title="Points Per Game",
542
+ height=400
543
+ )
544
+
545
+ st.plotly_chart(fig, use_container_width=True)
546
+
547
+ def similar_players_page():
548
+ st.markdown('<h2 class="section-header">Find Similar Players</h2>', unsafe_allow_html=True)
549
+
550
+ all_players = get_all_players()
551
+ player_names = [player['full_name'] for player in all_players]
552
+
553
+ target_player = st.selectbox("Select Target Player", player_names)
554
+
555
+ similarity_criteria = st.multiselect(
556
+ "Select Similarity Criteria",
557
+ ["Position", "Height/Weight", "Playing Style", "Statistical Profile", "Age/Experience"],
558
+ default=["Playing Style", "Statistical Profile"]
559
+ )
560
+
561
+ if target_player and similarity_criteria:
562
+ if st.button("Find Similar Players"):
563
+ prompt = f"""
564
+ Find NBA players similar to {target_player} based on the following criteria:
565
+ {', '.join(similarity_criteria)}
566
+
567
+ Please provide:
568
+ 1. Top 5 most similar current NBA players
569
+ 2. Top 3 historical comparisons
570
+ 3. Explanation of similarities for each player
571
+ 4. Key differences that distinguish them
572
+ 5. Playing style analysis
573
+
574
+ Focus on both statistical similarities and playing style/role similarities.
575
+ """
576
+
577
+ with st.spinner("Finding similar players..."):
578
+ similar_players = query_perplexity(prompt, max_tokens=800)
579
+ st.markdown("### Similar Players Analysis")
580
+ st.write(similar_players)
581
+
582
+ # Alternative: Manual similarity finder
583
+ st.subheader("Manual Player Comparison Tool")
584
+
585
+ col1, col2 = st.columns(2)
586
+
587
+ with col1:
588
+ player1 = st.selectbox("Player 1", player_names, key="sim1")
589
+
590
+ with col2:
591
+ player2 = st.selectbox("Player 2", player_names, key="sim2")
592
+
593
+ if player1 and player2 and player1 != player2:
594
+ if st.button("Compare Players"):
595
+ prompt = f"""
596
+ Compare {player1} and {player2} in detail:
597
+
598
+ Please analyze:
599
+ 1. Statistical comparison (current season)
600
+ 2. Playing style similarities and differences
601
+ 3. Strengths and weaknesses of each
602
+ 4. Team impact and role
603
+ 5. Overall similarity score (1-10)
604
+
605
+ Provide a comprehensive comparison with specific examples.
606
+ """
607
+
608
+ comparison = query_perplexity(prompt, max_tokens=700)
609
+ st.markdown("### Player Comparison Analysis")
610
+ st.write(comparison)
611
+
612
+ def roster_builder_page():
613
+ st.markdown('<h2 class="section-header">NBA Roster Builder</h2>', unsafe_allow_html=True)
614
+
615
+ st.subheader("Build Your Ideal NBA Roster")
616
+
617
+ # Roster building parameters
618
+ col1, col2 = st.columns(2)
619
+
620
+ with col1:
621
+ salary_cap = st.number_input("Salary Cap (Millions)", min_value=100, max_value=200, value=136)
622
+ team_strategy = st.selectbox(
623
+ "Team Strategy",
624
+ ["Championship Contender", "Young Core Development", "Balanced Veteran Mix", "Small Ball", "Defense First"]
625
+ )
626
+
627
+ with col2:
628
+ key_positions = st.multiselect(
629
+ "Priority Positions",
630
+ ["Point Guard", "Shooting Guard", "Small Forward", "Power Forward", "Center"],
631
+ default=["Point Guard", "Center"]
632
+ )
633
+
634
+ # Player budget allocation
635
+ st.subheader("Budget Allocation")
636
+ position_budgets = {}
637
+
638
+ positions = ["PG", "SG", "SF", "PF", "C"]
639
+ cols = st.columns(5)
640
+
641
+ total_allocated = 0
642
+ for i, pos in enumerate(positions):
643
+ with cols[i]:
644
+ budget = st.number_input(f"{pos} Budget ($M)", min_value=0, max_value=50, value=20, key=f"budget_{pos}")
645
+ position_budgets[pos] = budget
646
+ total_allocated += budget
647
+
648
+ st.write(f"Total Allocated: ${total_allocated}M / ${salary_cap}M")
649
+
650
+ if total_allocated > salary_cap:
651
+ st.error("Budget exceeds salary cap!")
652
+
653
+ # Generate roster suggestions
654
+ if st.button("Generate Roster Suggestions"):
655
+ prompt = f"""
656
+ Build an NBA roster with the following constraints:
657
+
658
+ - Salary Cap: ${salary_cap} million
659
+ - Team Strategy: {team_strategy}
660
+ - Priority Positions: {', '.join(key_positions)}
661
+ - Position Budgets: {position_budgets}
662
+
663
+ Please provide:
664
+ 1. Starting lineup with specific player recommendations
665
+ 2. Key bench players (6th man, backup center, etc.)
666
+ 3. Total estimated salary breakdown
667
+ 4. Rationale for each major signing
668
+ 5. How this roster fits the chosen strategy
669
+ 6. Potential weaknesses and how to address them
670
+
671
+ Focus on realistic player availability and current market values.
672
+ """
673
+
674
+ with st.spinner("Building your roster..."):
675
+ roster_suggestions = query_perplexity(prompt, max_tokens=900)
676
+ st.markdown("### AI Roster Recommendations")
677
+ st.write(roster_suggestions)
678
+
679
+ # Trade scenario analyzer
680
+ st.subheader("Trade Scenario Analyzer")
681
+
682
+ trade_team1 = st.text_input("Team 1 Trading:")
683
+ trade_team2 = st.text_input("Team 2 Trading:")
684
+
685
+ if trade_team1 and trade_team2:
686
+ if st.button("Analyze Trade"):
687
+ prompt = f"""
688
+ Analyze this potential NBA trade:
689
+
690
+ Team 1 trades: {trade_team1}
691
+ Team 2 trades: {trade_team2}
692
+
693
+ Please evaluate:
694
+ 1. Fair value assessment
695
+ 2. How this trade helps each team
696
+ 3. Salary cap implications
697
+ 4. Impact on team chemistry and performance
698
+ 5. Likelihood of this trade happening
699
+ 6. Alternative trade suggestions
700
+
701
+ Consider current team needs and player contracts.
702
+ """
703
+
704
+ trade_analysis = query_perplexity(prompt, max_tokens=700)
705
+ st.markdown("### Trade Analysis")
706
+ st.write(trade_analysis)
707
+
708
+ if __name__ == "__main__":
709
+ main()