Exemplo n.º 1
0
def _json_game_player_stats(game, data):
    """
    Parses the 'home' and 'away' team stats and returns an OrderedDict
    mapping player id to their total game statistics as instances of
    nflgame.player.GamePlayerStats.
    """
    players = OrderedDict()
    for team in ('home', 'away'):
        for category in nflgame.statmap.categories:
            if category not in data[team]['stats']:
                continue
            for pid, raw in iteritems(data[team]['stats'][category]):
                stats = {}
                for k, v in iteritems(raw):
                    if k == 'name':
                        continue
                    stats['%s_%s' % (category, k)] = v
                if pid not in players:
                    home = team == 'home'
                    if home:
                        team_name = game.home
                    else:
                        team_name = game.away
                    players[pid] = nflgame.player.GamePlayerStats(
                        pid, raw['name'], home, team_name)
                players[pid]._add_stats(stats)
    return players
Exemplo n.º 2
0
    def __sub__(self, other):
        assert self.playerid == other.playerid
        assert type(self) == type(other)

        new_player = GamePlayerStats(self.playerid, self.name, self.home,
                                     self.team)
        new_player._add_stats(self._stats)
        for bk, bv in iteritems(other._stats):
            if bk not in new_player._stats:  # stat was taken away? ignore.
                continue

            new_player._stats[bk] -= bv
            if new_player._stats[bk] == 0:
                del new_player._stats[bk]
            else:
                new_player.__dict__[bk] = new_player._stats[bk]

        anydiffs = False
        for k, v in iteritems(new_player._stats):
            if v > 0:
                anydiffs = True
                break
        if not anydiffs:
            return None
        return new_player
Exemplo n.º 3
0
    def __init__(self, drive, playid, data):
        self.data = data
        self.drive = drive
        self.playid = playid
        self.team = data['posteam']
        self.home = self.drive.home
        self.desc = data['desc']
        self.note = data['note']
        self.down = int(data['down'])
        self.yards_togo = int(data['ydstogo'])
        self.touchdown = 'touchdown' in self.desc.lower()
        self._stats = {}

        if not self.team:
            self.time, self.yardline = None, None
        else:
            self.time = GameClock(data['qtr'], data['time'])
            self.yardline = FieldPosition(self.team, data['yrdln'])

        # Load team statistics directly into the Play instance.
        # Things like third down attempts, first downs, etc.
        if '0' in data['players']:
            for info in data['players']['0']:
                if info['statId'] not in nflgame.statmap.idmap:
                    continue
                statvals = nflgame.statmap.values(info['statId'],
                                                  info['yards'])
                for k, v in iteritems(statvals):
                    v = self.__dict__.get(k, 0) + v
                    self.__dict__[k] = v
                    self._stats[k] = v

        # Load the sequence of "events" in a play into a list of dictionaries.
        self.events = _json_play_events(data['players'])

        # Now load cumulative player data for this play into
        # a GenPlayerStats generator. We then flatten this data
        # and add it to the play itself so that plays can be
        # filter by these statistics.
        self.__players = _json_play_players(self, data['players'])
        self.players = nflgame.seq.GenPlayerStats(self.__players)
        for p in self.players:
            for k, v in iteritems(p.stats):
                # Sometimes we may see duplicate statistics (like tackle
                # assists). Let's just overwrite in this case, since this
                # data is from the perspective of the play. i.e., there
                # is one assisted tackle rather than two.
                self.__dict__[k] = v
                self._stats[k] = v
