nflgame.game module
from collections import namedtuple import os import os.path as path import gzip import json import socket import sys import urllib2 from nflgame import OrderedDict import nflgame.player import nflgame.sched import nflgame.seq import nflgame.statmap _MAX_INT = sys.maxint _jsonf = path.join(path.split(__file__)[0], 'gamecenter-json', '%s.json.gz') _json_base_url = "http://www.nfl.com/liveupdate/game-center/%s/%s_gtd.json" GameDiff = namedtuple('GameDiff', ['before', 'after', 'plays', 'players']) """ Represents the difference between two points in time of the same game in terms of plays and player statistics. """ TeamStats = namedtuple('TeamStats', ['first_downs', 'total_yds', 'passing_yds', 'rushing_yds', 'penalty_cnt', 'penalty_yds', 'turnovers', 'punt_cnt', 'punt_yds', 'punt_avg', 'pos_time']) """A collection of team statistics for an entire game.""" class FieldPosition (object): """ Represents field position. The representation here is an integer offset where the 50 yard line corresponds to '0'. Being in the own territory corresponds to a negative offset while being in the opponent's territory corresponds to a positive offset. e.g., NE has the ball on the NE 45, the offset is -5. e.g., NE has the ball on the NYG 2, the offset is 48. This representation allows for gains in any particular play to be added to the field offset to get the new field position as the result of the play. """ def __new__(cls, pos_team=None, yardline=None, offset=None): if not yardline and offset is None: return None return object.__new__(cls) def __init__(self, pos_team=None, yardline=None, offset=None): """ pos_team is the team on offense, and yardline is a string formatted like 'team-territory yard-line'. e.g., "NE 32". An offset can be given directly by specifying an integer for offset. """ if isinstance(offset, int): self.offset = offset return if yardline == '50': self.offset = 0 return territory, yd_str = yardline.split() yd = int(yd_str) if territory == pos_team: self.offset = -(50 - yd) else: self.offset = 50 - yd def __cmp__(self, other): if isinstance(other, int): return cmp(self.offset, other) return cmp(self.offset, other.offset) def __str__(self): if self.offset > 0: return 'OPP %d' % (50 - self.offset) elif self.offset < 0: return 'OWN %d' % (50 + self.offset) else: return 'MIDFIELD' def add_yards(self, yards): """ Returns a new field position with the yards added to self. Yards may be negative. """ newoffset = max(-50, min(50, self.offset + yards)) return FieldPosition(offset=newoffset) class PossessionTime (object): """ Represents the amount of time a drive lasted in (minutes, seconds). """ def __init__(self, clock): self.clock = clock try: self.minutes, self.seconds = map(int, self.clock.split(':')) except ValueError: self.minutes, self.seconds = 0, 0 def total_seconds(self): """ Returns the total number of seconds that this possession lasted for. """ return self.seconds + self.minutes * 60 def __cmp__(self, other): a, b = (self.minutes, self.seconds), (other.minutes, other.seconds) return cmp(a, b) def __add__(self, other): new_time = PossessionTime('0:00') total_seconds = self.total_seconds() + other.total_seconds() new_time.minutes = total_seconds / 60 new_time.seconds = total_seconds % 60 new_time.clock = '%.2d:%.2d' % (new_time.minutes, new_time.seconds) return new_time def __sub__(self, other): assert self >= other new_time = PossessionTime('0:00') total_seconds = self.total_seconds() - other.total_seconds() new_time.minutes = total_seconds / 60 new_time.seconds = total_seconds % 60 new_time.clock = '%.2d:%.2d' % (new_time.minutes, new_time.seconds) return new_time def __str__(self): return self.clock class GameClock (object): """ Represents the current time in a game. Namely, it keeps track of the quarter and clock time. Also, GameClock can represent whether the game hasn't started yet, is half time or if it's over. """ def __init__(self, qtr, clock): self.qtr = qtr self.clock = clock try: self._minutes, self._seconds = map(int, self.clock.split(':')) except ValueError: self._minutes, self._seconds = 0, 0 except AttributeError: self._minutes, self._seconds = 0, 0 try: self.__qtr = int(self.qtr) if self.__qtr >= 3: self.__qtr += 1 # Let halftime be quarter 3 except ValueError: if self.is_pregame(): self.__qtr = 0 elif self.is_halftime(): self.__qtr = 3 elif self.is_final(): self.__qtr = sys.maxint else: self.qtr = 'Pregame' @property def quarter(self): return self.__qtr @quarter.setter def quarter(self, value): if isinstance(value, int): assert value >= 0 and value <= 4 self.qtr = str(value) self.__qtr = value else: self.qtr = value self.__qtr = 0 def is_pregame(self): return self.qtr == 'Pregame' def is_halftime(self): return self.qtr == 'Halftime' def is_final(self): return 'final' in self.qtr.lower() def __cmp__(self, other): if self.__qtr != other.__qtr: return cmp(self.__qtr, other.__qtr) elif self._minutes != other._minutes: return cmp(other._minutes, self._minutes) return cmp(other._seconds, self._seconds) def __str__(self): """ Returns a nicely formatted string indicating the current time of the game. Examples include "Q1 10:52", "Q4 1:25", "Pregame", "Halftime" and "Final". """ try: q = int(self.qtr) return 'Q%d %s' % (q, self.clock) except ValueError: return self.qtr class Game (object): """ Game represents a single pre- or regular-season game. It provides a window into the statistics of every player that played into the game, along with the winner of the game, the score and a list of all the scoring plays. """ 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 urllib2.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 game.data.iteritems(): if isinstance(v, dict): game.eid = k game.data = v break assert game.eid is not None except ValueError: return None return game def __init__(self, eid=None, fpath=None): """ Creates a new Game instance given a game identifier. The game identifier is used by NFL.com's GameCenter live update web pages. It is used to construct a URL to download JSON data for the game. If the game has been completed, the JSON data will be cached to disk so that subsequent accesses will not re-download the data but instead read it from disk. When the JSON data is written to disk, it is compressed using gzip. """ # Make the schedule info more accessible. self.schedule = nflgame.sched.games.get(self.eid, None) # Home and team cumulative statistics. self.home = self.data['home']['abbr'] self.away = self.data['away']['abbr'] self.stats_home = _json_team_stats(self.data['home']['stats']['team']) self.stats_away = _json_team_stats(self.data['away']['stats']['team']) # Load up some simple static values. self.gamekey = nflgame.sched.games[self.eid]['gamekey'] self.time = GameClock(self.data['qtr'], self.data['clock']) self.down = _tryint(self.data['down']) self.togo = _tryint(self.data['togo']) self.score_home = int(self.data['home']['score']['T']) self.score_away = int(self.data['away']['score']['T']) for q in (1, 2, 3, 4, 5): for team in ('home', 'away'): score = self.data[team]['score'][str(q)] self.__dict__['score_%s_q%d' % (team, q)] = int(score) if not self.game_over(): self.winner = None else: if self.score_home > self.score_away: self.winner = self.home self.loser = self.away elif self.score_away > self.score_home: self.winner = self.away self.loser = self.home else: self.winner = '%s/%s' % (self.home, self.away) self.loser = '%s/%s' % (self.home, self.away) # Load the scoring summary into a simple list of strings. self.scores = [] for k in sorted(map(int, self.data['scrsummary'])): play = self.data['scrsummary'][str(k)] s = '%s - Q%d - %s - %s' \ % (play['team'], play['qtr'], play['type'], play['desc']) self.scores.append(s) # Check to see if the game is over, and if so, cache the data. if self.game_over() and not os.access(_jsonf % eid, os.R_OK): self.save() def is_home(self, team): """Returns true if team (i.e., 'NE') is the home team.""" return team == self.home def season(self): """Returns the year of the season this game belongs to.""" year = int(self.eid[0:4]) month = int(self.eid[4:6]) if month <= 3: year -= 1 return year def game_over(self): """game_over returns true if the game is no longer being played.""" return self.time.is_final() def playing(self): """playing returns true if the game is currently being played.""" return not self.time.is_pregame() and not self.time.is_final() def save(self, fpath=None): """ Save the JSON data to fpath. This is done automatically if the game is over. """ if fpath is None: fpath = _jsonf % self.eid try: print >> gzip.open(fpath, 'w+'), self.rawData, except IOError: print >> sys.stderr, "Could not cache JSON data. Please " \ "make '%s' writable." \ % os.path.dirname(fpath) def nice_score(self): """ Returns a string of the score of the game. e.g., "NE (32) vs. NYG (0)". """ return '%s (%d) at %s (%d)' \ % (self.away, self.score_away, self.home, self.score_home) 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 pplay._stats.iteritems(): maxstats[stat] = val newp._overwrite_stats(maxstats) max_players[pplay.playerid] = newp for newp in max_players.itervalues(): for pgame in game_players: if pgame.playerid != newp.playerid: continue maxstats = {} for stat, val in pgame._stats.iteritems(): maxstats[stat] = max([val, newp._stats.get(stat, -_MAX_INT)]) newp._overwrite_stats(maxstats) break return nflgame.seq.GenPlayerStats(max_players) def __getattr__(self, name): if name == 'players': self.__players = _json_game_player_stats(self, self.data) self.players = nflgame.seq.GenPlayerStats(self.__players) return self.players if name == 'drives': self.__drives = _json_drives(self, self.home, self.data['drives']) self.drives = nflgame.seq.GenDrives(self.__drives) return self.drives raise AttributeError def __sub__(self, other): return diff(other, self) def __str__(self): return self.nice_score() def diff(before, after): """ Returns the difference between two points of time in a game in terms of plays and player statistics. The return value is a GameDiff namedtuple with two attributes: plays and players. Each contains *only* the data that is in the after game but not in the before game. This is useful for sending alerts where you're guaranteed to see each play statistic only once (assuming NFL.com behaves itself). """ assert after.eid == before.eid plays = [] after_plays = list(after.drives.plays()) before_plays = list(before.drives.plays()) for play in after_plays: if play not in before_plays: plays.append(play) # You might think that updated play data is enough. You could scan # it for statistics you're looking for (like touchdowns). # But sometimes a play can sneak in twice if its description gets # updated (late call? play review? etc.) # Thus, we do a diff on the play statistics for player data too. _players = OrderedDict() after_players = list(after.max_player_stats()) before_players = list(before.max_player_stats()) for aplayer in after_players: has_before = False for bplayer in before_players: if aplayer.playerid == bplayer.playerid: has_before = True pdiff = aplayer - bplayer if pdiff is not None: _players[aplayer.playerid] = pdiff if not has_before: _players[aplayer.playerid] = aplayer players = nflgame.seq.GenPlayerStats(_players) return GameDiff(before=before, after=after, plays=plays, players=players) class Drive (object): """ Drive represents a single drive in an NFL game. It contains a list of all plays that happened in the drive, in chronological order. It also contains meta information about the drive such as the start and stop times and field position, length of possession, the number of first downs and a short descriptive string of the result of the drive. """ def __init__(self, game, drive_num, home_team, data): if data is None or 'plays' not in data or len(data['plays']) == 0: return self.game = game self.drive_num = drive_num self.team = data['posteam'] self.home = self.team == home_team self.first_downs = int(data['fds']) self.result = data['result'] self.penalty_yds = int(data['penyds']) self.total_yds = int(data['ydsgained']) self.pos_time = PossessionTime(data['postime']) self.play_cnt = int(data['numplays']) self.field_start = FieldPosition(self.team, data['start']['yrdln']) self.time_start = GameClock(data['start']['qtr'], data['start']['time']) # When the game is over, the yardline isn't reported. So find the # last play that does report a yardline. if data['end']['yrdln'].strip(): self.field_end = FieldPosition(self.team, data['end']['yrdln']) else: self.field_end = None playids = sorted(map(int, data['plays'].keys()), reverse=True) for pid in playids: yrdln = data['plays'][str(pid)]['yrdln'].strip() if yrdln: self.field_end = FieldPosition(self.team, yrdln) break if self.field_end is None: self.field_end = FieldPosition(self.team, '50') # When a drive lasts from Q1 to Q2 or Q3 to Q4, the 'end' doesn't # seem to change to the proper quarter. So scan all of the plays # and use the maximal quarter listed. (Just taking the last doesn't # seem to always work.) # lastplayid = str(max(map(int, data['plays'].keys()))) # endqtr = data['plays'][lastplayid]['qtr'] qtrs = [p['qtr'] for p in data['plays'].values()] maxq = str(max(map(int, qtrs))) self.time_end = GameClock(maxq, data['end']['time']) # One last sanity check. If the end time is less than the start time, # then bump the quarter if it seems reasonable. # This technique will blow up if a drive lasts more than fifteen # minutes and the quarter numbering is messed up. if self.time_end <= self.time_start \ and self.time_end.quarter in (1, 3): self.time_end.quarter += 1 self.__plays = _json_plays(self, data['plays']) self.plays = nflgame.seq.GenPlays(self.__plays) def __add__(self, other): """ Adds the statistics of two drives together. Note that once two drives are added, the following fields automatically get None values: result, field_start, field_end, time_start and time_end. """ assert self.team == other.team, \ 'Cannot add drives from different teams "%s" and "%s".' \ % (self.team, other.team) new_drive = Drive(None, 0, '', None) new_drive.team = self.team new_drive.home = self.home new_drive.first_downs = self.first_downs + other.first_downs new_drive.penalty_yds = self.penalty_yds + other.penalty_yds new_drive.total_yds = self.total_yds + other.total_yds new_drive.pos_time = self.pos_time + other.pos_time new_drive.play_cnt = self.play_cnt + other.play_cnt new_drive.__plays = self.__plays + other.__plays new_drive.result = None new_drive.field_start = None new_drive.field_end = None new_drive.time_start = None new_drive.time_end = None return new_drive def __str__(self): return '%s (Start: %s, End: %s) %s' \ % (self.team, self.time_start, self.time_end, self.result) class Play (object): """ Play represents a single play. It contains a list of all players that participated in the play (including offense, defense and special teams). The play also includes meta information about what down it is, field position, clock time, etc. Play objects also contain team-level statistics, such as whether the play was a first down, a fourth down failure, etc. """ 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 statvals.iteritems(): 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 p.stats.iteritems(): # 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 def has_player(self, playerid): """Whether a player with id playerid participated in this play.""" return playerid in self.__players def __str__(self): if self.team: if self.down != 0: return '(%s, %s, Q%d, %d and %d) %s' \ % (self.team, self.data['yrdln'], self.time.qtr, self.down, self.yards_togo, self.desc) else: return '(%s, %s, Q%d) %s' \ % (self.team, self.data['yrdln'], self.time.qtr, self.desc) return self.desc def __eq__(self, other): """ We use the play description to determine equality because the play description can be changed. (Like when a play is reversed.) """ return self.playid == other.playid and self.desc == other.desc def __getattr__(self, name): if name.startswith('__'): raise AttributeError return 0 def _json_team_stats(data): """ Takes a team stats JSON entry and converts it to a TeamStats namedtuple. """ return TeamStats( first_downs=int(data['totfd']), total_yds=int(data['totyds']), passing_yds=int(data['pyds']), rushing_yds=int(data['ryds']), penalty_cnt=int(data['pen']), penalty_yds=int(data['penyds']), turnovers=int(data['trnovr']), punt_cnt=int(data['pt']), punt_yds=int(data['ptyds']), punt_avg=int(data['ptavg']), pos_time=PossessionTime(data['top'])) def _json_drives(game, home_team, data): """ Takes a home or away JSON entry and converts it to a list of Drive objects. """ drive_nums = [] for drive_num in data: try: drive_nums.append(int(drive_num)) except: pass drives = [] for i, drive_num in enumerate(sorted(drive_nums), 1): d = Drive(game, i, home_team, data[str(drive_num)]) if not hasattr(d, 'game'): # not a valid drive continue drives.append(d) return drives def _json_plays(drive, data): """ Takes a single JSON drive entry (data) and converts it to a list of Play objects. This includes trying to resolve duplicate play conflicts by only taking the first instance of a play. """ plays = [] seen_ids = set() seen_desc = set() # Sometimes duplicates have different play ids... for playid in map(str, sorted(map(int, data))): p = data[playid] desc = (p['desc'], p['time'], p['yrdln'], p['qtr']) if playid in seen_ids or desc in seen_desc: continue seen_ids.add(playid) seen_desc.add(desc) plays.append(Play(drive, playid, data[playid])) return plays 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 data.iteritems(): 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 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 data.iteritems(): 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])] 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 data[team]['stats'][category].iteritems(): stats = {} for k, v in raw.iteritems(): 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 def _get_json_data(eid=None, fpath=None): """ Returns the JSON data corresponding to the game represented by eid. If the JSON data is already on disk, it is read, decompressed and returned. Otherwise, the JSON data is downloaded from the NFL web site. If the data doesn't exist yet or there was an error, _get_json_data returns None. If eid is None, then the JSON data is read from the file at fpath. """ assert eid is not None or fpath is not None if fpath is not None: return gzip.open(fpath).read() fpath = _jsonf % eid if os.access(fpath, os.R_OK): return gzip.open(fpath).read() try: return urllib2.urlopen(_json_base_url % (eid, eid), timeout=5).read() except urllib2.HTTPError: pass except socket.timeout: pass return None def _tryint(v): """ Tries to convert v to an integer. If it fails, return 0. """ try: return int(v) except: return 0
Functions
def diff(
before, after)
Returns the difference between two points of time in a game in terms of plays and player statistics. The return value is a GameDiff namedtuple with two attributes: plays and players. Each contains only the data that is in the after game but not in the before game.
This is useful for sending alerts where you're guaranteed to see each play statistic only once (assuming NFL.com behaves itself).
def diff(before, after): """ Returns the difference between two points of time in a game in terms of plays and player statistics. The return value is a GameDiff namedtuple with two attributes: plays and players. Each contains *only* the data that is in the after game but not in the before game. This is useful for sending alerts where you're guaranteed to see each play statistic only once (assuming NFL.com behaves itself). """ assert after.eid == before.eid plays = [] after_plays = list(after.drives.plays()) before_plays = list(before.drives.plays()) for play in after_plays: if play not in before_plays: plays.append(play) # You might think that updated play data is enough. You could scan # it for statistics you're looking for (like touchdowns). # But sometimes a play can sneak in twice if its description gets # updated (late call? play review? etc.) # Thus, we do a diff on the play statistics for player data too. _players = OrderedDict() after_players = list(after.max_player_stats()) before_players = list(before.max_player_stats()) for aplayer in after_players: has_before = False for bplayer in before_players: if aplayer.playerid == bplayer.playerid: has_before = True pdiff = aplayer - bplayer if pdiff is not None: _players[aplayer.playerid] = pdiff if not has_before: _players[aplayer.playerid] = aplayer players = nflgame.seq.GenPlayerStats(_players) return GameDiff(before=before, after=after, plays=plays, players=players)
Classes
class Drive
Drive represents a single drive in an NFL game. It contains a list of all plays that happened in the drive, in chronological order. It also contains meta information about the drive such as the start and stop times and field position, length of possession, the number of first downs and a short descriptive string of the result of the drive.
class Drive (object): """ Drive represents a single drive in an NFL game. It contains a list of all plays that happened in the drive, in chronological order. It also contains meta information about the drive such as the start and stop times and field position, length of possession, the number of first downs and a short descriptive string of the result of the drive. """ def __init__(self, game, drive_num, home_team, data): if data is None or 'plays' not in data or len(data['plays']) == 0: return self.game = game self.drive_num = drive_num self.team = data['posteam'] self.home = self.team == home_team self.first_downs = int(data['fds']) self.result = data['result'] self.penalty_yds = int(data['penyds']) self.total_yds = int(data['ydsgained']) self.pos_time = PossessionTime(data['postime']) self.play_cnt = int(data['numplays']) self.field_start = FieldPosition(self.team, data['start']['yrdln']) self.time_start = GameClock(data['start']['qtr'], data['start']['time']) # When the game is over, the yardline isn't reported. So find the # last play that does report a yardline. if data['end']['yrdln'].strip(): self.field_end = FieldPosition(self.team, data['end']['yrdln']) else: self.field_end = None playids = sorted(map(int, data['plays'].keys()), reverse=True) for pid in playids: yrdln = data['plays'][str(pid)]['yrdln'].strip() if yrdln: self.field_end = FieldPosition(self.team, yrdln) break if self.field_end is None: self.field_end = FieldPosition(self.team, '50') # When a drive lasts from Q1 to Q2 or Q3 to Q4, the 'end' doesn't # seem to change to the proper quarter. So scan all of the plays # and use the maximal quarter listed. (Just taking the last doesn't # seem to always work.) # lastplayid = str(max(map(int, data['plays'].keys()))) # endqtr = data['plays'][lastplayid]['qtr'] qtrs = [p['qtr'] for p in data['plays'].values()] maxq = str(max(map(int, qtrs))) self.time_end = GameClock(maxq, data['end']['time']) # One last sanity check. If the end time is less than the start time, # then bump the quarter if it seems reasonable. # This technique will blow up if a drive lasts more than fifteen # minutes and the quarter numbering is messed up. if self.time_end <= self.time_start \ and self.time_end.quarter in (1, 3): self.time_end.quarter += 1 self.__plays = _json_plays(self, data['plays']) self.plays = nflgame.seq.GenPlays(self.__plays) def __add__(self, other): """ Adds the statistics of two drives together. Note that once two drives are added, the following fields automatically get None values: result, field_start, field_end, time_start and time_end. """ assert self.team == other.team, \ 'Cannot add drives from different teams "%s" and "%s".' \ % (self.team, other.team) new_drive = Drive(None, 0, '', None) new_drive.team = self.team new_drive.home = self.home new_drive.first_downs = self.first_downs + other.first_downs new_drive.penalty_yds = self.penalty_yds + other.penalty_yds new_drive.total_yds = self.total_yds + other.total_yds new_drive.pos_time = self.pos_time + other.pos_time new_drive.play_cnt = self.play_cnt + other.play_cnt new_drive.__plays = self.__plays + other.__plays new_drive.result = None new_drive.field_start = None new_drive.field_end = None new_drive.time_start = None new_drive.time_end = None return new_drive def __str__(self): return '%s (Start: %s, End: %s) %s' \ % (self.team, self.time_start, self.time_end, self.result)
Ancestors (in MRO)
- Drive
- __builtin__.object
Instance variables
var drive_num
var field_start
var first_downs
var game
var home
var penalty_yds
var play_cnt
var plays
var pos_time
var result
var team
var time_end
var time_start
var total_yds
Methods
def __init__(
self, game, drive_num, home_team, data)
def __init__(self, game, drive_num, home_team, data): if data is None or 'plays' not in data or len(data['plays']) == 0: return self.game = game self.drive_num = drive_num self.team = data['posteam'] self.home = self.team == home_team self.first_downs = int(data['fds']) self.result = data['result'] self.penalty_yds = int(data['penyds']) self.total_yds = int(data['ydsgained']) self.pos_time = PossessionTime(data['postime']) self.play_cnt = int(data['numplays']) self.field_start = FieldPosition(self.team, data['start']['yrdln']) self.time_start = GameClock(data['start']['qtr'], data['start']['time']) # When the game is over, the yardline isn't reported. So find the # last play that does report a yardline. if data['end']['yrdln'].strip(): self.field_end = FieldPosition(self.team, data['end']['yrdln']) else: self.field_end = None playids = sorted(map(int, data['plays'].keys()), reverse=True) for pid in playids: yrdln = data['plays'][str(pid)]['yrdln'].strip() if yrdln: self.field_end = FieldPosition(self.team, yrdln) break if self.field_end is None: self.field_end = FieldPosition(self.team, '50') # When a drive lasts from Q1 to Q2 or Q3 to Q4, the 'end' doesn't # seem to change to the proper quarter. So scan all of the plays # and use the maximal quarter listed. (Just taking the last doesn't # seem to always work.) # lastplayid = str(max(map(int, data['plays'].keys()))) # endqtr = data['plays'][lastplayid]['qtr'] qtrs = [p['qtr'] for p in data['plays'].values()] maxq = str(max(map(int, qtrs))) self.time_end = GameClock(maxq, data['end']['time']) # One last sanity check. If the end time is less than the start time, # then bump the quarter if it seems reasonable. # This technique will blow up if a drive lasts more than fifteen # minutes and the quarter numbering is messed up. if self.time_end <= self.time_start \ and self.time_end.quarter in (1, 3): self.time_end.quarter += 1 self.__plays = _json_plays(self, data['plays']) self.plays = nflgame.seq.GenPlays(self.__plays)
class FieldPosition
Represents field position.
The representation here is an integer offset where the 50 yard line corresponds to '0'. Being in the own territory corresponds to a negative offset while being in the opponent's territory corresponds to a positive offset.
e.g., NE has the ball on the NE 45, the offset is -5. e.g., NE has the ball on the NYG 2, the offset is 48.
This representation allows for gains in any particular play to be added to the field offset to get the new field position as the result of the play.
class FieldPosition (object): """ Represents field position. The representation here is an integer offset where the 50 yard line corresponds to '0'. Being in the own territory corresponds to a negative offset while being in the opponent's territory corresponds to a positive offset. e.g., NE has the ball on the NE 45, the offset is -5. e.g., NE has the ball on the NYG 2, the offset is 48. This representation allows for gains in any particular play to be added to the field offset to get the new field position as the result of the play. """ def __new__(cls, pos_team=None, yardline=None, offset=None): if not yardline and offset is None: return None return object.__new__(cls) def __init__(self, pos_team=None, yardline=None, offset=None): """ pos_team is the team on offense, and yardline is a string formatted like 'team-territory yard-line'. e.g., "NE 32". An offset can be given directly by specifying an integer for offset. """ if isinstance(offset, int): self.offset = offset return if yardline == '50': self.offset = 0 return territory, yd_str = yardline.split() yd = int(yd_str) if territory == pos_team: self.offset = -(50 - yd) else: self.offset = 50 - yd def __cmp__(self, other): if isinstance(other, int): return cmp(self.offset, other) return cmp(self.offset, other.offset) def __str__(self): if self.offset > 0: return 'OPP %d' % (50 - self.offset) elif self.offset < 0: return 'OWN %d' % (50 + self.offset) else: return 'MIDFIELD' def add_yards(self, yards): """ Returns a new field position with the yards added to self. Yards may be negative. """ newoffset = max(-50, min(50, self.offset + yards)) return FieldPosition(offset=newoffset)
Ancestors (in MRO)
- FieldPosition
- __builtin__.object
Methods
def __init__(
self, pos_team=None, yardline=None, offset=None)
pos_team is the team on offense, and yardline is a string formatted like 'team-territory yard-line'. e.g., "NE 32".
An offset can be given directly by specifying an integer for offset.
def __init__(self, pos_team=None, yardline=None, offset=None): """ pos_team is the team on offense, and yardline is a string formatted like 'team-territory yard-line'. e.g., "NE 32". An offset can be given directly by specifying an integer for offset. """ if isinstance(offset, int): self.offset = offset return if yardline == '50': self.offset = 0 return territory, yd_str = yardline.split() yd = int(yd_str) if territory == pos_team: self.offset = -(50 - yd) else: self.offset = 50 - yd
def add_yards(
self, yards)
Returns a new field position with the yards added to self. Yards may be negative.
def add_yards(self, yards): """ Returns a new field position with the yards added to self. Yards may be negative. """ newoffset = max(-50, min(50, self.offset + yards)) return FieldPosition(offset=newoffset)
class Game
Game represents a single pre- or regular-season game. It provides a window into the statistics of every player that played into the game, along with the winner of the game, the score and a list of all the scoring plays.
class Game (object): """ Game represents a single pre- or regular-season game. It provides a window into the statistics of every player that played into the game, along with the winner of the game, the score and a list of all the scoring plays. """ 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 urllib2.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 game.data.iteritems(): if isinstance(v, dict): game.eid = k game.data = v break assert game.eid is not None except ValueError: return None return game def __init__(self, eid=None, fpath=None): """ Creates a new Game instance given a game identifier. The game identifier is used by NFL.com's GameCenter live update web pages. It is used to construct a URL to download JSON data for the game. If the game has been completed, the JSON data will be cached to disk so that subsequent accesses will not re-download the data but instead read it from disk. When the JSON data is written to disk, it is compressed using gzip. """ # Make the schedule info more accessible. self.schedule = nflgame.sched.games.get(self.eid, None) # Home and team cumulative statistics. self.home = self.data['home']['abbr'] self.away = self.data['away']['abbr'] self.stats_home = _json_team_stats(self.data['home']['stats']['team']) self.stats_away = _json_team_stats(self.data['away']['stats']['team']) # Load up some simple static values. self.gamekey = nflgame.sched.games[self.eid]['gamekey'] self.time = GameClock(self.data['qtr'], self.data['clock']) self.down = _tryint(self.data['down']) self.togo = _tryint(self.data['togo']) self.score_home = int(self.data['home']['score']['T']) self.score_away = int(self.data['away']['score']['T']) for q in (1, 2, 3, 4, 5): for team in ('home', 'away'): score = self.data[team]['score'][str(q)] self.__dict__['score_%s_q%d' % (team, q)] = int(score) if not self.game_over(): self.winner = None else: if self.score_home > self.score_away: self.winner = self.home self.loser = self.away elif self.score_away > self.score_home: self.winner = self.away self.loser = self.home else: self.winner = '%s/%s' % (self.home, self.away) self.loser = '%s/%s' % (self.home, self.away) # Load the scoring summary into a simple list of strings. self.scores = [] for k in sorted(map(int, self.data['scrsummary'])): play = self.data['scrsummary'][str(k)] s = '%s - Q%d - %s - %s' \ % (play['team'], play['qtr'], play['type'], play['desc']) self.scores.append(s) # Check to see if the game is over, and if so, cache the data. if self.game_over() and not os.access(_jsonf % eid, os.R_OK): self.save() def is_home(self, team): """Returns true if team (i.e., 'NE') is the home team.""" return team == self.home def season(self): """Returns the year of the season this game belongs to.""" year = int(self.eid[0:4]) month = int(self.eid[4:6]) if month <= 3: year -= 1 return year def game_over(self): """game_over returns true if the game is no longer being played.""" return self.time.is_final() def playing(self): """playing returns true if the game is currently being played.""" return not self.time.is_pregame() and not self.time.is_final() def save(self, fpath=None): """ Save the JSON data to fpath. This is done automatically if the game is over. """ if fpath is None: fpath = _jsonf % self.eid try: print >> gzip.open(fpath, 'w+'), self.rawData, except IOError: print >> sys.stderr, "Could not cache JSON data. Please " \ "make '%s' writable." \ % os.path.dirname(fpath) def nice_score(self): """ Returns a string of the score of the game. e.g., "NE (32) vs. NYG (0)". """ return '%s (%d) at %s (%d)' \ % (self.away, self.score_away, self.home, self.score_home) 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 pplay._stats.iteritems(): maxstats[stat] = val newp._overwrite_stats(maxstats) max_players[pplay.playerid] = newp for newp in max_players.itervalues(): for pgame in game_players: if pgame.playerid != newp.playerid: continue maxstats = {} for stat, val in pgame._stats.iteritems(): maxstats[stat] = max([val, newp._stats.get(stat, -_MAX_INT)]) newp._overwrite_stats(maxstats) break return nflgame.seq.GenPlayerStats(max_players) def __getattr__(self, name): if name == 'players': self.__players = _json_game_player_stats(self, self.data) self.players = nflgame.seq.GenPlayerStats(self.__players) return self.players if name == 'drives': self.__drives = _json_drives(self, self.home, self.data['drives']) self.drives = nflgame.seq.GenDrives(self.__drives) return self.drives raise AttributeError def __sub__(self, other): return diff(other, self) def __str__(self): return self.nice_score()
Ancestors (in MRO)
- Game
- __builtin__.object
Instance variables
var away
var down
var gamekey
var home
var schedule
var score_away
var score_home
var scores
var stats_away
var stats_home
var time
var togo
Methods
def __init__(
self, eid=None, fpath=None)
Creates a new Game instance given a game identifier.
The game identifier is used by NFL.com's GameCenter live update web pages. It is used to construct a URL to download JSON data for the game.
If the game has been completed, the JSON data will be cached to disk so that subsequent accesses will not re-download the data but instead read it from disk.
When the JSON data is written to disk, it is compressed using gzip.
def __init__(self, eid=None, fpath=None): """ Creates a new Game instance given a game identifier. The game identifier is used by NFL.com's GameCenter live update web pages. It is used to construct a URL to download JSON data for the game. If the game has been completed, the JSON data will be cached to disk so that subsequent accesses will not re-download the data but instead read it from disk. When the JSON data is written to disk, it is compressed using gzip. """ # Make the schedule info more accessible. self.schedule = nflgame.sched.games.get(self.eid, None) # Home and team cumulative statistics. self.home = self.data['home']['abbr'] self.away = self.data['away']['abbr'] self.stats_home = _json_team_stats(self.data['home']['stats']['team']) self.stats_away = _json_team_stats(self.data['away']['stats']['team']) # Load up some simple static values. self.gamekey = nflgame.sched.games[self.eid]['gamekey'] self.time = GameClock(self.data['qtr'], self.data['clock']) self.down = _tryint(self.data['down']) self.togo = _tryint(self.data['togo']) self.score_home = int(self.data['home']['score']['T']) self.score_away = int(self.data['away']['score']['T']) for q in (1, 2, 3, 4, 5): for team in ('home', 'away'): score = self.data[team]['score'][str(q)] self.__dict__['score_%s_q%d' % (team, q)] = int(score) if not self.game_over(): self.winner = None else: if self.score_home > self.score_away: self.winner = self.home self.loser = self.away elif self.score_away > self.score_home: self.winner = self.away self.loser = self.home else: self.winner = '%s/%s' % (self.home, self.away) self.loser = '%s/%s' % (self.home, self.away) # Load the scoring summary into a simple list of strings. self.scores = [] for k in sorted(map(int, self.data['scrsummary'])): play = self.data['scrsummary'][str(k)] s = '%s - Q%d - %s - %s' \ % (play['team'], play['qtr'], play['type'], play['desc']) self.scores.append(s) # Check to see if the game is over, and if so, cache the data. if self.game_over() and not os.access(_jsonf % eid, os.R_OK): self.save()
def game_over(
self)
game_over returns true if the game is no longer being played.
def game_over(self): """game_over returns true if the game is no longer being played.""" return self.time.is_final()
def is_home(
self, team)
Returns true if team (i.e., 'NE') is the home team.
def is_home(self, team): """Returns true if team (i.e., 'NE') is the home team.""" return team == self.home
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.
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 pplay._stats.iteritems(): maxstats[stat] = val newp._overwrite_stats(maxstats) max_players[pplay.playerid] = newp for newp in max_players.itervalues(): for pgame in game_players: if pgame.playerid != newp.playerid: continue maxstats = {} for stat, val in pgame._stats.iteritems(): maxstats[stat] = max([val, newp._stats.get(stat, -_MAX_INT)]) newp._overwrite_stats(maxstats) break return nflgame.seq.GenPlayerStats(max_players)
def nice_score(
self)
Returns a string of the score of the game. e.g., "NE (32) vs. NYG (0)".
def nice_score(self): """ Returns a string of the score of the game. e.g., "NE (32) vs. NYG (0)". """ return '%s (%d) at %s (%d)' \ % (self.away, self.score_away, self.home, self.score_home)
def playing(
self)
playing returns true if the game is currently being played.
def playing(self): """playing returns true if the game is currently being played.""" return not self.time.is_pregame() and not self.time.is_final()
def save(
self, fpath=None)
Save the JSON data to fpath. This is done automatically if the game is over.
def save(self, fpath=None): """ Save the JSON data to fpath. This is done automatically if the game is over. """ if fpath is None: fpath = _jsonf % self.eid try: print >> gzip.open(fpath, 'w+'), self.rawData, except IOError: print >> sys.stderr, "Could not cache JSON data. Please " \ "make '%s' writable." \ % os.path.dirname(fpath)
def season(
self)
Returns the year of the season this game belongs to.
def season(self): """Returns the year of the season this game belongs to.""" year = int(self.eid[0:4]) month = int(self.eid[4:6]) if month <= 3: year -= 1 return year
class GameClock
Represents the current time in a game. Namely, it keeps track of the quarter and clock time. Also, GameClock can represent whether the game hasn't started yet, is half time or if it's over.
class GameClock (object): """ Represents the current time in a game. Namely, it keeps track of the quarter and clock time. Also, GameClock can represent whether the game hasn't started yet, is half time or if it's over. """ def __init__(self, qtr, clock): self.qtr = qtr self.clock = clock try: self._minutes, self._seconds = map(int, self.clock.split(':')) except ValueError: self._minutes, self._seconds = 0, 0 except AttributeError: self._minutes, self._seconds = 0, 0 try: self.__qtr = int(self.qtr) if self.__qtr >= 3: self.__qtr += 1 # Let halftime be quarter 3 except ValueError: if self.is_pregame(): self.__qtr = 0 elif self.is_halftime(): self.__qtr = 3 elif self.is_final(): self.__qtr = sys.maxint else: self.qtr = 'Pregame' @property def quarter(self): return self.__qtr @quarter.setter def quarter(self, value): if isinstance(value, int): assert value >= 0 and value <= 4 self.qtr = str(value) self.__qtr = value else: self.qtr = value self.__qtr = 0 def is_pregame(self): return self.qtr == 'Pregame' def is_halftime(self): return self.qtr == 'Halftime' def is_final(self): return 'final' in self.qtr.lower() def __cmp__(self, other): if self.__qtr != other.__qtr: return cmp(self.__qtr, other.__qtr) elif self._minutes != other._minutes: return cmp(other._minutes, self._minutes) return cmp(other._seconds, self._seconds) def __str__(self): """ Returns a nicely formatted string indicating the current time of the game. Examples include "Q1 10:52", "Q4 1:25", "Pregame", "Halftime" and "Final". """ try: q = int(self.qtr) return 'Q%d %s' % (q, self.clock) except ValueError: return self.qtr
Ancestors (in MRO)
- GameClock
- __builtin__.object
Instance variables
var clock
var qtr
var quarter
Methods
def __init__(
self, qtr, clock)
def __init__(self, qtr, clock): self.qtr = qtr self.clock = clock try: self._minutes, self._seconds = map(int, self.clock.split(':')) except ValueError: self._minutes, self._seconds = 0, 0 except AttributeError: self._minutes, self._seconds = 0, 0 try: self.__qtr = int(self.qtr) if self.__qtr >= 3: self.__qtr += 1 # Let halftime be quarter 3 except ValueError: if self.is_pregame(): self.__qtr = 0 elif self.is_halftime(): self.__qtr = 3 elif self.is_final(): self.__qtr = sys.maxint else: self.qtr = 'Pregame'
def is_final(
self)
def is_final(self): return 'final' in self.qtr.lower()
def is_halftime(
self)
def is_halftime(self): return self.qtr == 'Halftime'
def is_pregame(
self)
def is_pregame(self): return self.qtr == 'Pregame'
class GameDiff
GameDiff(before, after, plays, players)
Ancestors (in MRO)
- GameDiff
- __builtin__.tuple
- __builtin__.object
Instance variables
var after
Alias for field number 1
var before
Alias for field number 0
var players
Alias for field number 3
var plays
Alias for field number 2
class Play
Play represents a single play. It contains a list of all players that participated in the play (including offense, defense and special teams). The play also includes meta information about what down it is, field position, clock time, etc.
Play objects also contain team-level statistics, such as whether the play was a first down, a fourth down failure, etc.
class Play (object): """ Play represents a single play. It contains a list of all players that participated in the play (including offense, defense and special teams). The play also includes meta information about what down it is, field position, clock time, etc. Play objects also contain team-level statistics, such as whether the play was a first down, a fourth down failure, etc. """ 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 statvals.iteritems(): 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 p.stats.iteritems(): # 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 def has_player(self, playerid): """Whether a player with id playerid participated in this play.""" return playerid in self.__players def __str__(self): if self.team: if self.down != 0: return '(%s, %s, Q%d, %d and %d) %s' \ % (self.team, self.data['yrdln'], self.time.qtr, self.down, self.yards_togo, self.desc) else: return '(%s, %s, Q%d) %s' \ % (self.team, self.data['yrdln'], self.time.qtr, self.desc) return self.desc def __eq__(self, other): """ We use the play description to determine equality because the play description can be changed. (Like when a play is reversed.) """ return self.playid == other.playid and self.desc == other.desc def __getattr__(self, name): if name.startswith('__'): raise AttributeError return 0
Ancestors (in MRO)
- Play
- __builtin__.object
Instance variables
var data
var desc
var down
var drive
var events
var home
var note
var players
var playid
var team
var touchdown
var yards_togo
Methods
def __init__(
self, drive, playid, data)
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 statvals.iteritems(): 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 p.stats.iteritems(): # 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
def has_player(
self, playerid)
Whether a player with id playerid participated in this play.
def has_player(self, playerid): """Whether a player with id playerid participated in this play.""" return playerid in self.__players
class PossessionTime
Represents the amount of time a drive lasted in (minutes, seconds).
class PossessionTime (object): """ Represents the amount of time a drive lasted in (minutes, seconds). """ def __init__(self, clock): self.clock = clock try: self.minutes, self.seconds = map(int, self.clock.split(':')) except ValueError: self.minutes, self.seconds = 0, 0 def total_seconds(self): """ Returns the total number of seconds that this possession lasted for. """ return self.seconds + self.minutes * 60 def __cmp__(self, other): a, b = (self.minutes, self.seconds), (other.minutes, other.seconds) return cmp(a, b) def __add__(self, other): new_time = PossessionTime('0:00') total_seconds = self.total_seconds() + other.total_seconds() new_time.minutes = total_seconds / 60 new_time.seconds = total_seconds % 60 new_time.clock = '%.2d:%.2d' % (new_time.minutes, new_time.seconds) return new_time def __sub__(self, other): assert self >= other new_time = PossessionTime('0:00') total_seconds = self.total_seconds() - other.total_seconds() new_time.minutes = total_seconds / 60 new_time.seconds = total_seconds % 60 new_time.clock = '%.2d:%.2d' % (new_time.minutes, new_time.seconds) return new_time def __str__(self): return self.clock
Ancestors (in MRO)
- PossessionTime
- __builtin__.object
Instance variables
var clock
Methods
def __init__(
self, clock)
def __init__(self, clock): self.clock = clock try: self.minutes, self.seconds = map(int, self.clock.split(':')) except ValueError: self.minutes, self.seconds = 0, 0
def total_seconds(
self)
Returns the total number of seconds that this possession lasted for.
def total_seconds(self): """ Returns the total number of seconds that this possession lasted for. """ return self.seconds + self.minutes * 60
class TeamStats
TeamStats(first_downs, total_yds, passing_yds, rushing_yds, penalty_cnt, penalty_yds, turnovers, punt_cnt, punt_yds, punt_avg, pos_time)
Ancestors (in MRO)
- TeamStats
- __builtin__.tuple
- __builtin__.object
Instance variables
var first_downs
Alias for field number 0
var passing_yds
Alias for field number 2
var penalty_cnt
Alias for field number 4
var penalty_yds
Alias for field number 5
var pos_time
Alias for field number 10
var punt_avg
Alias for field number 9
var punt_cnt
Alias for field number 7
var punt_yds
Alias for field number 8
var rushing_yds
Alias for field number 3
var total_yds
Alias for field number 1
var turnovers
Alias for field number 6


