Beispiel #1
0
    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]
Beispiel #2
0
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)
Beispiel #3
0
def create_play_by_play_for_game(game):
    log.debug("Creating Play By Play Events for Game " + str(game.game_id))
    pbp_events = []
    url = (NBA_BASE_URL + PBP_URL).format(game_id=game.game_id,
                                          season=make_season_str(game.season),
                                          season_type='foo')
    json_data = get_json_response(url)
    pbp_data = json_data['resultSets'][0]
    headers = pbp_data['headers']
    for pbp_event in pbp_data['rowSet']:
        temp_dict = dict(zip(headers, pbp_event))
        temp_dict['GAME'] = game
        # TODO: Write a method that will look for a player and if it doesn't find, creates it.
        # TODO: The method should then return the player object

        if temp_dict['PLAYER1_NAME']:
            player1 = Player.objects.filter(
                player_id=temp_dict['PLAYER1_ID']).first()
            if not player1:
                player1 = Player(player_id=temp_dict['PLAYER1_ID'],
                                 display_first_last=temp_dict['PLAYER1_NAME'])
                player1.save()
            temp_dict['PLAYER1'] = player1
        if temp_dict['PLAYER1_TEAM_ID']:
            temp_dict['PLAYER1_TEAM'] = Team.objects.filter(
                team_id=temp_dict['PLAYER1_TEAM_ID']).first()

        if temp_dict['PLAYER2_NAME']:
            player2 = Player.objects.filter(
                player_id=temp_dict['PLAYER2_ID']).first()
            if not player2:
                player2 = Player(player_id=temp_dict['PLAYER2_ID'],
                                 display_first_last=temp_dict['PLAYER2_NAME'])
                player2.save()
            temp_dict['PLAYER2'] = player2
        if temp_dict['PLAYER2_TEAM_ID']:
            temp_dict['PLAYER2_TEAM'] = Team.objects.filter(
                team_id=temp_dict['PLAYER2_TEAM_ID']).first()

        if temp_dict['PLAYER3_NAME']:
            player3 = Player.objects.filter(
                player_id=temp_dict['PLAYER3_ID']).first()
            if not player3:
                player3 = Player(player_id=temp_dict['PLAYER3_ID'],
                                 display_first_last=temp_dict['PLAYER1_NAME'])
                player3.save()
            temp_dict['PLAYER3'] = player3
        if temp_dict['PLAYER3_TEAM_ID']:
            temp_dict['PLAYER3_TEAM'] = Team.objects.filter(
                team_id=temp_dict['PLAYER3_TEAM_ID']).first()

        if temp_dict['SCOREMARGIN'] == 'TIE':
            temp_dict['SCOREMARGIN'] = 0

        pbp_create_data = convert_dict_keys_to_lowercase(temp_dict)
        pbp_obj = PlayByPlayEvent(**pbp_create_data)
        pbp_events.append(pbp_obj)
    return pbp_events
Beispiel #4
0
 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
Beispiel #5
0
def create_all_shotchart_details_player(player):
    player_scdtls = []
    # I *think* it should be + 1
    for year in range(2001, player.to_year + 1):
        team = None
        for season_type in ["Regular Season", "Playoffs"]:
            season_str = make_season_str(year)
            log.debug("Season: " + season_str)
            raw_json = get_player_shotchart(player, season_str,
                                            season_type=season_type)
            # log.debug("Raw JSON: \n" + str(raw_json))
            player_scdtls += create_player_shotchart_details_from_json(player, raw_json)
    return player_scdtls
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #8
0
def create_update_all_splits_for_entity(entity, year=None, season_type="Regular Season"):
    splits = {'Base': [], 'Advanced': [], 'Misc': [],
              'Scoring': [], 'Usage': [], 'Shooting': []}

    parms = GENERAL_SPLITS_PARMS
    if isinstance(entity, Player):
        parms['PlayerID'] = ent_nba_id = entity.player_id
        endpoint = PLAYER_GENERAL_SPLITS_ENDPOINT
        shooting_endpoint = PLAYER_SHOOTING_SPLITS_ENDPOINT
    elif isinstance(entity, Team):
        parms['TeamID'] = ent_nba_id = entity.team_id
        endpoint = TEAM_GEN_SPLITS_ENDPOINT
        shooting_endpoint = TEAM_SHOOTING_SPLITS_ENDPOINT
    else:
        raise Exception("What are you doing. This function requires a Player or Team.")

    # teams default to 1996-2015-16 season
    first_year = getattr(entity, 'from_year', None) or 1996
    first_year = 1996 if first_year < 1996 else first_year
    final_year = getattr(entity, 'to_year', None) or date.today().year

    if year is not None:
        if year < first_year or year > final_year:
            raise ValueError("You passed an invalid year: {yr}. "
                             "Year must be between {first} and {last} "
                             "for {ent}.".format(yr=year, first=first_year,
                                                 last=final_year, ent=str(entity)))
        else:
            first_year = year
            final_year = year + 1

    # Need to loop over every measure_type, per_mode, season, season_type
    # Could cut this down to Totals & Per100, then calculate everything else.
    # That cuts the requests in half. Could also jut get box scores, but I think that would
    # Make it tough (impossible) to get/do per possession data.
    for per_mode in ['Totals', 'Per100Possessions']:
        parms['PerMode'] = per_mode
        parms['SeasonType'] = season_type
        for cur_year in range(first_year, final_year):
            parms['Season'] = make_season_str(cur_year)
            # This is probably the most effective place to make a cut,
            # But I'm not sure if it can be done.
            for measure_type in ['Base', 'Advanced', 'Misc', 'Scoring', 'Usage']:
                parms['MeasureType'] = measure_type
                log.debug((ent_nba_id, cur_year, season_type, per_mode, measure_type))
                url = NBA_BASE_URL + endpoint
                # Temp. for Hornets
                try:
                    # This is where like 90% of the time is being spent
                    data = get_json_response(url, parms)
                except Exception as e:
                    log.exception(e)
                    continue
                entity_splits = create_update_split_from_raw_json(entity, data)
                splits[measure_type] += entity_splits
            url = NBA_BASE_URL + shooting_endpoint
            # I don't think this actually matters
            parms['MeasureType'] = "Base"
            data = get_json_response(url, parms)
            log.debug((ent_nba_id, cur_year, season_type, per_mode, "Shooting"))
            shooting_splits = create_update_split_from_raw_json(entity, data)
            splits['Shooting'] += shooting_splits

    return splits
