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,224 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "game_log"
|
|
5
|
+
require_relative "team_game_log"
|
|
6
|
+
require_relative "utils"
|
|
7
|
+
|
|
8
|
+
module NBA
|
|
9
|
+
# Provides methods to retrieve league-wide game logs
|
|
10
|
+
module LeagueGameLog
|
|
11
|
+
# Season type constant for regular season
|
|
12
|
+
# @return [String] the season type
|
|
13
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
14
|
+
|
|
15
|
+
# Season type constant for playoffs
|
|
16
|
+
# @return [String] the season type
|
|
17
|
+
PLAYOFFS = "Playoffs".freeze
|
|
18
|
+
|
|
19
|
+
# Player or team constant for player logs
|
|
20
|
+
# @return [String] the player/team type
|
|
21
|
+
PLAYER = "P".freeze
|
|
22
|
+
|
|
23
|
+
# Player or team constant for team logs
|
|
24
|
+
# @return [String] the player/team type
|
|
25
|
+
TEAM = "T".freeze
|
|
26
|
+
|
|
27
|
+
# Result set name for league game log
|
|
28
|
+
# @return [String] the result set name
|
|
29
|
+
LEAGUE_GAME_LOG = "LeagueGameLog".freeze
|
|
30
|
+
|
|
31
|
+
# Retrieves league-wide player game logs
|
|
32
|
+
#
|
|
33
|
+
# @api public
|
|
34
|
+
# @example
|
|
35
|
+
# logs = NBA::LeagueGameLog.player_logs(season: 2024)
|
|
36
|
+
# logs.each { |l| puts "#{l.game_date}: #{l.matchup} - #{l.pts} pts" }
|
|
37
|
+
# @param season [Integer] the season year
|
|
38
|
+
# @param season_type [String] the season type (Regular Season or Playoffs)
|
|
39
|
+
# @param client [Client] the API client to use
|
|
40
|
+
# @return [Collection] a collection of game logs
|
|
41
|
+
def self.player_logs(season: Utils.current_season, season_type: REGULAR_SEASON, client: CLIENT)
|
|
42
|
+
path = build_path(season, season_type, PLAYER)
|
|
43
|
+
response = client.get(path)
|
|
44
|
+
parse_response(response)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Retrieves league-wide team game logs
|
|
48
|
+
#
|
|
49
|
+
# @api public
|
|
50
|
+
# @example
|
|
51
|
+
# logs = NBA::LeagueGameLog.team_logs(season: 2024)
|
|
52
|
+
# logs.each { |l| puts "#{l.game_date}: #{l.matchup} - #{l.pts} pts" }
|
|
53
|
+
# @param season [Integer] the season year
|
|
54
|
+
# @param season_type [String] the season type (Regular Season or Playoffs)
|
|
55
|
+
# @param client [Client] the API client to use
|
|
56
|
+
# @return [Collection] a collection of game logs
|
|
57
|
+
def self.team_logs(season: Utils.current_season, season_type: REGULAR_SEASON, client: CLIENT)
|
|
58
|
+
path = build_path(season, season_type, TEAM)
|
|
59
|
+
response = client.get(path)
|
|
60
|
+
parse_team_response(response)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Builds the API path
|
|
64
|
+
#
|
|
65
|
+
# @api private
|
|
66
|
+
# @param season [Integer] the season year
|
|
67
|
+
# @param season_type [String] the season type
|
|
68
|
+
# @param player_or_team [String] player or team type
|
|
69
|
+
# @return [String] the API path
|
|
70
|
+
def self.build_path(season, season_type, player_or_team)
|
|
71
|
+
season_str = Utils.format_season(season)
|
|
72
|
+
encoded_type = season_type
|
|
73
|
+
"leaguegamelog?LeagueID=00&Season=#{season_str}&SeasonType=#{encoded_type}&PlayerOrTeam=#{player_or_team}"
|
|
74
|
+
end
|
|
75
|
+
private_class_method :build_path
|
|
76
|
+
|
|
77
|
+
# Parses the API response for player logs
|
|
78
|
+
#
|
|
79
|
+
# @api private
|
|
80
|
+
# @param response [String] the JSON response body
|
|
81
|
+
# @return [Collection] a collection of game logs
|
|
82
|
+
def self.parse_response(response)
|
|
83
|
+
return Collection.new unless response
|
|
84
|
+
|
|
85
|
+
data = JSON.parse(response)
|
|
86
|
+
result_set = find_result_set(data)
|
|
87
|
+
return Collection.new unless result_set
|
|
88
|
+
|
|
89
|
+
headers = result_set["headers"]
|
|
90
|
+
rows = result_set["rowSet"]
|
|
91
|
+
return Collection.new unless headers && rows
|
|
92
|
+
|
|
93
|
+
logs = rows.map { |row| build_game_log(headers, row) }
|
|
94
|
+
Collection.new(logs)
|
|
95
|
+
end
|
|
96
|
+
private_class_method :parse_response
|
|
97
|
+
|
|
98
|
+
# Parses the API response for team logs
|
|
99
|
+
#
|
|
100
|
+
# @api private
|
|
101
|
+
# @param response [String] the JSON response body
|
|
102
|
+
# @return [Collection] a collection of team game log entries
|
|
103
|
+
def self.parse_team_response(response)
|
|
104
|
+
return Collection.new unless response
|
|
105
|
+
|
|
106
|
+
data = JSON.parse(response)
|
|
107
|
+
result_set = find_result_set(data)
|
|
108
|
+
return Collection.new unless result_set
|
|
109
|
+
|
|
110
|
+
headers = result_set["headers"]
|
|
111
|
+
rows = result_set["rowSet"]
|
|
112
|
+
return Collection.new unless headers && rows
|
|
113
|
+
|
|
114
|
+
logs = rows.map { |row| build_team_game_log(headers, row) }
|
|
115
|
+
Collection.new(logs)
|
|
116
|
+
end
|
|
117
|
+
private_class_method :parse_team_response
|
|
118
|
+
|
|
119
|
+
# Finds the result set
|
|
120
|
+
#
|
|
121
|
+
# @api private
|
|
122
|
+
# @param data [Hash] the parsed JSON data
|
|
123
|
+
# @return [Hash, nil] the result set
|
|
124
|
+
def self.find_result_set(data)
|
|
125
|
+
result_sets = data["resultSets"]
|
|
126
|
+
return unless result_sets
|
|
127
|
+
|
|
128
|
+
result_sets.find { |rs| rs["name"].eql?(LEAGUE_GAME_LOG) }
|
|
129
|
+
end
|
|
130
|
+
private_class_method :find_result_set
|
|
131
|
+
|
|
132
|
+
# Builds a game log from a row
|
|
133
|
+
#
|
|
134
|
+
# @api private
|
|
135
|
+
# @param headers [Array<String>] the column headers
|
|
136
|
+
# @param row [Array] the row data
|
|
137
|
+
# @return [GameLog] the game log object
|
|
138
|
+
def self.build_game_log(headers, row)
|
|
139
|
+
data = headers.zip(row).to_h
|
|
140
|
+
GameLog.new(**game_log_attributes(data))
|
|
141
|
+
end
|
|
142
|
+
private_class_method :build_game_log
|
|
143
|
+
|
|
144
|
+
# Builds a team game log from a row
|
|
145
|
+
#
|
|
146
|
+
# @api private
|
|
147
|
+
# @param headers [Array<String>] the column headers
|
|
148
|
+
# @param row [Array] the row data
|
|
149
|
+
# @return [TeamGameLogEntry] the team game log object
|
|
150
|
+
def self.build_team_game_log(headers, row)
|
|
151
|
+
data = headers.zip(row).to_h
|
|
152
|
+
TeamGameLogEntry.new(**team_game_log_attributes(data))
|
|
153
|
+
end
|
|
154
|
+
private_class_method :build_team_game_log
|
|
155
|
+
|
|
156
|
+
# Extracts game log attributes from row data
|
|
157
|
+
#
|
|
158
|
+
# @api private
|
|
159
|
+
# @param data [Hash] the game log row data
|
|
160
|
+
# @return [Hash] the game log attributes
|
|
161
|
+
def self.game_log_attributes(data)
|
|
162
|
+
game_info_attributes(data).merge(shooting_attributes(data), counting_attributes(data))
|
|
163
|
+
end
|
|
164
|
+
private_class_method :game_log_attributes
|
|
165
|
+
|
|
166
|
+
# Extracts team game log attributes from row data
|
|
167
|
+
#
|
|
168
|
+
# @api private
|
|
169
|
+
# @param data [Hash] the game log row data
|
|
170
|
+
# @return [Hash] the game log attributes
|
|
171
|
+
def self.team_game_log_attributes(data)
|
|
172
|
+
team_info_attributes(data).merge(shooting_attributes(data), counting_attributes(data))
|
|
173
|
+
end
|
|
174
|
+
private_class_method :team_game_log_attributes
|
|
175
|
+
|
|
176
|
+
# Extracts game info attributes
|
|
177
|
+
#
|
|
178
|
+
# @api private
|
|
179
|
+
# @param data [Hash] the game log data
|
|
180
|
+
# @return [Hash] the game info attributes
|
|
181
|
+
def self.game_info_attributes(data)
|
|
182
|
+
{season_id: data.fetch("SEASON_ID"), player_id: data.fetch("PLAYER_ID"),
|
|
183
|
+
game_id: data.fetch("GAME_ID"), game_date: data.fetch("GAME_DATE"),
|
|
184
|
+
matchup: data.fetch("MATCHUP"), wl: data.fetch("WL"), min: data.fetch("MIN")}
|
|
185
|
+
end
|
|
186
|
+
private_class_method :game_info_attributes
|
|
187
|
+
|
|
188
|
+
# Extracts team info attributes
|
|
189
|
+
#
|
|
190
|
+
# @api private
|
|
191
|
+
# @param data [Hash] the game log data
|
|
192
|
+
# @return [Hash] the team info attributes
|
|
193
|
+
def self.team_info_attributes(data)
|
|
194
|
+
{team_id: data.fetch("TEAM_ID"), game_id: data.fetch("GAME_ID"),
|
|
195
|
+
game_date: data.fetch("GAME_DATE"), matchup: data.fetch("MATCHUP"),
|
|
196
|
+
wl: data.fetch("WL"), min: data.fetch("MIN")}
|
|
197
|
+
end
|
|
198
|
+
private_class_method :team_info_attributes
|
|
199
|
+
|
|
200
|
+
# Extracts shooting attributes
|
|
201
|
+
#
|
|
202
|
+
# @api private
|
|
203
|
+
# @param data [Hash] the game log data
|
|
204
|
+
# @return [Hash] the shooting attributes
|
|
205
|
+
def self.shooting_attributes(data)
|
|
206
|
+
{fgm: data.fetch("FGM"), fga: data.fetch("FGA"), fg_pct: data.fetch("FG_PCT"),
|
|
207
|
+
fg3m: data.fetch("FG3M"), fg3a: data.fetch("FG3A"), fg3_pct: data.fetch("FG3_PCT"),
|
|
208
|
+
ftm: data.fetch("FTM"), fta: data.fetch("FTA"), ft_pct: data.fetch("FT_PCT")}
|
|
209
|
+
end
|
|
210
|
+
private_class_method :shooting_attributes
|
|
211
|
+
|
|
212
|
+
# Extracts counting stats attributes
|
|
213
|
+
#
|
|
214
|
+
# @api private
|
|
215
|
+
# @param data [Hash] the game log data
|
|
216
|
+
# @return [Hash] the counting stats attributes
|
|
217
|
+
def self.counting_attributes(data)
|
|
218
|
+
{oreb: data.fetch("OREB"), dreb: data.fetch("DREB"), reb: data.fetch("REB"),
|
|
219
|
+
ast: data.fetch("AST"), stl: data.fetch("STL"), blk: data.fetch("BLK"),
|
|
220
|
+
tov: data.fetch("TOV"), pf: data.fetch("PF"), pts: data.fetch("PTS"), plus_minus: data.fetch("PLUS_MINUS")}
|
|
221
|
+
end
|
|
222
|
+
private_class_method :counting_attributes
|
|
223
|
+
end
|
|
224
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "utils"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve league-wide player hustle statistics
|
|
8
|
+
module LeagueHustleStatsPlayer
|
|
9
|
+
# Result set name for hustle stats
|
|
10
|
+
# @return [String] the result set name
|
|
11
|
+
HUSTLE_STATS_PLAYER = "HustleStatsPlayer".freeze
|
|
12
|
+
|
|
13
|
+
# Season type constant for regular season
|
|
14
|
+
# @return [String] the season type
|
|
15
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
16
|
+
|
|
17
|
+
# Season type constant for playoffs
|
|
18
|
+
# @return [String] the season type
|
|
19
|
+
PLAYOFFS = "Playoffs".freeze
|
|
20
|
+
|
|
21
|
+
# Per mode constant for per game stats
|
|
22
|
+
# @return [String] the per mode
|
|
23
|
+
PER_GAME = "PerGame".freeze
|
|
24
|
+
|
|
25
|
+
# Per mode constant for totals
|
|
26
|
+
# @return [String] the per mode
|
|
27
|
+
TOTALS = "Totals".freeze
|
|
28
|
+
|
|
29
|
+
# Retrieves league-wide player hustle statistics
|
|
30
|
+
#
|
|
31
|
+
# @api public
|
|
32
|
+
# @example
|
|
33
|
+
# stats = NBA::LeagueHustleStatsPlayer.all(season: 2024)
|
|
34
|
+
# stats.each { |s| puts "#{s.player_name}: #{s.deflections} deflections" }
|
|
35
|
+
# @param season [Integer] the season year
|
|
36
|
+
# @param season_type [String] the season type
|
|
37
|
+
# @param per_mode [String] the per mode
|
|
38
|
+
# @param client [Client] the API client to use
|
|
39
|
+
# @return [Collection] a collection of player hustle stats
|
|
40
|
+
def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
|
|
41
|
+
path = build_path(season, season_type, per_mode)
|
|
42
|
+
response = client.get(path)
|
|
43
|
+
parse_response(response)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Builds the API path
|
|
47
|
+
#
|
|
48
|
+
# @api private
|
|
49
|
+
# @param season [Integer] the season year
|
|
50
|
+
# @param season_type [String] the season type
|
|
51
|
+
# @param per_mode [String] the per mode
|
|
52
|
+
# @return [String] the API path
|
|
53
|
+
def self.build_path(season, season_type, per_mode)
|
|
54
|
+
season_str = Utils.format_season(season)
|
|
55
|
+
"leaguehustlestatsplayer?LeagueID=00&Season=#{season_str}&SeasonType=#{season_type}&PerMode=#{per_mode}"
|
|
56
|
+
end
|
|
57
|
+
private_class_method :build_path
|
|
58
|
+
|
|
59
|
+
# Parses the API response
|
|
60
|
+
#
|
|
61
|
+
# @api private
|
|
62
|
+
# @param response [String] the JSON response body
|
|
63
|
+
# @return [Collection] a collection of player hustle stats
|
|
64
|
+
def self.parse_response(response)
|
|
65
|
+
return Collection.new unless response
|
|
66
|
+
|
|
67
|
+
data = JSON.parse(response)
|
|
68
|
+
result_set = find_result_set(data)
|
|
69
|
+
return Collection.new unless result_set
|
|
70
|
+
|
|
71
|
+
headers = result_set["headers"]
|
|
72
|
+
rows = result_set["rowSet"]
|
|
73
|
+
return Collection.new unless headers && rows
|
|
74
|
+
|
|
75
|
+
stats = rows.map { |row| build_player_stat(headers, row) }
|
|
76
|
+
Collection.new(stats)
|
|
77
|
+
end
|
|
78
|
+
private_class_method :parse_response
|
|
79
|
+
|
|
80
|
+
# Finds the result set
|
|
81
|
+
#
|
|
82
|
+
# @api private
|
|
83
|
+
# @param data [Hash] the parsed JSON data
|
|
84
|
+
# @return [Hash, nil] the result set
|
|
85
|
+
def self.find_result_set(data)
|
|
86
|
+
result_sets = data["resultSets"]
|
|
87
|
+
return unless result_sets
|
|
88
|
+
|
|
89
|
+
result_sets.find { |rs| rs["name"].eql?(HUSTLE_STATS_PLAYER) }
|
|
90
|
+
end
|
|
91
|
+
private_class_method :find_result_set
|
|
92
|
+
|
|
93
|
+
# Builds a player stat from a row
|
|
94
|
+
#
|
|
95
|
+
# @api private
|
|
96
|
+
# @param headers [Array<String>] the column headers
|
|
97
|
+
# @param row [Array] the row data
|
|
98
|
+
# @return [LeagueHustleStatsPlayerStat] the player stat object
|
|
99
|
+
def self.build_player_stat(headers, row)
|
|
100
|
+
data = headers.zip(row).to_h
|
|
101
|
+
LeagueHustleStatsPlayerStat.new(**player_stat_attributes(data))
|
|
102
|
+
end
|
|
103
|
+
private_class_method :build_player_stat
|
|
104
|
+
|
|
105
|
+
# Extracts player stat attributes from row data
|
|
106
|
+
#
|
|
107
|
+
# @api private
|
|
108
|
+
# @param data [Hash] the player stat row data
|
|
109
|
+
# @return [Hash] the player stat attributes
|
|
110
|
+
def self.player_stat_attributes(data)
|
|
111
|
+
identity_attributes(data).merge(hustle_attributes(data), box_out_attributes(data))
|
|
112
|
+
end
|
|
113
|
+
private_class_method :player_stat_attributes
|
|
114
|
+
|
|
115
|
+
# Extracts identity attributes
|
|
116
|
+
#
|
|
117
|
+
# @api private
|
|
118
|
+
# @param data [Hash] the player stat data
|
|
119
|
+
# @return [Hash] the identity attributes
|
|
120
|
+
def self.identity_attributes(data)
|
|
121
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
122
|
+
team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
|
|
123
|
+
age: data["AGE"], g: data["G"], min: data["MIN"]}
|
|
124
|
+
end
|
|
125
|
+
private_class_method :identity_attributes
|
|
126
|
+
|
|
127
|
+
# Extracts hustle attributes
|
|
128
|
+
#
|
|
129
|
+
# @api private
|
|
130
|
+
# @param data [Hash] the player stat data
|
|
131
|
+
# @return [Hash] the hustle attributes
|
|
132
|
+
def self.hustle_attributes(data)
|
|
133
|
+
{contested_shots: data["CONTESTED_SHOTS"],
|
|
134
|
+
contested_shots_2pt: data["CONTESTED_SHOTS_2PT"],
|
|
135
|
+
contested_shots_3pt: data["CONTESTED_SHOTS_3PT"],
|
|
136
|
+
deflections: data["DEFLECTIONS"], charges_drawn: data["CHARGES_DRAWN"],
|
|
137
|
+
screen_assists: data["SCREEN_ASSISTS"], screen_ast_pts: data["SCREEN_AST_PTS"],
|
|
138
|
+
off_loose_balls_recovered: data["OFF_LOOSE_BALLS_RECOVERED"],
|
|
139
|
+
def_loose_balls_recovered: data["DEF_LOOSE_BALLS_RECOVERED"],
|
|
140
|
+
loose_balls_recovered: data["LOOSE_BALLS_RECOVERED"],
|
|
141
|
+
pct_loose_balls_recovered_off: data["PCT_LOOSE_BALLS_RECOVERED_OFF"],
|
|
142
|
+
pct_loose_balls_recovered_def: data["PCT_LOOSE_BALLS_RECOVERED_DEF"]}
|
|
143
|
+
end
|
|
144
|
+
private_class_method :hustle_attributes
|
|
145
|
+
|
|
146
|
+
# Extracts box out attributes
|
|
147
|
+
#
|
|
148
|
+
# @api private
|
|
149
|
+
# @param data [Hash] the player stat data
|
|
150
|
+
# @return [Hash] the box out attributes
|
|
151
|
+
def self.box_out_attributes(data)
|
|
152
|
+
{off_boxouts: data["OFF_BOXOUTS"], def_boxouts: data["DEF_BOXOUTS"],
|
|
153
|
+
box_out_player_team_rebs: data["BOX_OUT_PLAYER_TEAM_REBS"],
|
|
154
|
+
box_out_player_rebs: data["BOX_OUT_PLAYER_REBS"], box_outs: data["BOX_OUTS"],
|
|
155
|
+
pct_box_outs_off: data["PCT_BOX_OUTS_OFF"], pct_box_outs_def: data["PCT_BOX_OUTS_DEF"],
|
|
156
|
+
pct_box_outs_team_reb: data["PCT_BOX_OUTS_TEAM_REB"],
|
|
157
|
+
pct_box_outs_reb: data["PCT_BOX_OUTS_REB"]}
|
|
158
|
+
end
|
|
159
|
+
private_class_method :box_out_attributes
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents league-wide hustle statistics for a player
|
|
6
|
+
class LeagueHustleStatsPlayerStat < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:player_id)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] player_id
|
|
10
|
+
# Returns the player ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# stat.player_id #=> 201939
|
|
14
|
+
# @return [Integer] the player ID
|
|
15
|
+
attribute :player_id, Shale::Type::Integer
|
|
16
|
+
|
|
17
|
+
# @!attribute [rw] player_name
|
|
18
|
+
# Returns the player name
|
|
19
|
+
# @api public
|
|
20
|
+
# @example
|
|
21
|
+
# stat.player_name #=> "Stephen Curry"
|
|
22
|
+
# @return [String] the player name
|
|
23
|
+
attribute :player_name, Shale::Type::String
|
|
24
|
+
|
|
25
|
+
# @!attribute [rw] team_id
|
|
26
|
+
# Returns the team ID
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# stat.team_id #=> 1610612744
|
|
30
|
+
# @return [Integer] the team ID
|
|
31
|
+
attribute :team_id, Shale::Type::Integer
|
|
32
|
+
|
|
33
|
+
# @!attribute [rw] team_abbreviation
|
|
34
|
+
# Returns the team abbreviation
|
|
35
|
+
# @api public
|
|
36
|
+
# @example
|
|
37
|
+
# stat.team_abbreviation #=> "GSW"
|
|
38
|
+
# @return [String] the team abbreviation
|
|
39
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
40
|
+
|
|
41
|
+
# @!attribute [rw] age
|
|
42
|
+
# Returns the player's age
|
|
43
|
+
# @api public
|
|
44
|
+
# @example
|
|
45
|
+
# stat.age #=> 36
|
|
46
|
+
# @return [Integer] the age
|
|
47
|
+
attribute :age, Shale::Type::Integer
|
|
48
|
+
|
|
49
|
+
# @!attribute [rw] g
|
|
50
|
+
# Returns games played
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# stat.g #=> 72
|
|
54
|
+
# @return [Integer] games played
|
|
55
|
+
attribute :g, Shale::Type::Integer
|
|
56
|
+
|
|
57
|
+
# @!attribute [rw] min
|
|
58
|
+
# Returns total minutes played
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.min #=> 2484.5
|
|
62
|
+
# @return [Float] total minutes
|
|
63
|
+
attribute :min, Shale::Type::Float
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] contested_shots
|
|
66
|
+
# Returns contested shots
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.contested_shots #=> 156
|
|
70
|
+
# @return [Integer] contested shots
|
|
71
|
+
attribute :contested_shots, Shale::Type::Integer
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] contested_shots_2pt
|
|
74
|
+
# Returns contested 2-point shots
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.contested_shots_2pt #=> 98
|
|
78
|
+
# @return [Integer] contested 2-point shots
|
|
79
|
+
attribute :contested_shots_2pt, Shale::Type::Integer
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] contested_shots_3pt
|
|
82
|
+
# Returns contested 3-point shots
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.contested_shots_3pt #=> 58
|
|
86
|
+
# @return [Integer] contested 3-point shots
|
|
87
|
+
attribute :contested_shots_3pt, Shale::Type::Integer
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] deflections
|
|
90
|
+
# Returns deflections
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.deflections #=> 85
|
|
94
|
+
# @return [Integer] deflections
|
|
95
|
+
attribute :deflections, Shale::Type::Integer
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] charges_drawn
|
|
98
|
+
# Returns charges drawn
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.charges_drawn #=> 5
|
|
102
|
+
# @return [Integer] charges drawn
|
|
103
|
+
attribute :charges_drawn, Shale::Type::Integer
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] screen_assists
|
|
106
|
+
# Returns screen assists
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.screen_assists #=> 142
|
|
110
|
+
# @return [Integer] screen assists
|
|
111
|
+
attribute :screen_assists, Shale::Type::Integer
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] screen_ast_pts
|
|
114
|
+
# Returns points from screen assists
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.screen_ast_pts #=> 284
|
|
118
|
+
# @return [Integer] screen assist points
|
|
119
|
+
attribute :screen_ast_pts, Shale::Type::Integer
|
|
120
|
+
|
|
121
|
+
# @!attribute [rw] off_loose_balls_recovered
|
|
122
|
+
# Returns offensive loose balls recovered
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.off_loose_balls_recovered #=> 25
|
|
126
|
+
# @return [Integer] offensive loose balls recovered
|
|
127
|
+
attribute :off_loose_balls_recovered, Shale::Type::Integer
|
|
128
|
+
|
|
129
|
+
# @!attribute [rw] def_loose_balls_recovered
|
|
130
|
+
# Returns defensive loose balls recovered
|
|
131
|
+
# @api public
|
|
132
|
+
# @example
|
|
133
|
+
# stat.def_loose_balls_recovered #=> 35
|
|
134
|
+
# @return [Integer] defensive loose balls recovered
|
|
135
|
+
attribute :def_loose_balls_recovered, Shale::Type::Integer
|
|
136
|
+
|
|
137
|
+
# @!attribute [rw] loose_balls_recovered
|
|
138
|
+
# Returns total loose balls recovered
|
|
139
|
+
# @api public
|
|
140
|
+
# @example
|
|
141
|
+
# stat.loose_balls_recovered #=> 60
|
|
142
|
+
# @return [Integer] loose balls recovered
|
|
143
|
+
attribute :loose_balls_recovered, Shale::Type::Integer
|
|
144
|
+
|
|
145
|
+
# @!attribute [rw] pct_loose_balls_recovered_off
|
|
146
|
+
# Returns percentage of offensive loose balls recovered
|
|
147
|
+
# @api public
|
|
148
|
+
# @example
|
|
149
|
+
# stat.pct_loose_balls_recovered_off #=> 0.417
|
|
150
|
+
# @return [Float] percentage of offensive loose balls recovered
|
|
151
|
+
attribute :pct_loose_balls_recovered_off, Shale::Type::Float
|
|
152
|
+
|
|
153
|
+
# @!attribute [rw] pct_loose_balls_recovered_def
|
|
154
|
+
# Returns percentage of defensive loose balls recovered
|
|
155
|
+
# @api public
|
|
156
|
+
# @example
|
|
157
|
+
# stat.pct_loose_balls_recovered_def #=> 0.583
|
|
158
|
+
# @return [Float] percentage of defensive loose balls recovered
|
|
159
|
+
attribute :pct_loose_balls_recovered_def, Shale::Type::Float
|
|
160
|
+
|
|
161
|
+
# @!attribute [rw] off_boxouts
|
|
162
|
+
# Returns offensive box outs
|
|
163
|
+
# @api public
|
|
164
|
+
# @example
|
|
165
|
+
# stat.off_boxouts #=> 12
|
|
166
|
+
# @return [Integer] offensive box outs
|
|
167
|
+
attribute :off_boxouts, Shale::Type::Integer
|
|
168
|
+
|
|
169
|
+
# @!attribute [rw] def_boxouts
|
|
170
|
+
# Returns defensive box outs
|
|
171
|
+
# @api public
|
|
172
|
+
# @example
|
|
173
|
+
# stat.def_boxouts #=> 45
|
|
174
|
+
# @return [Integer] defensive box outs
|
|
175
|
+
attribute :def_boxouts, Shale::Type::Integer
|
|
176
|
+
|
|
177
|
+
# @!attribute [rw] box_out_player_team_rebs
|
|
178
|
+
# Returns team rebounds from player box outs
|
|
179
|
+
# @api public
|
|
180
|
+
# @example
|
|
181
|
+
# stat.box_out_player_team_rebs #=> 38
|
|
182
|
+
# @return [Integer] team rebounds from box outs
|
|
183
|
+
attribute :box_out_player_team_rebs, Shale::Type::Integer
|
|
184
|
+
|
|
185
|
+
# @!attribute [rw] box_out_player_rebs
|
|
186
|
+
# Returns player rebounds from box outs
|
|
187
|
+
# @api public
|
|
188
|
+
# @example
|
|
189
|
+
# stat.box_out_player_rebs #=> 22
|
|
190
|
+
# @return [Integer] player rebounds from box outs
|
|
191
|
+
attribute :box_out_player_rebs, Shale::Type::Integer
|
|
192
|
+
|
|
193
|
+
# @!attribute [rw] box_outs
|
|
194
|
+
# Returns total box outs
|
|
195
|
+
# @api public
|
|
196
|
+
# @example
|
|
197
|
+
# stat.box_outs #=> 57
|
|
198
|
+
# @return [Integer] total box outs
|
|
199
|
+
attribute :box_outs, Shale::Type::Integer
|
|
200
|
+
|
|
201
|
+
# @!attribute [rw] pct_box_outs_off
|
|
202
|
+
# Returns percentage of offensive box outs
|
|
203
|
+
# @api public
|
|
204
|
+
# @example
|
|
205
|
+
# stat.pct_box_outs_off #=> 0.211
|
|
206
|
+
# @return [Float] percentage of offensive box outs
|
|
207
|
+
attribute :pct_box_outs_off, Shale::Type::Float
|
|
208
|
+
|
|
209
|
+
# @!attribute [rw] pct_box_outs_def
|
|
210
|
+
# Returns percentage of defensive box outs
|
|
211
|
+
# @api public
|
|
212
|
+
# @example
|
|
213
|
+
# stat.pct_box_outs_def #=> 0.789
|
|
214
|
+
# @return [Float] percentage of defensive box outs
|
|
215
|
+
attribute :pct_box_outs_def, Shale::Type::Float
|
|
216
|
+
|
|
217
|
+
# @!attribute [rw] pct_box_outs_team_reb
|
|
218
|
+
# Returns percentage of box outs resulting in team rebounds
|
|
219
|
+
# @api public
|
|
220
|
+
# @example
|
|
221
|
+
# stat.pct_box_outs_team_reb #=> 0.667
|
|
222
|
+
# @return [Float] percentage of box outs resulting in team rebounds
|
|
223
|
+
attribute :pct_box_outs_team_reb, Shale::Type::Float
|
|
224
|
+
|
|
225
|
+
# @!attribute [rw] pct_box_outs_reb
|
|
226
|
+
# Returns percentage of box outs resulting in player rebounds
|
|
227
|
+
# @api public
|
|
228
|
+
# @example
|
|
229
|
+
# stat.pct_box_outs_reb #=> 0.386
|
|
230
|
+
# @return [Float] percentage of box outs resulting in player rebounds
|
|
231
|
+
attribute :pct_box_outs_reb, Shale::Type::Float
|
|
232
|
+
|
|
233
|
+
# Returns the player object
|
|
234
|
+
#
|
|
235
|
+
# @api public
|
|
236
|
+
# @example
|
|
237
|
+
# stat.player #=> #<NBA::Player>
|
|
238
|
+
# @return [Player, nil] the player object
|
|
239
|
+
def player
|
|
240
|
+
Players.find(player_id)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Returns the team object
|
|
244
|
+
#
|
|
245
|
+
# @api public
|
|
246
|
+
# @example
|
|
247
|
+
# stat.team #=> #<NBA::Team>
|
|
248
|
+
# @return [Team, nil] the team object
|
|
249
|
+
def team
|
|
250
|
+
Teams.find(team_id)
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|