U-571
Review by John Beachem
* * * 1/2
Directed by: Jonathan Mostow Written by: Jonathan Mostow
Hollywood can be awfully patriotic at times. It may not seem that way, with movies like "Three Kings" and "Platoon" making the US look like a villainous bully; but Hollywood gets particularly patriotic when making WWII movies like "Patton" and "Saving Private Ryan". You can now add Jonathan Mostow's ("Breakdown") "U-571" to that list of red blooded, gung-ho, fight till we die, all American movies.  "U-571" may be the sort of brainless but uplifting movie that will never stand the test of time like the far superior "Das Boot" and "The Hunt for Red October"; however, one can't blame the movie for being brainless as this film's only purposes are to get your pulse pounding and your spirit soaring. It succeeds admirably on both counts.
It's the middle of WWII, and the Allied forces are getting pasted in the Atlantic due to a German code they have been unable to crack. Captain Dahlgren (Bill Paxton, in what amounts to little more than a cameo) has been assigned to lead a submarine crew, while posing as a German resupply ship, to a stranded German sub, and steal their code book. His first officer, Lt. Andrew Tyler (Matthew McConaughey), has just been turned down for a promotion because Dahlgren doesn't believe he is ready for the strains of command. The crew carries out its mission only to have their ship sunk by the real resupply ship. Lt. Tyler now finds himself in command of the captured German sub. He has only a handful of raw cadets and one grizzled old sea dog (Harvey Keitel) to help him get the code book back to Allied soil before the German fleet discovers what they have stolen.
Like I said, "U-571" is mindless entertainment at its best; as a result, the dialogue sounds a bit forced at times and the events depicted are more than a little implausible (and quite historically inaccurate). Those few flaws aside, this movie is a blast. The set designs for the insides of WWII submarines are remarkably accurate and are dark and dank like a submarine interior should be. As in all submarine movies, the ability to properly convey the feelings of claustrophobia and dread experienced by the submarine crew is very important. Jonathan Mostow writes these emotions into his characters perfectly. As for the score by Richad Marvin ("Breakdown"), it is as rousing and patriotic as the movie itself (I'm surprised they didn't have American flags hanging from the ceiling in the theater).
Unfortunately, the acting in the movie isn't quite up to par. I'm not sure if this is a result of the rather cheesy dialogue; but whatever the reason it does at times hinder the film. Matthew McConaughey ("Cutthroat Island") gives the movie's worst performance. I think this is because he never quite finds his footing playing his character. Lt. Tyler switches from being unsure of himself and his crewmen, to being a great submarine captain in the blink of an eye and then suddenly back again. Bill Paxton ("Titanic", "A Simple Plan") is given a bit part, which is somewhat confusing as he is possibly the most recognized name on the cast list. The remainder of the supporting cast is adequate at best, with the only exception being Harvey Keitel ("Reservoir Dogs", "Pulp Fiction"). Keitel is perfect as the veteran of the submarine crew, getting such wonderful lines as "You're the Captain now, and that means you have to know everything whether you actually do or not."
The high point of the story comes shortly after the crew begin making their escape in the captured submarine and are discovered by a German destroyer. The two play cat and mouse through the Atlantic, with the sub staying as deep as possible while the destroyer drops depth charges. These scenes do an excellent job of displaying the fear felt by the submarine crew as the explosions come closer and closer and the sub shakes more and more. "U-571" has only one other flaw, which is that it does take awhile to really get going. The nice thing is that once it finds its footing it's a heck of a ride. The movie runs a respectable 118 minutes, though a little trimming at the film's start wouldn't have hurt. I'd recommend it to fans of WWII movies, and especially to fans of "Das Boot" and give the film three and a half out of five stars. Now if you'll excuse me, I feel like singing "The Star Spangled Banner" or buying a flag or something.
Comments? Feel free to e-mail them to<EMAIL_ADDRESS>For past reviews, movie news, and other fun stuff, visit: http://www.dependentfilms.net
* * * * * - One of the greatest movies ever made, see it now. * * * * - Great flick, try and catch this one. * * * - Okay movie, hits and misses. * * - Pretty bad, see it only if you have nothing better to do. * - One of the worst movies ever made. See it only if you enjoy pain.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Piping Response Output
The {@link oajrc.RestCall} class provides various convenience pipeTo()
methods to pipe output to output streams and writers.
If you want to pipe output without any intermediate buffering, you can use the {@link oajrc.RestCall#byLines()} method. This will cause the output to be piped and flushed after every line. This can be useful if you want to display the results in real-time from a long running process producing output on a REST call.


Library website intro
We’ve been introduced the use of the library website by the head of the library himself and he showed us how to do an online advanced research, referencing and citations with APA Harvard and how to get in contact with the university library staff.
I read a marking criteria table about the first coursework to have an idea what to concetrate on while I was working on it.
I started doing my literature review.
I created a folder dedicated to the coursework in my student drive and started doing my research on the topic using the library’s website. Found a lot of work on the topic and read through a lot of documents.
I started writing a draft about the topic.


--- layout: post title: 'Outlook 2010: Calendar permission for Room Mailbox' categories: - Exchange tags: [] status: publish type: post published: true meta: _sd_is_markdown: '1' _edit_last: '1' sharing_disabled: '1' _wpas_done_all: '1' ---
Allow all user to calendar details in Outlook.


| Home | Libraries | People | FAQ | More |
boost::interprocess::intrusive_ptr
// In header: <boost/interprocess/smart_ptr/intrusive_ptr.hpp> template<typename T, typename VoidPointer> class intrusive_ptr { public: // types typedef boost::pointer_to_other< VoidPointer, T >::type pointer; // Provides the type of the internal stored pointer. typedef T element_type; // Provides the type of the stored pointer. // construct/copy/destruct intrusive_ptr(); intrusive_ptr(const pointer &, bool = true); intrusive_ptr(intrusive_ptr const &); template<typename U> intrusive_ptr(intrusive_ptr< U, VP > const &); intrusive_ptr& operator=(intrusive_ptr const &); template<typename U> intrusive_ptr& operator=(intrusive_ptr< U, VP > const &); intrusive_ptr& operator=(pointer); ~intrusive_ptr(); // public member functions pointer & get() ; const pointer & get() const; T & operator*() const; const pointer & operator->() const; pointer & operator->() ; operator unspecified_bool_type() const; bool operator!() const; void swap(intrusive_ptr &) ; };
The intrusive_ptr class template stores a pointer to an object with an embedded reference count. intrusive_ptr is parameterized on T (the type of the object pointed to) and VoidPointer(a void pointer type that defines the type of pointer that intrusive_ptr will store). intrusive_ptr<T, void *> defines a class with a T* member whereas intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member. Relies on unqualified calls to:
void intrusive_ptr_add_ref(T * p); void intrusive_ptr_release(T * p);
with (p != 0)
The object is responsible for destroying itself.
intrusive_ptr
public
construct/copy/destructintrusive_ptr();
Constructor. Initializes internal pointer to 0. Does not throw
intrusive_ptr(const pointer & p, bool add_ref = true);
Constructor. Copies pointer and if "p" is not zero and "add_ref" is true calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw
intrusive_ptr(intrusive_ptr const & rhs);
Copy constructor. Copies the internal pointer and if "p" is not zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw
template<typename U> intrusive_ptr(intrusive_ptr< U, VP > const & rhs);
Constructor from related. Copies the internal pointer and if "p" is not zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw
intrusive_ptr& operator=(intrusive_ptr const & rhs);
Assignment operator. Equivalent to intrusive_ptr(r).swap(*this). Does not throw
template<typename U> intrusive_ptr& operator=(intrusive_ptr< U, VP > const & rhs);
Assignment from related. Equivalent to intrusive_ptr(r).swap(*this). Does not throw
intrusive_ptr& operator=(pointer rhs);
Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this). Does not throw
~intrusive_ptr();
Destructor. If internal pointer is not 0, calls intrusive_ptr_release(get_pointer(m_ptr)). Does not throw
intrusive_ptr
public member functionspointer & get() ;
Returns a reference to the internal pointer. Does not throw
const pointer & get() const;
Returns a reference to the internal pointer. Does not throw
T & operator*() const;
Returns *get(). Does not throw
const pointer & operator->() const;
Returns *get(). Does not throw
pointer & operator->() ;
Returns get(). Does not throw
operator unspecified_bool_type() const;
Conversion to boolean. Does not throw
bool operator!() const;
Not operator. Does not throw
void swap(intrusive_ptr & rhs) ;
Exchanges the contents of the two smart pointers. Does not throw


BRIAN KIPTOO
Home
BMI Calculator
Cooking App
Calculator
Addition Project
Subtraction Project
Multiplication Project
Division Project


scale-a-tron
Draw a polygon
Click "add to map"
Pan around and compare the area you selected to other areas
add to map
rotate
clear
opacity:
Made with ♥ by
Stamen
. Fork the code on
GitHub
.


60px right from in the this line (horizontal)
i think you like it
and some div here -60 (text go left)


I am a coder,web developer,web designer,app developer,machine learning and deep learning enthusiast and what not.
I turn coffee into CODE.
I am currently taking my undergraduate course at MANIT,Bhopal,INDIA.
I contribute to the society through my codepens,jsfiddles,github.
Download my resume.


Please accept the HIT before beginning work.
Recommended browsers: Firefox 42, Chrome 35, Safari 9.f
to advance to the next step, b
to go back. Warning! Do not zoom in or out while marking points. Zoom to a comfortable level and reload the app before beginning work.


No photos found.
Click here to submit photos.
{% elif prev_error %}No photos found.
You haven't voted on any photo previously.
{% else %}Were we let in for our looks? No. Will we be judged on them? Yes.
Who's Hotter? Click to Choose.
{% endif %}{% extends 'base.html' %} {% load static %} {% block title %}
Were we let in for our looks? No. Will we be judged on them? Yes.
Who's Hotter? Click to Choose.
{% endif %}


