Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import datetime
- import tkinter as tk
- from tkinter import ttk
- import urllib.request # Standard library for HTTP calls.
- import json # Standard library for JSON parsing.
- from fractions import Fraction
- from urllib.parse import quote
- def convert_decimal_to_fractional(decimal_odds):
- """
- Convert digital (decimal) odds to UK-style (fractional) odds.
- The conversion subtracts 1 from the decimal odd and expresses it as a fraction.
- For example, 2.5 in decimal becomes 1.5, which is represented as "3/2".
- """
- if decimal_odds is None or decimal_odds <= 1:
- return "N/A"
- fractional_value = decimal_odds - 1
- frac = Fraction(fractional_value).limit_denominator(20)
- return f"{frac.numerator}/{frac.denominator}"
- def fetch_odds_from_source(url):
- """
- Try to fetch odds from a given URL.
- The URL is expected to return JSON data containing a key "odds" with a numeric value.
- If anything goes wrong, the function returns None.
- """
- try:
- with urllib.request.urlopen(url) as response:
- if response.getcode() == 200:
- data = json.loads(response.read().decode('utf-8'))
- # We assume the API returns a JSON object like {"odds": 2.5}
- return data.get("odds")
- else:
- return None
- except Exception as e:
- print(f"Error fetching odds from {url}: {e}")
- return None
- def fetch_representative_odd_simulated(match):
- """
- Fallback method: simulate an odd using a hash-based pseudo-random generation.
- """
- odd_range = (1.5, 5.0)
- h = abs(hash(match["bout"]))
- factor = (h % 1000) / 1000.0 # A pseudo-random factor between 0 and 1.
- odd = odd_range[0] + factor * (odd_range[1] - odd_range[0])
- return round(odd, 2)
- def fetch_representative_odd(match):
- """
- Gather a representative odd from multiple online sources.
- Two example endpoints are called (using the bout name as an identifier).
- If one or both online calls return a valid odd, the average is taken.
- Otherwise, the function falls back to a simulated odd.
- """
- # Encode the bout name to use it as a query parameter.
- match_id = quote(match["bout"])
- # Example API endpoints—replace these with real odds API URLs.
- url1 = f"http://api1.example.com/boxing_odds?match_id={match_id}"
- url2 = f"http://api2.example.com/boxing_odds?match_id={match_id}"
- odd1 = fetch_odds_from_source(url1)
- odd2 = fetch_odds_from_source(url2)
- # Collect odds that were successfully fetched.
- odds = [o for o in (odd1, odd2) if o is not None]
- if odds:
- avg_odd = round(sum(odds) / len(odds), 2)
- return avg_odd
- else:
- # Fallback to simulated odd if online sources fail.
- return fetch_representative_odd_simulated(match)
- def fetch_boxing_matches_source1(start_date, end_date):
- """
- Simulate fetching boxing matches from Source 1.
- Each match is a dictionary including:
- - date (ISO formatted)
- - bout (bout name)
- - fighter1, fighter2 (names)
- - promoter
- - status ("Confirmed" or "Provisional")
- """
- matches = [
- {
- "date": (start_date + datetime.timedelta(days=15)).isoformat(),
- "bout": "Heavyweight Showdown",
- "fighter1": "John Doe",
- "fighter2": "Max Power",
- "promoter": "Big Fights Inc.",
- "status": "Confirmed"
- },
- {
- "date": (start_date + datetime.timedelta(days=45)).isoformat(),
- "bout": "Middleweight Battle",
- "fighter1": "Alex Swift",
- "fighter2": "Carlos Mendez",
- "promoter": "Knockout Promotions",
- "status": "Confirmed"
- },
- {
- "date": (start_date + datetime.timedelta(days=75)).isoformat(),
- "bout": "Lightweight Clash",
- "fighter1": "Sam Quick",
- "fighter2": "Leo Strike",
- "promoter": "Punch Masters",
- "status": "Provisional"
- },
- {
- "date": (start_date + datetime.timedelta(days=110)).isoformat(),
- "bout": "Super Bantamweight Brawl",
- "fighter1": "Dylan Swift",
- "fighter2": "Marcus Bolt",
- "promoter": "Rising Stars Promotions",
- "status": "Confirmed"
- },
- ]
- return matches
- def fetch_boxing_matches_source2(start_date, end_date):
- """
- Simulate fetching boxing matches from Source 2.
- """
- matches = [
- {
- "date": (start_date + datetime.timedelta(days=30)).isoformat(),
- "bout": "Featherweight Frenzy",
- "fighter1": "Liam Swift",
- "fighter2": "Noah Strike",
- "promoter": "Punch Masters",
- "status": "Confirmed"
- },
- {
- "date": (start_date + datetime.timedelta(days=60)).isoformat(),
- "bout": "Welterweight War",
- "fighter1": "Ethan Power",
- "fighter2": "Mason Fury",
- "promoter": "Golden Gloves",
- "status": "Provisional"
- },
- {
- "date": (start_date + datetime.timedelta(days=90)).isoformat(),
- "bout": "Cruiserweight Combat",
- "fighter1": "Oliver Bold",
- "fighter2": "Elijah Brave",
- "promoter": "Fight Club Promotions",
- "status": "Confirmed"
- },
- {
- "date": (start_date + datetime.timedelta(days=130)).isoformat(),
- "bout": "Light Middleweight Melee",
- "fighter1": "Zachary Quick",
- "fighter2": "Ryan Swift",
- "promoter": "City Lights Boxing",
- "status": "Provisional"
- },
- ]
- return matches
- def fetch_boxing_matches(start_date, end_date):
- """
- Combine matches from multiple sources and sort them by date.
- """
- matches = []
- matches.extend(fetch_boxing_matches_source1(start_date, end_date))
- matches.extend(fetch_boxing_matches_source2(start_date, end_date))
- matches.sort(key=lambda x: x["date"])
- return matches
- def main():
- # Create the main window.
- root = tk.Tk()
- root.title("Upcoming Boxing Matches")
- root.geometry("950x400")
- # Define the date range (today to one year later).
- today = datetime.date.today()
- one_year_later = today + datetime.timedelta(days=365)
- # Top frame: display the date range.
- top_frame = ttk.Frame(root, padding="10")
- top_frame.pack(fill=tk.X)
- start_label = ttk.Label(top_frame, text=f"Start Date: {today.isoformat()}")
- start_label.pack(side=tk.LEFT, padx=5)
- end_label = ttk.Label(top_frame, text=f"End Date: {one_year_later.isoformat()}")
- end_label.pack(side=tk.LEFT, padx=5)
- # Create a Treeview widget to display match details.
- columns = ("date", "bout", "fighter1", "fighter2", "promoter", "status", "odds")
- tree = ttk.Treeview(root, columns=columns, show="headings", height=10)
- # Set up column headings.
- tree.heading("date", text="Date")
- tree.heading("bout", text="Bout")
- tree.heading("fighter1", text="Fighter 1")
- tree.heading("fighter2", text="Fighter 2")
- tree.heading("promoter", text="Promoter")
- tree.heading("status", text="Status")
- tree.heading("odds", text="Odds (Decimal / Fractional)")
- # Set column widths and alignment.
- tree.column("date", width=100, anchor=tk.CENTER)
- tree.column("bout", width=200, anchor=tk.W)
- tree.column("fighter1", width=150, anchor=tk.W)
- tree.column("fighter2", width=150, anchor=tk.W)
- tree.column("promoter", width=150, anchor=tk.W)
- tree.column("status", width=100, anchor=tk.CENTER)
- tree.column("odds", width=150, anchor=tk.CENTER)
- tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
- # Fetch and display boxing matches.
- matches = fetch_boxing_matches(today, one_year_later)
- for match in matches:
- # Gather a representative odd from multiple online sources.
- odd_digital = fetch_representative_odd(match)
- odd_fractional = convert_decimal_to_fractional(odd_digital)
- odds_display = f"{odd_digital} ({odd_fractional})"
- tree.insert("", tk.END, values=(
- match["date"],
- match["bout"],
- match["fighter1"],
- match["fighter2"],
- match["promoter"],
- match["status"],
- odds_display
- ))
- # Start the Tkinter event loop.
- root.mainloop()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement