Advertisement
GMan_LDN

UpComingFights

Feb 1st, 2025 (edited)
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.62 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. import datetime
  3. import tkinter as tk
  4. from tkinter import ttk
  5. import urllib.request  # Standard library for HTTP calls.
  6. import json           # Standard library for JSON parsing.
  7. from fractions import Fraction
  8. from urllib.parse import quote
  9.  
  10. def convert_decimal_to_fractional(decimal_odds):
  11.     """
  12.    Convert digital (decimal) odds to UK-style (fractional) odds.
  13.    The conversion subtracts 1 from the decimal odd and expresses it as a fraction.
  14.    
  15.    For example, 2.5 in decimal becomes 1.5, which is represented as "3/2".
  16.    """
  17.     if decimal_odds is None or decimal_odds <= 1:
  18.         return "N/A"
  19.     fractional_value = decimal_odds - 1
  20.     frac = Fraction(fractional_value).limit_denominator(20)
  21.     return f"{frac.numerator}/{frac.denominator}"
  22.  
  23. def fetch_odds_from_source(url):
  24.     """
  25.    Try to fetch odds from a given URL.
  26.    The URL is expected to return JSON data containing a key "odds" with a numeric value.
  27.    If anything goes wrong, the function returns None.
  28.    """
  29.     try:
  30.         with urllib.request.urlopen(url) as response:
  31.             if response.getcode() == 200:
  32.                 data = json.loads(response.read().decode('utf-8'))
  33.                 # We assume the API returns a JSON object like {"odds": 2.5}
  34.                 return data.get("odds")
  35.             else:
  36.                 return None
  37.     except Exception as e:
  38.         print(f"Error fetching odds from {url}: {e}")
  39.         return None
  40.  
  41. def fetch_representative_odd_simulated(match):
  42.     """
  43.    Fallback method: simulate an odd using a hash-based pseudo-random generation.
  44.    """
  45.     odd_range = (1.5, 5.0)
  46.     h = abs(hash(match["bout"]))
  47.     factor = (h % 1000) / 1000.0  # A pseudo-random factor between 0 and 1.
  48.     odd = odd_range[0] + factor * (odd_range[1] - odd_range[0])
  49.     return round(odd, 2)
  50.  
  51. def fetch_representative_odd(match):
  52.     """
  53.    Gather a representative odd from multiple online sources.
  54.    
  55.    Two example endpoints are called (using the bout name as an identifier).
  56.    If one or both online calls return a valid odd, the average is taken.
  57.    Otherwise, the function falls back to a simulated odd.
  58.    """
  59.     # Encode the bout name to use it as a query parameter.
  60.     match_id = quote(match["bout"])
  61.    
  62.     # Example API endpoints—replace these with real odds API URLs.
  63.     url1 = f"http://api1.example.com/boxing_odds?match_id={match_id}"
  64.     url2 = f"http://api2.example.com/boxing_odds?match_id={match_id}"
  65.    
  66.     odd1 = fetch_odds_from_source(url1)
  67.     odd2 = fetch_odds_from_source(url2)
  68.    
  69.     # Collect odds that were successfully fetched.
  70.     odds = [o for o in (odd1, odd2) if o is not None]
  71.    
  72.     if odds:
  73.         avg_odd = round(sum(odds) / len(odds), 2)
  74.         return avg_odd
  75.     else:
  76.         # Fallback to simulated odd if online sources fail.
  77.         return fetch_representative_odd_simulated(match)
  78.  
  79. def fetch_boxing_matches_source1(start_date, end_date):
  80.     """
  81.    Simulate fetching boxing matches from Source 1.
  82.    
  83.    Each match is a dictionary including:
  84.      - date (ISO formatted)
  85.      - bout (bout name)
  86.      - fighter1, fighter2 (names)
  87.      - promoter
  88.      - status ("Confirmed" or "Provisional")
  89.    """
  90.     matches = [
  91.         {
  92.             "date": (start_date + datetime.timedelta(days=15)).isoformat(),
  93.             "bout": "Heavyweight Showdown",
  94.             "fighter1": "John Doe",
  95.             "fighter2": "Max Power",
  96.             "promoter": "Big Fights Inc.",
  97.             "status": "Confirmed"
  98.         },
  99.         {
  100.             "date": (start_date + datetime.timedelta(days=45)).isoformat(),
  101.             "bout": "Middleweight Battle",
  102.             "fighter1": "Alex Swift",
  103.             "fighter2": "Carlos Mendez",
  104.             "promoter": "Knockout Promotions",
  105.             "status": "Confirmed"
  106.         },
  107.         {
  108.             "date": (start_date + datetime.timedelta(days=75)).isoformat(),
  109.             "bout": "Lightweight Clash",
  110.             "fighter1": "Sam Quick",
  111.             "fighter2": "Leo Strike",
  112.             "promoter": "Punch Masters",
  113.             "status": "Provisional"
  114.         },
  115.         {
  116.             "date": (start_date + datetime.timedelta(days=110)).isoformat(),
  117.             "bout": "Super Bantamweight Brawl",
  118.             "fighter1": "Dylan Swift",
  119.             "fighter2": "Marcus Bolt",
  120.             "promoter": "Rising Stars Promotions",
  121.             "status": "Confirmed"
  122.         },
  123.     ]
  124.     return matches
  125.  
  126. def fetch_boxing_matches_source2(start_date, end_date):
  127.     """
  128.    Simulate fetching boxing matches from Source 2.
  129.    """
  130.     matches = [
  131.         {
  132.             "date": (start_date + datetime.timedelta(days=30)).isoformat(),
  133.             "bout": "Featherweight Frenzy",
  134.             "fighter1": "Liam Swift",
  135.             "fighter2": "Noah Strike",
  136.             "promoter": "Punch Masters",
  137.             "status": "Confirmed"
  138.         },
  139.         {
  140.             "date": (start_date + datetime.timedelta(days=60)).isoformat(),
  141.             "bout": "Welterweight War",
  142.             "fighter1": "Ethan Power",
  143.             "fighter2": "Mason Fury",
  144.             "promoter": "Golden Gloves",
  145.             "status": "Provisional"
  146.         },
  147.         {
  148.             "date": (start_date + datetime.timedelta(days=90)).isoformat(),
  149.             "bout": "Cruiserweight Combat",
  150.             "fighter1": "Oliver Bold",
  151.             "fighter2": "Elijah Brave",
  152.             "promoter": "Fight Club Promotions",
  153.             "status": "Confirmed"
  154.         },
  155.         {
  156.             "date": (start_date + datetime.timedelta(days=130)).isoformat(),
  157.             "bout": "Light Middleweight Melee",
  158.             "fighter1": "Zachary Quick",
  159.             "fighter2": "Ryan Swift",
  160.             "promoter": "City Lights Boxing",
  161.             "status": "Provisional"
  162.         },
  163.     ]
  164.     return matches
  165.  
  166. def fetch_boxing_matches(start_date, end_date):
  167.     """
  168.    Combine matches from multiple sources and sort them by date.
  169.    """
  170.     matches = []
  171.     matches.extend(fetch_boxing_matches_source1(start_date, end_date))
  172.     matches.extend(fetch_boxing_matches_source2(start_date, end_date))
  173.     matches.sort(key=lambda x: x["date"])
  174.     return matches
  175.  
  176. def main():
  177.     # Create the main window.
  178.     root = tk.Tk()
  179.     root.title("Upcoming Boxing Matches")
  180.     root.geometry("950x400")
  181.    
  182.     # Define the date range (today to one year later).
  183.     today = datetime.date.today()
  184.     one_year_later = today + datetime.timedelta(days=365)
  185.    
  186.     # Top frame: display the date range.
  187.     top_frame = ttk.Frame(root, padding="10")
  188.     top_frame.pack(fill=tk.X)
  189.     start_label = ttk.Label(top_frame, text=f"Start Date: {today.isoformat()}")
  190.     start_label.pack(side=tk.LEFT, padx=5)
  191.     end_label = ttk.Label(top_frame, text=f"End Date: {one_year_later.isoformat()}")
  192.     end_label.pack(side=tk.LEFT, padx=5)
  193.    
  194.     # Create a Treeview widget to display match details.
  195.     columns = ("date", "bout", "fighter1", "fighter2", "promoter", "status", "odds")
  196.     tree = ttk.Treeview(root, columns=columns, show="headings", height=10)
  197.    
  198.     # Set up column headings.
  199.     tree.heading("date", text="Date")
  200.     tree.heading("bout", text="Bout")
  201.     tree.heading("fighter1", text="Fighter 1")
  202.     tree.heading("fighter2", text="Fighter 2")
  203.     tree.heading("promoter", text="Promoter")
  204.     tree.heading("status", text="Status")
  205.     tree.heading("odds", text="Odds (Decimal / Fractional)")
  206.    
  207.     # Set column widths and alignment.
  208.     tree.column("date", width=100, anchor=tk.CENTER)
  209.     tree.column("bout", width=200, anchor=tk.W)
  210.     tree.column("fighter1", width=150, anchor=tk.W)
  211.     tree.column("fighter2", width=150, anchor=tk.W)
  212.     tree.column("promoter", width=150, anchor=tk.W)
  213.     tree.column("status", width=100, anchor=tk.CENTER)
  214.     tree.column("odds", width=150, anchor=tk.CENTER)
  215.    
  216.     tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
  217.    
  218.     # Fetch and display boxing matches.
  219.     matches = fetch_boxing_matches(today, one_year_later)
  220.     for match in matches:
  221.         # Gather a representative odd from multiple online sources.
  222.         odd_digital = fetch_representative_odd(match)
  223.         odd_fractional = convert_decimal_to_fractional(odd_digital)
  224.         odds_display = f"{odd_digital} ({odd_fractional})"
  225.        
  226.         tree.insert("", tk.END, values=(
  227.             match["date"],
  228.             match["bout"],
  229.             match["fighter1"],
  230.             match["fighter2"],
  231.             match["promoter"],
  232.             match["status"],
  233.             odds_display
  234.         ))
  235.    
  236.     # Start the Tkinter event loop.
  237.     root.mainloop()
  238.  
  239. if __name__ == "__main__":
  240.     main()
  241.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement