supercontest.core.stats

Handles the building of all plots on the statistics page. Queries the raw data, reformats, and encodes the json for plotly before passing it to the frontend js to render.

Remember that the statistical analysis works by looping over every game (both teams) and then creating a dictionary of COUNTS for something happening. Eg vikings were the favorite, eagles were the home team, and vikings covered. Coverage would be the value, the count is +1, and the dimension for “by” or “per” may be prediction or location. You can slice however you’d like.

Dimensions for statistical analysis are divided into multiple categories:

  • 1: This is the toplevel statistic. The thing we care about measuring. It’s coverage. The thing the user is searching for as a decisionmaker. It must be grouped by an identity from class 2.

  • 2: These are the primary dimensions along which the toplevel statistic is analyzed. They’re identities. “X” covered / did not cover. They can also be compared with one another (for stats that are not coverage based, but still interesting).

  • 3: These are secondary dimensions that cannot directly classify coverage. They’re not identities. But once coverage is grouped with an identity, it can be compared against these. They can also be compared against one another. Example: A line cannot cover, but “favorite by line” makes sense.

  • 4: These are resultant dimensions. They can’t be the used as the X/rows dimension (as in Y by X, you can’t group by them), but they can be used as Y/cols. Example: Location by Margin does not make sense, but Margin by Location does.

Module Attributes

COLOR_TRIO

Colors used for 3-item datasets, matching the green/yellow/red of bootstrap's table-success, table-warning, and table-danger.

ADJ_MATRIX

The relationships between dimensions.

DIMENSIONS

All dimension definitions for statistical analysis.

Functions

build_bivariate_plots

Lock an identity (category 2) to each value, then compare the joined (primary dimenion + identity) to the other dimensions.

build_nfl_plots

The plot builder.

build_plots

Takes the dimensions that a view cares about, and constructs the data + plots.

build_sbsc_plots

The plot builder.

build_univariate_plots

Compares all combinations of dimensions that are compatible 1:1.

Classes

StatsDim

Our database has dimensions we care to analyze for stats.

supercontest.core.stats.ADJ_MATRIX = {1: [2], 2: [2, 3], 3: [2, 3], 4: [2, 3]}

The relationships between dimensions. Essentially what a variable can be compared against.

supercontest.core.stats.COLOR_TRIO = ('#c3e6cb', '#ffeeba', '#f5c6cb')

Colors used for 3-item datasets, matching the green/yellow/red of bootstrap’s table-success, table-warning, and table-danger.

supercontest.core.stats.DIMENSIONS = [<supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>, <supercontest.core.stats.StatsDim object>]

All dimension definitions for statistical analysis. This is ordered.

class supercontest.core.stats.StatsDim(name: str, category: int, scope: str, val_getter: Callable[[Contestant], int | float | str], val_sort_key: Callable[[int | float | str], int | float | str], main_agg: Callable[[Iterable[str | int | float]], int | float] | None = None, main_plot_sort_reverse: bool = True, main_colors: tuple[str, ...] | None = None, by_val_getter: Callable[[Contestant], int | float | str] | None = None)

Bases: object

Our database has dimensions we care to analyze for stats. These are their properties.

supercontest.core.stats.build_bivariate_plots(games: list[Game], dims: list[StatsDim], join_to: int = 1) list[str]

Lock an identity (category 2) to each value, then compare the joined (primary dimenion + identity) to the other dimensions.

Parameters:
  • games – List of games to iterate over.

  • dims – All dimensions to consider.

  • join_to – The primary dimension category to join an identity with. Shouldn’t change.

Returns:

List of json-encoded plot strings.

supercontest.core.stats.build_nfl_plots(season: int | None) tuple[list[str], int]

The plot builder.

Parameters:

season – The season to restrict the scope to.

Returns:

List of json-encoded plot strings, and total number of games in scope.

supercontest.core.stats.build_plots(games: list[Game], main_dim: StatsDim, by_dims: list[StatsDim], per_dim: StatsDim | None = None) list[str]

Takes the dimensions that a view cares about, and constructs the data + plots.

The “main” dimension sets the cols on the hbar, the xaxis vals. The “by” list creates a plot for each item, main dimension against this as rows, the yaxis vals. The “per” is multivariate - a group of “main by x” plots for each value along this dimension.

Therefore the main dimension is a dict instead of defaultdict. It’s bounded, and we need to show all data, even if zero (else we might have 1 bar instead of stacked bars). The “per” dimension is also bounded ahead of time. The “by” dimensions are not; we pull whatever values are in the db in realtime and show those ranges.

Objects which require DB queries are fetched before iteration.

This function works by simply iterating over all the raw data and building COUNTS based on keys across all the dimensions. Then the plotter will default to calculate percentage-of-total from those counts, or agg can flatten into an average, etc.

Loops over all games (including both contestants) to get the data. This could be genericized, defined alongside that dimension. It’s a param so that multiple plot builders can be passed the same iterable instead of requerying.

Parameters:
  • games – List of games to iterate over.

  • main_dim – The primary dimension to analyze (eg coverage).

  • by_dims – The list of dimensions to slice the primary dimension by (eg coverage by team).

  • per_dim – The multivariate dimension to repeate the above analysis for (eg coverage by team by prediction, so coverage by team when favorite and coverage by team when pickem and coverage by team when underdog).

Returns:

List of json-encoded plot strings.

supercontest.core.stats.build_sbsc_plots(season: int | None) tuple[list[str], int]

The plot builder.

Parameters:

season – The season to restrict the scope to.

Returns:

List of json-encoded plot strings, and total number of games in scope.

supercontest.core.stats.build_univariate_plots(games: list[Game], dims: list[StatsDim], only: list[StatsDim] | None = None) list[str]

Compares all combinations of dimensions that are compatible 1:1.

Parameters:
  • games – List of games to iterate over.

  • dims – All dimensions to consider.

  • only – To restrict the main dimension.

Returns:

List of json-encoded plot strings.