import base64 import json from datetime import datetime, timedelta import pandas as pd import pytz import streamlit as st # File paths as constants PREDICTIONS_CSV = 'predictions.csv' USERS_JSON = 'users.json' MATCHES_JSON = 'matches.json' OUTCOMES_JSON = 'match_outcomes.json' PLAYERS_JSON = 'players.json' image_path = 'ipl_image.png' # Initialize CSV and JSON files if they don't exist def initialize_files(): # Initialize predictions CSV try: pd.read_csv(PREDICTIONS_CSV) except FileNotFoundError: df = pd.DataFrame(columns=['user_name', 'match_id', 'predicted_winner', 'predicted_motm', 'bid_points']) df.to_csv(PREDICTIONS_CSV, index=False) @st.cache_data def load_data(file_path): """ Load data from a JSON or CSV file. Args: file_path (str): The path to the file to load. Returns: pd.DataFrame or dict: The loaded data. """ try: if file_path.endswith('.json'): with open(file_path, 'r') as file: return json.load(file) elif file_path.endswith('.csv'): return pd.read_csv(file_path) except FileNotFoundError: if file_path.endswith('.json'): return {} elif file_path.endswith('.csv'): return pd.DataFrame() def get_base64_of_image(path): with open(path, "rb") as image_file: return base64.b64encode(image_file.read()).decode() # Get today's date in IST to load today's match def get_current_date_ist(): tz_IST = pytz.timezone('Asia/Kolkata') datetime_ist = datetime.now(tz_IST) return datetime_ist.strftime('%Y-%m-%d') # Function to get matches for today def get_today_matches(): today = get_current_date_ist() matches = load_data(MATCHES_JSON) today_matches = [match for match in matches if match['date'] == today] return today_matches # Function to check if prediction submission is allowed def is_submission_allowed(match_id): matches = load_data(MATCHES_JSON) # This loads matches correctly with IST times for match in matches: if match["match_id"] == match_id: # Parse the match start time in IST tz_IST = pytz.timezone('Asia/Kolkata') match_datetime_str = f'{match["date"]} {match["time"]}' # The match time string is like "2024-03-21 7:30 PM" match_datetime = datetime.strptime(match_datetime_str, "%Y-%m-%d %I:%M %p") match_datetime = tz_IST.localize(match_datetime) # Set the timezone to IST # Get the current time in IST current_datetime = datetime.now(tz_IST) if current_datetime > match_datetime + timedelta(minutes=30): return False else: return True return False # If match_id not found, default to False # Submit prediction function def submit_prediction( user_name, match_id, predicted_winner, predicted_motm, bid_points, max_bid_points ): # Validation for user selection if user_name == "Select a user...": st.warning("Please select a valid user.") return # Check if prediction submission is allowed for the match if not is_submission_allowed(match_id): st.error("Prediction submission time has passed. Predictions can't be submitted after match start.") return if bid_points > max_bid_points: st.error(f"Your bid points exceed the 20% limit of your total points. Maximum allowed bid points: {max_bid_points}") return # Ensure predictions DataFrame is loaded or initialized correctly try: predictions = load_predictions(PREDICTIONS_CSV) # Check if all expected columns are present, if not, reinitialize the DataFrame expected_columns = ['user_name', 'match_id', 'predicted_winner', 'predicted_motm', 'bid_points'] if not all(column in predictions.columns for column in expected_columns): raise ValueError("CSV file missing one or more columns; Reinitializing.") except (FileNotFoundError, ValueError) as e: predictions = pd.DataFrame(columns=expected_columns) # Check for duplicate prediction for the same match by the same user if user_name != "Select a user...": existing_predictions = predictions[(predictions['user_name'] == user_name) & (predictions['match_id'] == match_id)] if not existing_predictions.empty: st.error("You've already submitted a prediction for this match.") return # Append new prediction new_prediction = { 'user_name': user_name, 'match_id': match_id, 'predicted_winner': predicted_winner, 'predicted_motm': predicted_motm, 'bid_points': bid_points } predictions = pd.concat([predictions, pd.DataFrame([new_prediction])], ignore_index=True) predictions.to_csv(PREDICTIONS_CSV, index=False) st.success("Prediction submitted successfully!") def get_user_total_points(user_name): users = load_data(USERS_JSON) return users.get(user_name, 0) # Define the new function def calculate_max_bid_points(user_name): total_points = get_user_total_points(user_name) max_bid_points = int(total_points * 0.20) # 20% of total points return max_bid_points def user_selection_and_prediction(): users = list(load_data(USERS_JSON)) user_name = st.selectbox("Select User", ["Select a user..."] + users) max_bid_points = None if user_name != "Select a user...": max_bid_points = calculate_max_bid_points(user_name) st.write(f"Maximum bid points you can submit: {max_bid_points}") matches = get_today_matches() if matches: match_choice = st.selectbox("Select Today's Match", matches, format_func=lambda match: f"{match['teams'][0]} vs {match['teams'][1]}") match_id = match_choice['match_id'] teams = match_choice['teams'] predicted_winner = st.selectbox("Predicted Winner", teams) player_list = load_data(PLAYERS_JSON) predicted_motm = "" if predicted_winner in player_list: players = player_list[predicted_winner] predicted_motm = st.selectbox("Predicted Man of the Match", players) bid_points = st.number_input("Bid Points", min_value=1, value=100, format="%d") if st.button("Submit Prediction"): submit_prediction(user_name, match_id, predicted_winner, predicted_motm, bid_points, max_bid_points) else: st.write("No matches are scheduled for today.") def display_predictions(): if st.button("Show Predictions"): try: todays_predictions = show_todays_match_predictions() if not todays_predictions.empty: st.dataframe(todays_predictions, hide_index=True) else: st.write("No predictions for today's matches yet.") except FileNotFoundError: st.write("No predictions have been submitted yet.") def display_leaderboard(): if st.button("Show Leaderboard"): try: users = load_data(USERS_JSON) # Adjusted for the new load_data function leaderboard = sorted(users.items(), key=lambda x: x[1], reverse=True) # Generate a list of dictionaries, each representing a row in the leaderboard leaderboard_dicts = [{"Rank": rank+1, "User": user[0], "Points": user[1]} for rank, user in enumerate(leaderboard)] # Convert the list of dictionaries to a DataFrame df_leaderboard = pd.DataFrame(leaderboard_dicts) st.dataframe(df_leaderboard, hide_index=True) except FileNotFoundError: st.write("Leaderboard data not available.") def load_predictions(PREDICTIONS_CSV): try: return pd.read_csv(PREDICTIONS_CSV) except FileNotFoundError: return pd.DataFrame() # Show Predictions functionality def show_todays_match_predictions(): # Get today's matches today_matches = get_today_matches() today_match_ids = [match['match_id'] for match in today_matches] # Load all predictions predictions = load_predictions(PREDICTIONS_CSV) # Filter predictions for today's matches today_predictions = predictions[predictions['match_id'].isin(today_match_ids)] return today_predictions # Streamlit UI encoded_image = get_base64_of_image(image_path) custom_css = f""" """ # Apply custom CSS st.markdown(custom_css, unsafe_allow_html=True) # Use the custom class in a div with your title st.markdown('