Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions src/nba_api/stats/library/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6661,3 +6661,83 @@
[],
],
]


# Conference and division mapping for NBA teams, keyed by team_id from `teams`.
# Alignment is stable since the 2004-05 season. WNBA teams are intentionally
# excluded because the WNBA uses a different alignment that changes with
# expansion.

team_conferences = {
# Eastern Conference
1610612737: "East", # Atlanta Hawks
1610612738: "East", # Boston Celtics
1610612739: "East", # Cleveland Cavaliers
1610612741: "East", # Chicago Bulls
1610612748: "East", # Miami Heat
1610612749: "East", # Milwaukee Bucks
1610612751: "East", # Brooklyn Nets
1610612752: "East", # New York Knicks
1610612753: "East", # Orlando Magic
1610612754: "East", # Indiana Pacers
1610612755: "East", # Philadelphia 76ers
1610612761: "East", # Toronto Raptors
1610612764: "East", # Washington Wizards
1610612765: "East", # Detroit Pistons
1610612766: "East", # Charlotte Hornets
# Western Conference
1610612740: "West", # New Orleans Pelicans
1610612742: "West", # Dallas Mavericks
1610612743: "West", # Denver Nuggets
1610612744: "West", # Golden State Warriors
1610612745: "West", # Houston Rockets
1610612746: "West", # Los Angeles Clippers
1610612747: "West", # Los Angeles Lakers
1610612750: "West", # Minnesota Timberwolves
1610612756: "West", # Phoenix Suns
1610612757: "West", # Portland Trail Blazers
1610612758: "West", # Sacramento Kings
1610612759: "West", # San Antonio Spurs
1610612760: "West", # Oklahoma City Thunder
1610612762: "West", # Utah Jazz
1610612763: "West", # Memphis Grizzlies
}

team_divisions = {
# Atlantic (Eastern Conference)
1610612738: "Atlantic", # Boston Celtics
1610612751: "Atlantic", # Brooklyn Nets
1610612752: "Atlantic", # New York Knicks
1610612755: "Atlantic", # Philadelphia 76ers
1610612761: "Atlantic", # Toronto Raptors
# Central (Eastern Conference)
1610612739: "Central", # Cleveland Cavaliers
1610612741: "Central", # Chicago Bulls
1610612749: "Central", # Milwaukee Bucks
1610612754: "Central", # Indiana Pacers
1610612765: "Central", # Detroit Pistons
# Southeast (Eastern Conference)
1610612737: "Southeast", # Atlanta Hawks
1610612748: "Southeast", # Miami Heat
1610612753: "Southeast", # Orlando Magic
1610612764: "Southeast", # Washington Wizards
1610612766: "Southeast", # Charlotte Hornets
# Northwest (Western Conference)
1610612743: "Northwest", # Denver Nuggets
1610612750: "Northwest", # Minnesota Timberwolves
1610612757: "Northwest", # Portland Trail Blazers
1610612760: "Northwest", # Oklahoma City Thunder
1610612762: "Northwest", # Utah Jazz
# Pacific (Western Conference)
1610612744: "Pacific", # Golden State Warriors
1610612746: "Pacific", # Los Angeles Clippers
1610612747: "Pacific", # Los Angeles Lakers
1610612756: "Pacific", # Phoenix Suns
1610612758: "Pacific", # Sacramento Kings
# Southwest (Western Conference)
1610612740: "Southwest", # New Orleans Pelicans
1610612742: "Southwest", # Dallas Mavericks
1610612745: "Southwest", # Houston Rockets
1610612759: "Southwest", # San Antonio Spurs
1610612763: "Southwest", # Memphis Grizzlies
}
42 changes: 42 additions & 0 deletions src/nba_api/stats/static/teams.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import re

