Source code for nhlscrapi.games.playbyplay

from nhlscrapi._tools import build_enum

from nhlscrapi.scrapr.rtss import RTSS
from nhlscrapi.games.repscrwrap import RepScrWrap
  
Strength = build_enum('Even', 'PP', 'SH')
"""Enum indicating play strength."""

class Play(object):
[docs] """Contains base level of state info about a given play.""" def __init__(self, play_num=0, period=0, strength=Strength.Even, time={ "min": 20, "sec": 0 }, vis_on_ice = { }, home_on_ice = { }, event=None): self.play_num = play_num """Number of player who made the play""" self.period = period """Current period""" self.strength = strength """Enum of type :py:class:`.Strength` indicating either even strength, shorthanded, or power play""" self.time = time """Time remaining in the period""" self.vis_on_ice = vis_on_ice """Visiting skaters on the ice. ``{ num: [position, name] }``""" self.home_on_ice = home_on_ice """Home skaters on the ice. ``{ num: [position, name] }``""" self.event = event """ An object that inherits from :py:class:`.Event` that contains other specifics related to the given type of play """ class PlayByPlay(RepScrWrap):
[docs] """ Aggregator of :py:class:`.Play` objects that maintains the play-by-play data for a given game. Allows for custom stats of type :py:class:`.AccumulateStats` to be computed for the game. :Example: .. code:: python from nhlscrapi.games.game import GameKey from nhlscrapi.games.cumstats import ShotCt from nhlscrapi.games.playbyplay import PlayByPlay # define the game of interest and a stat accumulator pbp = PlayByPlay( game_key=GameKey(2015, 3, 224), cum_stats={ 'ShotCount': ShotCt() } ) # compute and print results shot_cts = pbp.compute_stats()['ShotCount'] print('Final Score:\t{}'.format(shot_cts.total)) """ def __init__(self, game_key, cum_stats = {}, init_cs_teams=True): super(PlayByPlay, self).__init__(game_key, RTSS(game_key)) self.cum_stats = cum_stats """Dictionary of :py:class:`.AccumulateStats` to be computed""" self.init_cs_teams = init_cs_teams """Boolean, (default) True if the :py:class:`.AccumulateStats` objects should have team names initialized.""" self.__have_stats = False self.__wrapped_plays = [] # doesn't need to be dispatched # this is managed by compute_stats @property def plays(self): """List of :py:class:`.Play` objects.""" self.compute_stats() return self.__wrapped_plays def compute_stats(self):
[docs] """ Compute the stats defined in ``self.cum_stats``. :returns: collection of all computed :py:class:`.AccumulateStats` :rtype: dict """ if not self.__have_stats: if self.init_cs_teams and self.cum_stats: self.__init_cs_teams() for play in self._rep_reader.parse_plays_stream(): p = Play(**play) self.__wrapped_plays.append(p) if self.cum_stats: self.__process(p, self.cum_stats, 'update') self.__have_stats = True return self.cum_stats def __process(self, play, d, meth):
for name, m in d.iteritems(): getattr(m, meth)(play) def __init_cs_teams(self): teams = [ self.matchup['home'], self.matchup['away'] ] for _, cs in self.cum_stats.items(): cs.initialize_teams(teams)