From ea85cd451eb052e80b38a04e25918290094325b4 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Sat, 29 Mar 2025 00:23:35 -0500 Subject: initial commit --- nba/__init__.py | 0 nba/__main__.py | 7 +++++ nba/cli.py | 25 ++++++++++++++++ nba/fetch_data.py | 28 ++++++++++++++++++ nba/scores.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ nba/standings.py | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 221 insertions(+) create mode 100644 nba/__init__.py create mode 100644 nba/__main__.py create mode 100644 nba/cli.py create mode 100644 nba/fetch_data.py create mode 100644 nba/scores.py create mode 100644 nba/standings.py (limited to 'nba') diff --git a/nba/__init__.py b/nba/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nba/__main__.py b/nba/__main__.py new file mode 100644 index 0000000..0605298 --- /dev/null +++ b/nba/__main__.py @@ -0,0 +1,7 @@ +""" +Entry point for the app. +""" + +if __name__ == "__main__": + from nba.cli import nba + nba() diff --git a/nba/cli.py b/nba/cli.py new file mode 100644 index 0000000..a1a3eb6 --- /dev/null +++ b/nba/cli.py @@ -0,0 +1,25 @@ +""" +This script uses argparse to parse command line arguments. + +It imports the required modules and sets up a parser with basic options for demonstration purposes. +""" +import argparse +from nba import fetch_data, scores, standings + +def nba() -> None: + """ + Parse command-line arguments and display either scoreboard or standings. + """ + parser = argparse.ArgumentParser(description="NBA Scoreboard and Standings") + parser.add_argument('--scores', action='store_true', help='Display the scoreboard') + parser.add_argument('--standings', action='store_true', help='Display the standings') + args = parser.parse_args() + + games, standings = fetch_data.fetch_data() + + if args.scores: + scores.build_scoreboard(games, standings) + elif args.standings: + standings.build_standings(standings) + else: + print("Please specify --scores or --standings") \ No newline at end of file diff --git a/nba/fetch_data.py b/nba/fetch_data.py new file mode 100644 index 0000000..bba3a59 --- /dev/null +++ b/nba/fetch_data.py @@ -0,0 +1,28 @@ +""" +Fetches data for use in other modules. +""" +import json +from nba_api.live.nba.endpoints import scoreboard +from nba_api.stats.endpoints import leaguestandings + +def fetch_data() -> tuple: + """ + Fetches live NBA scoreboard data and standings from the NBA API. + + Returns: + games (dict): JSON parsed games data. + standings (dict): JSON parsed team standings data. + """ + # Get today's scoreboard data + games_endpoint = scoreboard.ScoreBoard() + games_json = games_endpoint.get_json() + + # Get league standings + standings_endpoint = leaguestandings.LeagueStandings() + standings_json = standings_endpoint.get_json() + + # Parse the JSON strings into Python dictionaries + games = json.loads(games_json) + standings = json.loads(standings_json) + + return games, standings \ No newline at end of file diff --git a/nba/scores.py b/nba/scores.py new file mode 100644 index 0000000..6c4b660 --- /dev/null +++ b/nba/scores.py @@ -0,0 +1,85 @@ +""" +Tabulates a scoreboard for today's games. +""" +from tabulate import tabulate + +# ANSI escape codes for text formatting +BOLD = '\033[1m' +END = '\033[0m' +RED = '\033[91m' +GREEN = '\033[32m' + +# Function to get team record from standings +def get_team_record(team_name, standings) -> str: + """ + Retrieves a team's win-loss record from the standings data. + + Args: + team_name (str): Name of the team. + standings (dict): Team standings data. + + Returns: + record (str): Team's win-loss record in 'W-L' format. Defaults to 'N/A'. + """ + for result_set in standings['resultSets']: + if result_set['name'] == 'Standings': + for team in result_set['rowSet']: + if team[4] == team_name: + return f"{team[12]}-{team[13]}" + return "N/A" + +def build_scoreboard(games, standings) -> None: + """ + Prints the current day's games in a table format. + + Args: + games (dict): JSON parsed games data. + standings (dict): Team standings data. + """ + scoreboard_data = games['scoreboard'] + games = scoreboard_data['games'] + + # Prepare the table data + table_data = [] + for game in games: + home_team = game['homeTeam']['teamName'] + away_team = game['awayTeam']['teamName'] + game_status = game['gameStatusText'] + home_score = game['homeTeam']['score'] + away_score = game['awayTeam']['score'] + + home_record = get_team_record(home_team, standings) + away_record = get_team_record(away_team, standings) + + # Determine the winning team + if home_score > away_score: + home_team_bold = f"{BOLD}{GREEN}{home_team} ({home_record}){END}{END}" + away_team_bold = f"{away_team} ({away_record}){END}" + home_score_bold = f"{BOLD}{GREEN}{home_score}{END}{END}" + away_score_bold = f"{away_score}{END}" + elif away_score > home_score: + home_team_bold = f"{home_team} ({home_record}){END}" + away_team_bold = f"{BOLD}{GREEN}{away_team} ({away_record}){END}{END}" + home_score_bold = f"{home_score}{END}" + away_score_bold = f"{BOLD}{GREEN}{away_score}{END}{END}" + else: + home_team_bold = f"{home_team} ({home_record})" + away_team_bold = f"{away_team} ({away_record})" + home_score_bold = f"{home_score}" + away_score_bold = f"{away_score}" + + # Determine games still in progress + if game_status != "Final": + game_status = f"{RED}{game_status}{END}" + + table_data.append([ + f"{home_team_bold}\n{away_team_bold}", + f"{home_score_bold}\n{away_score_bold}", + f"{BOLD}{game_status}{END}" + ]) + + # Define the table headers + headers = ["Team", "Score", "Game Status"] + + # Print the table + print(tabulate(table_data, headers=headers, tablefmt="grid")) diff --git a/nba/standings.py b/nba/standings.py new file mode 100644 index 0000000..a7773fe --- /dev/null +++ b/nba/standings.py @@ -0,0 +1,76 @@ +""" +Tabulate the current conference standings. +""" +from tabulate import tabulate + +# ANSI escape codes for text formatting +END = '\033[0m' +RED = '\033[91m' +GREEN = '\033[32m' + +def build_standings(standings) -> None: + """ + Prints team standings in two separate tables. + + Args: + standings (dict): Team standings data. + """ + eastern_data = [] + western_data = [] + eastern_rank = 1 + western_rank = 1 + + for result_set in standings['resultSets']: + if result_set['name'] == 'Standings': + for team in result_set['rowSet']: + conference = team[5] + team_name = team[4] + wins = team[12] + losses = team[13] + win_pct = team[14] + gb = team[37] + home_record = team[17] + away_record = team[18] + last_10 = team[19] + streak = team[35] + + if int(streak) < 0: + strk_color = f"{RED}{streak}{END}" + else: + strk_color = f"{GREEN}{streak}{END}" + + if conference == "East": + eastern_data.append([ + f"{eastern_rank}", + f"{team_name}", + f"{wins}-{losses}", + f"{win_pct:.3f}", + f"{gb}", + f"{strk_color}", + f"{last_10}", + f"{home_record}", + f"{away_record}" + ]) + eastern_rank += 1 + elif conference == "West": + western_data.append([ + f"{western_rank}", + f"{team_name}", + f"{wins}-{losses}", + f"{win_pct:.3f}", + f"{gb}", + f"{strk_color}", + f"{last_10}", + f"{home_record}", + f"{away_record}" + ]) + western_rank += 1 + + headers = ["Rank", "Team", "W-L", "PCT", "GB", "STRK", "L10", "HOME", "AWAY"] + + print(f"{BOLD}Eastern Conference Standings:{END}") + print(tabulate(eastern_data, headers=headers, tablefmt="grid")) + + print("\n") + print(f"{BOLD}Western Conference Standings:{END}") + print(tabulate(western_data, headers=headers, tablefmt="grid")) -- cgit v1.2.3-70-g09d2