BOWImgDescriptorExtractor Class to compute an image descriptor using the bag of visual words
Such a computation consists of the following steps:
- Compute descriptors for a given image and its keypoints set.
- Find the nearest visual words from the vocabulary for each keypoint
descriptor.
- Compute the bag-of-words image descriptor as is a normalized
histogram of vocabulary words encountered in the image. The i-th bin
of the histogram is a frequency of i-th word of the vocabulary in
the given image.
Example
% create bag of visual words
trainer = cv.BOWKMeansTrainer(K);
dictionary = trainer.cluster(train_descs);
% Compute histogram of visual word occurrences of an image
extractor = cv.BOWImgDescriptorExtractor('SIFT','BruteForce');
extractor.setVocabulary(dictionary);
descs = extractor.compute(im, keypoints);
|
|
addlistener |
Add listener for event. |
|
|
compute |
Computes an image descriptor using the set visual vocabulary |
|
|
compute1 |
Computes an image descriptor using keypoint descriptors |
|
|
compute2 |
Computes an image descriptor using the set visual vocabulary |
|
|
delete |
Destructor |
|
|
descriptorSize |
Returns image discriptor size |
|
|
descriptorType |
Returns image descriptor type |
|
|
eq |
== (EQ) Test handle equality. |
|
|
findobj |
Find objects matching specified conditions. |
|
|
findprop |
Find property of MATLAB handle object. |
|
|
ge |
>= (GE) Greater than or equal relation for handles. |
|
|
gt |
> (GT) Greater than relation for handles. |
| Sealed
|
isvalid |
Test handle validity. |
|
|
le |
<= (LE) Less than or equal relation for handles. |
|
|
lt |
< (LT) Less than relation for handles. |
|
|
ne |
~= (NE) Not equal relation for handles. |
|
|
notify |
Notify listeners of event. |


