Reports Module

Report generators for displaying NHL Scrabble analysis results.

The reports module provides various report formats for visualizing team standings, playoff brackets, and statistics using Rich for terminal output.

Reporting modules.

class nhl_scrabble.reports.BaseReporter[source]

Bases: ABC

Abstract base class for all reporters.

All report generators should inherit from this class and implement the generate() method to produce their specific output format.

The base class provides common utilities for: - Header and subheader formatting - Sorting and filtering data - Pagination and limiting results - Number formatting (scores, averages) - Team and player listing

abstractmethod generate(data)[source]

Generate report output.

Parameters:

data (Any) – The data to generate a report from

Return type:

str

Returns:

Formatted report string

class nhl_scrabble.reports.ConferenceReporter[source]

Bases: BaseReporter

Generate conference standings reports.

generate(standings)[source]

Generate conference standings report.

Parameters:

standings (dict[str, ConferenceStandings]) – Dictionary mapping conference names to ConferenceStandings

Return type:

str

Returns:

Formatted conference report string

class nhl_scrabble.reports.DivisionReporter[source]

Bases: BaseReporter

Generate division standings reports.

generate(standings)[source]

Generate division standings report.

Parameters:

standings (dict[str, DivisionStandings]) – Dictionary mapping division names to DivisionStandings

Return type:

str

Returns:

Formatted division report string

class nhl_scrabble.reports.PlayoffReporter[source]

Bases: BaseReporter

Generate playoff standings reports in NHL wild card format.

generate(standings)[source]

Generate playoff standings report.

Parameters:

standings (dict[str, list[PlayoffTeam]]) – Dictionary mapping conference names to lists of PlayoffTeam objects

Return type:

str

Returns:

Formatted playoff report string

class nhl_scrabble.reports.StatsReporter(top_players_count=20)[source]

Bases: BaseReporter

Generate fun statistics and top players reports.

__init__(top_players_count=20)[source]

Initialize stats reporter.

Parameters:

top_players_count (int) – Number of top players to show

generate(data)[source]

Generate statistics report.

Parameters:

data (tuple[list[PlayerScore], dict[str, DivisionStandings], dict[str, ConferenceStandings]]) – Tuple containing (all_players, division_standings, conference_standings)

Return type:

str

Returns:

Formatted statistics report string

class nhl_scrabble.reports.TeamReporter(top_players_per_team=5)[source]

Bases: BaseReporter

Generate team scores reports with top players.

__init__(top_players_per_team=5)[source]

Initialize team reporter.

Parameters:

top_players_per_team (int) – Number of top players to show per team

generate(team_scores)[source]

Generate team scores report.

Parameters:

team_scores (dict[str, TeamScore]) – Dictionary mapping team abbreviations to TeamScore objects

Return type:

str

Returns:

Formatted team report string

Base Report

Base reporter class for all report types.

class nhl_scrabble.reports.base.BaseReporter[source]

Bases: ABC

Abstract base class for all reporters.

All report generators should inherit from this class and implement the generate() method to produce their specific output format.

The base class provides common utilities for: - Header and subheader formatting - Sorting and filtering data - Pagination and limiting results - Number formatting (scores, averages) - Team and player listing

abstractmethod generate(data)[source]

Generate report output.

Parameters:

data (Any) – The data to generate a report from

Return type:

str

Returns:

Formatted report string

BaseReport

Abstract base class for all report generators.

All report classes inherit from BaseReport and implement the generate() method.

Subclasses:

  • ConferenceReport

  • DivisionReport

  • PlayoffReport

  • TeamReport

  • StatsReport

Conference Report

Conference standings reporter.

class nhl_scrabble.reports.conference_report.ConferenceReporter[source]

Bases: BaseReporter

Generate conference standings reports.

generate(standings)[source]

Generate conference standings report.

Parameters:

standings (dict[str, ConferenceStandings]) – Dictionary mapping conference names to ConferenceStandings

Return type:

str

Returns:

Formatted conference report string