from nba_api.stats.library.data import (
team_conferences,
team_divisions,
team_index_abbreviation,
team_index_championship_year,
team_index_city,
Expand Down Expand Up @@ -148,3 +150,43 @@ def find_wnba_team_name_by_id(team_id):

def get_wnba_teams():
return _get_teams(teams=wnba_teams)


def get_team_conference(team_id):
"""Return the conference name ("East" or "West") for an NBA team id,
or None if the team id is not an NBA team. WNBA teams are not covered."""
return team_conferences.get(team_id)


def get_team_division(team_id):
"""Return the division name for an NBA team id (one of "Atlantic",
"Central", "Southeast", "Northwest", "Pacific", "Southwest"), or None
if the team id is not an NBA team."""
return team_divisions.get(team_id)


def find_teams_by_conference(conference):
"""Return all NBA teams in the given conference. Conference matching
is case-insensitive ("East" and "east" both work). Returns an empty
list for falsy input."""
if not conference:
return []
target = conference.lower()
return [
_get_team_dict(team)
for team in teams
if team_conferences.get(team[team_index_id], "").lower() == target
]


def find_teams_by_division(division):
"""Return all NBA teams in the given division. Division matching is
case-insensitive. Returns an empty list for falsy input."""
if not division:
return []
target = division.lower()
return [
_get_team_dict(team)
for team in teams
if team_divisions.get(team[team_index_id], "").lower() == target
]
103 changes: 103 additions & 0 deletions tests/unit/stats/static/test_static_data.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

from nba_api.stats.static import teams


Expand All @@ -7,3 +9,104 @@ def test_nba_teams():

def test_wnba_teams():
assert len(teams.wnba_teams) == 13


# --- Conference and division static data -----------------------------------


CONFERENCES = ("East", "West")
DIVISIONS = ("Atlantic", "Central", "Southeast", "Northwest", "Pacific", "Southwest")


def test_every_nba_team_has_conference_and_division():
nba_ids = {team["id"] for team in teams.get_teams()}
assert set(teams.team_conferences) == nba_ids
assert set(teams.team_divisions) == nba_ids


def test_conferences_are_evenly_split():
by_conference = dict.fromkeys(CONFERENCES, 0)
for conference in teams.team_conferences.values():
assert conference in CONFERENCES
by_conference[conference] += 1
assert by_conference == {"East": 15, "West": 15}


def test_divisions_have_five_teams_each():
by_division = dict.fromkeys(DIVISIONS, 0)
for division in teams.team_divisions.values():
assert division in DIVISIONS
by_division[division] += 1
assert all(count == 5 for count in by_division.values())


@pytest.mark.parametrize(
"team_id, expected_conference, expected_division",
[
(1610612747, "West", "Pacific"), # Los Angeles Lakers
(1610612738, "East", "Atlantic"), # Boston Celtics
(1610612749, "East", "Central"), # Milwaukee Bucks
(1610612759, "West", "Southwest"), # San Antonio Spurs
(1610612737, "East", "Southeast"), # Atlanta Hawks
(1610612760, "West", "Northwest"), # Oklahoma City Thunder
],
)
def test_known_team_conference_and_division_lookups(
team_id, expected_conference, expected_division
):
assert teams.get_team_conference(team_id) == expected_conference
assert teams.get_team_division(team_id) == expected_division


def test_unknown_team_id_returns_none_for_both_helpers():
assert teams.get_team_conference(1) is None
assert teams.get_team_division(1) is None
# WNBA team ids are intentionally not covered.
assert teams.get_team_conference(1611661313) is None # New York Liberty
assert teams.get_team_division(1611661313) is None


def test_find_teams_by_conference():
east = teams.find_teams_by_conference("East")
west = teams.find_teams_by_conference("West")
assert len(east) == 15
assert len(west) == 15
# Case-insensitive.
assert {t["id"] for t in east} == {
t["id"] for t in teams.find_teams_by_conference("east")
}


def test_find_teams_by_division():
pacific = teams.find_teams_by_division("Pacific")
assert len(pacific) == 5
assert {t["abbreviation"] for t in pacific} == {"GSW", "LAC", "LAL", "PHX", "SAC"}
# Case-insensitive.
assert {t["id"] for t in pacific} == {
t["id"] for t in teams.find_teams_by_division("pacific")
}


def test_find_teams_by_conference_exact_membership_is_disjoint():
"""Guard against a team being swapped between conferences. Count-only
assertions would still pass if two teams traded conferences; exact
membership + disjointness will not."""
east = {t["id"] for t in teams.find_teams_by_conference("East")}
west = {t["id"] for t in teams.find_teams_by_conference("West")}
nba_ids = {t["id"] for t in teams.get_teams()}
assert len(east) == 15
assert len(west) == 15
assert east.isdisjoint(west)
assert east | west == nba_ids


def test_find_teams_by_unknown_value_returns_empty():
# Division names passed to the conference helper, and vice versa, must
# return empty rather than silently matching.
assert teams.find_teams_by_conference("Central") == []
assert teams.find_teams_by_conference("Pacific") == []
assert teams.find_teams_by_division("East") == []
assert teams.find_teams_by_division("Midwest") == []
# Falsy input is tolerated, not crashing.
assert teams.find_teams_by_conference(None) == []
assert teams.find_teams_by_division("") == []