JsonPath.Net
JSON Path is a query language for JSON documents inspired by what XPath provides for XML documents. It was originally proposed by Matt Goessner, and now a specification is in progress.
Syntax
A path consists of a series of selectors, chained one after another. Each selector takes in a collection of JSON nodes and produces a collection of JSON nodes based on their function.
$
- This is the root selector. A path must always begin with it. It returns the root document. It can also be used in query expressions, which we'll come to later..
- This is a property-name selector. The property names that you can use with this must only contain alphanumeric or underscore_
characters. Otherwise you'll need to use the property-name indexer (see below). This selector also provides a recursive-descent function when immediately followed by another selector. (More on recursive descents below.) The property name can be replaced with an asterisk*
to indicate that all properties should be returned.[]
- This is an indexing selector. It can contain multiple indices, separated by commas. Indices come in several flavors:- Simple integer - The basic integer index that we're all familiar with. Negative numbers will start counting from the end of an array. If the value is out of the range of the array, no nodes will be returned.
- Slice - This allows selection of a range of nodes from an array.
- Property name - This allows property selection of objects by matching the full name. This is required when a property key doesn't match the requirements of the
.
selector from above. Keys can be single- or double-quoted and special characters must be encoded as is required by JSON. *
literal - This is a wildcard that simply returns all values from within the object or array.- Container query - This is an expression that evaluates to a single integer index and operates on the node being passed to the selector. It is denoted by parentheses surrounding the expression
(...)
. - Item query - This is an expression that evaluates to a boolean and operates on the child nodes of the node being passed to the selector. It is denoted by a question mark followed by parentheses surrounding the expresssion
?(...)
.
Query Expressions
Both container queries and item queries take an expression. This expression uses a single variable, which is some JSON node as described above. The node is denoted by @
and any valid JSON Path can follow it.
For example, an item query expression may be ?(@.price<10)
. This expression will find all items in either an object or an array that contains a price
property with a value less than 10.
Additionally, the $
selector may be used to reference back to the root node, even inside an expression. This allows queries like ?(@.price<$.maxPrice)
where we want to find all of the items of the current container that contain a price
value that is less than the value in the root node's maxPrice
property.
Exressions support the following operations:
- Arithmetic
+
-
*
/
%
(modulus)
- Comparison
==
!=
<
<=
>
>=
- Boolean logic
&&
||
*NOTE There is an open issue regarding expression support on the specification GitHub repository.
Recursive Descents
When the .
selector is immediately followed by another selector (.
or []
), the initial .
indicates a recursive descent selector. This will return all nodes recursively. So for { "a": [ 1, 2, 3 ] }
it will return all of the following:
{ "a": [ 1, 2, 3 ] }
[ 1, 2, 3 ]
1
2
3
Special Considerations
There is also support for a special-case .length
property, which will return the number of items within an object or array. It is valid on both the base path as well as paths found in expressions.
If you find that you need the value of a length
property, you'll need to use the indexer syntax ["length"]
.
This allows expressions such as the container expression (@.length-1)
which is equivalent to the integer index -1
and returns the last value in an array.
In Code
To obtain an instance of a JSON Path, you'll need to parse it from a string.
var path = JsonPath.Parse("$.prop[0:6:2]");
or
var success = JsonPath.TryParse("$.prop[0:6:2]", out JsonPath path);
This will create a JsonPath
instance that will select the prop
property of an object, then items, 0, 2, and 4 of an array that resides there.
Once your path is created, you can start evaluating instances.
var instance = JsonDocument.Parse("{\"prop\":[0,1,2,3]}");
var results = path.Evaluate(instance);
This will return a results object that contains an array of matches or an error.
The match object contains both the value that was found and the location in the instance where it was found.
Adherence to the Proposed Specification
As the specification is still under authorship, there are features present in traditional JSON Path that haven't been properly described yet. For these features, this library has been configured to mimic the consensus behaviors of other libraries as determined by the JSON Path Comparison project.
This library will strive to prioritize the specification over the comparison consensus where any conflict exists.


