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()