Exemplo n.º 4
0
Arquivo: seq.py Projeto: srome/nflgame
    def csv(self, fileName, allfields=False):
        """
        Given a file-name fileName, csv will write the contents of
        the Players sequence to fileName formatted as comma-separated values.
        The resulting file can then be opened directly with programs like
        Excel, Google Docs, Libre Office and Open Office.

        Note that since each player in a Players sequence may have differing
        statistical categories (like a quarterback and a receiver), the
        minimum constraining set of statisical categories is used as the
        header row for the resulting CSV file. This behavior can be changed
        by setting 'allfields' to True, which will use every available field
        in the header.
        """
        import csv

        fields, rows = set([]), []
        players = list(self)
        for p in players:
            for field, stat in iteritems(p.stats):
                fields.add(field)
        if allfields:
            for statId, info in iteritems(statmap.idmap):
                for field in info['fields']:
                    fields.add(field)
        fields = sorted(list(fields))

        for p in players:
            d = {
                'name': p.name,
                'id': p.playerid,
                'home': p.home and 'yes' or 'no',
                'team': p.team,
                'pos': 'N/A',
            }
            if p.player is not None:
                d['pos'] = p.player.position

            for field in fields:
                if field in p.__dict__:
                    d[field] = p.__dict__[field]
                else:
                    d[field] = ""
            rows.append(d)

        fieldNames = ["name", "id", "home", "team", "pos"] + fields
        rows = [dict((f, f) for f in fieldNames)] + rows
        csv.DictWriter(open(fileName, 'w+'), fieldNames).writerows(rows)
Exemplo n.º 5
0
    def csv(self, fileName, allfields=False):
        """
        Given a file-name fileName, csv will write the contents of
        the Players sequence to fileName formatted as comma-separated values.
        The resulting file can then be opened directly with programs like
        Excel, Google Docs, Libre Office and Open Office.

        Note that since each player in a Players sequence may have differing
        statistical categories (like a quarterback and a receiver), the
        minimum constraining set of statisical categories is used as the
        header row for the resulting CSV file. This behavior can be changed
        by setting 'allfields' to True, which will use every available field
        in the header.
        """
        import csv

        fields, rows = set([]), []
        players = list(self)
        for p in players:
            for field, stat in iteritems(p.stats):
                fields.add(field)
        if allfields:
            for statId, info in iteritems(statmap.idmap):
                for field in info['fields']:
                    fields.add(field)
        fields = sorted(list(fields))

        for p in players:
            d = {
                'name': p.name,
                'id': p.playerid,
                'home': p.home and 'yes' or 'no',
                'team': p.team,
                'pos': 'N/A',
            }
            if p.player is not None:
                d['pos'] = p.player.position

            for field in fields:
                if field in p.__dict__:
                    d[field] = p.__dict__[field]
                else:
                    d[field] = ""
            rows.append(d)

        fieldNames = ["name", "id", "home", "team", "pos"] + fields
        rows = [dict((f, f) for f in fieldNames)] + rows
        csv.DictWriter(open(fileName, 'w+'), fieldNames).writerows(rows)
Exemplo n.º 6
0
def _json_play_players(play, data):
    """
    Takes a single JSON play entry (data) and converts it to an OrderedDict
    of player statistics.

    play is the instance of Play that this data is part of. It is used
    to determine whether the player belong to the home team or not.
    """
    players = OrderedDict()
    for playerid, statcats in iteritems(data):
        if playerid == '0':
            continue
        for info in statcats:
            if info['statId'] not in nflgame.statmap.idmap:
                continue
            if playerid not in players:
                home = play.drive.game.is_home(info['clubcode'])
                if home:
                    team_name = play.drive.game.home
                else:
                    team_name = play.drive.game.away
                stats = nflgame.player.PlayPlayerStats(playerid,
                                                       info['playerName'],
                                                       home, team_name)
                players[playerid] = stats
            statvals = nflgame.statmap.values(info['statId'], info['yards'])
            players[playerid]._add_stats(statvals)
    return players
Exemplo n.º 7
0
    def __new__(cls, eid=None, fpath=None):
        # If we can't get a valid JSON data, exit out and return None.
        try:
            rawData = _get_json_data(eid, fpath)
        except urllib.URLError:
            return None
        if rawData is None or rawData.strip() == '{}':
            return None
        game = object.__new__(cls)
        game.rawData = rawData

        try:
            if eid is not None:
                game.eid = eid
                game.data = json.loads(game.rawData)[game.eid]
            else:  # For when we have rawData (fpath) and no eid.
                game.eid = None
                game.data = json.loads(game.rawData)
                for k, v in iteritems(game.data):
                    if isinstance(v, dict):
                        game.eid = k
                        game.data = v
                        break
                assert game.eid is not None
        except ValueError:
            return None

        return game