In Euclidean plane geometry, a rectangle is a quadrilateral with four right angles. It can also be defined as an equiangular quadrilateral, since equiangular means that all of its angles are equal. It can also be defined as a parallelogram containing a right angle.
The word rectangle comes from the Latin rectangulus, which is a combination of rectus and angulus.


In this example the options are set after a five seconds delay, to simulate loading data from, for example, a REST API.


FREQUENCY
Review by John Beachem
* * * *
Directed by: Gregory Hoblit Written by: Toby Emmerich
If there is one thing that science-fiction movies love to grapple with, it is the possibility of time travel. According to most Hollywood writers, there seem to be two different ways of dealing with time travel. Either the past can be altered and the future improved, as in the "Terminator" movies, or the seldom used possibility that the past cannot be changed, as explored in Terry Gilliam's "12 Monkeys". "Frequency", the new film from director Gregory Hoblit ("Primal Fear"), is a movie which falls under the first category yet it is different from most films like this; we are able to see the effects of changes to the past on the future as they occur. For example, we get interesting scenes like one in which a character in the past burns a message into a desk, while a person in the future watches the words appear. However, "Frequency" does not attempt to deal with the paradox problems which arise when dealing with time travel. You'll have to decide for yourself if this was a good idea.
John Sullivan (James Caviezel) is a burned out cop (burned out cop seems to be a common profession) who is having marital problems with his wife, Samantha (Melissa Errico). One evening, while drowning away his miseries with beer, he stumbles across his father's old ham radio. John turns it on and discovers that he can somehow use it to communicate back through time and speak to his father, Frank Sullivan (Dennis Quaid), who has been dead for thirty years. While the two are, at first, disbelieving what has happened, they are soon catching up like old friends. John finds that he may be able to save his father's life if he can warn him about the accident which will soon claim it. While John does manage to save his father's life, it alters the future in ways which he could never have forseen.
 The ham radio being able to communicate back in time is only explained as having to do with massive solar activity at the time, which isn't much of a scientific explanation. The time paradox, which would be created by changing the past, is never even brought up. A time paradox would be something like this: If a person is not originally killed in the past, and a person in the future changes it so that person is killed in the past, he wouldn't have existed in the future for the person in the future to try and change the past. In other words, this is the sort of thing which you can think about forever and it just goes around in circles. This is why I personally think it's best that the movie didn't try to explain it. Besides, you'll be having far too much fun with the rest of the film to care about little plot inconsistencies like that.
