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,417 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a player matchup statistic from the BoxScoreMatchupsV3 endpoint
|
|
6
|
+
class BoxScoreMatchupStat < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:game_id, :person_id_off, :person_id_def)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] game_id
|
|
10
|
+
# Returns the game ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# stat.game_id #=> "0022400350"
|
|
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_city
|
|
26
|
+
# Returns the team city
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# stat.team_city #=> "Golden State"
|
|
30
|
+
# @return [String] the team city
|
|
31
|
+
attribute :team_city, Shale::Type::String
|
|
32
|
+
|
|
33
|
+
# @!attribute [rw] team_name
|
|
34
|
+
# Returns the team name
|
|
35
|
+
# @api public
|
|
36
|
+
# @example
|
|
37
|
+
# stat.team_name #=> "Warriors"
|
|
38
|
+
# @return [String] the team name
|
|
39
|
+
attribute :team_name, Shale::Type::String
|
|
40
|
+
|
|
41
|
+
# @!attribute [rw] team_tricode
|
|
42
|
+
# Returns the team tricode
|
|
43
|
+
# @api public
|
|
44
|
+
# @example
|
|
45
|
+
# stat.team_tricode #=> "GSW"
|
|
46
|
+
# @return [String] the team tricode
|
|
47
|
+
attribute :team_tricode, Shale::Type::String
|
|
48
|
+
|
|
49
|
+
# @!attribute [rw] team_slug
|
|
50
|
+
# Returns the team slug
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# stat.team_slug #=> "warriors"
|
|
54
|
+
# @return [String] the team slug
|
|
55
|
+
attribute :team_slug, Shale::Type::String
|
|
56
|
+
|
|
57
|
+
# @!attribute [rw] person_id_off
|
|
58
|
+
# Returns the offensive player ID
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.person_id_off #=> 201939
|
|
62
|
+
# @return [Integer] the offensive player ID
|
|
63
|
+
attribute :person_id_off, Shale::Type::Integer
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] first_name_off
|
|
66
|
+
# Returns the offensive player first name
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.first_name_off #=> "Stephen"
|
|
70
|
+
# @return [String] the offensive player first name
|
|
71
|
+
attribute :first_name_off, Shale::Type::String
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] family_name_off
|
|
74
|
+
# Returns the offensive player family name
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.family_name_off #=> "Curry"
|
|
78
|
+
# @return [String] the offensive player family name
|
|
79
|
+
attribute :family_name_off, Shale::Type::String
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] name_i_off
|
|
82
|
+
# Returns the offensive player name initial format
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.name_i_off #=> "S. Curry"
|
|
86
|
+
# @return [String] the offensive player name initial format
|
|
87
|
+
attribute :name_i_off, Shale::Type::String
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] player_slug_off
|
|
90
|
+
# Returns the offensive player slug
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.player_slug_off #=> "stephen-curry"
|
|
94
|
+
# @return [String] the offensive player slug
|
|
95
|
+
attribute :player_slug_off, Shale::Type::String
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] jersey_num_off
|
|
98
|
+
# Returns the offensive player jersey number
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.jersey_num_off #=> "30"
|
|
102
|
+
# @return [String] the offensive player jersey number
|
|
103
|
+
attribute :jersey_num_off, Shale::Type::String
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] person_id_def
|
|
106
|
+
# Returns the defensive player ID
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.person_id_def #=> 203507
|
|
110
|
+
# @return [Integer] the defensive player ID
|
|
111
|
+
attribute :person_id_def, Shale::Type::Integer
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] first_name_def
|
|
114
|
+
# Returns the defensive player first name
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.first_name_def #=> "Giannis"
|
|
118
|
+
# @return [String] the defensive player first name
|
|
119
|
+
attribute :first_name_def, Shale::Type::String
|
|
120
|
+
|
|
121
|
+
# @!attribute [rw] family_name_def
|
|
122
|
+
# Returns the defensive player family name
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.family_name_def #=> "Antetokounmpo"
|
|
126
|
+
# @return [String] the defensive player family name
|
|
127
|
+
attribute :family_name_def, Shale::Type::String
|
|
128
|
+
|
|
129
|
+
# @!attribute [rw] name_i_def
|
|
130
|
+
# Returns the defensive player name initial format
|
|
131
|
+
# @api public
|
|
132
|
+
# @example
|
|
133
|
+
# stat.name_i_def #=> "G. Antetokounmpo"
|
|
134
|
+
# @return [String] the defensive player name initial format
|
|
135
|
+
attribute :name_i_def, Shale::Type::String
|
|
136
|
+
|
|
137
|
+
# @!attribute [rw] player_slug_def
|
|
138
|
+
# Returns the defensive player slug
|
|
139
|
+
# @api public
|
|
140
|
+
# @example
|
|
141
|
+
# stat.player_slug_def #=> "giannis-antetokounmpo"
|
|
142
|
+
# @return [String] the defensive player slug
|
|
143
|
+
attribute :player_slug_def, Shale::Type::String
|
|
144
|
+
|
|
145
|
+
# @!attribute [rw] position_def
|
|
146
|
+
# Returns the defensive player position
|
|
147
|
+
# @api public
|
|
148
|
+
# @example
|
|
149
|
+
# stat.position_def #=> "F"
|
|
150
|
+
# @return [String] the defensive player position
|
|
151
|
+
attribute :position_def, Shale::Type::String
|
|
152
|
+
|
|
153
|
+
# @!attribute [rw] comment_def
|
|
154
|
+
# Returns the defensive player comment
|
|
155
|
+
# @api public
|
|
156
|
+
# @example
|
|
157
|
+
# stat.comment_def #=> ""
|
|
158
|
+
# @return [String] the defensive player comment
|
|
159
|
+
attribute :comment_def, Shale::Type::String
|
|
160
|
+
|
|
161
|
+
# @!attribute [rw] jersey_num_def
|
|
162
|
+
# Returns the defensive player jersey number
|
|
163
|
+
# @api public
|
|
164
|
+
# @example
|
|
165
|
+
# stat.jersey_num_def #=> "34"
|
|
166
|
+
# @return [String] the defensive player jersey number
|
|
167
|
+
attribute :jersey_num_def, Shale::Type::String
|
|
168
|
+
|
|
169
|
+
# @!attribute [rw] matchup_minutes
|
|
170
|
+
# Returns the matchup minutes in display format
|
|
171
|
+
# @api public
|
|
172
|
+
# @example
|
|
173
|
+
# stat.matchup_minutes #=> "05:30"
|
|
174
|
+
# @return [String] the matchup minutes
|
|
175
|
+
attribute :matchup_minutes, Shale::Type::String
|
|
176
|
+
|
|
177
|
+
# @!attribute [rw] matchup_minutes_sort
|
|
178
|
+
# Returns the matchup minutes as sortable float
|
|
179
|
+
# @api public
|
|
180
|
+
# @example
|
|
181
|
+
# stat.matchup_minutes_sort #=> 5.5
|
|
182
|
+
# @return [Float] the matchup minutes sortable
|
|
183
|
+
attribute :matchup_minutes_sort, Shale::Type::Float
|
|
184
|
+
|
|
185
|
+
# @!attribute [rw] partial_possessions
|
|
186
|
+
# Returns the partial possessions
|
|
187
|
+
# @api public
|
|
188
|
+
# @example
|
|
189
|
+
# stat.partial_possessions #=> 12.5
|
|
190
|
+
# @return [Float] the partial possessions
|
|
191
|
+
attribute :partial_possessions, Shale::Type::Float
|
|
192
|
+
|
|
193
|
+
# @!attribute [rw] percentage_defender_total_time
|
|
194
|
+
# Returns the percentage of defender's total time
|
|
195
|
+
# @api public
|
|
196
|
+
# @example
|
|
197
|
+
# stat.percentage_defender_total_time #=> 0.15
|
|
198
|
+
# @return [Float] the percentage of defender's total time
|
|
199
|
+
attribute :percentage_defender_total_time, Shale::Type::Float
|
|
200
|
+
|
|
201
|
+
# @!attribute [rw] percentage_offensive_total_time
|
|
202
|
+
# Returns the percentage of offensive player's total time
|
|
203
|
+
# @api public
|
|
204
|
+
# @example
|
|
205
|
+
# stat.percentage_offensive_total_time #=> 0.18
|
|
206
|
+
# @return [Float] the percentage of offensive player's total time
|
|
207
|
+
attribute :percentage_offensive_total_time, Shale::Type::Float
|
|
208
|
+
|
|
209
|
+
# @!attribute [rw] percentage_total_time_both_on
|
|
210
|
+
# Returns the percentage of time both players were on court
|
|
211
|
+
# @api public
|
|
212
|
+
# @example
|
|
213
|
+
# stat.percentage_total_time_both_on #=> 0.25
|
|
214
|
+
# @return [Float] the percentage of time both players were on
|
|
215
|
+
attribute :percentage_total_time_both_on, Shale::Type::Float
|
|
216
|
+
|
|
217
|
+
# @!attribute [rw] switches_on
|
|
218
|
+
# Returns the number of switches onto the matchup
|
|
219
|
+
# @api public
|
|
220
|
+
# @example
|
|
221
|
+
# stat.switches_on #=> 3
|
|
222
|
+
# @return [Integer] the switches on
|
|
223
|
+
attribute :switches_on, Shale::Type::Integer
|
|
224
|
+
|
|
225
|
+
# @!attribute [rw] player_points
|
|
226
|
+
# Returns the points scored by the offensive player
|
|
227
|
+
# @api public
|
|
228
|
+
# @example
|
|
229
|
+
# stat.player_points #=> 8
|
|
230
|
+
# @return [Integer] the player points
|
|
231
|
+
attribute :player_points, Shale::Type::Integer
|
|
232
|
+
|
|
233
|
+
# @!attribute [rw] team_points
|
|
234
|
+
# Returns the team points while in matchup
|
|
235
|
+
# @api public
|
|
236
|
+
# @example
|
|
237
|
+
# stat.team_points #=> 12
|
|
238
|
+
# @return [Integer] the team points
|
|
239
|
+
attribute :team_points, Shale::Type::Integer
|
|
240
|
+
|
|
241
|
+
# @!attribute [rw] matchup_assists
|
|
242
|
+
# Returns the assists in the matchup
|
|
243
|
+
# @api public
|
|
244
|
+
# @example
|
|
245
|
+
# stat.matchup_assists #=> 2
|
|
246
|
+
# @return [Integer] the matchup assists
|
|
247
|
+
attribute :matchup_assists, Shale::Type::Integer
|
|
248
|
+
|
|
249
|
+
# @!attribute [rw] matchup_potential_assists
|
|
250
|
+
# Returns the potential assists in the matchup
|
|
251
|
+
# @api public
|
|
252
|
+
# @example
|
|
253
|
+
# stat.matchup_potential_assists #=> 3
|
|
254
|
+
# @return [Integer] the matchup potential assists
|
|
255
|
+
attribute :matchup_potential_assists, Shale::Type::Integer
|
|
256
|
+
|
|
257
|
+
# @!attribute [rw] matchup_turnovers
|
|
258
|
+
# Returns the turnovers in the matchup
|
|
259
|
+
# @api public
|
|
260
|
+
# @example
|
|
261
|
+
# stat.matchup_turnovers #=> 1
|
|
262
|
+
# @return [Integer] the matchup turnovers
|
|
263
|
+
attribute :matchup_turnovers, Shale::Type::Integer
|
|
264
|
+
|
|
265
|
+
# @!attribute [rw] matchup_blocks
|
|
266
|
+
# Returns the blocks in the matchup
|
|
267
|
+
# @api public
|
|
268
|
+
# @example
|
|
269
|
+
# stat.matchup_blocks #=> 0
|
|
270
|
+
# @return [Integer] the matchup blocks
|
|
271
|
+
attribute :matchup_blocks, Shale::Type::Integer
|
|
272
|
+
|
|
273
|
+
# @!attribute [rw] matchup_field_goals_made
|
|
274
|
+
# Returns the field goals made in the matchup
|
|
275
|
+
# @api public
|
|
276
|
+
# @example
|
|
277
|
+
# stat.matchup_field_goals_made #=> 3
|
|
278
|
+
# @return [Integer] the matchup field goals made
|
|
279
|
+
attribute :matchup_field_goals_made, Shale::Type::Integer
|
|
280
|
+
|
|
281
|
+
# @!attribute [rw] matchup_field_goals_attempted
|
|
282
|
+
# Returns the field goals attempted in the matchup
|
|
283
|
+
# @api public
|
|
284
|
+
# @example
|
|
285
|
+
# stat.matchup_field_goals_attempted #=> 6
|
|
286
|
+
# @return [Integer] the matchup field goals attempted
|
|
287
|
+
attribute :matchup_field_goals_attempted, Shale::Type::Integer
|
|
288
|
+
|
|
289
|
+
# @!attribute [rw] matchup_field_goals_percentage
|
|
290
|
+
# Returns the field goal percentage in the matchup
|
|
291
|
+
# @api public
|
|
292
|
+
# @example
|
|
293
|
+
# stat.matchup_field_goals_percentage #=> 0.5
|
|
294
|
+
# @return [Float] the matchup field goal percentage
|
|
295
|
+
attribute :matchup_field_goals_percentage, Shale::Type::Float
|
|
296
|
+
|
|
297
|
+
# @!attribute [rw] matchup_three_pointers_made
|
|
298
|
+
# Returns the three pointers made in the matchup
|
|
299
|
+
# @api public
|
|
300
|
+
# @example
|
|
301
|
+
# stat.matchup_three_pointers_made #=> 1
|
|
302
|
+
# @return [Integer] the matchup three pointers made
|
|
303
|
+
attribute :matchup_three_pointers_made, Shale::Type::Integer
|
|
304
|
+
|
|
305
|
+
# @!attribute [rw] matchup_three_pointers_attempted
|
|
306
|
+
# Returns the three pointers attempted in the matchup
|
|
307
|
+
# @api public
|
|
308
|
+
# @example
|
|
309
|
+
# stat.matchup_three_pointers_attempted #=> 3
|
|
310
|
+
# @return [Integer] the matchup three pointers attempted
|
|
311
|
+
attribute :matchup_three_pointers_attempted, Shale::Type::Integer
|
|
312
|
+
|
|
313
|
+
# @!attribute [rw] matchup_three_pointers_percentage
|
|
314
|
+
# Returns the three point percentage in the matchup
|
|
315
|
+
# @api public
|
|
316
|
+
# @example
|
|
317
|
+
# stat.matchup_three_pointers_percentage #=> 0.333
|
|
318
|
+
# @return [Float] the matchup three point percentage
|
|
319
|
+
attribute :matchup_three_pointers_percentage, Shale::Type::Float
|
|
320
|
+
|
|
321
|
+
# @!attribute [rw] help_blocks
|
|
322
|
+
# Returns the help blocks in the matchup
|
|
323
|
+
# @api public
|
|
324
|
+
# @example
|
|
325
|
+
# stat.help_blocks #=> 1
|
|
326
|
+
# @return [Integer] the help blocks
|
|
327
|
+
attribute :help_blocks, Shale::Type::Integer
|
|
328
|
+
|
|
329
|
+
# @!attribute [rw] help_field_goals_made
|
|
330
|
+
# Returns the help field goals made in the matchup
|
|
331
|
+
# @api public
|
|
332
|
+
# @example
|
|
333
|
+
# stat.help_field_goals_made #=> 2
|
|
334
|
+
# @return [Integer] the help field goals made
|
|
335
|
+
attribute :help_field_goals_made, Shale::Type::Integer
|
|
336
|
+
|
|
337
|
+
# @!attribute [rw] help_field_goals_attempted
|
|
338
|
+
# Returns the help field goals attempted in the matchup
|
|
339
|
+
# @api public
|
|
340
|
+
# @example
|
|
341
|
+
# stat.help_field_goals_attempted #=> 4
|
|
342
|
+
# @return [Integer] the help field goals attempted
|
|
343
|
+
attribute :help_field_goals_attempted, Shale::Type::Integer
|
|
344
|
+
|
|
345
|
+
# @!attribute [rw] help_field_goals_percentage
|
|
346
|
+
# Returns the help field goal percentage in the matchup
|
|
347
|
+
# @api public
|
|
348
|
+
# @example
|
|
349
|
+
# stat.help_field_goals_percentage #=> 0.5
|
|
350
|
+
# @return [Float] the help field goal percentage
|
|
351
|
+
attribute :help_field_goals_percentage, Shale::Type::Float
|
|
352
|
+
|
|
353
|
+
# @!attribute [rw] matchup_free_throws_made
|
|
354
|
+
# Returns the free throws made in the matchup
|
|
355
|
+
# @api public
|
|
356
|
+
# @example
|
|
357
|
+
# stat.matchup_free_throws_made #=> 2
|
|
358
|
+
# @return [Integer] the matchup free throws made
|
|
359
|
+
attribute :matchup_free_throws_made, Shale::Type::Integer
|
|
360
|
+
|
|
361
|
+
# @!attribute [rw] matchup_free_throws_attempted
|
|
362
|
+
# Returns the free throws attempted in the matchup
|
|
363
|
+
# @api public
|
|
364
|
+
# @example
|
|
365
|
+
# stat.matchup_free_throws_attempted #=> 2
|
|
366
|
+
# @return [Integer] the matchup free throws attempted
|
|
367
|
+
attribute :matchup_free_throws_attempted, Shale::Type::Integer
|
|
368
|
+
|
|
369
|
+
# @!attribute [rw] shooting_fouls
|
|
370
|
+
# Returns the shooting fouls drawn in the matchup
|
|
371
|
+
# @api public
|
|
372
|
+
# @example
|
|
373
|
+
# stat.shooting_fouls #=> 1
|
|
374
|
+
# @return [Integer] the shooting fouls
|
|
375
|
+
attribute :shooting_fouls, Shale::Type::Integer
|
|
376
|
+
|
|
377
|
+
# Returns the offensive player object
|
|
378
|
+
#
|
|
379
|
+
# @api public
|
|
380
|
+
# @example
|
|
381
|
+
# stat.offensive_player #=> #<NBA::Player>
|
|
382
|
+
# @return [Player, nil] the offensive player object
|
|
383
|
+
def offensive_player
|
|
384
|
+
Players.find(person_id_off)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# Returns the defensive player object
|
|
388
|
+
#
|
|
389
|
+
# @api public
|
|
390
|
+
# @example
|
|
391
|
+
# stat.defensive_player #=> #<NBA::Player>
|
|
392
|
+
# @return [Player, nil] the defensive player object
|
|
393
|
+
def defensive_player
|
|
394
|
+
Players.find(person_id_def)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Returns the team object
|
|
398
|
+
#
|
|
399
|
+
# @api public
|
|
400
|
+
# @example
|
|
401
|
+
# stat.team #=> #<NBA::Team>
|
|
402
|
+
# @return [Team, nil] the team object
|
|
403
|
+
def team
|
|
404
|
+
Teams.find(team_id)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Returns the game object for this matchup
|
|
408
|
+
#
|
|
409
|
+
# @api public
|
|
410
|
+
# @example
|
|
411
|
+
# stat.game #=> #<NBA::Game>
|
|
412
|
+
# @return [Game, nil] the game object
|
|
413
|
+
def game
|
|
414
|
+
Games.find(game_id)
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "box_score_matchup_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve player matchup statistics using V3 API
|
|
9
|
+
module BoxScoreMatchupsV3
|
|
10
|
+
# @return [String] JSON key for matchup box score data
|
|
11
|
+
BOX_SCORE_KEY = "boxScoreMatchups".freeze
|
|
12
|
+
# @return [String] JSON key for player stats result set
|
|
13
|
+
PLAYER_STATS = "PlayerStats".freeze
|
|
14
|
+
|
|
15
|
+
# Retrieves player matchup stats for a game
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
# @example
|
|
19
|
+
# stats = NBA::BoxScoreMatchupsV3.find(game: "0022400001")
|
|
20
|
+
# stats.each { |stat| puts "#{stat.first_name_off} vs #{stat.first_name_def}" }
|
|
21
|
+
# @param game [String, Integer, Game] the game ID or Game object
|
|
22
|
+
# @param client [Client] the API client to use
|
|
23
|
+
# @return [Collection] a collection of player matchup stats
|
|
24
|
+
def self.find(game:, client: CLIENT)
|
|
25
|
+
game_id = Utils.extract_id(game)
|
|
26
|
+
response = client.get(build_path(game_id))
|
|
27
|
+
parse_response(response, game_id)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Builds the API request path
|
|
31
|
+
# @api private
|
|
32
|
+
# @return [String] the request path
|
|
33
|
+
def self.build_path(game_id)
|
|
34
|
+
"boxscorematchupsv3?GameID=#{game_id}"
|
|
35
|
+
end
|
|
36
|
+
private_class_method :build_path
|
|
37
|
+
|
|
38
|
+
# Parses the API response into matchup stat objects
|
|
39
|
+
# @api private
|
|
40
|
+
# @return [Collection] collection of matchup stats
|
|
41
|
+
def self.parse_response(response, game_id)
|
|
42
|
+
return Collection.new unless response
|
|
43
|
+
|
|
44
|
+
data = JSON.parse(response)
|
|
45
|
+
matchups = extract_matchups(data)
|
|
46
|
+
return Collection.new unless matchups
|
|
47
|
+
|
|
48
|
+
Collection.new(matchups.map { |m| build_matchup_stat(m, game_id) })
|
|
49
|
+
end
|
|
50
|
+
private_class_method :parse_response
|
|
51
|
+
|
|
52
|
+
# Extracts matchups from box score data
|
|
53
|
+
# @api private
|
|
54
|
+
# @param data [Hash] parsed JSON response
|
|
55
|
+
# @return [Array, nil] array of matchup data or nil if not found
|
|
56
|
+
def self.extract_matchups(data)
|
|
57
|
+
box_score = data[BOX_SCORE_KEY]
|
|
58
|
+
return unless box_score
|
|
59
|
+
|
|
60
|
+
home = box_score.dig("homeTeam", "players") || []
|
|
61
|
+
away = box_score.dig("awayTeam", "players") || []
|
|
62
|
+
home + away
|
|
63
|
+
end
|
|
64
|
+
private_class_method :extract_matchups
|
|
65
|
+
|
|
66
|
+
# Builds a matchup stat object from raw data
|
|
67
|
+
# @api private
|
|
68
|
+
# @return [BoxScoreMatchupStat] the matchup stat object
|
|
69
|
+
def self.build_matchup_stat(matchup, game_id)
|
|
70
|
+
BoxScoreMatchupStat.new(game_id: game_id, **team_identity(matchup), **player_identities(matchup),
|
|
71
|
+
**matchup_stats(matchup))
|
|
72
|
+
end
|
|
73
|
+
private_class_method :build_matchup_stat
|
|
74
|
+
|
|
75
|
+
# Extracts team identity attributes from matchup data
|
|
76
|
+
# @api private
|
|
77
|
+
# @return [Hash] team identity attributes
|
|
78
|
+
def self.team_identity(matchup)
|
|
79
|
+
{team_id: matchup["teamId"], team_city: matchup["teamCity"],
|
|
80
|
+
team_name: matchup["teamName"], team_tricode: matchup["teamTricode"],
|
|
81
|
+
team_slug: matchup["teamSlug"]}
|
|
82
|
+
end
|
|
83
|
+
private_class_method :team_identity
|
|
84
|
+
|
|
85
|
+
# Extracts both offensive and defensive player identity attributes
|
|
86
|
+
# @api private
|
|
87
|
+
# @return [Hash] player identity attributes
|
|
88
|
+
def self.player_identities(matchup)
|
|
89
|
+
offensive_player_identity(matchup).merge(defensive_player_identity(matchup))
|
|
90
|
+
end
|
|
91
|
+
private_class_method :player_identities
|
|
92
|
+
|
|
93
|
+
# Extracts offensive player identity attributes from matchup data
|
|
94
|
+
# @api private
|
|
95
|
+
# @return [Hash] offensive player identity attributes
|
|
96
|
+
def self.offensive_player_identity(matchup)
|
|
97
|
+
{person_id_off: matchup["personIdOff"], first_name_off: matchup["firstNameOff"],
|
|
98
|
+
family_name_off: matchup["familyNameOff"], name_i_off: matchup["nameIOff"],
|
|
99
|
+
player_slug_off: matchup["playerSlugOff"], jersey_num_off: matchup["jerseyNumOff"]}
|
|
100
|
+
end
|
|
101
|
+
private_class_method :offensive_player_identity
|
|
102
|
+
|
|
103
|
+
# Extracts defensive player identity attributes from matchup data
|
|
104
|
+
# @api private
|
|
105
|
+
# @return [Hash] defensive player identity attributes
|
|
106
|
+
def self.defensive_player_identity(matchup)
|
|
107
|
+
{person_id_def: matchup["personIdDef"], first_name_def: matchup["firstNameDef"],
|
|
108
|
+
family_name_def: matchup["familyNameDef"], name_i_def: matchup["nameIDef"],
|
|
109
|
+
player_slug_def: matchup["playerSlugDef"], position_def: matchup["positionDef"],
|
|
110
|
+
comment_def: matchup["commentDef"], jersey_num_def: matchup["jerseyNumDef"]}
|
|
111
|
+
end
|
|
112
|
+
private_class_method :defensive_player_identity
|
|
113
|
+
|
|
114
|
+
# Extracts all matchup statistics
|
|
115
|
+
# @api private
|
|
116
|
+
# @return [Hash] combined matchup statistics
|
|
117
|
+
def self.matchup_stats(matchup)
|
|
118
|
+
matchup_time_stats(matchup).merge(matchup_counting_stats(matchup), matchup_shooting_stats(matchup))
|
|
119
|
+
end
|
|
120
|
+
private_class_method :matchup_stats
|
|
121
|
+
|
|
122
|
+
# Extracts matchup time statistics from matchup data
|
|
123
|
+
# @api private
|
|
124
|
+
# @return [Hash] matchup time statistics
|
|
125
|
+
def self.matchup_time_stats(matchup)
|
|
126
|
+
{matchup_minutes: matchup["matchupMinutes"], matchup_minutes_sort: matchup["matchupMinutesSort"],
|
|
127
|
+
partial_possessions: matchup["partialPossessions"],
|
|
128
|
+
percentage_defender_total_time: matchup["percentageDefenderTotalTime"],
|
|
129
|
+
percentage_offensive_total_time: matchup["percentageOffensiveTotalTime"],
|
|
130
|
+
percentage_total_time_both_on: matchup["percentageTotalTimeBothOn"], switches_on: matchup["switchesOn"]}
|
|
131
|
+
end
|
|
132
|
+
private_class_method :matchup_time_stats
|
|
133
|
+
|
|
134
|
+
# Extracts matchup counting statistics from matchup data
|
|
135
|
+
# @api private
|
|
136
|
+
# @return [Hash] matchup counting statistics
|
|
137
|
+
def self.matchup_counting_stats(matchup)
|
|
138
|
+
{player_points: matchup["playerPoints"], team_points: matchup["teamPoints"],
|
|
139
|
+
matchup_assists: matchup["matchupAssists"], matchup_potential_assists: matchup["matchupPotentialAssists"],
|
|
140
|
+
matchup_turnovers: matchup["matchupTurnovers"], matchup_blocks: matchup["matchupBlocks"]}
|
|
141
|
+
end
|
|
142
|
+
private_class_method :matchup_counting_stats
|
|
143
|
+
|
|
144
|
+
# Extracts all matchup shooting statistics from matchup data
|
|
145
|
+
# @api private
|
|
146
|
+
# @return [Hash] matchup shooting statistics
|
|
147
|
+
def self.matchup_shooting_stats(matchup)
|
|
148
|
+
fg_stats(matchup).merge(three_pt_stats(matchup), help_and_ft_stats(matchup))
|
|
149
|
+
end
|
|
150
|
+
private_class_method :matchup_shooting_stats
|
|
151
|
+
|
|
152
|
+
# Extracts field goal statistics from matchup data
|
|
153
|
+
# @api private
|
|
154
|
+
# @return [Hash] field goal statistics
|
|
155
|
+
def self.fg_stats(data)
|
|
156
|
+
{matchup_field_goals_made: data["matchupFieldGoalsMade"],
|
|
157
|
+
matchup_field_goals_attempted: data["matchupFieldGoalsAttempted"],
|
|
158
|
+
matchup_field_goals_percentage: data["matchupFieldGoalsPercentage"]}
|
|
159
|
+
end
|
|
160
|
+
private_class_method :fg_stats
|
|
161
|
+
|
|
162
|
+
# Extracts three-pointer statistics from matchup data
|
|
163
|
+
# @api private
|
|
164
|
+
# @return [Hash] three-pointer statistics
|
|
165
|
+
def self.three_pt_stats(data)
|
|
166
|
+
{matchup_three_pointers_made: data["matchupThreePointersMade"],
|
|
167
|
+
matchup_three_pointers_attempted: data["matchupThreePointersAttempted"],
|
|
168
|
+
matchup_three_pointers_percentage: data["matchupThreePointersPercentage"]}
|
|
169
|
+
end
|
|
170
|
+
private_class_method :three_pt_stats
|
|
171
|
+
|
|
172
|
+
# Extracts help defense and free throw statistics from matchup data
|
|
173
|
+
# @api private
|
|
174
|
+
# @return [Hash] help defense and free throw statistics
|
|
175
|
+
def self.help_and_ft_stats(data)
|
|
176
|
+
{help_blocks: data["helpBlocks"], help_field_goals_made: data["helpFieldGoalsMade"],
|
|
177
|
+
help_field_goals_attempted: data["helpFieldGoalsAttempted"],
|
|
178
|
+
help_field_goals_percentage: data["helpFieldGoalsPercentage"],
|
|
179
|
+
matchup_free_throws_made: data["matchupFreeThrowsMade"],
|
|
180
|
+
matchup_free_throws_attempted: data["matchupFreeThrowsAttempted"], shooting_fouls: data["shootingFouls"]}
|
|
181
|
+
end
|
|
182
|
+
private_class_method :help_and_ft_stats
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require_relative "client"
|
|
2
|
+
require_relative "response_parser"
|
|
3
|
+
require_relative "box_score_misc_player_stat"
|
|
4
|
+
require_relative "box_score_misc_team_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve miscellaneous box score statistics
|
|
9
|
+
module BoxScoreMisc
|
|
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 miscellaneous box score stats for a game
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
# @example
|
|
22
|
+
# stats = NBA::BoxScoreMisc.player_stats(game: "0022400001")
|
|
23
|
+
# stats.each { |s| puts "#{s.player_name}: #{s.pts_paint} paint pts" }
|
|
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 miscellaneous box score stats
|
|
27
|
+
def self.player_stats(game:, client: CLIENT)
|
|
28
|
+
path = "boxscoremiscv2?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 miscellaneous box score stats for a game
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# stats = NBA::BoxScoreMisc.team_stats(game: "0022400001")
|
|
37
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.pts_fb} fast break 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 miscellaneous box score stats
|
|
41
|
+
def self.team_stats(game:, client: CLIENT)
|
|
42
|
+
path = "boxscoremiscv2?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 miscellaneous stat from API data
|
|
47
|
+
# @api private
|
|
48
|
+
# @return [BoxScoreMiscPlayerStat]
|
|
49
|
+
def self.build_player_stat(data)
|
|
50
|
+
BoxScoreMiscPlayerStat.new(**player_identity(data), **scoring_stats(data), **defense_stats(data))
|
|
51
|
+
end
|
|
52
|
+
private_class_method :build_player_stat
|
|
53
|
+
|
|
54
|
+
# Builds a team miscellaneous stat from API data
|
|
55
|
+
# @api private
|
|
56
|
+
# @return [BoxScoreMiscTeamStat]
|
|
57
|
+
def self.build_team_stat(data)
|
|
58
|
+
BoxScoreMiscTeamStat.new(**team_identity(data), **scoring_stats(data), **defense_stats(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 scoring statistics from data
|
|
82
|
+
# @api private
|
|
83
|
+
# @return [Hash]
|
|
84
|
+
def self.scoring_stats(data)
|
|
85
|
+
{pts_off_tov: data["PTS_OFF_TOV"], pts_2nd_chance: data["PTS_2ND_CHANCE"],
|
|
86
|
+
pts_fb: data["PTS_FB"], pts_paint: data["PTS_PAINT"],
|
|
87
|
+
opp_pts_off_tov: data["OPP_PTS_OFF_TOV"], opp_pts_2nd_chance: data["OPP_PTS_2ND_CHANCE"],
|
|
88
|
+
opp_pts_fb: data["OPP_PTS_FB"], opp_pts_paint: data["OPP_PTS_PAINT"]}
|
|
89
|
+
end
|
|
90
|
+
private_class_method :scoring_stats
|
|
91
|
+
|
|
92
|
+
# Extracts defense statistics from data
|
|
93
|
+
# @api private
|
|
94
|
+
# @return [Hash]
|
|
95
|
+
def self.defense_stats(data)
|
|
96
|
+
{blk: data["BLK"], blka: data["BLKA"], pf: data["PF"], pfd: data["PFD"]}
|
|
97
|
+
end
|
|
98
|
+
private_class_method :defense_stats
|
|
99
|
+
end
|
|
100
|
+
end
|