Beispiel #9
0
from django import forms
from datetime import date
from nba_stats.utils import make_season_str

PLAYER_SPLIT_TYPE_CHOICES = [("Traditional", "Traditional"),
                             ("Advanced", "Advanced"), ("Misc", "Misc"),
                             ("Shooting", "Shooting"), ("Usage", "Usage"),
                             ("Scoring", "Scoring")]
SEASON_CHOICES = [(str(year), make_season_str(year))
                  for year in range(1996,
                                    date.today().year)]


class GameUpdateForm(forms.Form):
    begin_date = forms.DateField()
    end_date = forms.DateField()


class SplitSearchForm(forms.Form):
    season_id = forms.ChoiceField(SEASON_CHOICES, required=False)
    season_type = forms.CharField(max_length=50,
                                  required=False,
                                  initial="Regular Season")
    split_type = forms.ChoiceField(PLAYER_SPLIT_TYPE_CHOICES, required=False)
    per_mode = forms.CharField(max_length=50,
                               required=False,
                               initial="PerGame")
    order_by = forms.CharField(max_length=50, required=False)


class UserQueryForm(forms.Form):
Beispiel #10
0
def create_box_scores_for_game(game,
                               url_suffix,
                               season_type="Regular+Season",
                               box_type="Traditional"):

    player_box_scores = []
    team_box_scores = []

    url = (NBA_BASE_URL + url_suffix).format(game_id=game.game_id,
                                             season=make_season_str(
                                                 game.season),
                                             season_type=season_type)
    data = get_json_response(url)
    if box_type == "Hustle":
        hustle_status = data['resultSets'][0]['rowSet'][0][1]
        if not hustle_status:
            player_stats = None
        else:
            player_stats = data['resultSets'][1]
    else:
        player_stats = data['resultSets'][0]

    if player_stats:
        player_headers = player_stats['headers']

        if box_type == "Hustle":
            team_stats = data['resultSets'][2]
        else:
            team_stats = data['resultSets'][1]

        team_headers = team_stats['headers']

        for p in player_stats['rowSet']:
            temp_dict = dict(zip(player_headers, p))

            temp_dict['GAME'] = game
            temp_dict['TEAM'] = Team.objects.filter(
                team_id=temp_dict['TEAM_ID']).first()

            player = Player.objects.filter(
                player_id=temp_dict['PLAYER_ID']).first()
            if not player:
                # TODO: Properly handle the situation where the given player doesn't exist yet
                log.debug("Player id and name about to look up: %s %s" %
                          (temp_dict['PLAYER_ID'], temp_dict['PLAYER_NAME']))
                # Laziest possible player creation...
                # should probably write a script that goes through the db and
                # attempts to fill in missing player data

                player = Player(display_first_last=temp_dict['PLAYER_NAME'],
                                player_id=temp_dict['PLAYER_ID'],
                                team=temp_dict['TEAM'])
                player.save()
            temp_dict['PLAYER'] = player

            if box_type == "Tracking":
                converted_dict = convert_tracking_dict_to_nbapex_fields(
                    temp_dict, player_flg=True)
            else:
                converted_dict = temp_dict
            p_box_data = convert_dict_keys_to_lowercase(converted_dict)

            if box_type == 'Hustle':
                p_box_data['minutes'] = convert_min_sec_to_float(
                    p_box_data['minutes'])
            else:
                p_box_data['min'] = convert_min_sec_to_float(p_box_data['min'])

            pbox = create_correct_type_of_player_box_score(
                p_box_data, box_type)
            player_box_scores.append(pbox)

        for t in team_stats['rowSet']:
            temp_dict = dict(zip(team_headers, t))
            temp_dict['GAME'] = game
            temp_dict['TEAM'] = Team.objects.filter(
                team_id=temp_dict['TEAM_ID']).first()

            if box_type == 'Tracking':
                converted_dict = convert_tracking_dict_to_nbapex_fields(
                    temp_dict, player_flg=False)
            else:
                converted_dict = temp_dict
            t_box_data = convert_dict_keys_to_lowercase(converted_dict)

            if box_type == "Hustle":
                t_box_data['minutes'] = convert_min_sec_to_float(
                    t_box_data['minutes'])
            else:
                t_box_data['min'] = convert_min_sec_to_float(t_box_data['min'])

            tbox = create_correct_type_of_team_box_score(t_box_data, box_type)
            team_box_scores.append(tbox)
    else:
        log.debug("Box scores of type {bt} not available for game {gm}".format(
            bt=box_type, gm=game.game_id))

    ret_dict = {'players': player_box_scores, 'teams': team_box_scores}
    return ret_dict
Beispiel #11
0
    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])
Beispiel #12
0
    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
Beispiel #13
0
    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