nba 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/AGENTS.md +362 -0
- data/CHANGELOG.md +169 -0
- data/CLAUDE.md +1 -0
- data/LICENSE +21 -0
- data/README.md +501 -101
- data/bin/console +10 -0
- data/bin/setup +6 -0
- data/exe/nba +8 -0
- data/lib/nba/all_time_leader.rb +77 -0
- data/lib/nba/all_time_leaders.rb +185 -0
- data/lib/nba/assist_leader.rb +92 -0
- data/lib/nba/assist_leaders.rb +64 -0
- data/lib/nba/assist_tracker.rb +108 -0
- data/lib/nba/assist_tracker_entry.rb +206 -0
- data/lib/nba/award.rb +128 -0
- data/lib/nba/box_score.rb +2 -0
- data/lib/nba/box_score_advanced.rb +114 -0
- data/lib/nba/box_score_advanced_player_stat.rb +297 -0
- data/lib/nba/box_score_advanced_team_stat.rb +237 -0
- data/lib/nba/box_score_advanced_v3.rb +124 -0
- data/lib/nba/box_score_defensive_player_stat.rb +281 -0
- data/lib/nba/box_score_defensive_team_stat.rb +85 -0
- data/lib/nba/box_score_defensive_v2.rb +190 -0
- data/lib/nba/box_score_four_factors.rb +91 -0
- data/lib/nba/box_score_four_factors_player_stat.rb +185 -0
- data/lib/nba/box_score_four_factors_team_stat.rb +141 -0
- data/lib/nba/box_score_four_factors_v3.rb +133 -0
- data/lib/nba/box_score_hustle.rb +226 -0
- data/lib/nba/box_score_hustle_player_stat.rb +233 -0
- data/lib/nba/box_score_hustle_team_stat.rb +189 -0
- data/lib/nba/box_score_matchup_stat.rb +417 -0
- data/lib/nba/box_score_matchups_v3.rb +184 -0
- data/lib/nba/box_score_misc.rb +100 -0
- data/lib/nba/box_score_misc_player_stat.rb +217 -0
- data/lib/nba/box_score_misc_team_stat.rb +173 -0
- data/lib/nba/box_score_misc_v3.rb +163 -0
- data/lib/nba/box_score_player_stat.rb +273 -0
- data/lib/nba/box_score_player_track.rb +223 -0
- data/lib/nba/box_score_player_track_stat.rb +273 -0
- data/lib/nba/box_score_player_track_team_stat.rb +229 -0
- data/lib/nba/box_score_scoring.rb +103 -0
- data/lib/nba/box_score_scoring_player_stat.rb +241 -0
- data/lib/nba/box_score_scoring_team_stat.rb +197 -0
- data/lib/nba/box_score_scoring_v3.rb +170 -0
- data/lib/nba/box_score_similarity_score.rb +119 -0
- data/lib/nba/box_score_similarity_stat.rb +76 -0
- data/lib/nba/box_score_starter_bench_stat.rb +257 -0
- data/lib/nba/box_score_summary.rb +285 -0
- data/lib/nba/box_score_summary_v2.rb +202 -0
- data/lib/nba/box_score_summary_v3.rb +120 -0
- data/lib/nba/box_score_summary_v3_data.rb +419 -0
- data/lib/nba/box_score_team_stat.rb +229 -0
- data/lib/nba/box_score_traditional.rb +101 -0
- data/lib/nba/box_score_traditional_v3.rb +195 -0
- data/lib/nba/box_score_usage.rb +102 -0
- data/lib/nba/box_score_usage_player_stat.rb +265 -0
- data/lib/nba/box_score_usage_team_stat.rb +221 -0
- data/lib/nba/box_score_usage_v3.rb +169 -0
- data/lib/nba/box_score_v3_helpers.rb +144 -0
- data/lib/nba/career_stats.rb +217 -0
- data/lib/nba/cli/display/player_display.rb +98 -0
- data/lib/nba/cli/display.rb +178 -0
- data/lib/nba/cli/formatters/game_formatters.rb +86 -0
- data/lib/nba/cli/formatters/leaders_formatters.rb +26 -0
- data/lib/nba/cli/formatters/player_formatters.rb +52 -0
- data/lib/nba/cli/formatters/standings_formatters.rb +26 -0
- data/lib/nba/cli/formatters/team_formatters.rb +67 -0
- data/lib/nba/cli/formatters/time_formatters.rb +82 -0
- data/lib/nba/cli/formatters.rb +56 -0
- data/lib/nba/cli/helpers.rb +135 -0
- data/lib/nba/cli.rb +171 -20
- data/lib/nba/client.rb +35 -0
- data/lib/nba/collection.rb +89 -0
- data/lib/nba/college_player_stat.rb +200 -0
- data/lib/nba/common_player_info.rb +142 -0
- data/lib/nba/common_playoff_series.rb +90 -0
- data/lib/nba/common_team_years.rb +113 -0
- data/lib/nba/conference.rb +39 -0
- data/lib/nba/connection.rb +84 -0
- data/lib/nba/cume_stats_player.rb +358 -0
- data/lib/nba/cume_stats_player_game.rb +217 -0
- data/lib/nba/cume_stats_player_games.rb +99 -0
- data/lib/nba/cume_stats_player_games_entry.rb +25 -0
- data/lib/nba/cume_stats_player_total.rb +481 -0
- data/lib/nba/cume_stats_team.rb +349 -0
- data/lib/nba/cume_stats_team_games.rb +145 -0
- data/lib/nba/cume_stats_team_games_entry.rb +25 -0
- data/lib/nba/cume_stats_team_player.rb +485 -0
- data/lib/nba/cume_stats_team_total.rb +267 -0
- data/lib/nba/data.rb +73 -0
- data/lib/nba/defense_hub.rb +109 -0
- data/lib/nba/defense_hub_stat.rb +57 -0
- data/lib/nba/defensive_shot_stat.rb +102 -0
- data/lib/nba/division.rb +49 -0
- data/lib/nba/draft_board.rb +126 -0
- data/lib/nba/draft_board_pick.rb +173 -0
- data/lib/nba/draft_combine_anthro_measurement.rb +163 -0
- data/lib/nba/draft_combine_drill_result.rb +115 -0
- data/lib/nba/draft_combine_drill_results.rb +112 -0
- data/lib/nba/draft_combine_non_stationary_shooting.rb +268 -0
- data/lib/nba/draft_combine_non_stationary_shooting_result.rb +355 -0
- data/lib/nba/draft_combine_player_anthro.rb +133 -0
- data/lib/nba/draft_combine_spot_shooting.rb +243 -0
- data/lib/nba/draft_combine_spot_shooting_result.rb +419 -0
- data/lib/nba/draft_combine_stat.rb +211 -0
- data/lib/nba/draft_combine_stats.rb +160 -0
- data/lib/nba/draft_history.rb +142 -0
- data/lib/nba/draft_pick.rb +154 -0
- data/lib/nba/dunk_score_leader.rb +93 -0
- data/lib/nba/dunk_score_leaders.rb +77 -0
- data/lib/nba/estimated_metrics_stat.rb +152 -0
- data/lib/nba/fantasy_profile_stat.rb +142 -0
- data/lib/nba/fantasy_widget.rb +72 -0
- data/lib/nba/fantasy_widget_player.rb +98 -0
- data/lib/nba/found_game.rb +260 -0
- data/lib/nba/franchise.rb +136 -0
- data/lib/nba/franchise_history.rb +142 -0
- data/lib/nba/franchise_leader.rb +147 -0
- data/lib/nba/franchise_leaders.rb +162 -0
- data/lib/nba/franchise_player.rb +224 -0
- data/lib/nba/franchise_players.rb +147 -0
- data/lib/nba/game.rb +80 -64
- data/lib/nba/game_log.rb +349 -0
- data/lib/nba/game_rotation.rb +152 -0
- data/lib/nba/game_streak.rb +102 -0
- data/lib/nba/games.rb +46 -0
- data/lib/nba/home_page_leader.rb +99 -0
- data/lib/nba/home_page_leaders.rb +75 -0
- data/lib/nba/home_page_stat.rb +57 -0
- data/lib/nba/home_page_v2.rb +110 -0
- data/lib/nba/hustle_stats_box_score.rb +182 -0
- data/lib/nba/infographic_fan_duel_player.rb +139 -0
- data/lib/nba/infographic_fan_duel_player_stat.rb +311 -0
- data/lib/nba/ist_standing.rb +167 -0
- data/lib/nba/ist_standings.rb +81 -0
- data/lib/nba/leader.rb +103 -0
- data/lib/nba/leaders.rb +110 -0
- data/lib/nba/leaders_tile.rb +57 -0
- data/lib/nba/leaders_tiles.rb +90 -0
- data/lib/nba/league.rb +37 -0
- data/lib/nba/league_dash_lineup_stat.rb +270 -0
- data/lib/nba/league_dash_lineups.rb +177 -0
- data/lib/nba/league_dash_opp_pt_shot.rb +150 -0
- data/lib/nba/league_dash_player_bio_stat.rb +217 -0
- data/lib/nba/league_dash_player_bio_stats.rb +164 -0
- data/lib/nba/league_dash_player_clutch.rb +212 -0
- data/lib/nba/league_dash_player_clutch_stat.rb +271 -0
- data/lib/nba/league_dash_player_pt_shot.rb +152 -0
- data/lib/nba/league_dash_player_pt_shot_stat.rb +193 -0
- data/lib/nba/league_dash_player_shot_location_stat.rb +265 -0
- data/lib/nba/league_dash_player_shot_locations.rb +210 -0
- data/lib/nba/league_dash_player_stat.rb +306 -0
- data/lib/nba/league_dash_player_stats.rb +176 -0
- data/lib/nba/league_dash_pt_defend.rb +160 -0
- data/lib/nba/league_dash_pt_defend_stat.rb +145 -0
- data/lib/nba/league_dash_pt_stats.rb +152 -0
- data/lib/nba/league_dash_pt_stats_stat.rb +169 -0
- data/lib/nba/league_dash_pt_team_defend.rb +158 -0
- data/lib/nba/league_dash_pt_team_defend_stat.rb +110 -0
- data/lib/nba/league_dash_team_clutch.rb +211 -0
- data/lib/nba/league_dash_team_clutch_stat.rb +237 -0
- data/lib/nba/league_dash_team_pt_shot.rb +150 -0
- data/lib/nba/league_dash_team_pt_shot_stat.rb +166 -0
- data/lib/nba/league_dash_team_shot_location_stat.rb +230 -0
- data/lib/nba/league_dash_team_shot_locations.rb +208 -0
- data/lib/nba/league_dash_team_stat.rb +275 -0
- data/lib/nba/league_dash_team_stats.rb +172 -0
- data/lib/nba/league_game_finder.rb +170 -0
- data/lib/nba/league_game_log.rb +224 -0
- data/lib/nba/league_hustle_stats_player.rb +161 -0
- data/lib/nba/league_hustle_stats_player_stat.rb +253 -0
- data/lib/nba/league_hustle_stats_team.rb +157 -0
- data/lib/nba/league_hustle_stats_team_stat.rb +179 -0
- data/lib/nba/league_lineup_viz.rb +184 -0
- data/lib/nba/league_lineup_viz_stat.rb +214 -0
- data/lib/nba/league_player_on_details.rb +175 -0
- data/lib/nba/league_player_on_details_stat.rb +313 -0
- data/lib/nba/league_season_matchup_stat.rb +241 -0
- data/lib/nba/league_season_matchups.rb +181 -0
- data/lib/nba/league_standing.rb +284 -0
- data/lib/nba/league_standings.rb +159 -0
- data/lib/nba/league_wide_shot_stat.rb +62 -0
- data/lib/nba/live_action.rb +240 -0
- data/lib/nba/live_box_score.rb +143 -0
- data/lib/nba/live_connection.rb +84 -0
- data/lib/nba/live_game.rb +230 -0
- data/lib/nba/live_play_by_play.rb +120 -0
- data/lib/nba/live_player_stat.rb +276 -0
- data/lib/nba/live_scoreboard.rb +102 -0
- data/lib/nba/matchup_rollup.rb +98 -0
- data/lib/nba/matchups_rollup.rb +81 -0
- data/lib/nba/pass_stat.rb +209 -0
- data/lib/nba/play.rb +258 -0
- data/lib/nba/play_by_play.rb +85 -0
- data/lib/nba/play_by_play_v3.rb +91 -0
- data/lib/nba/play_type_stat.rb +206 -0
- data/lib/nba/player.rb +242 -24
- data/lib/nba/player_awards.rb +110 -0
- data/lib/nba/player_career_by_college.rb +86 -0
- data/lib/nba/player_career_by_college_rollup.rb +143 -0
- data/lib/nba/player_career_stats.rb +77 -0
- data/lib/nba/player_compare.rb +156 -0
- data/lib/nba/player_comparison_stat.rb +242 -0
- data/lib/nba/player_dash_pt_pass.rb +164 -0
- data/lib/nba/player_dash_pt_reb.rb +235 -0
- data/lib/nba/player_dash_pt_shot_defend.rb +119 -0
- data/lib/nba/player_dash_pt_shots.rb +279 -0
- data/lib/nba/player_dashboard.rb +259 -0
- data/lib/nba/player_dashboard_stat.rb +248 -0
- data/lib/nba/player_estimated_metrics.rb +84 -0
- data/lib/nba/player_fantasy_profile_bar_graph.rb +147 -0
- data/lib/nba/player_game_log.rb +72 -0
- data/lib/nba/player_game_logs.rb +117 -0
- data/lib/nba/player_game_streak_finder.rb +108 -0
- data/lib/nba/player_index.rb +135 -0
- data/lib/nba/player_index_entry.rb +266 -0
- data/lib/nba/player_info.rb +225 -0
- data/lib/nba/player_next_n_games.rb +64 -0
- data/lib/nba/player_profile_v2.rb +169 -0
- data/lib/nba/player_vs_player.rb +153 -0
- data/lib/nba/players.rb +107 -0
- data/lib/nba/playoff_matchup.rb +84 -0
- data/lib/nba/playoff_picture.rb +98 -0
- data/lib/nba/playoff_series.rb +76 -0
- data/lib/nba/position.rb +48 -0
- data/lib/nba/rebound_stat.rb +189 -0
- data/lib/nba/response_parser.rb +116 -0
- data/lib/nba/roster.rb +74 -0
- data/lib/nba/rotation_entry.rb +154 -0
- data/lib/nba/schedule.rb +183 -0
- data/lib/nba/schedule_international.rb +182 -0
- data/lib/nba/scheduled_game.rb +240 -0
- data/lib/nba/scoreboard.rb +183 -0
- data/lib/nba/scoreboard_v3.rb +104 -0
- data/lib/nba/shot.rb +208 -0
- data/lib/nba/shot_chart.rb +75 -0
- data/lib/nba/shot_chart_league_wide.rb +102 -0
- data/lib/nba/shot_chart_lineup_detail.rb +109 -0
- data/lib/nba/shot_stat.rb +174 -0
- data/lib/nba/standing.rb +129 -0
- data/lib/nba/standings.rb +75 -0
- data/lib/nba/static.rb +107 -0
- data/lib/nba/synergy_play_types.rb +211 -0
- data/lib/nba/team.rb +203 -127
- data/lib/nba/team_and_players_vs_players.rb +227 -0
- data/lib/nba/team_and_players_vs_players_stat.rb +155 -0
- data/lib/nba/team_dash_pt_pass.rb +157 -0
- data/lib/nba/team_dash_pt_reb.rb +216 -0
- data/lib/nba/team_dash_pt_shots.rb +244 -0
- data/lib/nba/team_dashboard.rb +275 -0
- data/lib/nba/team_dashboard_stat.rb +248 -0
- data/lib/nba/team_detail.rb +117 -0
- data/lib/nba/team_details.rb +173 -0
- data/lib/nba/team_estimated_metrics.rb +91 -0
- data/lib/nba/team_estimated_metrics_stat.rb +146 -0
- data/lib/nba/team_game_log.rb +143 -0
- data/lib/nba/team_game_log_entry.rb +246 -0
- data/lib/nba/team_game_log_stat.rb +275 -0
- data/lib/nba/team_game_logs.rb +163 -0
- data/lib/nba/team_game_streak.rb +111 -0
- data/lib/nba/team_game_streak_finder.rb +109 -0
- data/lib/nba/team_historical_leader.rb +207 -0
- data/lib/nba/team_historical_leaders.rb +98 -0
- data/lib/nba/team_historical_record.rb +139 -0
- data/lib/nba/team_info.rb +150 -0
- data/lib/nba/team_info_common.rb +177 -0
- data/lib/nba/team_on_off_overall_stat.rb +477 -0
- data/lib/nba/team_on_off_player_stat.rb +523 -0
- data/lib/nba/team_on_off_player_summary.rb +135 -0
- data/lib/nba/team_pass_stat.rb +183 -0
- data/lib/nba/team_player_dashboard.rb +212 -0
- data/lib/nba/team_player_on_off_details.rb +218 -0
- data/lib/nba/team_player_on_off_summary.rb +214 -0
- data/lib/nba/team_player_stat.rb +275 -0
- data/lib/nba/team_rebound_stat.rb +189 -0
- data/lib/nba/team_season_rank.rb +110 -0
- data/lib/nba/team_shot_stat.rb +173 -0
- data/lib/nba/team_vs_player.rb +151 -0
- data/lib/nba/team_vs_player_stat.rb +157 -0
- data/lib/nba/team_year.rb +55 -0
- data/lib/nba/team_year_by_year_stats.rb +152 -0
- data/lib/nba/team_year_stat.rb +282 -0
- data/lib/nba/teams.rb +33 -0
- data/lib/nba/upcoming_game.rb +115 -0
- data/lib/nba/utils.rb +94 -0
- data/lib/nba/version.rb +5 -2
- data/lib/nba/video_detail.rb +103 -0
- data/lib/nba/video_details.rb +118 -0
- data/lib/nba/video_details_asset.rb +115 -0
- data/lib/nba/video_details_asset_entry.rb +91 -0
- data/lib/nba/video_event.rb +83 -0
- data/lib/nba/video_event_asset.rb +91 -0
- data/lib/nba/video_events.rb +106 -0
- data/lib/nba/video_events_asset.rb +107 -0
- data/lib/nba/video_status.rb +129 -0
- data/lib/nba/video_status_entry.rb +161 -0
- data/lib/nba/vs_player_stat.rb +156 -0
- data/lib/nba/win_probability.rb +117 -0
- data/lib/nba/win_probability_point.rb +140 -0
- data/lib/nba.rb +249 -5
- data/sig/equalizer.rbs +3 -0
- data/sig/nba.rbs +7297 -0
- data/sig/shale.rbs +24 -0
- data/sig/thor.rbs +19 -0
- metadata +324 -95
- data/.gitignore +0 -18
- data/.travis.yml +0 -22
- data/Gemfile +0 -23
- data/LICENSE.md +0 -22
- data/Rakefile +0 -18
- data/bin/nba +0 -7
- data/cache/teams.json +0 -16529
- data/lib/faraday_middleware/scrape_game.rb +0 -41
- data/lib/nba/request.rb +0 -37
- data/nba.gemspec +0 -28
- data/spec/fixtures/games.html +0 -785
- data/spec/fixtures/teams.json +0 -16529
- data/spec/game_spec.rb +0 -40
- data/spec/spec_helper.rb +0 -25
- data/spec/team_spec.rb +0 -93
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require_relative "client"
|
|
2
|
+
require_relative "response_parser"
|
|
3
|
+
require_relative "box_score"
|
|
4
|
+
require_relative "utils"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve traditional box score statistics
|
|
8
|
+
module BoxScoreTraditional
|
|
9
|
+
# Result set name for player stats
|
|
10
|
+
# @return [String] the result set name
|
|
11
|
+
PLAYER_STATS = "PlayerStats".freeze
|
|
12
|
+
|
|
13
|
+
# Result set name for team stats
|
|
14
|
+
# @return [String] the result set name
|
|
15
|
+
TEAM_STATS = "TeamStats".freeze
|
|
16
|
+
|
|
17
|
+
# Retrieves player box score stats for a game
|
|
18
|
+
#
|
|
19
|
+
# @api public
|
|
20
|
+
# @example
|
|
21
|
+
# stats = NBA::BoxScoreTraditional.player_stats(game: "0022400001")
|
|
22
|
+
# stats.each { |s| puts "#{s.player_name}: #{s.pts} pts" }
|
|
23
|
+
# @param game [String, Game] the game ID or Game object
|
|
24
|
+
# @param client [Client] the API client to use
|
|
25
|
+
# @return [Collection] a collection of player box score stats
|
|
26
|
+
def self.player_stats(game:, client: CLIENT)
|
|
27
|
+
path = "boxscoretraditionalv2?GameID=#{Utils.extract_id(game)}"
|
|
28
|
+
ResponseParser.parse(client.get(path), result_set: PLAYER_STATS) { |data| build_player_stat(data) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Retrieves team box score stats for a game
|
|
32
|
+
#
|
|
33
|
+
# @api public
|
|
34
|
+
# @example
|
|
35
|
+
# stats = NBA::BoxScoreTraditional.team_stats(game: "0022400001")
|
|
36
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.pts} pts" }
|
|
37
|
+
# @param game [String, Game] the game ID or Game object
|
|
38
|
+
# @param client [Client] the API client to use
|
|
39
|
+
# @return [Collection] a collection of team box score stats
|
|
40
|
+
def self.team_stats(game:, client: CLIENT)
|
|
41
|
+
path = "boxscoretraditionalv2?GameID=#{Utils.extract_id(game)}"
|
|
42
|
+
ResponseParser.parse(client.get(path), result_set: TEAM_STATS) { |data| build_team_stat(data) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Builds a player stat object from API data
|
|
46
|
+
# @api private
|
|
47
|
+
# @return [BoxScorePlayerStat]
|
|
48
|
+
def self.build_player_stat(data)
|
|
49
|
+
BoxScorePlayerStat.new(**player_identity(data), **shooting_stats(data), **counting_stats(data))
|
|
50
|
+
end
|
|
51
|
+
private_class_method :build_player_stat
|
|
52
|
+
|
|
53
|
+
# Builds a team stat object from API data
|
|
54
|
+
# @api private
|
|
55
|
+
# @return [BoxScoreTeamStat]
|
|
56
|
+
def self.build_team_stat(data)
|
|
57
|
+
BoxScoreTeamStat.new(**team_identity(data), **shooting_stats(data), **counting_stats(data))
|
|
58
|
+
end
|
|
59
|
+
private_class_method :build_team_stat
|
|
60
|
+
|
|
61
|
+
# Extracts player identity attributes from data
|
|
62
|
+
# @api private
|
|
63
|
+
# @return [Hash]
|
|
64
|
+
def self.player_identity(data)
|
|
65
|
+
{game_id: data["GAME_ID"], team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
|
|
66
|
+
team_city: data["TEAM_CITY"], player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
67
|
+
start_position: data["START_POSITION"], comment: data["COMMENT"], min: data["MIN"]}
|
|
68
|
+
end
|
|
69
|
+
private_class_method :player_identity
|
|
70
|
+
|
|
71
|
+
# Extracts team identity attributes from data
|
|
72
|
+
# @api private
|
|
73
|
+
# @return [Hash]
|
|
74
|
+
def self.team_identity(data)
|
|
75
|
+
{game_id: data["GAME_ID"], team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
|
|
76
|
+
team_abbreviation: data["TEAM_ABBREVIATION"], team_city: data["TEAM_CITY"], min: data["MIN"]}
|
|
77
|
+
end
|
|
78
|
+
private_class_method :team_identity
|
|
79
|
+
|
|
80
|
+
# Extracts shooting statistics from data
|
|
81
|
+
# @api private
|
|
82
|
+
# @return [Hash]
|
|
83
|
+
def self.shooting_stats(data)
|
|
84
|
+
{fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
|
|
85
|
+
fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
|
|
86
|
+
ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
|
|
87
|
+
end
|
|
88
|
+
private_class_method :shooting_stats
|
|
89
|
+
|
|
90
|
+
# Extracts counting statistics from data
|
|
91
|
+
# @api private
|
|
92
|
+
# @return [Hash]
|
|
93
|
+
def self.counting_stats(data)
|
|
94
|
+
{oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
|
|
95
|
+
ast: data["AST"], stl: data["STL"], blk: data["BLK"],
|
|
96
|
+
tov: data["TO"], pf: data["PF"], pts: data["PTS"],
|
|
97
|
+
plus_minus: data["PLUS_MINUS"]}
|
|
98
|
+
end
|
|
99
|
+
private_class_method :counting_stats
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "box_score_player_stat"
|
|
5
|
+
require_relative "box_score_team_stat"
|
|
6
|
+
require_relative "box_score_starter_bench_stat"
|
|
7
|
+
require_relative "box_score_v3_helpers"
|
|
8
|
+
require_relative "utils"
|
|
9
|
+
|
|
10
|
+
module NBA
|
|
11
|
+
# Provides methods to retrieve traditional box score statistics using V3 API
|
|
12
|
+
module BoxScoreTraditionalV3
|
|
13
|
+
# @return [String] JSON key for traditional box score data
|
|
14
|
+
BOX_SCORE_KEY = "boxScoreTraditional".freeze
|
|
15
|
+
# @return [String] JSON key for player statistics
|
|
16
|
+
PLAYER_STATS = "PlayerStats".freeze
|
|
17
|
+
# @return [String] JSON key for team statistics
|
|
18
|
+
TEAM_STATS = "TeamStats".freeze
|
|
19
|
+
# @return [String] JSON key for starter/bench statistics
|
|
20
|
+
STARTER_BENCH_STATS = "TeamStarterBenchStats".freeze
|
|
21
|
+
|
|
22
|
+
# Retrieves player box score stats for a game
|
|
23
|
+
#
|
|
24
|
+
# @api public
|
|
25
|
+
# @example
|
|
26
|
+
# stats = NBA::BoxScoreTraditionalV3.player_stats(game: "0022400001")
|
|
27
|
+
# stats.each { |stat| puts "#{stat.player_name}: #{stat.pts} pts" }
|
|
28
|
+
# @param game [String, Integer] the game ID
|
|
29
|
+
# @param start_period [Integer] the starting period
|
|
30
|
+
# @param end_period [Integer] the ending period
|
|
31
|
+
# @param client [Client] the API client to use
|
|
32
|
+
# @return [Collection] a collection of player stats
|
|
33
|
+
def self.player_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
|
|
34
|
+
game_id = Utils.extract_id(game)
|
|
35
|
+
response = client.get(build_path(game_id, start_period, end_period))
|
|
36
|
+
parse_player_response(response, game_id)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Retrieves team box score stats for a game
|
|
40
|
+
#
|
|
41
|
+
# @api public
|
|
42
|
+
# @example
|
|
43
|
+
# stats = NBA::BoxScoreTraditionalV3.team_stats(game: "0022400001")
|
|
44
|
+
# stats.each { |stat| puts "#{stat.team_abbreviation}: #{stat.pts} pts" }
|
|
45
|
+
# @param game [String, Integer] the game ID
|
|
46
|
+
# @param start_period [Integer] the starting period
|
|
47
|
+
# @param end_period [Integer] the ending period
|
|
48
|
+
# @param client [Client] the API client to use
|
|
49
|
+
# @return [Collection] a collection of team stats
|
|
50
|
+
def self.team_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
|
|
51
|
+
game_id = Utils.extract_id(game)
|
|
52
|
+
response = client.get(build_path(game_id, start_period, end_period))
|
|
53
|
+
parse_team_response(response, game_id)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Retrieves starter vs bench breakdown stats for a game
|
|
57
|
+
#
|
|
58
|
+
# @api public
|
|
59
|
+
# @example
|
|
60
|
+
# stats = NBA::BoxScoreTraditionalV3.starter_bench_stats(game: "0022400001")
|
|
61
|
+
# stats.each { |stat| puts "#{stat.team_abbreviation} #{stat.starters_bench}: #{stat.pts} pts" }
|
|
62
|
+
# @param game [String, Integer] the game ID
|
|
63
|
+
# @param start_period [Integer] the starting period
|
|
64
|
+
# @param end_period [Integer] the ending period
|
|
65
|
+
# @param client [Client] the API client to use
|
|
66
|
+
# @return [Collection] a collection of starter/bench stats
|
|
67
|
+
def self.starter_bench_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
|
|
68
|
+
game_id = Utils.extract_id(game)
|
|
69
|
+
response = client.get(build_path(game_id, start_period, end_period))
|
|
70
|
+
parse_starter_bench_response(response, game_id)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Builds the API request path
|
|
74
|
+
# @api private
|
|
75
|
+
# @return [String] the request path
|
|
76
|
+
def self.build_path(game_id, start_period, end_period)
|
|
77
|
+
"boxscoretraditionalv3?GameID=#{game_id}&StartPeriod=#{start_period}" \
|
|
78
|
+
"&EndPeriod=#{end_period}&StartRange=0&EndRange=0&RangeType=0"
|
|
79
|
+
end
|
|
80
|
+
private_class_method :build_path
|
|
81
|
+
|
|
82
|
+
# Parses the API response into player stat objects
|
|
83
|
+
# @api private
|
|
84
|
+
# @return [Collection] collection of player stats
|
|
85
|
+
def self.parse_player_response(response, game_id)
|
|
86
|
+
return Collection.new unless response
|
|
87
|
+
|
|
88
|
+
data = JSON.parse(response)
|
|
89
|
+
players = BoxScoreV3Helpers.extract_players(data, BOX_SCORE_KEY)
|
|
90
|
+
return Collection.new unless players
|
|
91
|
+
|
|
92
|
+
Collection.new(players.map { |p| build_player_stat(p, game_id) })
|
|
93
|
+
end
|
|
94
|
+
private_class_method :parse_player_response
|
|
95
|
+
|
|
96
|
+
# Parses the API response into team stat objects
|
|
97
|
+
# @api private
|
|
98
|
+
# @return [Collection] collection of team stats
|
|
99
|
+
def self.parse_team_response(response, game_id)
|
|
100
|
+
return Collection.new unless response
|
|
101
|
+
|
|
102
|
+
data = JSON.parse(response)
|
|
103
|
+
teams = BoxScoreV3Helpers.extract_teams(data, BOX_SCORE_KEY)
|
|
104
|
+
return Collection.new unless teams
|
|
105
|
+
|
|
106
|
+
Collection.new(teams.map { |t| build_team_stat(t, game_id) })
|
|
107
|
+
end
|
|
108
|
+
private_class_method :parse_team_response
|
|
109
|
+
|
|
110
|
+
# Parses the API response into starter/bench stat objects
|
|
111
|
+
# @api private
|
|
112
|
+
# @return [Collection] collection of starter/bench stats
|
|
113
|
+
def self.parse_starter_bench_response(response, game_id)
|
|
114
|
+
return Collection.new unless response
|
|
115
|
+
|
|
116
|
+
data = JSON.parse(response)
|
|
117
|
+
stat_data = extract_starter_bench(data)
|
|
118
|
+
return Collection.new unless stat_data
|
|
119
|
+
|
|
120
|
+
Collection.new(stat_data.map { |d| build_starter_bench_stat(d, game_id) })
|
|
121
|
+
end
|
|
122
|
+
private_class_method :parse_starter_bench_response
|
|
123
|
+
|
|
124
|
+
# Extracts starter/bench data from parsed response
|
|
125
|
+
# @api private
|
|
126
|
+
# @return [Array, nil] array of starter/bench data or nil
|
|
127
|
+
def self.extract_starter_bench(data)
|
|
128
|
+
box_score = data[BOX_SCORE_KEY]
|
|
129
|
+
return unless box_score
|
|
130
|
+
|
|
131
|
+
stats = []
|
|
132
|
+
add_team_starter_bench(stats, box_score, "homeTeam")
|
|
133
|
+
add_team_starter_bench(stats, box_score, "awayTeam")
|
|
134
|
+
stats
|
|
135
|
+
end
|
|
136
|
+
private_class_method :extract_starter_bench
|
|
137
|
+
|
|
138
|
+
# Adds starter/bench data for a team
|
|
139
|
+
# @api private
|
|
140
|
+
# @return [void]
|
|
141
|
+
def self.add_team_starter_bench(stats, box_score, team_key)
|
|
142
|
+
team = box_score[team_key]
|
|
143
|
+
return unless team
|
|
144
|
+
|
|
145
|
+
%w[starters bench].each do |group|
|
|
146
|
+
group_stats = team.dig("statistics", group)
|
|
147
|
+
stats << {team: team, group: group, stats: group_stats} if group_stats
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
private_class_method :add_team_starter_bench
|
|
151
|
+
|
|
152
|
+
# Builds a player stat object from raw data
|
|
153
|
+
# @api private
|
|
154
|
+
# @return [BoxScorePlayerStat] the player stat object
|
|
155
|
+
def self.build_player_stat(player, game_id)
|
|
156
|
+
stats = player.fetch("statistics", {})
|
|
157
|
+
BoxScorePlayerStat.new(
|
|
158
|
+
**BoxScoreV3Helpers.player_identity(player, game_id),
|
|
159
|
+
min: stats["minutes"],
|
|
160
|
+
**BoxScoreV3Helpers.shooting_stats(stats),
|
|
161
|
+
**BoxScoreV3Helpers.counting_stats(stats)
|
|
162
|
+
)
|
|
163
|
+
end
|
|
164
|
+
private_class_method :build_player_stat
|
|
165
|
+
|
|
166
|
+
# Builds a team stat object from raw data
|
|
167
|
+
# @api private
|
|
168
|
+
# @return [BoxScoreTeamStat] the team stat object
|
|
169
|
+
def self.build_team_stat(team, game_id)
|
|
170
|
+
stats = team.fetch("statistics", {})
|
|
171
|
+
BoxScoreTeamStat.new(
|
|
172
|
+
**BoxScoreV3Helpers.team_identity(team, game_id),
|
|
173
|
+
min: stats["minutes"],
|
|
174
|
+
**BoxScoreV3Helpers.shooting_stats(stats),
|
|
175
|
+
**BoxScoreV3Helpers.counting_stats(stats)
|
|
176
|
+
)
|
|
177
|
+
end
|
|
178
|
+
private_class_method :build_team_stat
|
|
179
|
+
|
|
180
|
+
# Builds a starter/bench stat object from raw data
|
|
181
|
+
# @api private
|
|
182
|
+
# @return [BoxScoreStarterBenchStat] the starter/bench stat object
|
|
183
|
+
def self.build_starter_bench_stat(data, game_id)
|
|
184
|
+
team = data.fetch(:team)
|
|
185
|
+
stats = data.fetch(:stats)
|
|
186
|
+
BoxScoreStarterBenchStat.new(
|
|
187
|
+
**BoxScoreV3Helpers.team_identity(team, game_id),
|
|
188
|
+
starters_bench: data.fetch(:group), min: stats["minutes"],
|
|
189
|
+
**BoxScoreV3Helpers.shooting_stats(stats),
|
|
190
|
+
**BoxScoreV3Helpers.counting_stats(stats)
|
|
191
|
+
)
|
|
192
|
+
end
|
|
193
|
+
private_class_method :build_starter_bench_stat
|
|
194
|
+
end
|
|
195
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require_relative "client"
|
|
2
|
+
require_relative "response_parser"
|
|
3
|
+
require_relative "box_score_usage_player_stat"
|
|
4
|
+
require_relative "box_score_usage_team_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve usage box score statistics
|
|
9
|
+
module BoxScoreUsage
|
|
10
|
+
# Result set name for player stats
|
|
11
|
+
# @return [String] the result set name
|
|
12
|
+
PLAYER_STATS = "PlayerStats".freeze
|
|
13
|
+
|
|
14
|
+
# Result set name for team stats
|
|
15
|
+
# @return [String] the result set name
|
|
16
|
+
TEAM_STATS = "TeamStats".freeze
|
|
17
|
+
|
|
18
|
+
# Retrieves player usage box score stats for a game
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
# @example
|
|
22
|
+
# stats = NBA::BoxScoreUsage.player_stats(game: "0022400001")
|
|
23
|
+
# stats.each { |s| puts "#{s.player_name}: #{s.usg_pct}% usage" }
|
|
24
|
+
# @param game [String, Game] the game ID or Game object
|
|
25
|
+
# @param client [Client] the API client to use
|
|
26
|
+
# @return [Collection] a collection of player usage box score stats
|
|
27
|
+
def self.player_stats(game:, client: CLIENT)
|
|
28
|
+
path = "boxscoreusagev2?GameID=#{Utils.extract_id(game)}"
|
|
29
|
+
ResponseParser.parse(client.get(path), result_set: PLAYER_STATS) { |data| build_player_stat(data) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Retrieves team usage box score stats for a game
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# stats = NBA::BoxScoreUsage.team_stats(game: "0022400001")
|
|
37
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.pct_pts}% of pts" }
|
|
38
|
+
# @param game [String, Game] the game ID or Game object
|
|
39
|
+
# @param client [Client] the API client to use
|
|
40
|
+
# @return [Collection] a collection of team usage box score stats
|
|
41
|
+
def self.team_stats(game:, client: CLIENT)
|
|
42
|
+
path = "boxscoreusagev2?GameID=#{Utils.extract_id(game)}"
|
|
43
|
+
ResponseParser.parse(client.get(path), result_set: TEAM_STATS) { |data| build_team_stat(data) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Builds a player usage stat from API data
|
|
47
|
+
# @api private
|
|
48
|
+
# @return [BoxScoreUsagePlayerStat]
|
|
49
|
+
def self.build_player_stat(data)
|
|
50
|
+
BoxScoreUsagePlayerStat.new(**player_identity(data), **shooting_usage(data), **other_usage(data))
|
|
51
|
+
end
|
|
52
|
+
private_class_method :build_player_stat
|
|
53
|
+
|
|
54
|
+
# Builds a team usage stat from API data
|
|
55
|
+
# @api private
|
|
56
|
+
# @return [BoxScoreUsageTeamStat]
|
|
57
|
+
def self.build_team_stat(data)
|
|
58
|
+
BoxScoreUsageTeamStat.new(**team_identity(data), **shooting_usage(data), **other_usage(data))
|
|
59
|
+
end
|
|
60
|
+
private_class_method :build_team_stat
|
|
61
|
+
|
|
62
|
+
# Extracts player identity attributes from data
|
|
63
|
+
# @api private
|
|
64
|
+
# @return [Hash]
|
|
65
|
+
def self.player_identity(data)
|
|
66
|
+
{game_id: data["GAME_ID"], team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
|
|
67
|
+
team_city: data["TEAM_CITY"], player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
68
|
+
start_position: data["START_POSITION"], comment: data["COMMENT"], min: data["MIN"]}
|
|
69
|
+
end
|
|
70
|
+
private_class_method :player_identity
|
|
71
|
+
|
|
72
|
+
# Extracts team identity attributes from data
|
|
73
|
+
# @api private
|
|
74
|
+
# @return [Hash]
|
|
75
|
+
def self.team_identity(data)
|
|
76
|
+
{game_id: data["GAME_ID"], team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
|
|
77
|
+
team_abbreviation: data["TEAM_ABBREVIATION"], team_city: data["TEAM_CITY"], min: data["MIN"]}
|
|
78
|
+
end
|
|
79
|
+
private_class_method :team_identity
|
|
80
|
+
|
|
81
|
+
# Extracts shooting usage statistics from data
|
|
82
|
+
# @api private
|
|
83
|
+
# @return [Hash]
|
|
84
|
+
def self.shooting_usage(data)
|
|
85
|
+
{usg_pct: data["USG_PCT"], pct_fgm: data["PCT_FGM"], pct_fga: data["PCT_FGA"],
|
|
86
|
+
pct_fg3m: data["PCT_FG3M"], pct_fg3a: data["PCT_FG3A"],
|
|
87
|
+
pct_ftm: data["PCT_FTM"], pct_fta: data["PCT_FTA"]}
|
|
88
|
+
end
|
|
89
|
+
private_class_method :shooting_usage
|
|
90
|
+
|
|
91
|
+
# Extracts other usage statistics from data
|
|
92
|
+
# @api private
|
|
93
|
+
# @return [Hash]
|
|
94
|
+
def self.other_usage(data)
|
|
95
|
+
{pct_oreb: data["PCT_OREB"], pct_dreb: data["PCT_DREB"], pct_reb: data["PCT_REB"],
|
|
96
|
+
pct_ast: data["PCT_AST"], pct_tov: data["PCT_TOV"], pct_stl: data["PCT_STL"],
|
|
97
|
+
pct_blk: data["PCT_BLK"], pct_blka: data["PCT_BLKA"],
|
|
98
|
+
pct_pf: data["PCT_PF"], pct_pfd: data["PCT_PFD"], pct_pts: data["PCT_PTS"]}
|
|
99
|
+
end
|
|
100
|
+
private_class_method :other_usage
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a player's usage box score statistics for a game
|
|
6
|
+
class BoxScoreUsagePlayerStat < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:game_id, :player_id)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] game_id
|
|
10
|
+
# Returns the game ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# stat.game_id #=> "0022400565"
|
|
14
|
+
# @return [String] the game ID
|
|
15
|
+
attribute :game_id, Shale::Type::String
|
|
16
|
+
|
|
17
|
+
# @!attribute [rw] team_id
|
|
18
|
+
# Returns the team ID
|
|
19
|
+
# @api public
|
|
20
|
+
# @example
|
|
21
|
+
# stat.team_id #=> 1610612744
|
|
22
|
+
# @return [Integer] the team ID
|
|
23
|
+
attribute :team_id, Shale::Type::Integer
|
|
24
|
+
|
|
25
|
+
# @!attribute [rw] team_abbreviation
|
|
26
|
+
# Returns the team abbreviation
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# stat.team_abbreviation #=> "GSW"
|
|
30
|
+
# @return [String] the team abbreviation
|
|
31
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
32
|
+
|
|
33
|
+
# @!attribute [rw] team_city
|
|
34
|
+
# Returns the team city
|
|
35
|
+
# @api public
|
|
36
|
+
# @example
|
|
37
|
+
# stat.team_city #=> "Golden State"
|
|
38
|
+
# @return [String] the team city
|
|
39
|
+
attribute :team_city, Shale::Type::String
|
|
40
|
+
|
|
41
|
+
# @!attribute [rw] player_id
|
|
42
|
+
# Returns the player ID
|
|
43
|
+
# @api public
|
|
44
|
+
# @example
|
|
45
|
+
# stat.player_id #=> 201939
|
|
46
|
+
# @return [Integer] the player ID
|
|
47
|
+
attribute :player_id, Shale::Type::Integer
|
|
48
|
+
|
|
49
|
+
# @!attribute [rw] player_name
|
|
50
|
+
# Returns the player name
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# stat.player_name #=> "Stephen Curry"
|
|
54
|
+
# @return [String] the player name
|
|
55
|
+
attribute :player_name, Shale::Type::String
|
|
56
|
+
|
|
57
|
+
# @!attribute [rw] start_position
|
|
58
|
+
# Returns the starting position
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.start_position #=> "G"
|
|
62
|
+
# @return [String] the starting position
|
|
63
|
+
attribute :start_position, Shale::Type::String
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] comment
|
|
66
|
+
# Returns any comment (e.g., "DNP - Rest")
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.comment #=> "DNP - Rest"
|
|
70
|
+
# @return [String] the comment
|
|
71
|
+
attribute :comment, Shale::Type::String
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] min
|
|
74
|
+
# Returns minutes played
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.min #=> "35:24"
|
|
78
|
+
# @return [String] the minutes played
|
|
79
|
+
attribute :min, Shale::Type::String
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] usg_pct
|
|
82
|
+
# Returns usage percentage
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.usg_pct #=> 0.285
|
|
86
|
+
# @return [Float] usage percentage
|
|
87
|
+
attribute :usg_pct, Shale::Type::Float
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] pct_fgm
|
|
90
|
+
# Returns percentage of team field goals made
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.pct_fgm #=> 0.24
|
|
94
|
+
# @return [Float] the percentage
|
|
95
|
+
attribute :pct_fgm, Shale::Type::Float
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] pct_fga
|
|
98
|
+
# Returns percentage of team field goals attempted
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.pct_fga #=> 0.27
|
|
102
|
+
# @return [Float] the percentage
|
|
103
|
+
attribute :pct_fga, Shale::Type::Float
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] pct_fg3m
|
|
106
|
+
# Returns percentage of team 3-pointers made
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.pct_fg3m #=> 0.35
|
|
110
|
+
# @return [Float] the percentage
|
|
111
|
+
attribute :pct_fg3m, Shale::Type::Float
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] pct_fg3a
|
|
114
|
+
# Returns percentage of team 3-pointers attempted
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.pct_fg3a #=> 0.38
|
|
118
|
+
# @return [Float] the percentage
|
|
119
|
+
attribute :pct_fg3a, Shale::Type::Float
|
|
120
|
+
|
|
121
|
+
# @!attribute [rw] pct_ftm
|
|
122
|
+
# Returns percentage of team free throws made
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.pct_ftm #=> 0.28
|
|
126
|
+
# @return [Float] the percentage
|
|
127
|
+
attribute :pct_ftm, Shale::Type::Float
|
|
128
|
+
|
|
129
|
+
# @!attribute [rw] pct_fta
|
|
130
|
+
# Returns percentage of team free throws attempted
|
|
131
|
+
# @api public
|
|
132
|
+
# @example
|
|
133
|
+
# stat.pct_fta #=> 0.30
|
|
134
|
+
# @return [Float] the percentage
|
|
135
|
+
attribute :pct_fta, Shale::Type::Float
|
|
136
|
+
|
|
137
|
+
# @!attribute [rw] pct_oreb
|
|
138
|
+
# Returns percentage of team offensive rebounds
|
|
139
|
+
# @api public
|
|
140
|
+
# @example
|
|
141
|
+
# stat.pct_oreb #=> 0.15
|
|
142
|
+
# @return [Float] the percentage
|
|
143
|
+
attribute :pct_oreb, Shale::Type::Float
|
|
144
|
+
|
|
145
|
+
# @!attribute [rw] pct_dreb
|
|
146
|
+
# Returns percentage of team defensive rebounds
|
|
147
|
+
# @api public
|
|
148
|
+
# @example
|
|
149
|
+
# stat.pct_dreb #=> 0.22
|
|
150
|
+
# @return [Float] the percentage
|
|
151
|
+
attribute :pct_dreb, Shale::Type::Float
|
|
152
|
+
|
|
153
|
+
# @!attribute [rw] pct_reb
|
|
154
|
+
# Returns percentage of team total rebounds
|
|
155
|
+
# @api public
|
|
156
|
+
# @example
|
|
157
|
+
# stat.pct_reb #=> 0.19
|
|
158
|
+
# @return [Float] the percentage
|
|
159
|
+
attribute :pct_reb, Shale::Type::Float
|
|
160
|
+
|
|
161
|
+
# @!attribute [rw] pct_ast
|
|
162
|
+
# Returns percentage of team assists
|
|
163
|
+
# @api public
|
|
164
|
+
# @example
|
|
165
|
+
# stat.pct_ast #=> 0.32
|
|
166
|
+
# @return [Float] the percentage
|
|
167
|
+
attribute :pct_ast, Shale::Type::Float
|
|
168
|
+
|
|
169
|
+
# @!attribute [rw] pct_tov
|
|
170
|
+
# Returns percentage of team turnovers
|
|
171
|
+
# @api public
|
|
172
|
+
# @example
|
|
173
|
+
# stat.pct_tov #=> 0.18
|
|
174
|
+
# @return [Float] the percentage
|
|
175
|
+
attribute :pct_tov, Shale::Type::Float
|
|
176
|
+
|
|
177
|
+
# @!attribute [rw] pct_stl
|
|
178
|
+
# Returns percentage of team steals
|
|
179
|
+
# @api public
|
|
180
|
+
# @example
|
|
181
|
+
# stat.pct_stl #=> 0.25
|
|
182
|
+
# @return [Float] the percentage
|
|
183
|
+
attribute :pct_stl, Shale::Type::Float
|
|
184
|
+
|
|
185
|
+
# @!attribute [rw] pct_blk
|
|
186
|
+
# Returns percentage of team blocks
|
|
187
|
+
# @api public
|
|
188
|
+
# @example
|
|
189
|
+
# stat.pct_blk #=> 0.20
|
|
190
|
+
# @return [Float] the percentage
|
|
191
|
+
attribute :pct_blk, Shale::Type::Float
|
|
192
|
+
|
|
193
|
+
# @!attribute [rw] pct_blka
|
|
194
|
+
# Returns percentage of team blocked attempts
|
|
195
|
+
# @api public
|
|
196
|
+
# @example
|
|
197
|
+
# stat.pct_blka #=> 0.12
|
|
198
|
+
# @return [Float] the percentage
|
|
199
|
+
attribute :pct_blka, Shale::Type::Float
|
|
200
|
+
|
|
201
|
+
# @!attribute [rw] pct_pf
|
|
202
|
+
# Returns percentage of team personal fouls
|
|
203
|
+
# @api public
|
|
204
|
+
# @example
|
|
205
|
+
# stat.pct_pf #=> 0.16
|
|
206
|
+
# @return [Float] the percentage
|
|
207
|
+
attribute :pct_pf, Shale::Type::Float
|
|
208
|
+
|
|
209
|
+
# @!attribute [rw] pct_pfd
|
|
210
|
+
# Returns percentage of team personal fouls drawn
|
|
211
|
+
# @api public
|
|
212
|
+
# @example
|
|
213
|
+
# stat.pct_pfd #=> 0.21
|
|
214
|
+
# @return [Float] the percentage
|
|
215
|
+
attribute :pct_pfd, Shale::Type::Float
|
|
216
|
+
|
|
217
|
+
# @!attribute [rw] pct_pts
|
|
218
|
+
# Returns percentage of team points
|
|
219
|
+
# @api public
|
|
220
|
+
# @example
|
|
221
|
+
# stat.pct_pts #=> 0.26
|
|
222
|
+
# @return [Float] the percentage
|
|
223
|
+
attribute :pct_pts, Shale::Type::Float
|
|
224
|
+
|
|
225
|
+
# Returns the player object
|
|
226
|
+
#
|
|
227
|
+
# @api public
|
|
228
|
+
# @example
|
|
229
|
+
# stat.player #=> #<NBA::Player>
|
|
230
|
+
# @return [Player, nil] the player object
|
|
231
|
+
def player
|
|
232
|
+
Players.find(player_id)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Returns the team object
|
|
236
|
+
#
|
|
237
|
+
# @api public
|
|
238
|
+
# @example
|
|
239
|
+
# stat.team #=> #<NBA::Team>
|
|
240
|
+
# @return [Team, nil] the team object
|
|
241
|
+
def team
|
|
242
|
+
Teams.find(team_id)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Returns whether the player started the game
|
|
246
|
+
#
|
|
247
|
+
# @api public
|
|
248
|
+
# @example
|
|
249
|
+
# stat.starter? #=> true
|
|
250
|
+
# @return [Boolean] true if the player started
|
|
251
|
+
def starter?
|
|
252
|
+
!start_position.nil? && !start_position.empty?
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Returns the game object for this box score
|
|
256
|
+
#
|
|
257
|
+
# @api public
|
|
258
|
+
# @example
|
|
259
|
+
# stat.game #=> #<NBA::Game>
|
|
260
|
+
# @return [Game, nil] the game object
|
|
261
|
+
def game
|
|
262
|
+
Games.find(game_id)
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|