def fetch_raw_data(self, season=None, season_type=REGULAR_SEASON, measure_type=BASE, per_mode=TOTALS): if season is None: season = make_season_str(determine_season_for_date(date.today())) log.debug(("Fetching raw data for: ", self.team, season, season_type, measure_type, per_mode)) self.raw_data = [] if self.summary is None: log.debug("Don't have a summary yet. Fetching it.") summary = TeamPlayerOnOffSummary(team_id=self.team.team_id, measure_type=measure_type, per_mode=per_mode, season=str(season), season_type=season_type) self.summary = summary.json detail = TeamPlayerOnOffDetail(team_id=self.team.team_id, measure_type=measure_type, per_mode=per_mode, season=str(season), season_type=season_type) self.detail = detail.json self.raw_data = [self.summary, self.detail]
def shot_chart(request): active_players = Player.active_players.all() cur_year = determine_season_for_date(date.today()) seasons = {} for year in range(2001, cur_year + 1): seasons[year] = make_season_str(year) context = {'players': active_players, 'seasons': seasons} return render(request, "nba_stats/shot_chart.html", context)
def fetch_raw_data(self, player, season=None): self.player = player if season is None: season = make_season_str(determine_season_for_date(date.today())) log.debug("Pre network call") shot_chart = ShotChart(player_id=player.player_id, season=str(season)) log.debug("post network call") scdtl_dicts = dictify(shot_chart.json['resultSets'][0]) self.raw_data = scdtl_dicts
def game_logs(self, game_ids=None, team_ids=None, player_ids=None): log.debug("Creating GameLogs") glogs = [] cur_team_id = None team = None cur_player_id = None player = None cur_game_id = None game = None for row in self.raw_data: # While the NBA does give a 'SEASON_ID' in its response, # It seems to be of the form '22016', or '22015', etc. # I don't know what's going on there, and I don't trust it. game_date = convert_datetime_string_to_date_instance( row['GAME_DATE']) row['GAME_DATE'] = game_date row['SEASON_ID'] = determine_season_for_date(game_date) row['WIN_FLAG'] = row['WL'] == "W" new_game_id = int(row['GAME_ID']) if new_game_id != cur_game_id: if game_ids is not None and new_game_id not in game_ids: continue game = Game.objects.get(game_id=new_game_id) cur_game_id = new_game_id row['GAME'] = game new_team_id = row['TEAM_ID'] if new_team_id != cur_team_id: if team_ids is not None and new_team_id not in team_ids: continue team = Team.objects.get(team_id=new_team_id) cur_team_id = new_team_id row['TEAM'] = team if self.entity_type == Player: new_player_id = row['PLAYER_ID'] if player_ids is not None and new_player_id not in player_ids: continue if new_player_id != cur_player_id: player = Player.objects.get(player_id=new_player_id) cur_player_id = new_player_id row['PLAYER'] = player gm_log = auto_strip_and_convert_fields(model=PlayerGameLog, data=row, uppercase=True, make_instance=True) glogs.append(gm_log) return glogs
def fetch_raw_data(self, season=None, season_type=REGULAR_SEASON, player_or_team="P"): if season is None: season = make_season_str(determine_season_for_date(date.today())) self.entity_type = Player if player_or_team == "P" else Team log.debug(("Fetching game logs for ", season, season_type, self.entity_type.__name__)) gl = GameLog(season=season, season_type=season_type, player_or_team=player_or_team) result_set = gl.json['resultSets'][0] self.raw_data = dictify(result_set)
def fetch_raw_data(self, season=None, measure_type="Base", per_mode=TOTALS, season_type=REGULAR_SEASON, group_quantity=5): self.measure_type = measure_type self.model = get_model(prefix=self.measure_type, suffix="Lineup") self.raw_data = [] if measure_type in [USAGE, DEFENSE]: raise ValueError("Usage is not a valid measure type for lineups.") if season is None: season = make_season_str(determine_season_for_date(date.today())) log.debug(("Fetching data", season, season_type, measure_type, per_mode, group_quantity)) # Really hope this respects season type. I've seen scenarios where it doesn't lineup = Lineups(season=str(season), season_type=season_type, per_mode=per_mode, group_quantity=group_quantity, measure_type=measure_type) resp_json = lineup.json parms = resp_json['parameters'] result_set = resp_json['resultSets'][0] lineup_rows = dictify(result_set) for row in lineup_rows: row['TEAM'] = Team.objects.get(team_id=int(row['TEAM_ID'])) row['SEASON_ID'] = make_season_int(parms['Season']) row['MEASURE_TYPE'] = parms['MeasureType'] row['SEASON_TYPE'] = parms['SeasonType'] row['PER_MODE'] = parms['PerMode'] row['GROUP_QUANTITY'] = parms['GroupQuantity'] row['SEASON'] = season if measure_type == "Misc": row['PTS_SECOND_CHANCE'] = row['PTS_2ND_CHANCE'] row['OPP_PTS_SECOND_CHANCE'] = row['OPP_PTS_2ND_CHANCE'] elif measure_type == "Scoring": row['PCT_PTS_2PT_MIDRANGE'] = row['PCT_PTS_2PT_MR'] proc_row = convert_dict_keys_to_lowercase(row) self.raw_data.append(proc_row)
class GameFactory(DjangoModelFactory): class Meta: model = Game game_id = FuzzyEntityIdentifier(model=Game, field='game_id') game_date_est = fuzzy.FuzzyDate(start_date=date.today() - timedelta(days=1000)) game_sequence = factory.Sequence(lambda n: n) game_status_id = fuzzy.FuzzyInteger(low=0, high=4) game_status_text = fuzzy.FuzzyText(length=50) gamecode = fuzzy.FuzzyText(length=100) home_team = factory.SubFactory(TeamFactory) visitor_team = factory.SubFactory(TeamFactory) season = factory.LazyAttribute( lambda obj: determine_season_for_date(obj.game_date_est)) live_period = fuzzy.FuzzyInteger(low=0, high=10) live_pc_time = factory.LazyFunction(generate_time_left_in_period_stamp) natl_tv_broadcaster_abbreviation = fuzzy.FuzzyText(length=6) live_period_time_bcast = factory.LazyAttribute( lambda obj: obj.natl_tv_broadcaster_abbreviation + " - " + obj. live_px_time) attendance = fuzzy.FuzzyInteger(low=0, high=25000) game_time = FuzzyDuration(min_seconds=7200, max_seconds=14400)
def get_queryset(self): current_season = determine_season_for_date(date.today()) return super(ActivePlayersManager, self).get_queryset().filter(to_year=current_season)
def __init__(self, position, lup_date, scoring_settings, entry=None): # TODO: Right now scoring fields will come out in random order. # Maybe we can assign an ordering at creation of scoring settings? self.position = position self.display_position = POSITION_ORDER.get(position)[1] self.matchup = "" self.matchup_status = "" if entry is None: self.player = "None" self.player_id = 0 self.team = "N/A" self.eligibility_classes = " ".join( ["elig-" + str(x) for x in POSITION_ORDER.get(position)[2]]) for fld in scoring_settings.scoring_fields_vals: setattr(self, fld, "") else: self.player = entry.player.display_first_last self.player_id = entry.player.id self.team = entry.player.team.abbreviation self.eligibility_classes = " ".join([ "elig-" + x for x in entry.player.numbered_positions.split(",")[:-1] ]) base_box_score = PlayerTraditionalBoxScore.objects.filter( player=entry.player, game__game_date_est=lup_date) if base_box_score.exists(): self.matchup = base_box_score.first().matchup self.matchup_status = base_box_score.first( ).game.game_status_text split_fields_dict = defaultdict(list) for fld in scoring_settings.scoring_fields_vals: split_type, field = fld.split("__") split_fields_dict[split_type].append(field) for split_type in split_fields_dict: fields = split_fields_dict[split_type] if split_type in [ 'PlayerTracking', 'PlayerFourFactors', 'PlayerHustleStats' ]: suffix = "BoxScore" for fld in fields: setattr(self, split_type + "__" + fld, "TODO") continue else: suffix = "Split" model = get_model(middle=split_type, suffix=suffix) year = determine_season_for_date(lup_date) season = make_season_str(year) season_long_vals = model.objects.filter( season_id=year, player=entry.player, season_type="Regular Season", per_mode="PerGame", group_set="Overall", group_value=season).values(*fields) if season_long_vals.exists(): split = season_long_vals.first() for fld in fields: log.debug((split_type, fld, split[fld])) setattr(self, split_type + "__" + fld, split[fld])
def fetch_raw_data(self, season=None, season_type=REGULAR_SEASON, pt_measure_type=SPEED_DISTANCE, per_mode=TOTALS, group_set="Overall", group_value=None): self.raw_data = [] self.pt_measure_type = pt_measure_type if self.pt_measure_type in ["CatchShoot", "PullUpShot"]: middle = "ShotType" elif "Touch" in self.pt_measure_type or "Drive" in self.pt_measure_type: middle = "Touch" else: middle = self.pt_measure_type self.model = get_model(prefix="Player", middle=middle, suffix="Tracking") # Silly way to do this, I know url = self.base_url + self.endpoint if season is None: season = make_season_str(determine_season_for_date(date.today())) if group_set == "Overall" and group_value is None: group_value = season self.params['Season'] = str(season) self.params['SeasonType'] = season_type self.params['PerMode'] = per_mode self.params['PtMeasureType'] = pt_measure_type if group_set != "Overall": self.params[group_set] = group_value if group_set != "Month": group_value = GROUP_VALUES[group_value] log.debug(("Fetching Player Stats: ", season, season_type, pt_measure_type, per_mode, group_set, group_value)) raw_json = get_json_response(url, self.params) rset = raw_json['resultSets'][0] player_rows = dictify(result_set=rset) processed_rows = [] for row in player_rows: row['PLAYER'] = Player.objects.get(player_id=row['PLAYER_ID']) row['GROUP_SET'] = group_set row['SEASON'] = season row['SEASON_TYPE'] = season_type row['PT_MEASURE_TYPE'] = pt_measure_type row['PER_MODE'] = per_mode if group_set == "Month": row['GROUP_VALUE'] = REVERSE_MONTH_MAP[group_value] else: row['GROUP_VALUE'] = group_value if self.pt_measure_type in ["CatchShoot", "PullUpShot"]: row = convert_shot_type_dict_to_apex(row) elif "Touch" in self.pt_measure_type or "Drive" in self.pt_measure_type: row = convert_touch_dict_to_apex(row) proc_row = convert_dict_keys_to_lowercase( row, override_list=['GROUP_SET', 'GROUP_VALUE']) processed_rows.append(proc_row) self.raw_data = processed_rows
def fetch_raw_data(self, player_or_team=PlayerStats, season=None, season_type=REGULAR_SEASON, measure_type=BASE, per_mode=TOTALS, group_set="Overall", group_value=None): self.measure_type = measure_type self.player_or_team = player_or_team if season is None: season = make_season_str(determine_season_for_date(date.today())) if group_set == "Overall" and group_value is None: group_value = season entity = "Player" if self.player_or_team == PlayerStats else "Team" log.debug( ("Fetching {entity} Stats: ".format(entity=entity), season, season_type, measure_type, per_mode, group_set, group_value)) if group_set != "Overall": if group_set != "Month": group_value = GROUP_VALUES[group_value] kwargs = {GROUP_SETS[group_set]: group_value} else: kwargs = {} stats = player_or_team(season=str(season), season_type=season_type, measure_type=measure_type, per_mode=per_mode, **kwargs) raw_json = stats.json rset = raw_json['resultSets'][0] stat_rows = dictify(result_set=rset) for row in stat_rows: if player_or_team == PlayerStats: row['PLAYER'] = Player.objects.get(player_id=row['PLAYER_ID']) else: row['TEAM'] = Team.objects.get(team_id=row['TEAM_ID']) row['GROUP_SET'] = group_set row['SEASON'] = season row['SEASON_TYPE'] = season_type row['MEASURE_TYPE'] = measure_type row['PER_MODE'] = per_mode if group_set == "Month": row['GROUP_VALUE'] = REVERSE_MONTH_MAP[group_value] else: row['GROUP_VALUE'] = group_value if measure_type == "Misc": row['PTS_SECOND_CHANCE'] = row['PTS_2ND_CHANCE'] row['OPP_PTS_SECOND_CHANCE'] = row['OPP_PTS_2ND_CHANCE'] elif measure_type == "Scoring": row['PCT_PTS_2PT_MIDRANGE'] = row['PCT_PTS_2PT_MR'] elif measure_type == "Shooting": if row['GROUP_SET'] == "Assisted By": row['GROUP_VALUE'] = row['PLAYER_NAME'] stat_rows = [ convert_dict_keys_to_lowercase( row, override_list=['GROUP_SET', 'GROUP_VALUE']) for row in stat_rows ] self.raw_data = stat_rows