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,281 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents defensive statistics for a player in a game
|
|
6
|
+
class BoxScoreDefensivePlayerStat < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:game_id, :person_id)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] game_id
|
|
10
|
+
# Returns the game ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# stat.game_id #=> "0022400001"
|
|
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
|
|
58
|
+
# Returns the person ID
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.person_id #=> 201939
|
|
62
|
+
# @return [Integer] the person ID
|
|
63
|
+
attribute :person_id, Shale::Type::Integer
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] first_name
|
|
66
|
+
# Returns the player first name
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.first_name #=> "Stephen"
|
|
70
|
+
# @return [String] the first name
|
|
71
|
+
attribute :first_name, Shale::Type::String
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] family_name
|
|
74
|
+
# Returns the player family name
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.family_name #=> "Curry"
|
|
78
|
+
# @return [String] the family name
|
|
79
|
+
attribute :family_name, Shale::Type::String
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] name_i
|
|
82
|
+
# Returns the player name initial format
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.name_i #=> "S. Curry"
|
|
86
|
+
# @return [String] the name initial format
|
|
87
|
+
attribute :name_i, Shale::Type::String
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] player_slug
|
|
90
|
+
# Returns the player slug
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.player_slug #=> "stephen-curry"
|
|
94
|
+
# @return [String] the player slug
|
|
95
|
+
attribute :player_slug, Shale::Type::String
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] position
|
|
98
|
+
# Returns the player position
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.position #=> "G"
|
|
102
|
+
# @return [String] the position
|
|
103
|
+
attribute :position, Shale::Type::String
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] comment
|
|
106
|
+
# Returns any comment about the player
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.comment #=> "DNP - Rest"
|
|
110
|
+
# @return [String] the comment
|
|
111
|
+
attribute :comment, Shale::Type::String
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] jersey_num
|
|
114
|
+
# Returns the jersey number
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.jersey_num #=> "30"
|
|
118
|
+
# @return [String] the jersey number
|
|
119
|
+
attribute :jersey_num, Shale::Type::String
|
|
120
|
+
|
|
121
|
+
# @!attribute [rw] matchup_minutes
|
|
122
|
+
# Returns the matchup minutes
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.matchup_minutes #=> 24.5
|
|
126
|
+
# @return [Float] the matchup minutes
|
|
127
|
+
attribute :matchup_minutes, Shale::Type::Float
|
|
128
|
+
|
|
129
|
+
# @!attribute [rw] partial_possessions
|
|
130
|
+
# Returns partial possessions
|
|
131
|
+
# @api public
|
|
132
|
+
# @example
|
|
133
|
+
# stat.partial_possessions #=> 15.2
|
|
134
|
+
# @return [Float] partial possessions
|
|
135
|
+
attribute :partial_possessions, Shale::Type::Float
|
|
136
|
+
|
|
137
|
+
# @!attribute [rw] switches_on
|
|
138
|
+
# Returns number of switches on
|
|
139
|
+
# @api public
|
|
140
|
+
# @example
|
|
141
|
+
# stat.switches_on #=> 8
|
|
142
|
+
# @return [Integer] switches on
|
|
143
|
+
attribute :switches_on, Shale::Type::Integer
|
|
144
|
+
|
|
145
|
+
# @!attribute [rw] player_points
|
|
146
|
+
# Returns points allowed
|
|
147
|
+
# @api public
|
|
148
|
+
# @example
|
|
149
|
+
# stat.player_points #=> 12
|
|
150
|
+
# @return [Integer] player points allowed
|
|
151
|
+
attribute :player_points, Shale::Type::Integer
|
|
152
|
+
|
|
153
|
+
# @!attribute [rw] defensive_rebounds
|
|
154
|
+
# Returns defensive rebounds
|
|
155
|
+
# @api public
|
|
156
|
+
# @example
|
|
157
|
+
# stat.defensive_rebounds #=> 5
|
|
158
|
+
# @return [Integer] defensive rebounds
|
|
159
|
+
attribute :defensive_rebounds, Shale::Type::Integer
|
|
160
|
+
|
|
161
|
+
# @!attribute [rw] matchup_assists
|
|
162
|
+
# Returns matchup assists
|
|
163
|
+
# @api public
|
|
164
|
+
# @example
|
|
165
|
+
# stat.matchup_assists #=> 3
|
|
166
|
+
# @return [Integer] matchup assists
|
|
167
|
+
attribute :matchup_assists, Shale::Type::Integer
|
|
168
|
+
|
|
169
|
+
# @!attribute [rw] matchup_turnovers
|
|
170
|
+
# Returns matchup turnovers
|
|
171
|
+
# @api public
|
|
172
|
+
# @example
|
|
173
|
+
# stat.matchup_turnovers #=> 2
|
|
174
|
+
# @return [Integer] matchup turnovers
|
|
175
|
+
attribute :matchup_turnovers, Shale::Type::Integer
|
|
176
|
+
|
|
177
|
+
# @!attribute [rw] steals
|
|
178
|
+
# Returns steals
|
|
179
|
+
# @api public
|
|
180
|
+
# @example
|
|
181
|
+
# stat.steals #=> 2
|
|
182
|
+
# @return [Integer] steals
|
|
183
|
+
attribute :steals, Shale::Type::Integer
|
|
184
|
+
|
|
185
|
+
# @!attribute [rw] blocks
|
|
186
|
+
# Returns blocks
|
|
187
|
+
# @api public
|
|
188
|
+
# @example
|
|
189
|
+
# stat.blocks #=> 1
|
|
190
|
+
# @return [Integer] blocks
|
|
191
|
+
attribute :blocks, Shale::Type::Integer
|
|
192
|
+
|
|
193
|
+
# @!attribute [rw] matchup_field_goals_made
|
|
194
|
+
# Returns matchup field goals made
|
|
195
|
+
# @api public
|
|
196
|
+
# @example
|
|
197
|
+
# stat.matchup_field_goals_made #=> 5
|
|
198
|
+
# @return [Integer] matchup field goals made
|
|
199
|
+
attribute :matchup_field_goals_made, Shale::Type::Integer
|
|
200
|
+
|
|
201
|
+
# @!attribute [rw] matchup_field_goals_attempted
|
|
202
|
+
# Returns matchup field goals attempted
|
|
203
|
+
# @api public
|
|
204
|
+
# @example
|
|
205
|
+
# stat.matchup_field_goals_attempted #=> 12
|
|
206
|
+
# @return [Integer] matchup field goals attempted
|
|
207
|
+
attribute :matchup_field_goals_attempted, Shale::Type::Integer
|
|
208
|
+
|
|
209
|
+
# @!attribute [rw] matchup_field_goal_percentage
|
|
210
|
+
# Returns matchup field goal percentage
|
|
211
|
+
# @api public
|
|
212
|
+
# @example
|
|
213
|
+
# stat.matchup_field_goal_percentage #=> 0.417
|
|
214
|
+
# @return [Float] matchup field goal percentage
|
|
215
|
+
attribute :matchup_field_goal_percentage, Shale::Type::Float
|
|
216
|
+
|
|
217
|
+
# @!attribute [rw] matchup_three_pointers_made
|
|
218
|
+
# Returns matchup three pointers made
|
|
219
|
+
# @api public
|
|
220
|
+
# @example
|
|
221
|
+
# stat.matchup_three_pointers_made #=> 2
|
|
222
|
+
# @return [Integer] matchup three pointers made
|
|
223
|
+
attribute :matchup_three_pointers_made, Shale::Type::Integer
|
|
224
|
+
|
|
225
|
+
# @!attribute [rw] matchup_three_pointers_attempted
|
|
226
|
+
# Returns matchup three pointers attempted
|
|
227
|
+
# @api public
|
|
228
|
+
# @example
|
|
229
|
+
# stat.matchup_three_pointers_attempted #=> 5
|
|
230
|
+
# @return [Integer] matchup three pointers attempted
|
|
231
|
+
attribute :matchup_three_pointers_attempted, Shale::Type::Integer
|
|
232
|
+
|
|
233
|
+
# @!attribute [rw] matchup_three_pointer_percentage
|
|
234
|
+
# Returns matchup three pointer percentage
|
|
235
|
+
# @api public
|
|
236
|
+
# @example
|
|
237
|
+
# stat.matchup_three_pointer_percentage #=> 0.4
|
|
238
|
+
# @return [Float] matchup three pointer percentage
|
|
239
|
+
attribute :matchup_three_pointer_percentage, Shale::Type::Float
|
|
240
|
+
|
|
241
|
+
# Returns the player object
|
|
242
|
+
#
|
|
243
|
+
# @api public
|
|
244
|
+
# @example
|
|
245
|
+
# stat.player #=> #<NBA::Player>
|
|
246
|
+
# @return [Player, nil] the player object
|
|
247
|
+
def player
|
|
248
|
+
Players.find(person_id)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Returns the team object
|
|
252
|
+
#
|
|
253
|
+
# @api public
|
|
254
|
+
# @example
|
|
255
|
+
# stat.team #=> #<NBA::Team>
|
|
256
|
+
# @return [Team, nil] the team object
|
|
257
|
+
def team
|
|
258
|
+
Teams.find(team_id)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Returns the game object
|
|
262
|
+
#
|
|
263
|
+
# @api public
|
|
264
|
+
# @example
|
|
265
|
+
# stat.game #=> #<NBA::Game>
|
|
266
|
+
# @return [Game, nil] the game object
|
|
267
|
+
def game
|
|
268
|
+
Games.find(game_id)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Returns whether the player started
|
|
272
|
+
#
|
|
273
|
+
# @api public
|
|
274
|
+
# @example
|
|
275
|
+
# stat.starter? #=> true
|
|
276
|
+
# @return [Boolean] true if starter
|
|
277
|
+
def starter?
|
|
278
|
+
!position.nil? && !position.empty?
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents defensive statistics for a team in a game
|
|
6
|
+
class BoxScoreDefensiveTeamStat < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:game_id, :team_id)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] game_id
|
|
10
|
+
# Returns the game ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# stat.game_id #=> "0022400001"
|
|
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] minutes
|
|
58
|
+
# Returns minutes played
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.minutes #=> "240:00"
|
|
62
|
+
# @return [String] the minutes
|
|
63
|
+
attribute :minutes, Shale::Type::String
|
|
64
|
+
|
|
65
|
+
# Returns the team object
|
|
66
|
+
#
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.team #=> #<NBA::Team>
|
|
70
|
+
# @return [Team, nil] the team object
|
|
71
|
+
def team
|
|
72
|
+
Teams.find(team_id)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns the game object
|
|
76
|
+
#
|
|
77
|
+
# @api public
|
|
78
|
+
# @example
|
|
79
|
+
# stat.game #=> #<NBA::Game>
|
|
80
|
+
# @return [Game, nil] the game object
|
|
81
|
+
def game
|
|
82
|
+
Games.find(game_id)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "box_score_defensive_player_stat"
|
|
5
|
+
require_relative "box_score_defensive_team_stat"
|
|
6
|
+
require_relative "utils"
|
|
7
|
+
|
|
8
|
+
module NBA
|
|
9
|
+
# Provides methods to retrieve defensive statistics for a game
|
|
10
|
+
module BoxScoreDefensiveV2
|
|
11
|
+
# Result set name for player stats
|
|
12
|
+
# @return [String] the result set name
|
|
13
|
+
PLAYER_STATS = "PlayerStats".freeze
|
|
14
|
+
|
|
15
|
+
# Result set name for team stats
|
|
16
|
+
# @return [String] the result set name
|
|
17
|
+
TEAM_STATS = "TeamStats".freeze
|
|
18
|
+
|
|
19
|
+
# Retrieves defensive statistics for players in a game
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# stats = NBA::BoxScoreDefensiveV2.player_stats(game: "0022400001")
|
|
24
|
+
# stats.each { |s| puts "#{s.name_i}: #{s.steals} steals" }
|
|
25
|
+
# @param game [String, Game] the game ID or Game object
|
|
26
|
+
# @param client [Client] the API client to use
|
|
27
|
+
# @return [Collection] a collection of player defensive stats
|
|
28
|
+
def self.player_stats(game:, client: CLIENT)
|
|
29
|
+
game_id = Utils.extract_id(game)
|
|
30
|
+
path = "boxscoredefensivev2?GameID=#{game_id}"
|
|
31
|
+
response = client.get(path)
|
|
32
|
+
parse_player_response(response, game_id)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Retrieves defensive statistics for teams in a game
|
|
36
|
+
#
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# stats = NBA::BoxScoreDefensiveV2.team_stats(game: "0022400001")
|
|
40
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.minutes} minutes" }
|
|
41
|
+
# @param game [String, Game] the game ID or Game object
|
|
42
|
+
# @param client [Client] the API client to use
|
|
43
|
+
# @return [Collection] a collection of team defensive stats
|
|
44
|
+
def self.team_stats(game:, client: CLIENT)
|
|
45
|
+
game_id = Utils.extract_id(game)
|
|
46
|
+
path = "boxscoredefensivev2?GameID=#{game_id}"
|
|
47
|
+
response = client.get(path)
|
|
48
|
+
parse_team_response(response, game_id)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Parses player stats response
|
|
52
|
+
# @api private
|
|
53
|
+
# @param response [String, nil] the JSON response
|
|
54
|
+
# @param game_id [String] the game ID
|
|
55
|
+
# @return [Collection] collection of player stats
|
|
56
|
+
def self.parse_player_response(response, game_id)
|
|
57
|
+
return Collection.new unless response
|
|
58
|
+
|
|
59
|
+
data = JSON.parse(response)
|
|
60
|
+
result_set = find_result_set(data, PLAYER_STATS)
|
|
61
|
+
return Collection.new unless result_set
|
|
62
|
+
|
|
63
|
+
build_player_stats(result_set, game_id)
|
|
64
|
+
end
|
|
65
|
+
private_class_method :parse_player_response
|
|
66
|
+
|
|
67
|
+
# Parses team stats response
|
|
68
|
+
# @api private
|
|
69
|
+
# @param response [String, nil] the JSON response
|
|
70
|
+
# @param game_id [String] the game ID
|
|
71
|
+
# @return [Collection] collection of team stats
|
|
72
|
+
def self.parse_team_response(response, game_id)
|
|
73
|
+
return Collection.new unless response
|
|
74
|
+
|
|
75
|
+
data = JSON.parse(response)
|
|
76
|
+
result_set = find_result_set(data, TEAM_STATS)
|
|
77
|
+
return Collection.new unless result_set
|
|
78
|
+
|
|
79
|
+
build_team_stats(result_set, game_id)
|
|
80
|
+
end
|
|
81
|
+
private_class_method :parse_team_response
|
|
82
|
+
|
|
83
|
+
# Finds a result set by name
|
|
84
|
+
# @api private
|
|
85
|
+
# @param data [Hash] the parsed JSON
|
|
86
|
+
# @param name [String] the result set name
|
|
87
|
+
# @return [Hash, nil] the result set
|
|
88
|
+
def self.find_result_set(data, name)
|
|
89
|
+
result_sets = data["resultSets"]
|
|
90
|
+
return unless result_sets
|
|
91
|
+
|
|
92
|
+
result_sets.find { |rs| rs.fetch("name").eql?(name) }
|
|
93
|
+
end
|
|
94
|
+
private_class_method :find_result_set
|
|
95
|
+
|
|
96
|
+
# Builds player stats collection
|
|
97
|
+
# @api private
|
|
98
|
+
# @param result_set [Hash] the result set
|
|
99
|
+
# @param game_id [String] the game ID
|
|
100
|
+
# @return [Collection] collection of player stats
|
|
101
|
+
def self.build_player_stats(result_set, game_id)
|
|
102
|
+
headers = result_set["headers"]
|
|
103
|
+
rows = result_set["rowSet"]
|
|
104
|
+
return Collection.new unless headers && rows
|
|
105
|
+
|
|
106
|
+
stats = rows.map { |row| build_player_stat(headers, row, game_id) }
|
|
107
|
+
Collection.new(stats)
|
|
108
|
+
end
|
|
109
|
+
private_class_method :build_player_stats
|
|
110
|
+
|
|
111
|
+
# Builds team stats collection
|
|
112
|
+
# @api private
|
|
113
|
+
# @param result_set [Hash] the result set
|
|
114
|
+
# @param game_id [String] the game ID
|
|
115
|
+
# @return [Collection] collection of team stats
|
|
116
|
+
def self.build_team_stats(result_set, game_id)
|
|
117
|
+
headers = result_set["headers"]
|
|
118
|
+
rows = result_set["rowSet"]
|
|
119
|
+
return Collection.new unless headers && rows
|
|
120
|
+
|
|
121
|
+
stats = rows.map { |row| build_team_stat(headers, row, game_id) }
|
|
122
|
+
Collection.new(stats)
|
|
123
|
+
end
|
|
124
|
+
private_class_method :build_team_stats
|
|
125
|
+
|
|
126
|
+
# Builds a player stat
|
|
127
|
+
# @api private
|
|
128
|
+
# @return [BoxScoreDefensivePlayerStat] the player stat
|
|
129
|
+
def self.build_player_stat(headers, row, game_id)
|
|
130
|
+
data = headers.zip(row).to_h
|
|
131
|
+
BoxScoreDefensivePlayerStat.new(**player_identity(data, game_id), **defensive_stats(data), **shooting_stats(data))
|
|
132
|
+
end
|
|
133
|
+
private_class_method :build_player_stat
|
|
134
|
+
|
|
135
|
+
# Builds a team stat
|
|
136
|
+
# @api private
|
|
137
|
+
# @return [BoxScoreDefensiveTeamStat] the team stat
|
|
138
|
+
def self.build_team_stat(headers, row, game_id)
|
|
139
|
+
data = headers.zip(row).to_h
|
|
140
|
+
BoxScoreDefensiveTeamStat.new(**team_identity(data, game_id))
|
|
141
|
+
end
|
|
142
|
+
private_class_method :build_team_stat
|
|
143
|
+
|
|
144
|
+
# Extracts player identity attributes
|
|
145
|
+
# @api private
|
|
146
|
+
# @return [Hash] identity attributes
|
|
147
|
+
def self.player_identity(data, game_id)
|
|
148
|
+
{game_id: game_id, team_id: data.fetch("teamId"), team_city: data.fetch("teamCity"),
|
|
149
|
+
team_name: data.fetch("teamName"), team_tricode: data.fetch("teamTricode"), team_slug: data.fetch("teamSlug"),
|
|
150
|
+
person_id: data.fetch("personId"), first_name: data.fetch("firstName"), family_name: data.fetch("familyName"),
|
|
151
|
+
name_i: data.fetch("nameI"), player_slug: data.fetch("playerSlug"), position: data.fetch("position"),
|
|
152
|
+
comment: data.fetch("comment"), jersey_num: data.fetch("jerseyNum")}
|
|
153
|
+
end
|
|
154
|
+
private_class_method :player_identity
|
|
155
|
+
|
|
156
|
+
# Extracts team identity attributes
|
|
157
|
+
# @api private
|
|
158
|
+
# @return [Hash] identity attributes
|
|
159
|
+
def self.team_identity(data, game_id)
|
|
160
|
+
{game_id: game_id, team_id: data.fetch("teamId"), team_city: data.fetch("teamCity"),
|
|
161
|
+
team_name: data.fetch("teamName"), team_tricode: data.fetch("teamTricode"), team_slug: data.fetch("teamSlug"),
|
|
162
|
+
minutes: data.fetch("minutes")}
|
|
163
|
+
end
|
|
164
|
+
private_class_method :team_identity
|
|
165
|
+
|
|
166
|
+
# Extracts defensive stats
|
|
167
|
+
# @api private
|
|
168
|
+
# @return [Hash] defensive stats
|
|
169
|
+
def self.defensive_stats(data)
|
|
170
|
+
{matchup_minutes: data.fetch("matchupMinutes"), partial_possessions: data.fetch("partialPossessions"),
|
|
171
|
+
switches_on: data.fetch("switchesOn"), player_points: data.fetch("playerPoints"),
|
|
172
|
+
defensive_rebounds: data.fetch("defensiveRebounds"), matchup_assists: data.fetch("matchupAssists"),
|
|
173
|
+
matchup_turnovers: data.fetch("matchupTurnovers"), steals: data.fetch("steals"), blocks: data.fetch("blocks")}
|
|
174
|
+
end
|
|
175
|
+
private_class_method :defensive_stats
|
|
176
|
+
|
|
177
|
+
# Extracts shooting stats
|
|
178
|
+
# @api private
|
|
179
|
+
# @return [Hash] shooting stats
|
|
180
|
+
def self.shooting_stats(data)
|
|
181
|
+
{matchup_field_goals_made: data.fetch("matchupFieldGoalsMade"),
|
|
182
|
+
matchup_field_goals_attempted: data.fetch("matchupFieldGoalsAttempted"),
|
|
183
|
+
matchup_field_goal_percentage: data.fetch("matchupFieldGoalPercentage"),
|
|
184
|
+
matchup_three_pointers_made: data.fetch("matchupThreePointersMade"),
|
|
185
|
+
matchup_three_pointers_attempted: data.fetch("matchupThreePointersAttempted"),
|
|
186
|
+
matchup_three_pointer_percentage: data.fetch("matchupThreePointerPercentage")}
|
|
187
|
+
end
|
|
188
|
+
private_class_method :shooting_stats
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require_relative "client"
|
|
2
|
+
require_relative "response_parser"
|
|
3
|
+
require_relative "box_score_four_factors_player_stat"
|
|
4
|
+
require_relative "box_score_four_factors_team_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve four factors box score statistics
|
|
9
|
+
module BoxScoreFourFactors
|
|
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 four factors box score stats for a game
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
# @example
|
|
22
|
+
# stats = NBA::BoxScoreFourFactors.player_stats(game: "0022400001")
|
|
23
|
+
# stats.each { |s| puts "#{s.player_name}: #{s.efg_pct}% eFG" }
|
|
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 four factors box score stats
|
|
27
|
+
def self.player_stats(game:, client: CLIENT)
|
|
28
|
+
path = "boxscorefourfactorsv2?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 four factors box score stats for a game
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# stats = NBA::BoxScoreFourFactors.team_stats(game: "0022400001")
|
|
37
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.tov_pct}% TOV" }
|
|
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 four factors box score stats
|
|
41
|
+
def self.team_stats(game:, client: CLIENT)
|
|
42
|
+
path = "boxscorefourfactorsv2?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 four factors stat from API data
|
|
47
|
+
# @api private
|
|
48
|
+
# @return [BoxScoreFourFactorsPlayerStat]
|
|
49
|
+
def self.build_player_stat(data)
|
|
50
|
+
BoxScoreFourFactorsPlayerStat.new(**player_identity(data), **four_factors(data))
|
|
51
|
+
end
|
|
52
|
+
private_class_method :build_player_stat
|
|
53
|
+
|
|
54
|
+
# Builds a team four factors stat from API data
|
|
55
|
+
# @api private
|
|
56
|
+
# @return [BoxScoreFourFactorsTeamStat]
|
|
57
|
+
def self.build_team_stat(data)
|
|
58
|
+
BoxScoreFourFactorsTeamStat.new(**team_identity(data), **four_factors(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 four factors statistics from data
|
|
82
|
+
# @api private
|
|
83
|
+
# @return [Hash]
|
|
84
|
+
def self.four_factors(data)
|
|
85
|
+
{efg_pct: data["EFG_PCT"], fta_rate: data["FTA_RATE"], tov_pct: data["TM_TOV_PCT"],
|
|
86
|
+
oreb_pct: data["OREB_PCT"], opp_efg_pct: data["OPP_EFG_PCT"], opp_fta_rate: data["OPP_FTA_RATE"],
|
|
87
|
+
opp_tov_pct: data["OPP_TOV_PCT"], opp_oreb_pct: data["OPP_OREB_PCT"]}
|
|
88
|
+
end
|
|
89
|
+
private_class_method :four_factors
|
|
90
|
+
end
|
|
91
|
+
end
|