Kadario NBA standings offer a useful starting point for a small programming project: turn win–loss records into a table that you can explain, reproduce, and test. Basketball fans in the Philippines often see teams with different numbers of games played, so comparing raw win totals can produce the wrong impression. Python makes the arithmetic visible rather than leaving it behind a scoreboard label.
We will use a dated excerpt from the Kadario NBA standings table to calculate win percentage (PCT) and games behind (GB). The script runs on standard Python without API keys, scraping, pandas, or hidden services. The important limit: this is a calculation tutorial, not an official conference-seeding algorithm.
1. Define the input before writing code
The six-team input was checked against Kadario's 2026–27 Western Conference view on November 10, 2026 (Philippine time). In that snapshot, the Lakers were 9–2, San Antonio and Oklahoma City were both 8–2, Minnesota was 8–3, and Houston and Golden State were both 7–3. The example intentionally covers teams with 10 and 11 games played. Do not treat this static sample as today's live standings when you reuse the script later.
The input uses a list of dictionaries: team, wins, and losses. The names make the code readable to someone new to Python, while integers prevent the common mistake of treating a string such as '9-2' as arithmetic. In a production data pipeline, you'd also store season, conference, capture timestamp, source, and whether the source is final or provisional.
2. Calculate winning percentage correctly
Winning percentage is wins / (wins + losses). The Lakers' 9–2 sample produces 9 / 11 = 0.81818, normally displayed as .818 or 81.8%. An 8–2 team has an .800 rate despite having one fewer win. The calculation respects games played; simply sorting by wins would erase that difference.
The function checks for negative records and a zero-game denominator. A club with no games played does not yet have a meaningful percentage in this two-column model; instead of pretending it is 0%, the example raises a clear error. The check is valuable because an empty record can be created accidentally during CSV import or an incomplete feed update.
3. Compute games behind the leader
GB measures the standings gap between a team and the selected leader. Use ((leader_wins - team_wins) + (team_losses - leader_losses)) / 2. With the Lakers at 9–2 and San Antonio at 8–2, the result is (1 + 0) / 2 = 0.5. Minnesota at 8–3 is (1 + 1) / 2 = 1.0 games behind. These are not percentages and should never share the same unit label.
Games behind can be a half game when schedules differ. That is expected: the formula combines both the win gap and the loss gap, then halves the result. The Basketball-Reference glossary documents this conventional definition. Always compute against a leader from the same conference or group; using the best team from the other conference would answer a different question.
4. Run the complete Python script
Copy the script below into a file named nba_standings.py and run python nba_standings.py with Python 3. The code deliberately uses the standard library only. It sorts rows by unrounded winning percentage, prints PCT to three decimals, and prints GB to one decimal. The last three assertions test a known percentage, a half-game gap, and the leader's zero-game gap.
A two-part sorting decision is important here: the sample uses team name as a deterministic secondary key when PCT is tied. Alphabetical order is not an NBA tiebreaker. Treat those equal-percentage rows as unresolved for official ranking; the script never claims to decide which team wins a tied postseason seed.
import math
KAD-54: a reproducible NBA standings calculation
Data: dated Western Conference example from Kadario,
checked November 10, 2026 (Philippine time).
This is not a live feed or official playoff-seeding engine.
teams = [
{"team": "Los Angeles Lakers", "wins": 9, "losses": 2},
{"team": "San Antonio Spurs", "wins": 8, "losses": 2},
{"team": "Oklahoma City Thunder", "wins": 8, "losses": 2},
{"team": "Minnesota Timberwolves", "wins": 8, "losses": 3},
{"team": "Houston Rockets", "wins": 7, "losses": 3},
{"team": "Golden State Warriors", "wins": 7, "losses": 3},
]
def win_percentage(wins: int, losses: int) -> float:
if min(wins, losses) < 0 or wins + losses == 0:
raise ValueError("Use non-negative W/L with games played")
return wins / (wins + losses)
def games_behind(leader: dict, team: dict) -> float:
return ((leader["wins"] - team["wins"]) +
(team["losses"] - leader["losses"])) / 2
Sort by percentage only. Alphabetical secondary order is
deterministic, NOT an application of NBA tiebreak rules.
rows = sorted(teams, key=lambda t: (
-win_percentage(t["wins"], t["losses"]), t["team"]
))
leader = rows[0]
print(f'{"Team":28} {"W-L":>5} {"PCT":>6} {"GB":>5}')
for t in rows:
pct = win_percentage(t["wins"], t["losses"])
gb = games_behind(leader, t)
record = f'{t["wins"]}-{t["losses"]}'
print(f'{t["team"]:28} {record:>5} {pct:.3f} {gb:5.1f}')
Minimal tests: win rate, half-game gap, zero gap.
assert math.isclose(win_percentage(9, 2), 9/11)
assert games_behind({"wins": 9, "losses": 2},
{"wins": 8, "losses": 2}) == 0.5
assert games_behind(leader, leader) == 0.0
*Expected output from the test run:
*
Team W-L PCT GB
Los Angeles Lakers 9-2 0.818 0.0
Oklahoma City Thunder 8-2 0.800 0.5
San Antonio Spurs 8-2 0.800 0.5
Minnesota Timberwolves 8-3 0.727 1.0
Golden State Warriors 7-3 0.700 1.5
Houston Rockets 7-3 0.700 1.5
5. Interpret the output without overstating it
The resulting sample puts Los Angeles at the top of this subset with .818 and 0.0 GB, followed by two .800 records at 0.5 GB. Minnesota appears at .727 and 1.0 GB; Houston and Golden State appear at .700 and 1.5 GB. These statements are arithmetic outputs from the dated input, not predictions about which clubs will make the playoffs.
The output also omits teams that were not selected for the demonstration. A full Western Conference table would require all 15 teams, and an Eastern Conference comparison would require its own leader. If you want to reproduce current results, revisit the Kadario NBA competition overview and update the records before running the calculation again. Record the time zone in any screenshot or article that presents the numbers as current.
6. Understand what this code does not decide
The NBA's official standings procedures use additional tiebreak criteria for postseason qualification and seeding. For two-team ties, head-to-head winning percentage is checked before several further criteria, while larger ties follow their own sequence. Those rules require game-level history, conference results, and sometimes additional context unavailable from a simple wins and losses pair. A sorted() call is not a valid replacement.
Likewise, do not confuse a regular-season standings calculation with NBA Cup group-play standings. Their competition formats and tie scenarios differ. A developer extending this tutorial should model the competition separately, write unit tests for the appropriate rule sequence, and preserve the raw data that justifies every ordering decision. The NBA's official standings page publishes the current tiebreak procedures.
7. Make the tool maintainable
For an actual project, separate fetching, validation, calculation, and display. First, obtain records from a source you are authorized to access; second, validate dates and unique team identities; third, compute the two columns; and fourth, render HTML, a terminal table, or a chart. Keep source and calculation timestamps, and make errors visible rather than silently substituting zeros.
A useful follow-up test changes a team's losses without changing its wins, then confirms that PCT falls and GB rises. Another test supplies a zero-game record and expects the documented exception. For visual output, plot PCT against team names, but label the figures as a sample if they came from the dated dataset. Do not suggest that a screenshot of this tutorial reflects a permanently current table.
Conclusion: a small script, a clearer standings discussion
A reliable sports-data workflow starts with understandable formulas. Python can compute PCT and GB in a few lines, but accuracy depends on the input, the selected leader, the competition, and the publication timestamp. The simplest improvement is to expose these assumptions next to the results. Readers can explore ongoing sports results from the Kadario scores homepage, while developers should cross-check official league rules before describing any team as having clinched a seed.
This is a reproducible calculation, not a live API feed or an official NBA tiebreak engine.
Sources and limitations
NBA official standings and tiebreak procedures
Basketball-Reference: definition of GB
Example standings snapshot (Kadario, Filipino view)


Top comments (0)