The nice thing about a movie like this, which has no big name stars (except the always underrated Dennis Quaid), is that it is forced to rely upon a good script to draw a crowd. Afterall, last year's godawful "Wild Wild West" proved that a movie with big name stars and no script simply doesn't work. This isn't to say that the no name actors in "Frequency" don't do a good job. James Caviezel ("The Thin Red Line") does a very good job of showing a wide range of emotions without going over the top. Dennis Quaid ("Dragonheart") gives his usual fine, understated performance, and Andre Braugher ("Primal Fear") turns in a great performance as Frank Sullivan's cop friend, Satch. Of course, the actors are assisted by some good, if at times a bit too sappy, dialogue. Great lines like "I wanted to let you know you went down thirty years ago, you just don't know it yet" are sprinkled throughout the movie.
In addition to the nice performances and dialogue, "Frequency" has a few other things going for it. Gregory Hoblit's direction is quite impressive, He keeps things interesting by moving events along at a steady pace and only allowing sequences to drag on a little too long once or twice. The soundtrack nicely compliments the story, It always plays softly in the background, rather than overwhelming what is being said (Which is a common practice these days). "Frequency" is one of those good natured movies which are now so ill received. While there may be violence, that isn't what this film is about. It's about a man able to reach back in time and talk to someone who he never had the chance to say goodbye to. "Frequency" is a good movie which will unforunately do poorly at the box office due to lack of star power, advertising, and the ever popular extreme violence. The film runs 117 minutes, which might have been cut down to 105 with a bit more editing. I'd recommend it to fans of time travel stories and give it four out of five stars.
Comments? Feel free to e-mail them to<EMAIL_ADDRESS>For past reviews, movie news, and other fun stuff, visit: http://www.dependentfilms.net
* * * * * - One of the best movies of the year, see it now. * * * * - Great flick, try and catch this one. * * * - Okay movie, hits and misses. * * - Pretty bad, see it only if you have nothing better to do. * - One of the worst movies ever made. See it only if you enjoy pain.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Highlights
Journey through the Arctic Forest for story time by the cozy fire. Take a break from your phone and devices, and let your mind rest as you snuggle under a warm blanket with a snack and listen to the Elf tale of your own choosing. And who knows - as the fire grows warmer and the Northern Lights begin their dance, you may just come to realize that all those stories you loved as a child are not just fairy tales after all.
Included
- Welcoming by the Elf
- Fairy tale walk in the snowy forest
- Hot drinks by the open log fire
- Making sausages on the fireplace
- A shortened Christmas story of your own choosing (5 different stories available)
- Return transfer
- Opportunity to take as many pictures with own camera as desired
- Opportunity to provide advance information about your nearest and dearest to make the experience even more special
- 89€ / adult; 69 € / child (2-12 years old); free for children under 2 years old
Extras/highlights
If you would like to have a private experience or request a time slot that better suits your itinerary, please contact us by email: info@prosanta.fi