ConferenceReport

Generate conference standings report.

Output Format:

EASTERN CONFERENCE STANDINGS
════════════════════════════════════════════════════════════════

Total Points: 32,456
Total Teams: 16
Average per Team: 2,028.5

Rank  Team                          Total    Avg/Player  Players
────────────────────────────────────────────────────────────────
  1   Toronto Maple Leafs           2,234      93.1       24
  2   Boston Bruins                 2,189      91.2       24
  3   Tampa Bay Lightning           2,145      89.4       24
...

Example:

from nhl_scrabble.reports import ConferenceReport

report = ConferenceReport(conference_standings)
report.generate()

Division Report

Division standings reporter.

class nhl_scrabble.reports.division_report.DivisionReporter[source]

Bases: BaseReporter

Generate division standings reports.

generate(standings)[source]

Generate division standings report.

Parameters:

standings (dict[str, DivisionStandings]) – Dictionary mapping division names to DivisionStandings

Return type:

str

Returns:

Formatted division report string

DivisionReport

Generate division standings report.

Output Format:

ATLANTIC DIVISION STANDINGS
════════════════════════════════════════════════════════════════

Total Points: 16,234
Total Teams: 8
Average per Team: 2,029.3

Rank  Team                          Total    Avg/Player  Players
────────────────────────────────────────────────────────────────
y 1   Toronto Maple Leafs           2,234      93.1       24
y 2   Boston Bruins                 2,189      91.2       24
y 3   Tampa Bay Lightning           2,145      89.4       24
...

Example:

from nhl_scrabble.reports import DivisionReport

report = DivisionReport(division_standings)
report.generate()

Playoff Report

Playoff standings reporter.

class nhl_scrabble.reports.playoff_report.PlayoffReporter[source]

Bases: BaseReporter

Generate playoff standings reports in NHL wild card format.

generate(standings)[source]

Generate playoff standings report.

Parameters:

standings (dict[str, list[PlayoffTeam]]) – Dictionary mapping conference names to lists of PlayoffTeam objects

Return type:

str

Returns:

Formatted playoff report string

PlayoffReport

Generate playoff bracket report.

Output Format:

NHL SCRABBLE PLAYOFF BRACKET
════════════════════════════════════════════════════════════════

EASTERN CONFERENCE
────────────────────────────────────────────────────────────────
p 1  Toronto Maple Leafs            2,234
y 2  Boston Bruins                  2,189
y 3  Tampa Bay Lightning            2,145
x 4  Florida Panthers               2,098
x 5  New York Rangers               2,067
  6  Carolina Hurricanes            2,045
  7  New Jersey Devils              2,023
  8  Pittsburgh Penguins            2,001

WESTERN CONFERENCE
────────────────────────────────────────────────────────────────
...

Playoff Indicators:

  • p - Presidents’ Trophy (best overall)

  • z - Conference leader

  • y - Division leader

  • x - Wild card team

  • e - Eliminated

Example:

from nhl_scrabble.reports import PlayoffReport

report = PlayoffReport(playoff_bracket)
report.generate()

Team Report

Team scores reporter.

class nhl_scrabble.reports.team_report.TeamReporter(top_players_per_team=5)[source]

Bases: BaseReporter

Generate team scores reports with top players.

__init__(top_players_per_team=5)[source]

Initialize team reporter.

Parameters:

top_players_per_team (int) – Number of top players to show per team

generate(team_scores)[source]

Generate team scores report.

Parameters:

team_scores (dict[str, TeamScore]) – Dictionary mapping team abbreviations to TeamScore objects

Return type:

str

Returns:

Formatted team report string

TeamReport

Generate detailed team roster report.

Output Format:

TORONTO MAPLE LEAFS - DETAILED ROSTER
════════════════════════════════════════════════════════════════

Team Total: 2,234 points
Roster Size: 24 players
Average per Player: 93.1 points