Exemplo n.º 8
0
 def formatted_stats(self):
     """
     Returns a roughly-formatted string of all statistics for this player.
     """
     s = []
     for stat, val in iteritems(self._stats):
         s.append('%s: %s' % (stat, val))
     return ', '.join(s)
Exemplo n.º 9
0
    def max_player_stats(self):
        """
        Returns a GenPlayers sequence of player statistics that combines
        game statistics and play statistics by taking the max value of
        each corresponding statistic.

        This is useful when accuracy is desirable. Namely, using only
        play-by-play data or using only game statistics can be unreliable.
        That is, both are inconsistently correct.

        Taking the max values of each statistic reduces the chance of being
        wrong (particularly for stats that are in both play-by-play data
        and game statistics), but does not eliminate them.
        """
        game_players = list(self.players)
        play_players = list(self.drives.plays().players())
        max_players = OrderedDict()

        # So this is a little tricky. It's possible for a player to have
        # only statistics at the play level, and therefore not be represented
        # in the game level statistics. Therefore, we initialize our
        # max_players with play-by-play stats first. Then go back through
        # and combine them with available game statistics.
        for pplay in play_players:
            newp = nflgame.player.GamePlayerStats(pplay.playerid, pplay.name,
                                                  pplay.home, pplay.team)
            maxstats = {}
            for stat, val in iteritems(pplay._stats):
                maxstats[stat] = val

            newp._overwrite_stats(maxstats)
            max_players[pplay.playerid] = newp

        for newp in itervalues(max_players):
            for pgame in game_players:
                if pgame.playerid != newp.playerid:
                    continue

                maxstats = {}
                for stat, val in iteritems(pgame._stats):
                    maxstats[stat] = max([val, newp._stats.get(stat, -MAXINT)])

                newp._overwrite_stats(maxstats)
                break
        return nflgame.seq.GenPlayerStats(max_players)
Exemplo n.º 10
0
Arquivo: seq.py Projeto: srome/nflgame
    def filter(self, **kwargs):
        """
        filters the sequence based on a set of criteria. Parameter
        names should be equivalent to the properties accessible in the items
        of the sequence. For example, where the items are instances of
        the Stats class::

            players.filter(home=True, passing_tds=1, rushing_yds=lambda x: x>0)

        Returns a sequence with only players on the home team that
        have a single passing touchdown and more than zero rushing yards.

        If a field specified does not exist for a particular item, that
        item is excluded from the result set.

        If a field is set to a value, then only items with fields that equal
        that value are returned.

        If a field is set to a function---which must be a predicate---then
        only items with field values satisfying that function will
        be returned.

        Also, special suffixes that begin with '__' may be added to the
        end of a field name to invoke built in predicates.
        For example, this::

            players.filter(receiving_rec=lambda v: v > 0)

        Is equivalent to::

            players.filter(receiving_rec__gt=0)

        Other suffixes includes gt, le, lt, ne, ge, etc.

        (Django users should feel right at home.)
        """
        preds = []
        for k, v in iteritems(kwargs):

            def pred(field, value, item):
                # TODO: Move pred function outside of loop
                for suffix, p in iteritems(_BUILTIN_PREDS):
                    if field.endswith(suffix):
                        f = field[:field.index(suffix)]
                        if not hasattr(item, f) or getattr(item, f) is None:
                            return False
                        return p(getattr(item, f), value)
                if not hasattr(item, field) or getattr(item, field) is None:
                    return False
                if isinstance(value, type(lambda x: x)):
                    return value(getattr(item, field))
                return getattr(item, field) == value

            preds.append(functools.partial(pred, k, v))

        gen = ifilter(lambda item: all([f(item) for f in preds]), self)
        return self.__class__(gen)
Exemplo n.º 11
0
 def tds(self):
     """
     Returns the total number of touchdowns credited to this player across
     all statistical categories.
     """
     n = 0
     for f, v in iteritems(self.__dict__):
         if f.endswith('tds'):
             n += v
     return n
Exemplo n.º 12
0
    def filter(self, **kwargs):
        """
        filters the sequence based on a set of criteria. Parameter
        names should be equivalent to the properties accessible in the items
        of the sequence. For example, where the items are instances of
        the Stats class::

            players.filter(home=True, passing_tds=1, rushing_yds=lambda x: x>0)

        Returns a sequence with only players on the home team that
        have a single passing touchdown and more than zero rushing yards.

        If a field specified does not exist for a particular item, that
        item is excluded from the result set.

        If a field is set to a value, then only items with fields that equal
        that value are returned.

        If a field is set to a function---which must be a predicate---then
        only items with field values satisfying that function will
        be returned.

        Also, special suffixes that begin with '__' may be added to the
        end of a field name to invoke built in predicates.
        For example, this::

            players.filter(receiving_rec=lambda v: v > 0)

        Is equivalent to::

            players.filter(receiving_rec__gt=0)

        Other suffixes includes gt, le, lt, ne, ge, etc.

        (Django users should feel right at home.)
        """
        preds = []
        for k, v in iteritems(kwargs):
            def pred(field, value, item):
                # TODO: Move pred function outside of loop
                for suffix, p in iteritems(_BUILTIN_PREDS):
                    if field.endswith(suffix):
                        f = field[:field.index(suffix)]
                        if not hasattr(item, f) or getattr(item, f) is None:
                            return False
                        return p(getattr(item, f), value)
                if not hasattr(item, field) or getattr(item, field) is None:
                    return False
                if isinstance(value, type(lambda x: x)):
                    return value(getattr(item, field))
                return getattr(item, field) == value
            preds.append(functools.partial(pred, k, v))

        gen = ifilter(lambda item: all([f(item) for f in preds]), self)
        return self.__class__(gen)
Exemplo n.º 13
0
 def pred(field, value, item):
     # TODO: Move pred function outside of loop
     for suffix, p in iteritems(_BUILTIN_PREDS):
         if field.endswith(suffix):
             f = field[:field.index(suffix)]
             if not hasattr(item, f) or getattr(item, f) is None:
                 return False
             return p(getattr(item, f), value)
     if not hasattr(item, field) or getattr(item, field) is None:
         return False
     if isinstance(value, type(lambda x: x)):
         return value(getattr(item, field))
     return getattr(item, field) == value
Exemplo n.º 14
0
Arquivo: seq.py Projeto: srome/nflgame
 def pred(field, value, item):
     # TODO: Move pred function outside of loop
     for suffix, p in iteritems(_BUILTIN_PREDS):
         if field.endswith(suffix):
             f = field[:field.index(suffix)]
             if not hasattr(item, f) or getattr(item, f) is None:
                 return False
             return p(getattr(item, f), value)
     if not hasattr(item, field) or getattr(item, field) is None:
         return False
     if isinstance(value, type(lambda x: x)):
         return value(getattr(item, field))
     return getattr(item, field) == value
Exemplo n.º 15
0
def _json_play_events(data):
    """
    Takes a single JSON play entry (data) and converts it to a list of events.
    """
    temp = list()
    for playerid, statcats in iteritems(data):
        for info in statcats:
            if info['statId'] not in nflgame.statmap.idmap:
                continue
            statvals = nflgame.statmap.values(info['statId'], info['yards'])
            statvals['playerid'] = None if playerid == '0' else playerid
            statvals['playername'] = info['playerName'] or None
            statvals['team'] = info['clubcode']
            temp.append((int(info['sequence']), statvals))
    return [t[1] for t in sorted(temp, key=lambda t: t[0])]
Exemplo n.º 16
0
 def _overwrite_stats(self, stats):
     for k, v in iteritems(stats):
         self.__dict__[k] = v
         self._stats[k] = self.__dict__[k]
Exemplo n.º 17
0
 def _add_stats(self, stats):
     for k, v in iteritems(stats):
         self.__dict__[k] = self.__dict__.get(k, 0) + v
         self._stats[k] = self.__dict__[k]