plugin.xml
descriptor.
This eases developing new components when using the "Create Class" intention and helps keep track of potentially obsolete components.
Provided quick-fix to register the component adds necessary registration in plugin.xml
descriptor.
Configure the inspection:


Suspect in KyoAni arson attack transferred to hospital in Kyoto after skin grafts
KYOTO – The suspect in a deadly arson attack on a Kyoto Animation Co. studio in July was sent Thursday to a Kyoto hospital from one in Osaka Prefecture after undergoing multiple skin grafts.
Kyoto police plan to arrest Shinji Aoba, 41, after he sufficiently recovers from severe burns to be able to withstand detention. But the timing of an arrest is unclear, as Aoba needs further rehabilitation.
The July 18 attack killed 36 people and injured 33 others.
The police have obtained an arrest warrant for Aoba on suspicion of murder and other charges. After the incident, he was taken to the Kyoto hospital before being airlifted to the Osaka hospital on July 20 to receive specialized treatment.
At around 9 a.m. Thursday, Aoba, on a stretcher under a blue blanket, was carried into a medical vehicle at the Osaka hospital.
The vehicle, called a “doctor car,” arrived at the Kyoto hospital around 75 minutes later.
His condition was declared to be no longer life-threatening in early August and has improved to the point where he can talk and eat.
During police questioning conducted on a voluntary basis on Nov. 8, Aoba admitted to the allegations and was quoted as telling police that he targeted the Kyoto studio because it was the company’s largest in terms of number of employees, according to investigative sources.
The studio in Kyoto’s Fushimi Ward, the center of the company’s anime production, was set ablaze after Aoba allegedly ignited gasoline inside the three-story building, where 70 people were working.
Kyoto Animation, often referred to as KyoAni by fans at home and abroad, is known for works such as “K-On!” and “The Melancholy of Haruhi Suzumiya.”
GET THE BEST OF THE JAPAN TIMES
IN FIVE EASY PIECES WITH TAKE 5
JOIN THE CONVERSATION


|
||||||||||
| PREV LETTER NEXT LETTER | FRAMES NO FRAMES |
ExecutionException
.
ExecutionException
and transforms it into a
runtime exception.
Annotation.hashCode()
API docs.
hashCode
from toHashCode() is returned due to the likelihood
of bugs in mis-calling toHashCode() and the unlikeliness of it mattering what the hashCode for
HashCodeBuilder itself is.
0
if the value is null
.
null
.
Object.hashCode()
methods.hashCode
.
Reader
has more lines.
String
for the given
character.
File
s that are hidden.EntityArrays.HTML40_EXTENDED_ESCAPE()
for unescaping purposes.
|
||||||||||
| PREV LETTER NEXT LETTER | FRAMES NO FRAMES |


| my_ip {pingr} | R Documentation |
It can use a DNS query to opendns.com, if method == "dns"
, or
an HTTPS query to icanhazip.com, see https://github.com/major/icanhaz.
The DNS query is much faster, the HTTPS query is secure.
my_ip(method = c("dns", "https"))
method |
Whether to use a DNS or HTTPS query. |
Computer's public IP address as a string.
my_ip() my_ip(method = "https")


CrimPapers
Articles published on 15 June 2019
On 15 June 2019, 6 new articles were published in 2 journals.
Do Specific Combinations of Parent–child Relationships Predict Moral Values? by Julie Grégoire, Lieven J.r. Pauwels
Race, Gender, and Perceptions of Peer Delinquency: A Within-Subject Analysis by James D. Unnever, Cecilia Chouhy
Barriers and Facilitators to Recovery Capital Among Justice-Involved Community Members by Linda S. Kahn, Bonnie M. Vest, Jessica A. Kulak, Diane E. Berdine, Robert Granfield
Research Note: Re-Examining the Gender Responsive Approach to Female Offending and Its Basis in the Pathways Literature by Candace Kruttschnitt, Katharina Joosen, Catrien Bijleveld
Through Their Lens: the Parental Experience of Formerly Incarcerated Black Fathers by Niedha Welch, Sesen Negash, Alba Nino, Kimberly Ayres, Scott Woolley
A Framework For Developing Justice Reinvestment Plans For Crime Prevention and Offender Rehabilitation in Australia’s Remote Indigenous Communities by Glenn Desmond Dawes, Andrea Davidson


Featured Work Humans vs Machines Click here! Animal Card Trading Click here! Pixel Art Maker Click here!


SCJP Reading Notes - 4
| |Summary
It is reading notes about the book – SCJP.
Operators
Compound operator: the expression on the right side of = will always evaluated first.
x *= 2 + 5; // x = x * (2 + 5);
String concatenation:
String a = "String"; int b = 3; int c = 7; System.out.println(a + b + c); // output: String37 System.out.println(a + (b + c)); //output: String10
Variables marked final cannot be incremented or decremented
^ operator(logical XOR): returns true if exactly one operand is true
Increment & Decrement
int x = 2; int y = 3; if ((y == x++) | (x < ++y)) { System.out.println("x="+x+", y="+y);// output: x = 3, y = 4 } a. y == x++ --> false: compare y == x first, then x+1 -> x = 3 b. x < ++y --> true: ++y first -> y = 4, then compare x < y ? -> 3 < 4 true c. a | b --> print
Flow Control, Exception & Assertions
Switch case:
eg: switch(new Integer(4)) { case 4: System.out.println("boxing is ok"); // it is legal }
if break is omitted, the program keeps executing the remaining cases blocks until break found or switch ends
default case: use when none of case matched; it doesn’t have to come at the end of switch
for loop
eg: a. for (initialization; condition; iteration) {} b. none of the tree sections required for (;;) {System.out.println("inside an endless loop"); } c. don't need to increment or set anything, can put in virtually any arbitrary code statements you want to happend with each iteration of the loop int b = 3; for (int a = 1; b != 1; System.out.println("iterate")) { b = b - a; } output: iterate iterate
break v.s continue
break: stop execution of the innermost loop, start the next line of code after block
continue: cease current execution, start next iteration of same loop if condition is still met
Handling Exceptions
a. code
try { //some code, if put clearnup code here, it's easy to forget and redundent } catch(Exception e) { } finally { //clean up; release any system resource we allocate in the try clause // code here is always runs even exception not caught/try not run, unless System.exit() issue in try or catch clause } it's legal to omit either the catch clause or the finally clause, but not both
b. Ducked exception: method call stack
c. exceptions are always subclass of Java.lang.Exception
two types:
Unchecked Exceptions: Error(Things that not normarlly happend during program execution (eg. JVM run out of memory)), RuntimeException Checked Exception
d. resist the temptation to write a single catch all exception handler
eg:
try { // some code } catch (Exception e) { e.printStackTrace(); }
// it defeats design objective, lose valuable information, reduce reliability of program since it’s likely an exception will be caught that the handler not know how to handle
e. looking available catch clause from top down
eg:
try{ ... }catch (FileNotFoundException fe) { ... }catch (IOException ie) { ... }
f. Handle or Declare: each method must either handle all checked exceptions(which is excluding Error and RuntimeException) by supplying a catch clause or list
g. some examples for Error and RuntimeException
Error: StackOverflow (OS run out of space to store call stack) RuntimeException: NullpointerException, ArrayOutOfIndex
String, I/O, Formatting and Parsing
String: immutable –> once assign a value, the value can never change; use once, remain in memory forever
eg: String x = "Java"; x.concat(" Rules!"); System.out.println(x); //output: Java
Specific case analysis
eg: String s1 = "spring"; //"spring" object referenced by s1 String s2 = s1 + " summer";// " summer" object, lost; spring summer object, referenced by s2 s1.contact("fall "); // "fall " object, lost; "fall spring" object, lost s2.concat(s1); //"spring summer spring" object, lost s1 += " winter"; //"winter" object, lost; "spring winter" object, referenced by s1, at the same time, "spring" object lost reference System.out.println(s1 + " "+ s2);// output: spring winter spring summer
String disanvertange: occupy large amount of memory, so JVM sets aside a special area of memory(String constant pool). When compiler encounters a string literal, it will check if the string literal in String constant pool or not first, if a match is found, no new objects created
String v.s StringBuffer/StringBuilder
String: immutable
StringBuffer/StringBuilder: changable, use when you have to make a lot of modifications to Strings of characters; common use: file I/O, handle large block of data, pass it on, and then reuse the same memory to have the next block of data
StringBuffer v.s StringBuilder
StringBuffer: thread-safe, synchronization
StringBuilder: faster, non-synchronization


Name
public enum Name: Hashable
A header name type. Each has a corresponding value type.
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
A header name type. Each has a corresponding value type.
Declaration
Swift
public var hashValue: Int
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable
-
Undocumented
Declaration
Swift
public enum Name: Hashable