Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import gradio as gr | |
| from openai import OpenAI | |
| import os | |
| # Load CSV files | |
| try: | |
| batters_df = pd.read_csv("batters.csv") | |
| bowlers_df = pd.read_csv("bowlers.csv") | |
| pitch_stats_df = pd.read_csv("pitch_stats.csv") | |
| except FileNotFoundError as e: | |
| print(f"Error: CSV file not found - {e}") | |
| raise | |
| # Initialize OpenAI client | |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| # IPL 2025 team-to-players mapping with players sorted alphabetically | |
| team_to_players = { | |
| "CSK": sorted([ | |
| "Andre Siddarth", "Anshul Kamboj", "Ayush Mhatre", "Deepak Hooda", "Devon Conway", "Gurjapneet Singh", | |
| "Jamie Overton", "Kamlesh Nagarkoti", "Khaleel Ahmed", "MS Dhoni", "Matheesha Pathirana", | |
| "Mukesh Choudhary", "Nathan Ellis", "Noor Ahmad", "Rachin Ravindra", "Rahul Tripathi", | |
| "Ramakrishna Ghosh", "Ravichandran Ashwin", "Ravindra Jadeja", "Shaik Rasheed", "Shivam Dube", | |
| "Shreyas Gopal", "Sam Curran", "Urvil Patel", "Vansh Bedi", "Vijay Shankar" | |
| ]), | |
| "MI": sorted([ | |
| "Arjun Tendulkar", "Ashwani Kumar", "Bevon Jacobs", "Deepak Chahar", "Hardik Pandya", | |
| "Jasprit Bumrah", "Karn Sharma", "Mitchell Santner", "Naman Dhir", "Raj Angad Bawa", | |
| "Reece Topley", "Robin Minz", "Rohit Sharma", "Ryan Rickelton", "Shrijith Krishnan", | |
| "Suryakumar Yadav", "Tilak Varma", "Trent Boult", "Venkat Satyanarayana Raju", | |
| "Vignesh Puthur", "Will Jacks" | |
| ]), | |
| "RCB": sorted([ | |
| "Abhinandan Singh", "Bhuvneshwar Kumar", "Devdutt Padikkal", "Jacob Bethell", "Jitesh Sharma", | |
| "Josh Hazlewood", "Krunal Pandya", "Liam Livingstone", "Lungi Ngidi", "Manoj Bhandage", | |
| "Mohit Rathee", "Nuwan Thushara", "Phil Salt", "Rajat Patidar", "Rasikh Dar", "Romario Shepherd", | |
| "Suyash Sharma", "Swastik Chhikara", "Swapnil Singh", "Tim David", "Virat Kohli", "Yash Dayal" | |
| ]), | |
| "KKR": sorted([ | |
| "Ajinkya Rahane", "Andre Russell", "Angkrish Raghuvanshi", "Anrich Nortje", "Anukul Roy", | |
| "Harshit Rana", "Luvnith Sisodia", "Manish Pandey", "Mayank Markande", "Quinton de Kock", | |
| "Rahmanullah Gurbaz", "Ramandeep Singh", "Rinku Singh", "Rovman Powell", "Spencer Johnson", | |
| "Sunil Narine", "Vaibhav Arora", "Varun Chakaravarthy", "Venkatesh Iyer" | |
| ]), | |
| "RR": sorted([ | |
| "Akash Madhwal", "Ashok Sharma", "Dhruv Jurel", "Fazal Farooqi", "Jofra Archer", "Kumar Kartikeya", | |
| "Kunal Rathore", "Kwena Maphaka", "Maheesh Theekshana", "Nitish Rana", "Riyan Parag", | |
| "Sandeep Sharma", "Sanju Samson", "Shimron Hetmyer", "Shubham Dubey", "Tushar Deshpande", | |
| "Vaibhav Suryavanshi", "Wanindu Hasaranga", "Yashasvi Jaiswal", "Yudhvir Charak" | |
| ]), | |
| "SRH": sorted([ | |
| "Abhinav Manohar", "Abhishek Sharma", "Adam Zampa", "Aniket Verma", "Atharva Taide", | |
| "Brydon Carse", "Eshan Malinga", "Harshal Patel", "Heinrich Klaasen", "Ishan Kishan", | |
| "Jaydev Unadkat", "Kamindu Mendis", "Mohammed Shami", "Nitish Reddy", "Pat Cummins", | |
| "Rahul Chahar", "Sachin Baby", "Simarjeet Singh", "Travis Head", "Zeeshan Ansari" | |
| ]), | |
| "GT": sorted([ | |
| "Anuj Rawat", "Arshad Khan", "Gerald Coetzee", "Glenn Phillips", "Gurnoor Brar", "Ishant Sharma", | |
| "Jayant Yadav", "Jos Buttler", "Kagiso Rabada", "Karim Janat", "Kulwant Khejroliya", | |
| "Kumar Kushagra", "Mahipal Lomror", "Manav Suthar", "Mohammed Siraj", "Nishant Sindhu", | |
| "Prasidh Krishna", "R. Sai Kishore", "Rahul Tewatia", "Rashid Khan", "Sai Sudharsan", | |
| "Shahrukh Khan", "Sherfane Rutherford", "Shubman Gill", "Washington Sundar" | |
| ]), | |
| "DC": sorted([ | |
| "Abishek Porel", "Ajay Mandal", "Ashutosh Sharma", "Axar Patel", "Darshan Nalkande", | |
| "Donovan Ferreira", "Dushmantha Chameera", "Faf du Plessis", "Jake Fraser-McGurk", | |
| "Karun Nair", "KL Rahul", "Kuldeep Yadav", "Madhav Tiwari", "Manvanth Kumar", "Mitchell Starc", | |
| "Mohit Sharma", "Mukesh Kumar", "Sameer Rizvi", "T. Natarajan", "Tristan Stubbs", | |
| "Tripurana Vijay", "Vipraj Nigam" | |
| ]), | |
| "PBKS": sorted([ | |
| "Aaron Hardie", "Arshdeep Singh", "Azmatullah Omarzai", "Glenn Maxwell", "Harnoor Panwar", | |
| "Harpreet Brar", "Josh Inglis", "Kuldeep Sen", "Lockie Ferguson", "Marco Jansen", "Marcus Stoinis", | |
| "Musheer Khan", "Nehal Wadhera", "Prabhsimran Singh", "Priyansh Arya", "Shashank Singh", | |
| "Shreyas Iyer", "Vishak Vijayakumar", "Vishnu Vinod", "Yash Thakur" | |
| ]), | |
| "LSG": sorted([ | |
| "Abdul Samad", "Aiden Markram", "Akash Deep", "Akash Singh", "Arshin Kulkarni", "Aryan Juyal", | |
| "Avesh Khan", "Ayush Badoni", "David Miller", "Digvesh Singh", "Himmat Singh", "Manimaran Siddharth", | |
| "Matthew Breetzke", "Mayank Yadav", "Mitchell Marsh", "Nicholas Pooran", "Prince Yadav", | |
| "Rajvardhan Hangargekar", "Ravi Bishnoi", "Rishabh Pant", "Shahbaz Ahmed", "Shamar Joseph", | |
| "Shardul Thakur", "Yuvraj Chaudhary" | |
| ]) | |
| } | |
| venues = [ | |
| "Wankhede Stadium (Mumbai)", "Eden Gardens (Kolkata)", | |
| "M. Chinnaswamy Stadium (Bangalore)", "Narendra Modi Stadium (Ahmedabad)", | |
| "M. A. Chidambaram Stadium (Chennai)", "Arun Jaitley Stadium (Delhi)", | |
| "Sawai Mansingh Stadium (Jaipur)", "Rajiv Gandhi Intl Cricket Stadium (Hyderabad)", | |
| "HPCA Stadium (Dharamshala)", "Ekana Cricket Stadium (Lucknow)", | |
| "Maharashtra Cricket Association Stadium (Pune)", "Barsapara Stadium (Guwahati)" | |
| ] | |
| def update_batter_out(team_a): | |
| print(f"Updating batter out for team: {team_a}") # Debug print | |
| if team_a: | |
| # Include all players from the selected team's squad | |
| players = team_to_players.get(team_a, []) | |
| print(f"Players for {team_a}: {players}") # Debug print | |
| return gr.update(choices=players, value=None) | |
| return gr.update(choices=[], value=None) | |
| def update_available_batters(team_a, batter_out): | |
| print(f"Updating available batters for team: {team_a}, batter out: {batter_out}") # Debug print | |
| if team_a: | |
| # Filter players who are batters (in batters_df) and exclude batter_out | |
| players = [p for p in team_to_players.get(team_a, []) if p in batters_df['batter_name'].values and p != batter_out] | |
| print(f"Available batters: {players}") # Debug print | |
| return gr.update(choices=players, value=[]) | |
| return gr.update(choices=[], value=[]) | |
| def update_venue_stats(venue): | |
| print(f"Updating venue stats for: {venue}") # Debug print | |
| pitch_info = pitch_stats_df[pitch_stats_df['venue'] == venue] | |
| if not pitch_info.empty: | |
| return f"Venue Stats: Avg 1st Innings: {pitch_info['avg_score_first_innings'].iloc[0]}, Win % Batting First: {pitch_info['win_pct_batting_first'].iloc[0]}%, Favours: {pitch_info['favours'].iloc[0]}" | |
| return "No venue stats available." | |
| def get_batter_stats(batter, batters_df, venue, bowler_type): | |
| batter_row = batters_df[batters_df['batter_name'] == batter] | |
| if not batter_row.empty: | |
| stats = batter_row.iloc[0] | |
| return f""" | |
| Batter: {batter} | |
| Avg vs {bowler_type}: {stats[f'avg_vs_{bowler_type.lower()}']} | |
| Strike Rate vs {bowler_type}: {stats[f'strike_rate_vs_{bowler_type.lower()}']} | |
| Dismissal % vs {bowler_type}: {stats[f'dismissal_pct_vs_{bowler_type.lower()}']} | |
| Form (Last 5): {stats['form_last_5']} | |
| Best Venue: {stats['best_venue']} (Current: {venue}) | |
| Role: {stats['role']} | |
| Handedness: {stats['handedness']} | |
| """ | |
| return f""" | |
| Batter: {batter} | |
| Avg vs {bowler_type}: Unknown | |
| Strike Rate vs {bowler_type}: Unknown | |
| Dismissal % vs {bowler_type}: Unknown | |
| Form (Last 5): Unknown | |
| Best Venue: Unknown (Current: {venue}) | |
| Role: Unknown | |
| Handedness: Unknown | |
| """ | |
| def score_batter(batter, batters_df, bowler_type, pitch_type, venue): | |
| batter_row = batters_df[batters_df['batter_name'] == batter] | |
| if batter_row.empty: | |
| return 0 # Default score for players without stats | |
| stats = batter_row.iloc[0] | |
| score = (stats[f'avg_vs_{bowler_type.lower()}'] * 0.4 + | |
| stats[f'strike_rate_vs_{bowler_type.lower()}'] * 0.3 + | |
| stats['form_last_5'] * 0.2 + | |
| (1 if stats['best_venue'] == venue else 0) * 0.1) | |
| return score | |
| def recommend_batter(over, wickets, runs, target, batter_out, bowler_type, pitch_type, venue, opposition, available_batters): | |
| if not team_a: | |
| return "Error: Please select a batting team." | |
| if not batter_out: | |
| return "Error: Please select a batter out." | |
| if not available_batters: | |
| return "Error: Please select at least one available batter." | |
| rrr = (target - runs) / (20 - over) if target and over < 20 else 0 | |
| pitch_info = pitch_stats_df[pitch_stats_df['venue'] == venue] | |
| pitch_favours = pitch_info['favours'].iloc[0] if not pitch_info.empty else "Unknown" | |
| # Pre-rank batters | |
| scores = [(batter, score_batter(batter, batters_df, bowler_type, pitch_type, venue)) for batter in available_batters] | |
| top_batters = sorted(scores, key=lambda x: x[1], reverse=True)[:3] | |
| top_batter_names = [b[0] for b in top_batters] | |
| # Get stats for prompt | |
| batter_stats = "\n".join([get_batter_stats(batter, batters_df, venue, bowler_type) for batter in top_batter_names]) | |
| prompt = f""" | |
| You are a cricket analyst selecting the best batter from: {', '.join(top_batter_names)} for an IPL 2025 match. Analyze the match context and batter stats to recommend the most suitable batter. Provide a detailed justification (3-4 sentences) that explains why this batter is the best choice, considering: | |
| - Their role (e.g., anchor, aggressor, finisher) and how it suits the current over, wickets, and required run rate. | |
| - Specific stats (e.g., average/strike rate vs. {bowler_type}, form, venue performance). | |
| - Tactical fit against the opposition ({opposition}) and pitch conditions ({pitch_type}, favours {pitch_favours} at {venue}). | |
| - Game situation (e.g., chasing {target}, {wickets} wickets down, {20-over} overs remaining). | |
| Ensure the justification is concise, data-driven, and tactically insightful. | |
| Match Context: | |
| - Over: {over} | |
| - Wickets: {wickets} | |
| - Runs: {runs} | |
| - Required Run Rate: {rrr:.2f} | |
| - Batter Out: {batter_out} | |
| - Bowler Type: {bowler_type} | |
| - Pitch Type: {pitch_type} | |
| - Venue: {venue} (Favours: {pitch_favours}) | |
| - Opposition: {opposition} | |
| Batter Stats: | |
| {batter_stats} | |
| Respond in this format: | |
| Batter: <Name> | |
| Justification: <3-4 sentences of reasoning> | |
| """ | |
| try: | |
| response = client.chat.completions.create( | |
| model="gpt-4", | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=0.7 | |
| ) | |
| return response.choices[0].message.content.strip() | |
| except Exception as e: | |
| return f"Error: {str(e)}" | |
| with gr.Blocks(title="IPL Batting Decision Maker") as app: | |
| gr.Markdown("# π§ IPL Batting Decision Maker\nLive-match assistant to suggest the best next batter after a wicket falls.") | |
| with gr.Group(): | |
| gr.Markdown("### π Match Setup") | |
| with gr.Row(): | |
| team_a = gr.Dropdown(choices=list(team_to_players.keys()), label="π‘ Batting Team", value=None, interactive=True) | |
| team_b = gr.Dropdown(choices=list(team_to_players.keys()), label="π΅ Bowling Team", value=None, interactive=True) | |
| venue = gr.Dropdown(choices=venues, label="ποΈ Venue", value=None, interactive=True) | |
| with gr.Group(): | |
| gr.Markdown("### π Match Situation") | |
| with gr.Row(): | |
| over = gr.Number(label="π Current Over (e.g., 10.2)", minimum=0, maximum=20, value=None) | |
| wickets = gr.Dropdown(choices=list(range(0, 11)), label="β Wickets Fallen", value=None) | |
| runs = gr.Number(label="πββοΈ Runs Scored", minimum=0, value=None) | |
| target = gr.Number(label="π― Target Score (if chasing)", minimum=0, value=None) | |
| with gr.Group(): | |
| gr.Markdown("### βοΈ Tactical Inputs") | |
| with gr.Row(): | |
| bowler_type = gr.Dropdown(["Spin", "Pace"], label="π― Bowler Type", value=None) | |
| pitch_type = gr.Dropdown(["Flat", "Dry", "Green", "Dusty"], label="π§± Pitch Type", value=None) | |
| batter_out = gr.Dropdown(label="π§ Batter Out", choices=[], value=None, interactive=True, info="Select a batting team to see players.") | |
| available_batters = gr.CheckboxGroup(label="π Available Batters", choices=[], value=[], info="Select available batters (must have stats in batters.csv).") | |
| # Event handlers | |
| team_a.change(fn=update_batter_out, inputs=team_a, outputs=batter_out) | |
| batter_out.change(fn=update_available_batters, inputs=[team_a, batter_out], outputs=available_batters) | |
| venue.change(fn=update_venue_stats, inputs=venue, outputs=gr.Textbox(label="ποΈ Venue Stats")) | |
| submit_btn = gr.Button("π Suggest Next Batter") | |
| result = gr.Textbox(label="β Recommended Batter & Justification", lines=5) | |
| submit_btn.click(fn=recommend_batter, inputs=[ | |
| over, wickets, runs, target, batter_out, bowler_type, pitch_type, venue, team_b, available_batters | |
| ], outputs=result) | |
| if __name__ == "__main__": | |
| app.launch() |