| """ |
| IPL Score Predictor β Hugging Face Space |
| app.py (entry point) |
| """ |
|
|
| import os, pickle, pathlib |
| import pandas as pd |
| import gradio as gr |
| from Mymodelfile import MyModel, ACTIVE_TEAMS, VENUE_NORM, SEASON_MAP |
|
|
| |
| DATA_DIR = pathlib.Path(".") |
| MODEL_PATH = DATA_DIR / "ipl_svr_model.pkl" |
|
|
| MATCHES_CSV = DATA_DIR / "matches_updated_ipl_upto_2025.csv" |
| DELIVERIES_CSV = DATA_DIR / "deliveries_updated_ipl_upto_2025.csv" |
| PLAYERS_CSV = DATA_DIR / "ipl_players_uniqueid.csv" |
|
|
| |
| VENUES = sorted(set(VENUE_NORM.values())) |
|
|
| |
| TEAMS = sorted(ACTIVE_TEAMS) |
|
|
| |
| TOSS_DECISIONS = ["bat", "field"] |
|
|
| |
| INNINGS = ["1", "2"] |
|
|
| |
| SEASONS = sorted(SEASON_MAP.keys(), key=lambda x: SEASON_MAP[x]) |
|
|
|
|
| |
| |
| |
|
|
| def _train_and_save() -> MyModel: |
| print("Training model on provided CSVs β¦") |
| deliveries = pd.read_csv(DELIVERIES_CSV) |
| matches = pd.read_csv(MATCHES_CSV) |
| players = pd.read_csv(PLAYERS_CSV) if PLAYERS_CSV.exists() else None |
|
|
| mdl = MyModel() |
| mdl.fit(deliveries, players_df=players, matches_df=matches) |
|
|
| with open(MODEL_PATH, "wb") as f: |
| pickle.dump(mdl, f) |
| print("Model saved to", MODEL_PATH) |
| return mdl |
|
|
|
|
| def _load_model() -> MyModel: |
| if MODEL_PATH.exists(): |
| print("Loading cached model β¦") |
| with open(MODEL_PATH, "rb") as f: |
| return pickle.load(f) |
| return _train_and_save() |
|
|
|
|
| |
| |
| |
|
|
| def predict_score( |
| batting_team: str, |
| bowling_team: str, |
| toss_winner: str, |
| toss_decision: str, |
| venue: str, |
| wickets: int, |
| inning: str, |
| season: str, |
| ) -> str: |
|
|
| if batting_team == bowling_team: |
| return "β οΈ Batting and bowling teams must be different." |
|
|
| test_df = pd.DataFrame([{ |
| "id": 1, |
| "innings": int(inning), |
| "venue": venue, |
| "season": season, |
| "batting_team": batting_team, |
| "bowling_team": bowling_team, |
| "toss_winner": toss_winner, |
| "toss_decision": toss_decision, |
| |
| "Batsman's Player Id": ",".join(["P"] * (wickets + 2)), |
| }]) |
|
|
| result_df = MODEL.predict(test_df) |
| score = int(result_df.iloc[0]["predicted_score"]) |
| return f"π Predicted innings score: **{score}**" |
|
|
|
|
| |
| |
| |
|
|
| CSS = """ |
| /* ββ root palette βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| :root { |
| --ipl-blue: #0a1628; |
| --ipl-gold: #d4a017; |
| --ipl-cream: #f5efe0; |
| --ipl-red: #c0392b; |
| --card-bg: rgba(255,255,255,0.04); |
| --radius: 12px; |
| } |
| |
| /* ββ global ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| body, .gradio-container { |
| background: var(--ipl-blue) !important; |
| font-family: 'Georgia', serif; |
| color: var(--ipl-cream) !important; |
| } |
| |
| /* ββ header band βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| #header { |
| text-align: center; |
| padding: 28px 0 10px; |
| border-bottom: 2px solid var(--ipl-gold); |
| margin-bottom: 24px; |
| } |
| #header h1 { |
| font-size: 2.4rem; |
| color: var(--ipl-gold); |
| letter-spacing: 0.08em; |
| margin: 0 0 4px; |
| text-shadow: 0 2px 12px rgba(212,160,23,.45); |
| } |
| #header p { |
| font-size: 0.95rem; |
| color: var(--ipl-cream); |
| opacity: .7; |
| margin: 0; |
| letter-spacing: 0.05em; |
| } |
| |
| /* ββ section labels ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| .gr-form label, .gr-block label span { |
| color: var(--ipl-gold) !important; |
| font-size: 0.82rem; |
| letter-spacing: 0.06em; |
| text-transform: uppercase; |
| } |
| |
| /* ββ dropdowns / inputs ββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| select, input[type=number] { |
| background: rgba(255,255,255,0.07) !important; |
| border: 1px solid rgba(212,160,23,.4) !important; |
| border-radius: var(--radius) !important; |
| color: var(--ipl-cream) !important; |
| padding: 8px 12px !important; |
| } |
| select:focus, input[type=number]:focus { |
| border-color: var(--ipl-gold) !important; |
| outline: none !important; |
| box-shadow: 0 0 0 2px rgba(212,160,23,.25) !important; |
| } |
| |
| /* ββ predict button ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| #predict-btn { |
| background: linear-gradient(135deg, var(--ipl-gold) 0%, #b8860b 100%) !important; |
| color: var(--ipl-blue) !important; |
| font-weight: 700; |
| font-size: 1rem; |
| letter-spacing: 0.1em; |
| text-transform: uppercase; |
| border: none !important; |
| border-radius: var(--radius) !important; |
| padding: 14px 0 !important; |
| margin-top: 12px; |
| transition: transform .15s, box-shadow .15s; |
| } |
| #predict-btn:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 6px 24px rgba(212,160,23,.45) !important; |
| } |
| |
| /* ββ result box ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| #result-box { |
| background: var(--card-bg) !important; |
| border: 1px solid var(--ipl-gold) !important; |
| border-radius: var(--radius) !important; |
| text-align: center; |
| font-size: 1.5rem !important; |
| color: var(--ipl-cream) !important; |
| padding: 18px !important; |
| min-height: 70px; |
| } |
| |
| /* ββ card wrappers βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| .gr-group, .gr-box { |
| background: var(--card-bg) !important; |
| border: 1px solid rgba(212,160,23,.18) !important; |
| border-radius: var(--radius) !important; |
| } |
| |
| /* ββ note block ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ |
| #note { |
| font-size: 0.78rem; |
| color: rgba(245,239,224,.5); |
| text-align: center; |
| margin-top: 8px; |
| } |
| """ |
|
|
| def build_ui() -> gr.Blocks: |
| with gr.Blocks(css=CSS, title="IPL Score Predictor") as demo: |
|
|
| |
| gr.HTML(""" |
| <div id="header"> |
| <h1>π IPL Score Predictor</h1> |
| <p>SVR model Β· trained on IPL 2007 β 2025 data</p> |
| </div> |
| """) |
|
|
| |
| with gr.Row(): |
| with gr.Column(): |
| batting_team = gr.Dropdown( |
| choices=TEAMS, |
| label="Batting Team", |
| value=TEAMS[0], |
| ) |
| bowling_team = gr.Dropdown( |
| choices=TEAMS, |
| label="Bowling Team", |
| value=TEAMS[1], |
| ) |
|
|
| with gr.Column(): |
| toss_winner = gr.Dropdown( |
| choices=TEAMS, |
| label="Toss Won By", |
| value=TEAMS[0], |
| ) |
| toss_decision = gr.Dropdown( |
| choices=TOSS_DECISIONS, |
| label="Toss Decision", |
| value="bat", |
| ) |
|
|
| with gr.Row(): |
| venue = gr.Dropdown( |
| choices=VENUES, |
| label="Venue", |
| value=VENUES[0], |
| ) |
| inning = gr.Dropdown( |
| choices=INNINGS, |
| label="Innings", |
| value="1", |
| ) |
| season = gr.Dropdown( |
| choices=SEASONS, |
| label="Season", |
| value="2025", |
| ) |
| wickets = gr.Number( |
| label="Wickets Fallen (0β10)", |
| value=0, |
| minimum=0, |
| maximum=10, |
| precision=0, |
| ) |
|
|
| |
| predict_btn = gr.Button("Predict Score", elem_id="predict-btn") |
|
|
| |
| result = gr.Markdown( |
| value="*Fill in the inputs above and click Predict Score.*", |
| elem_id="result-box", |
| ) |
|
|
| gr.HTML(""" |
| <p id="note"> |
| Predictions are rounded up to the nearest 5. Model uses venue Γ wickets Γ h2h Γ form features. |
| </p> |
| """) |
|
|
| |
| predict_btn.click( |
| fn=predict_score, |
| inputs=[ |
| batting_team, bowling_team, |
| toss_winner, toss_decision, |
| venue, wickets, inning, season, |
| ], |
| outputs=result, |
| ) |
|
|
| return demo |
|
|
|
|
| |
| |
| |
|
|
| if __name__ == "__main__": |
| MODEL = _load_model() |
| app = build_ui() |
| app.launch() |
| else: |
| |
| MODEL = _load_model() |
| app = build_ui() |