nflgame.seq module
import functools
import itertools
import operator
from collections import OrderedDict
from nflgame import statmap
_BUILTIN_PREDS = {
'__lt': operator.lt,
'__le': operator.le,
'__ne': operator.ne,
'__ge': operator.ge,
'__gt': operator.gt,
}
"""
A dictionary of suffixes to predicates that can be used in Gen.filter.
The suffix corresponds to what to add to the end of a field name to invoke
the predicate it corresponds to. For example, this::
players.filter(receiving_rec=lambda v: v > 0)
Is equivalent to::
players.filter(receiving_rec__gt=0)
(Django users should feel right at home.)
"""
class Gen (object):
"""
Players implements a sequence type and provides a convenient API for
searching sets of players.
"""
def __init__(self, iterable):
"""
Creates a new Players sequence from an iterable where each element
of the iterable is an instance of the Player class.
"""
self.__iter = iterable
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 kwargs.iteritems():
def pred(field, value, item):
for suffix, p in _BUILTIN_PREDS.iteritems():
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 = itertools.ifilter(lambda item: all([f(item) for f in preds]),
self)
return self.__class__(gen)
def limit(self, n):
"""
Limit the sequence to N items.
"""
return self.__class__(itertools.islice(self, n))
def sort(self, field, descending=True):
"""
sorts the sequence according to the field specified---where field is
a property on an item in the sequence. If descending is false, items
will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a
KeyError will be raised.
"""
def attrget(item):
return getattr(item, field, 0)
return self.__class__(sorted(self, reverse=descending, key=attrget))
def __str__(self):
"""Returns a list of items in the sequence."""
return '[%s]' % ', '.join([str(item) for item in self])
def __iter__(self):
"""Make this an iterable sequence."""
if self.__iter is None:
return iter([])
if isinstance(self.__iter, OrderedDict):
return self.__iter.itervalues()
return iter(self.__iter)
def __reversed__(self):
"""Satisfy the built in reversed."""
return reversed(self.__iter)
class GenDrives (Gen):
"""
GenDrives implements a sequence type and provides a convenient API
for searching drives.
"""
def plays(self):
"""
Returns all of the plays, in order, belonging to every drive in
the sequence.
"""
return GenPlays(itertools.chain(*map(lambda d: d.plays, self)))
def players(self):
"""
Returns the combined player stats for every player that participated
in any of the drives in the sequence.
"""
return self.plays().players()
def number(self, n, team=None):
"""
Gets the Nth drive where the first drive corresponds to n=1. This is
only useful given a complete collection of drives for an entire game.
If the team parameter is specified (i.e., team='NE'), then n will
be interpreted as *that* team's Nth drive.
"""
assert n > 0
n -= 1
if team is None:
return list(self)[n]
else:
i = 0
for d in self:
if d.team == team:
if i == n:
return d
i += 1
assert False, \
'Could not find drive %d for team %s.' % (n + 1, team)
class GenPlays (Gen):
"""
GenPlays implements a sequence type and provides a convenient API
for searching plays.
"""
def players(self):
"""
Returns the combined player stats for every play in the sequence.
"""
players = OrderedDict()
for play in self:
for player in play.players:
if player.playerid not in players:
players[player.playerid] = player
else:
players[player.playerid] += player
return GenPlayerStats(players)
class GenPlayerStats (Gen):
"""
GenPlayerStats implements a sequence type and provides a convenient API for
searching sets of player statistics.
"""
def name(self, name):
"""
Returns a single player whose name equals `name`. If no such player
can be found, None is returned.
Note that NFL GameCenter formats their names like "T.Brady" and
"W.Welker". Thus, `name` should also be in this format.
"""
for p in self:
if p.name == name:
return p
return None
def playerid(self, playerid):
"""
Returns a single player whose NFL GameCenter identifier equals
`playerid`. This probably isn't too useful, unless you're trying
to do ID mapping. (Players have different identifiers across NFL.com.)
If no such player with the given identifier is found, None is
returned.
"""
for p in self:
if p.playerid == playerid:
return p
return None
def touchdowns(self):
"""
touchdowns is a convenience method for returning a Players
sequence of all players with at least one touchdown.
"""
def gen():
for p in self:
for f in p.__dict__:
if f.endswith('tds') and p.__dict__[f] > 0:
yield p
break
return self.__class__(gen())
def __filter_category(self, cat):
return self.__class__(itertools.ifilter(lambda p: p.has_cat(cat),
self))
def passing(self):
"""Returns players that have a "passing" statistical category."""
return self.__filter_category('passing')
def rushing(self):
"""Returns players that have a "rushing" statistical category."""
return self.__filter_category('rushing')
def receiving(self):
"""Returns players that have a "receiving" statistical category."""
return self.__filter_category('receiving')
def fumbles(self):
"""Returns players that have a "fumbles" statistical category."""
return self.__filter_category('fumbles')
def kicking(self):
"""Returns players that have a "kicking" statistical category."""
return self.__filter_category('kicking')
def punting(self):
"""Returns players that have a "punting" statistical category."""
return self.__filter_category('punting')
def kickret(self):
"""Returns players that have a "kickret" statistical category."""
return self.__filter_category('kickret')
def puntret(self):
"""Returns players that have a "puntret" statistical category."""
return self.__filter_category('puntret')
def defense(self):
"""Returns players that have a "defense" statistical category."""
return self.__filter_category('defense')
def penalty(self):
"""Returns players that have a "penalty" statistical category."""
return self.__filter_category('penalty')
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 p.stats.iteritems():
fields.add(field)
if allfields:
for statId, info in statmap.idmap.iteritems():
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, 'wb+'), fieldNames).writerows(rows)
def __add__(self, other):
"""
Adds two sequences of players by combining repeat players and summing
their statistics.
"""
players = OrderedDict()
for p in itertools.chain(self, other):
if p.playerid not in players:
players[p.playerid] = p
else:
players[p.playerid] += p
return GenPlayerStats(players)
Classes
class Gen
Players implements a sequence type and provides a convenient API for searching sets of players.
class Gen (object):
"""
Players implements a sequence type and provides a convenient API for
searching sets of players.
"""
def __init__(self, iterable):
"""
Creates a new Players sequence from an iterable where each element
of the iterable is an instance of the Player class.
"""
self.__iter = iterable
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 kwargs.iteritems():
def pred(field, value, item):
for suffix, p in _BUILTIN_PREDS.iteritems():
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 = itertools.ifilter(lambda item: all([f(item) for f in preds]),
self)
return self.__class__(gen)
def limit(self, n):
"""
Limit the sequence to N items.
"""
return self.__class__(itertools.islice(self, n))
def sort(self, field, descending=True):
"""
sorts the sequence according to the field specified---where field is
a property on an item in the sequence. If descending is false, items
will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a
KeyError will be raised.
"""
def attrget(item):
return getattr(item, field, 0)
return self.__class__(sorted(self, reverse=descending, key=attrget))
def __str__(self):
"""Returns a list of items in the sequence."""
return '[%s]' % ', '.join([str(item) for item in self])
def __iter__(self):
"""Make this an iterable sequence."""
if self.__iter is None:
return iter([])
if isinstance(self.__iter, OrderedDict):
return self.__iter.itervalues()
return iter(self.__iter)
def __reversed__(self):
"""Satisfy the built in reversed."""
return reversed(self.__iter)
Ancestors (in MRO)
- Gen
- __builtin__.object
Methods
def __init__(
self, iterable)
Creates a new Players sequence from an iterable where each element of the iterable is an instance of the Player class.
def __init__(self, iterable):
"""
Creates a new Players sequence from an iterable where each element
of the iterable is an instance of the Player class.
"""
self.__iter = iterable
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.)
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 kwargs.iteritems():
def pred(field, value, item):
for suffix, p in _BUILTIN_PREDS.iteritems():
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 = itertools.ifilter(lambda item: all([f(item) for f in preds]),
self)
return self.__class__(gen)
def limit(
self, n)
Limit the sequence to N items.
def limit(self, n):
"""
Limit the sequence to N items.
"""
return self.__class__(itertools.islice(self, n))
def sort(
self, field, descending=True)
sorts the sequence according to the field specified---where field is a property on an item in the sequence. If descending is false, items will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a KeyError will be raised.
def sort(self, field, descending=True):
"""
sorts the sequence according to the field specified---where field is
a property on an item in the sequence. If descending is false, items
will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a
KeyError will be raised.
"""
def attrget(item):
return getattr(item, field, 0)
return self.__class__(sorted(self, reverse=descending, key=attrget))
class GenDrives
GenDrives implements a sequence type and provides a convenient API for searching drives.
class GenDrives (Gen):
"""
GenDrives implements a sequence type and provides a convenient API
for searching drives.
"""
def plays(self):
"""
Returns all of the plays, in order, belonging to every drive in
the sequence.
"""
return GenPlays(itertools.chain(*map(lambda d: d.plays, self)))
def players(self):
"""
Returns the combined player stats for every player that participated
in any of the drives in the sequence.
"""
return self.plays().players()
def number(self, n, team=None):
"""
Gets the Nth drive where the first drive corresponds to n=1. This is
only useful given a complete collection of drives for an entire game.
If the team parameter is specified (i.e., team='NE'), then n will
be interpreted as *that* team's Nth drive.
"""
assert n > 0
n -= 1
if team is None:
return list(self)[n]
else:
i = 0
for d in self:
if d.team == team:
if i == n:
return d
i += 1
assert False, \
'Could not find drive %d for team %s.' % (n + 1, team)
Ancestors (in MRO)
Methods
def __init__(
self, iterable)
Creates a new Players sequence from an iterable where each element of the iterable is an instance of the Player class.
def __init__(self, iterable):
"""
Creates a new Players sequence from an iterable where each element
of the iterable is an instance of the Player class.
"""
self.__iter = iterable
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.)
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 kwargs.iteritems():
def pred(field, value, item):
for suffix, p in _BUILTIN_PREDS.iteritems():
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 = itertools.ifilter(lambda item: all([f(item) for f in preds]),
self)
return self.__class__(gen)
def limit(
self, n)
Limit the sequence to N items.
def limit(self, n):
"""
Limit the sequence to N items.
"""
return self.__class__(itertools.islice(self, n))
def number(
self, n, team=None)
Gets the Nth drive where the first drive corresponds to n=1. This is only useful given a complete collection of drives for an entire game.
If the team parameter is specified (i.e., team='NE'), then n will be interpreted as that team's Nth drive.
def number(self, n, team=None):
"""
Gets the Nth drive where the first drive corresponds to n=1. This is
only useful given a complete collection of drives for an entire game.
If the team parameter is specified (i.e., team='NE'), then n will
be interpreted as *that* team's Nth drive.
"""
assert n > 0
n -= 1
if team is None:
return list(self)[n]
else:
i = 0
for d in self:
if d.team == team:
if i == n:
return d
i += 1
assert False, \
'Could not find drive %d for team %s.' % (n + 1, team)
def players(
self)
Returns the combined player stats for every player that participated in any of the drives in the sequence.
def players(self):
"""
Returns the combined player stats for every player that participated
in any of the drives in the sequence.
"""
return self.plays().players()
def plays(
self)
Returns all of the plays, in order, belonging to every drive in the sequence.
def plays(self):
"""
Returns all of the plays, in order, belonging to every drive in
the sequence.
"""
return GenPlays(itertools.chain(*map(lambda d: d.plays, self)))
def sort(
self, field, descending=True)
sorts the sequence according to the field specified---where field is a property on an item in the sequence. If descending is false, items will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a KeyError will be raised.
def sort(self, field, descending=True):
"""
sorts the sequence according to the field specified---where field is
a property on an item in the sequence. If descending is false, items
will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a
KeyError will be raised.
"""
def attrget(item):
return getattr(item, field, 0)
return self.__class__(sorted(self, reverse=descending, key=attrget))
class GenPlayerStats
GenPlayerStats implements a sequence type and provides a convenient API for searching sets of player statistics.
class GenPlayerStats (Gen):
"""
GenPlayerStats implements a sequence type and provides a convenient API for
searching sets of player statistics.
"""
def name(self, name):
"""
Returns a single player whose name equals `name`. If no such player
can be found, None is returned.
Note that NFL GameCenter formats their names like "T.Brady" and
"W.Welker". Thus, `name` should also be in this format.
"""
for p in self:
if p.name == name:
return p
return None
def playerid(self, playerid):
"""
Returns a single player whose NFL GameCenter identifier equals
`playerid`. This probably isn't too useful, unless you're trying
to do ID mapping. (Players have different identifiers across NFL.com.)
If no such player with the given identifier is found, None is
returned.
"""
for p in self:
if p.playerid == playerid:
return p
return None
def touchdowns(self):
"""
touchdowns is a convenience method for returning a Players
sequence of all players with at least one touchdown.
"""
def gen():
for p in self:
for f in p.__dict__:
if f.endswith('tds') and p.__dict__[f] > 0:
yield p
break
return self.__class__(gen())
def __filter_category(self, cat):
return self.__class__(itertools.ifilter(lambda p: p.has_cat(cat),
self))
def passing(self):
"""Returns players that have a "passing" statistical category."""
return self.__filter_category('passing')
def rushing(self):
"""Returns players that have a "rushing" statistical category."""
return self.__filter_category('rushing')
def receiving(self):
"""Returns players that have a "receiving" statistical category."""
return self.__filter_category('receiving')
def fumbles(self):
"""Returns players that have a "fumbles" statistical category."""
return self.__filter_category('fumbles')
def kicking(self):
"""Returns players that have a "kicking" statistical category."""
return self.__filter_category('kicking')
def punting(self):
"""Returns players that have a "punting" statistical category."""
return self.__filter_category('punting')
def kickret(self):
"""Returns players that have a "kickret" statistical category."""
return self.__filter_category('kickret')
def puntret(self):
"""Returns players that have a "puntret" statistical category."""
return self.__filter_category('puntret')
def defense(self):
"""Returns players that have a "defense" statistical category."""
return self.__filter_category('defense')
def penalty(self):
"""Returns players that have a "penalty" statistical category."""
return self.__filter_category('penalty')
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 p.stats.iteritems():
fields.add(field)
if allfields:
for statId, info in statmap.idmap.iteritems():
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, 'wb+'), fieldNames).writerows(rows)
def __add__(self, other):
"""
Adds two sequences of players by combining repeat players and summing
their statistics.
"""
players = OrderedDict()
for p in itertools.chain(self, other):
if p.playerid not in players:
players[p.playerid] = p
else:
players[p.playerid] += p
return GenPlayerStats(players)
Ancestors (in MRO)
- GenPlayerStats
- Gen
- __builtin__.object
Methods
def __init__(
self, iterable)
Creates a new Players sequence from an iterable where each element of the iterable is an instance of the Player class.
def __init__(self, iterable):
"""
Creates a new Players sequence from an iterable where each element
of the iterable is an instance of the Player class.
"""
self.__iter = iterable
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.
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 p.stats.iteritems():
fields.add(field)
if allfields:
for statId, info in statmap.idmap.iteritems():
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, 'wb+'), fieldNames).writerows(rows)
def defense(
self)
Returns players that have a "defense" statistical category.
def defense(self):
"""Returns players that have a "defense" statistical category."""
return self.__filter_category('defense')
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.)
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 kwargs.iteritems():
def pred(field, value, item):
for suffix, p in _BUILTIN_PREDS.iteritems():
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 = itertools.ifilter(lambda item: all([f(item) for f in preds]),
self)
return self.__class__(gen)
def fumbles(
self)
Returns players that have a "fumbles" statistical category.
def fumbles(self):
"""Returns players that have a "fumbles" statistical category."""
return self.__filter_category('fumbles')
def kicking(
self)
Returns players that have a "kicking" statistical category.
def kicking(self):
"""Returns players that have a "kicking" statistical category."""
return self.__filter_category('kicking')
def kickret(
self)
Returns players that have a "kickret" statistical category.
def kickret(self):
"""Returns players that have a "kickret" statistical category."""
return self.__filter_category('kickret')
def limit(
self, n)
Limit the sequence to N items.
def limit(self, n):
"""
Limit the sequence to N items.
"""
return self.__class__(itertools.islice(self, n))
def name(
self, name)
Returns a single player whose name equals name
. If no such player
can be found, None is returned.
Note that NFL GameCenter formats their names like "T.Brady" and
"W.Welker". Thus, name
should also be in this format.
def name(self, name):
"""
Returns a single player whose name equals `name`. If no such player
can be found, None is returned.
Note that NFL GameCenter formats their names like "T.Brady" and
"W.Welker". Thus, `name` should also be in this format.
"""
for p in self:
if p.name == name:
return p
return None
def passing(
self)
Returns players that have a "passing" statistical category.
def passing(self):
"""Returns players that have a "passing" statistical category."""
return self.__filter_category('passing')
def penalty(
self)
Returns players that have a "penalty" statistical category.
def penalty(self):
"""Returns players that have a "penalty" statistical category."""
return self.__filter_category('penalty')
def playerid(
self, playerid)
Returns a single player whose NFL GameCenter identifier equals
playerid
. This probably isn't too useful, unless you're trying
to do ID mapping. (Players have different identifiers across NFL.com.)
If no such player with the given identifier is found, None is returned.
def playerid(self, playerid):
"""
Returns a single player whose NFL GameCenter identifier equals
`playerid`. This probably isn't too useful, unless you're trying
to do ID mapping. (Players have different identifiers across NFL.com.)
If no such player with the given identifier is found, None is
returned.
"""
for p in self:
if p.playerid == playerid:
return p
return None
def punting(
self)
Returns players that have a "punting" statistical category.
def punting(self):
"""Returns players that have a "punting" statistical category."""
return self.__filter_category('punting')
def puntret(
self)
Returns players that have a "puntret" statistical category.
def puntret(self):
"""Returns players that have a "puntret" statistical category."""
return self.__filter_category('puntret')
def receiving(
self)
Returns players that have a "receiving" statistical category.
def receiving(self):
"""Returns players that have a "receiving" statistical category."""
return self.__filter_category('receiving')
def rushing(
self)
Returns players that have a "rushing" statistical category.
def rushing(self):
"""Returns players that have a "rushing" statistical category."""
return self.__filter_category('rushing')
def sort(
self, field, descending=True)
sorts the sequence according to the field specified---where field is a property on an item in the sequence. If descending is false, items will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a KeyError will be raised.
def sort(self, field, descending=True):
"""
sorts the sequence according to the field specified---where field is
a property on an item in the sequence. If descending is false, items
will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a
KeyError will be raised.
"""
def attrget(item):
return getattr(item, field, 0)
return self.__class__(sorted(self, reverse=descending, key=attrget))
def touchdowns(
self)
touchdowns is a convenience method for returning a Players sequence of all players with at least one touchdown.
def touchdowns(self):
"""
touchdowns is a convenience method for returning a Players
sequence of all players with at least one touchdown.
"""
def gen():
for p in self:
for f in p.__dict__:
if f.endswith('tds') and p.__dict__[f] > 0:
yield p
break
return self.__class__(gen())
class GenPlays
GenPlays implements a sequence type and provides a convenient API for searching plays.
class GenPlays (Gen):
"""
GenPlays implements a sequence type and provides a convenient API
for searching plays.
"""
def players(self):
"""
Returns the combined player stats for every play in the sequence.
"""
players = OrderedDict()
for play in self:
for player in play.players:
if player.playerid not in players:
players[player.playerid] = player
else:
players[player.playerid] += player
return GenPlayerStats(players)
Ancestors (in MRO)
Methods
def __init__(
self, iterable)
Creates a new Players sequence from an iterable where each element of the iterable is an instance of the Player class.
def __init__(self, iterable):
"""
Creates a new Players sequence from an iterable where each element
of the iterable is an instance of the Player class.
"""
self.__iter = iterable
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.)
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 kwargs.iteritems():
def pred(field, value, item):
for suffix, p in _BUILTIN_PREDS.iteritems():
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 = itertools.ifilter(lambda item: all([f(item) for f in preds]),
self)
return self.__class__(gen)
def limit(
self, n)
Limit the sequence to N items.
def limit(self, n):
"""
Limit the sequence to N items.
"""
return self.__class__(itertools.islice(self, n))
def players(
self)
Returns the combined player stats for every play in the sequence.
def players(self):
"""
Returns the combined player stats for every play in the sequence.
"""
players = OrderedDict()
for play in self:
for player in play.players:
if player.playerid not in players:
players[player.playerid] = player
else:
players[player.playerid] += player
return GenPlayerStats(players)
def sort(
self, field, descending=True)
sorts the sequence according to the field specified---where field is a property on an item in the sequence. If descending is false, items will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a KeyError will be raised.
def sort(self, field, descending=True):
"""
sorts the sequence according to the field specified---where field is
a property on an item in the sequence. If descending is false, items
will be sorted in order from least to greatest.
Note that if field does not exist in any item being sorted, a
KeyError will be raised.
"""
def attrget(item):
return getattr(item, field, 0)
return self.__class__(sorted(self, reverse=descending, key=attrget))