Top Players:
Rank  Player                   Pos    First   Last   Total
────────────────────────────────────────────────────────────────
  1   William Nylander         RW       65     59     124
  2   Auston Matthews          C        67     51     118
  3   Mitchell Marner          RW       63     50     113
...

Example:

from nhl_scrabble.reports import TeamReport

# Report for specific team
tor_team = next(t for t in team_scores if t.team.abbrev == "TOR")
report = TeamReport(tor_team, top_n=10)
report.generate()

Stats Report

Fun statistics reporter.

class nhl_scrabble.reports.stats_report.StatsReporter(top_players_count=20)[source]

Bases: BaseReporter

Generate fun statistics and top players reports.

__init__(top_players_count=20)[source]

Initialize stats reporter.

Parameters:

top_players_count (int) – Number of top players to show

generate(data)[source]

Generate statistics report.

Parameters:

data (tuple[list[PlayerScore], dict[str, DivisionStandings], dict[str, ConferenceStandings]]) – Tuple containing (all_players, division_standings, conference_standings)

Return type:

str

Returns:

Formatted statistics report string

StatsReport

Generate overall statistics report.

Output Format:

NHL SCRABBLE STATISTICS
════════════════════════════════════════════════════════════════

Overall Statistics:
  Total Players: 768
  Total Teams: 32
  Average Players per Team: 24.0
  League Total Score: 71,456
  League Average Score: 93.1

Top Individual Scores:
Rank  Player                   Team   First   Last   Total
────────────────────────────────────────────────────────────────
  1   William Nylander         TOR      65     59     124
  2   Quinn Hughes             VAN      53     68     121
  3   Artemi Panarin           NYR      54     65     119
...

Example:

from nhl_scrabble.reports import StatsReport

report = StatsReport(all_player_scores, team_scores, top_n=20)
report.generate()

Usage Patterns

Generate All Reports:

from nhl_scrabble.reports import ConferenceReport, DivisionReport, PlayoffReport, StatsReport

# Conference standings
for conf_name, standings in conference_standings.items():
    report = ConferenceReport({conf_name: standings})
    report.generate()

# Division standings
for div_name, standings in division_standings.items():
    report = DivisionReport({div_name: standings})
    report.generate()

# Playoff bracket
playoff_report = PlayoffReport(playoff_bracket)
playoff_report.generate()

# Overall statistics
stats_report = StatsReport(all_players, team_scores)
stats_report.generate()

Custom Report Output:

from rich.console import Console
import io

# Capture report output
string_io = io.StringIO()
console = Console(file=string_io, force_terminal=True)

report = ConferenceReport(conference_standings)
report.generate()  # Uses default console

# Get output as string
output = string_io.getvalue()

JSON Export:

While reports generate text/terminal output, you can export the underlying data structures as JSON:

import json
from nhl_scrabble.models import TeamScore


# Convert to dict for JSON serialization
def team_score_to_dict(ts: TeamScore) -> dict:
    return {
        "team": ts.team.name,
        "total": ts.total,
        "avg_per_player": ts.avg_per_player,
        "player_count": ts.player_count,
        "players": [
            {"name": f"{ps.player.firstName} {ps.player.lastName}", "score": ps.total}
            for ps in ts.player_scores
        ],
    }


# Export team scores
data = [team_score_to_dict(ts) for ts in team_scores]
with open("team_scores.json", "w") as f:
    json.dump(data, f, indent=2)

Rich Console Features

All reports use Rich for enhanced terminal output:

  • Colors - Team names, scores, headers

  • Tables - Aligned columns with borders

  • Formatting - Bold, italic, underline for emphasis

  • Unicode - Box drawing characters for visual appeal

Example with Rich:

from rich.console import Console
from rich.table import Table

console = Console()

table = Table(title="Top Scorers")
table.add_column("Rank", justify="right")
table.add_column("Player")
table.add_column("Score", justify="right")

for i, ps in enumerate(top_players[:10], 1):
    table.add_row(str(i), f"{ps.player.firstName} {ps.player.lastName}", str(ps.total))

console.print(table)