Spaces:
Runtime error
Runtime error
| import pandas as pd | |
| import numpy as np | |
| from scipy.stats import poisson | |
| import gradio as gr | |
| import os | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| import requests | |
| import json | |
| # --- 1. แแแแคแแแฃแ แแชแแ --- | |
| GEMINI_API_KEY = "AIzaSyBe9TNXLWuZO995kKxbj4KvqjSLhZcJwvo" | |
| # --- 2. แแแแแชแแแแแแก แแแแแแแแแ --- | |
| file_path = 'top_50_european_teams_2026.csv' | |
| if os.path.exists(file_path): | |
| df = pd.read_csv(file_path, sep=None, engine='python') | |
| df.columns = df.columns.str.strip() | |
| else: | |
| data = { | |
| 'team_nam': [ | |
| 'Real Madrid', 'Manchester City', 'Bayern Munich', | |
| 'FC Barcelona', 'Arsenal', 'PSG', 'Inter Milan', 'Liverpool' | |
| ], | |
| 'fifa_elo': [1950, 1980, 1890, 1910, 1880, 1860, 1870, 1885], | |
| 'last_10_w': [8, 7, 6, 7, 8, 6, 7, 5], | |
| 'win_vs_high': [3, 4, 2, 3, 2, 1, 2, 1], | |
| 'injuries': [1, 0, 3, 1, 2, 4, 1, 2] | |
| } | |
| df = pd.DataFrame(data) | |
| # --- 3. แจแแแ แแแแแแแ แแจแแแแก แคแฃแแฅแชแแแแ (แฃแชแแแแแ) --- | |
| def plot_score_heatmap(matrix, home_name, away_name): | |
| fig, ax = plt.subplots(figsize=(8, 6)) | |
| sns.heatmap( | |
| matrix, | |
| annot=True, | |
| fmt=".1%", | |
| cmap="YlGnBu", | |
| cbar_kws={'label': 'แแแแแแแแ'}, | |
| ax=ax | |
| ) | |
| ax.set_title(f"แแฃแกแขแ แแแแแ แแจแแก แแแแแแแแแแ: {home_name} vs {away_name}") | |
| ax.set_xlabel(f"{away_name} (แกแขแฃแแแ แ) แแแแแแ") | |
| ax.set_ylabel(f"{home_name} (แแแกแแแแซแแแ) แแแแแแ") | |
| ax.set_xticks(np.arange(0.5, 8.5, 1)) | |
| ax.set_xticklabels(range(8)) | |
| ax.set_yticks(np.arange(0.5, 8.5, 1)) | |
| ax.set_yticklabels(range(8)) | |
| plt.tight_layout() | |
| plot_path = "score_matrix_heatmap.png" | |
| plt.savefig(plot_path, dpi=120) | |
| plt.close(fig) | |
| return plot_path | |
| def calculate_balanced_odds_with_plot(home_team, away_team): | |
| if home_team == away_team: | |
| return "แแแ แฉแแแ แแแแกแฎแแแแแแฃแแ แแฃแแแแแ", 0, 0, 0, None | |
| try: | |
| h = df[df['team_nam'] == home_team].iloc[0] | |
| a = df[df['team_nam'] == away_team].iloc[0] | |
| except IndexError: | |
| return "แแฃแแแ แแ แแแแซแแแแ", 0, 0, 0, None | |
| def get_conservative_power(row): | |
| base_elo = row['fifa_elo'] / 400 | |
| form_bonus = np.log1p(row['last_10_w']) * 0.15 | |
| giant_killer = row['win_vs_high'] * 0.05 | |
| injury_penalty = row['injuries'] * 0.05 | |
| return base_elo + form_bonus + giant_killer - injury_penalty | |
| h_power = get_conservative_power(h) | |
| a_power = get_conservative_power(a) | |
| diff = h_power - a_power | |
| l1 = max(0.6, 1.35 + diff * 0.8 + 0.2) | |
| l2 = max(0.6, 1.35 - diff * 0.8) | |
| max_goals = 8 | |
| home_probs = poisson.pmf(range(max_goals), l1) | |
| away_probs = poisson.pmf(range(max_goals), l2) | |
| matrix = np.outer(home_probs, away_probs) | |
| plot_file = plot_score_heatmap(matrix, home_team, away_team) | |
| p_win = np.sum(np.tril(matrix, -1)) | |
| p_draw = np.sum(np.diag(matrix)) | |
| p_lose = np.sum(np.triu(matrix, 1)) | |
| total = p_win + p_draw + p_lose | |
| if total == 0: total = 1 | |
| p_win, p_draw, p_lose = p_win / total, p_draw / total, p_lose / total | |
| margin = 0.06 | |
| o1 = round(1 / (p_win + margin / 3), 2) if p_win > 0 else 10.0 | |
| ox = round(1 / (p_draw + margin / 3), 2) if p_draw > 0 else 10.0 | |
| o2 = round(1 / (p_lose + margin / 3), 2) if p_lose > 0 else 10.0 | |
| return f"xG {l1:.2f} - {l2:.2f}", max(o1, 1.15), max(ox, 1.15), max(o2, 1.15), plot_file | |
| # --- 4. แฉแแขแ (แจแแแ แแแแฎแแแแแแ แคแฃแแฅแชแแ) --- | |
| def football_chat_bot(message, history): | |
| api_key = GEMINI_API_KEY.strip() | |
| list_url = f"https://generativelanguage.googleapis.com/v1/models?key={api_key}" | |
| try: | |
| models_res = requests.get(list_url).json() | |
| working_models = [m['name'] for m in models_res.get('models', []) | |
| if 'generateContent' in m.get('supportedGenerationMethods', [])] | |
| if not working_models: | |
| return "แจแแชแแแแ: แแฅแแแแก API แแแกแแฆแแแแ แแ แชแแ แแ แแแแแแ แแ แแ แแก แแแแฅแขแแฃแ แแแฃแแ." | |
| target_model = working_models[0] | |
| except Exception as e: | |
| return f"แแแแแแแแแก แซแแแแแก แจแแชแแแแ: {str(e)}" | |
| chat_url = f"https://generativelanguage.googleapis.com/v1/{target_model}:generateContent?key={api_key}" | |
| headers = {'Content-Type': 'application/json'} | |
| data = { | |
| "contents": [{"parts": [{"text": f"แจแแ แฎแแ แคแแฎแแฃแ แแแก แแฅแกแแแ แขแ 2026 แฌแแแก. แฃแแแกแฃแฎแ แฅแแ แแฃแแแ: {message}"}]}] | |
| } | |
| try: | |
| response = requests.post(chat_url, headers=headers, data=json.dumps(data)) | |
| res_json = response.json() | |
| if response.status_code == 200: | |
| return res_json['candidates'][0]['content']['parts'][0]['text'] | |
| else: | |
| return f"API แฃแแ แ ({target_model}): {res_json.get('error', {}).get('message', 'แฃแชแแแแ แจแแชแแแแ')}" | |
| except Exception as e: | |
| return f"แแแแจแแ แแก แจแแชแแแแ: {str(e)}" | |
| # --- 5. Gradio แแแขแแ แคแแแกแ --- | |
| teams_list = sorted(df['team_nam'].unique()) | |
| start_home = 'Real Madrid' if 'Real Madrid' in teams_list else teams_list[0] | |
| start_away = 'FC Barcelona' if 'FC Barcelona' in teams_list else teams_list[1] | |
| with gr.Blocks(theme=gr.themes.Soft()) as demo: | |
| with gr.Row(): | |
| gr.Image( | |
| "https://images.eu.ctfassets.net/psnuheg7hu1m/2855AOJwV8YSxZmk2TfF5T/1d0af7cd5353cd782e217f91e3bfc77b/TBC-ge.png?fm=jpg&fl=progressive&q=90", | |
| show_label=False, height=100, width=200) | |
| gr.Markdown("# โฝ Football AI Hub 2026") | |
| with gr.Tabs(): | |
| with gr.TabItem("๐ แแ แแแแแแ แแ แแแขแ แแชแ"): | |
| gr.Markdown("แแแ แฉแแแ แแฃแแแแแ AI แแแแแแแก แแแแแแแแกแแแแก") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| h_drop = gr.Dropdown(teams_list, label="แแแกแแแแซแแแ", value=start_home) | |
| a_drop = gr.Dropdown(teams_list, label="แกแขแฃแแแ แ", value=start_away) | |
| btn = gr.Button("๐ แแแแแแแแก แแแฌแงแแแ", variant="primary") | |
| xg_val = gr.Textbox(label="แแแกแแแแแแแแ แแแแแแ (xG)") | |
| out_1 = gr.Number(label="1 (Home Win)") | |
| out_x = gr.Number(label="X (Draw)") | |
| out_2 = gr.Number(label="2 (Away Win)") | |
| with gr.Column(scale=2): | |
| matrix_plot = gr.Image(label="แแฃแกแขแ แแแแแ แแจแแก แแแขแ แแชแ") | |
| with gr.TabItem("๐ฌ แฉแแขแ แแฅแกแแแ แขแแแ"): | |
| gr.ChatInterface(fn=football_chat_bot) | |
| btn.click( | |
| calculate_balanced_odds_with_plot, | |
| inputs=[h_drop, a_drop], | |
| outputs=[xg_val, out_1, out_x, out_2, matrix_plot] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |