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,185 @@
|
|
|
1
|
+
require "shale"
|
|
2
|
+
require "equalizer"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a player's four factors box score statistics for a game
|
|
6
|
+
class BoxScoreFourFactorsPlayerStat < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:game_id, :player_id)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] game_id
|
|
10
|
+
# Returns the game ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# stat.game_id #=> "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_abbreviation
|
|
26
|
+
# Returns the team abbreviation
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# stat.team_abbreviation #=> "GSW"
|
|
30
|
+
# @return [String] the team abbreviation
|
|
31
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
32
|
+
|
|
33
|
+
# @!attribute [rw] team_city
|
|
34
|
+
# Returns the team city
|
|
35
|
+
# @api public
|
|
36
|
+
# @example
|
|
37
|
+
# stat.team_city #=> "Golden State"
|
|
38
|
+
# @return [String] the team city
|
|
39
|
+
attribute :team_city, Shale::Type::String
|
|
40
|
+
|
|
41
|
+
# @!attribute [rw] player_id
|
|
42
|
+
# Returns the player ID
|
|
43
|
+
# @api public
|
|
44
|
+
# @example
|
|
45
|
+
# stat.player_id #=> 201939
|
|
46
|
+
# @return [Integer] the player ID
|
|
47
|
+
attribute :player_id, Shale::Type::Integer
|
|
48
|
+
|
|
49
|
+
# @!attribute [rw] player_name
|
|
50
|
+
# Returns the player name
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# stat.player_name #=> "Stephen Curry"
|
|
54
|
+
# @return [String] the player name
|
|
55
|
+
attribute :player_name, Shale::Type::String
|
|
56
|
+
|
|
57
|
+
# @!attribute [rw] start_position
|
|
58
|
+
# Returns the starting position
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.start_position #=> "G"
|
|
62
|
+
# @return [String] the starting position
|
|
63
|
+
attribute :start_position, Shale::Type::String
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] comment
|
|
66
|
+
# Returns any comment (e.g., "DNP - Rest")
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.comment #=> "DNP - Rest"
|
|
70
|
+
# @return [String] the comment
|
|
71
|
+
attribute :comment, Shale::Type::String
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] min
|
|
74
|
+
# Returns minutes played
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.min #=> "32:45"
|
|
78
|
+
# @return [String] the minutes played
|
|
79
|
+
attribute :min, Shale::Type::String
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] efg_pct
|
|
82
|
+
# Returns effective field goal percentage
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.efg_pct #=> 0.625
|
|
86
|
+
# @return [Float] the effective field goal percentage
|
|
87
|
+
attribute :efg_pct, Shale::Type::Float
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] fta_rate
|
|
90
|
+
# Returns free throw attempt rate
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.fta_rate #=> 0.45
|
|
94
|
+
# @return [Float] the free throw attempt rate
|
|
95
|
+
attribute :fta_rate, Shale::Type::Float
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] tov_pct
|
|
98
|
+
# Returns turnover percentage
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.tov_pct #=> 12.3
|
|
102
|
+
# @return [Float] the turnover percentage
|
|
103
|
+
attribute :tov_pct, Shale::Type::Float
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] oreb_pct
|
|
106
|
+
# Returns offensive rebound percentage
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.oreb_pct #=> 3.2
|
|
110
|
+
# @return [Float] the offensive rebound percentage
|
|
111
|
+
attribute :oreb_pct, Shale::Type::Float
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] opp_efg_pct
|
|
114
|
+
# Returns opponent effective field goal percentage
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.opp_efg_pct #=> 0.485
|
|
118
|
+
# @return [Float] the opponent effective field goal percentage
|
|
119
|
+
attribute :opp_efg_pct, Shale::Type::Float
|
|
120
|
+
|
|
121
|
+
# @!attribute [rw] opp_fta_rate
|
|
122
|
+
# Returns opponent free throw attempt rate
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.opp_fta_rate #=> 0.28
|
|
126
|
+
# @return [Float] the opponent free throw attempt rate
|
|
127
|
+
attribute :opp_fta_rate, Shale::Type::Float
|
|
128
|
+
|
|
129
|
+
# @!attribute [rw] opp_tov_pct
|
|
130
|
+
# Returns opponent turnover percentage
|
|
131
|
+
# @api public
|
|
132
|
+
# @example
|
|
133
|
+
# stat.opp_tov_pct #=> 15.6
|
|
134
|
+
# @return [Float] the opponent turnover percentage
|
|
135
|
+
attribute :opp_tov_pct, Shale::Type::Float
|
|
136
|
+
|
|
137
|
+
# @!attribute [rw] opp_oreb_pct
|
|
138
|
+
# Returns opponent offensive rebound percentage
|
|
139
|
+
# @api public
|
|
140
|
+
# @example
|
|
141
|
+
# stat.opp_oreb_pct #=> 22.5
|
|
142
|
+
# @return [Float] the opponent offensive rebound percentage
|
|
143
|
+
attribute :opp_oreb_pct, Shale::Type::Float
|
|
144
|
+
|
|
145
|
+
# Returns the player object
|
|
146
|
+
#
|
|
147
|
+
# @api public
|
|
148
|
+
# @example
|
|
149
|
+
# stat.player #=> #<NBA::Player>
|
|
150
|
+
# @return [Player, nil] the player object
|
|
151
|
+
def player
|
|
152
|
+
Players.find(player_id)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Returns the team object
|
|
156
|
+
#
|
|
157
|
+
# @api public
|
|
158
|
+
# @example
|
|
159
|
+
# stat.team #=> #<NBA::Team>
|
|
160
|
+
# @return [Team, nil] the team object
|
|
161
|
+
def team
|
|
162
|
+
Teams.find(team_id)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Returns whether the player started the game
|
|
166
|
+
#
|
|
167
|
+
# @api public
|
|
168
|
+
# @example
|
|
169
|
+
# stat.starter? #=> true
|
|
170
|
+
# @return [Boolean] true if the player started
|
|
171
|
+
def starter?
|
|
172
|
+
!start_position.nil? && !start_position.empty?
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Returns the game object for this box score
|
|
176
|
+
#
|
|
177
|
+
# @api public
|
|
178
|
+
# @example
|
|
179
|
+
# stat.game #=> #<NBA::Game>
|
|
180
|
+
# @return [Game, nil] the game object
|
|
181
|
+
def game
|
|
182
|
+
Games.find(game_id)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
require "shale"
|
|
2
|
+
require "equalizer"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a team's four factors box score statistics for a game
|
|
6
|
+
class BoxScoreFourFactorsTeamStat < 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 #=> "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_name
|
|
26
|
+
# Returns the team name
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# stat.team_name #=> "Warriors"
|
|
30
|
+
# @return [String] the team name
|
|
31
|
+
attribute :team_name, Shale::Type::String
|
|
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] team_city
|
|
42
|
+
# Returns the team city
|
|
43
|
+
# @api public
|
|
44
|
+
# @example
|
|
45
|
+
# stat.team_city #=> "Golden State"
|
|
46
|
+
# @return [String] the team city
|
|
47
|
+
attribute :team_city, Shale::Type::String
|
|
48
|
+
|
|
49
|
+
# @!attribute [rw] min
|
|
50
|
+
# Returns total minutes played
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# stat.min #=> "240:00"
|
|
54
|
+
# @return [String] the minutes
|
|
55
|
+
attribute :min, Shale::Type::String
|
|
56
|
+
|
|
57
|
+
# @!attribute [rw] efg_pct
|
|
58
|
+
# Returns effective field goal percentage
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.efg_pct #=> 0.562
|
|
62
|
+
# @return [Float] the effective field goal percentage
|
|
63
|
+
attribute :efg_pct, Shale::Type::Float
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] fta_rate
|
|
66
|
+
# Returns free throw attempt rate
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.fta_rate #=> 0.284
|
|
70
|
+
# @return [Float] the free throw attempt rate
|
|
71
|
+
attribute :fta_rate, Shale::Type::Float
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] tov_pct
|
|
74
|
+
# Returns turnover percentage
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.tov_pct #=> 14.5
|
|
78
|
+
# @return [Float] the turnover percentage
|
|
79
|
+
attribute :tov_pct, Shale::Type::Float
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] oreb_pct
|
|
82
|
+
# Returns offensive rebound percentage
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.oreb_pct #=> 22.2
|
|
86
|
+
# @return [Float] the offensive rebound percentage
|
|
87
|
+
attribute :oreb_pct, Shale::Type::Float
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] opp_efg_pct
|
|
90
|
+
# Returns opponent effective field goal percentage
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.opp_efg_pct #=> 0.485
|
|
94
|
+
# @return [Float] the opponent effective field goal percentage
|
|
95
|
+
attribute :opp_efg_pct, Shale::Type::Float
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] opp_fta_rate
|
|
98
|
+
# Returns opponent free throw attempt rate
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.opp_fta_rate #=> 0.310
|
|
102
|
+
# @return [Float] the opponent free throw attempt rate
|
|
103
|
+
attribute :opp_fta_rate, Shale::Type::Float
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] opp_tov_pct
|
|
106
|
+
# Returns opponent turnover percentage
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.opp_tov_pct #=> 17.8
|
|
110
|
+
# @return [Float] the opponent turnover percentage
|
|
111
|
+
attribute :opp_tov_pct, Shale::Type::Float
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] opp_oreb_pct
|
|
114
|
+
# Returns opponent offensive rebound percentage
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.opp_oreb_pct #=> 20.5
|
|
118
|
+
# @return [Float] the opponent offensive rebound percentage
|
|
119
|
+
attribute :opp_oreb_pct, Shale::Type::Float
|
|
120
|
+
|
|
121
|
+
# Returns the team object
|
|
122
|
+
#
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.team #=> #<NBA::Team>
|
|
126
|
+
# @return [Team, nil] the team object
|
|
127
|
+
def team
|
|
128
|
+
Teams.find(team_id)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Returns the game object for this box score
|
|
132
|
+
#
|
|
133
|
+
# @api public
|
|
134
|
+
# @example
|
|
135
|
+
# stat.game #=> #<NBA::Game>
|
|
136
|
+
# @return [Game, nil] the game object
|
|
137
|
+
def game
|
|
138
|
+
Games.find(game_id)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "box_score_four_factors_player_stat"
|
|
5
|
+
require_relative "box_score_four_factors_team_stat"
|
|
6
|
+
require_relative "box_score_v3_helpers"
|
|
7
|
+
require_relative "utils"
|
|
8
|
+
|
|
9
|
+
module NBA
|
|
10
|
+
# Provides methods to retrieve four factors box score statistics using V3 API
|
|
11
|
+
module BoxScoreFourFactorsV3
|
|
12
|
+
# @return [String] JSON key for four factors box score data
|
|
13
|
+
BOX_SCORE_KEY = "boxScoreFourFactors".freeze
|
|
14
|
+
# @return [String] JSON key for player statistics
|
|
15
|
+
PLAYER_STATS = "PlayerStats".freeze
|
|
16
|
+
# @return [String] JSON key for team statistics
|
|
17
|
+
TEAM_STATS = "TeamStats".freeze
|
|
18
|
+
|
|
19
|
+
# Retrieves four factors player box score stats for a game
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# stats = NBA::BoxScoreFourFactorsV3.player_stats(game: "0022400001")
|
|
24
|
+
# stats.each { |stat| puts "#{stat.player_name}: #{stat.efg_pct}" }
|
|
25
|
+
# @param game [String, Integer] the game ID
|
|
26
|
+
# @param start_period [Integer] the starting period
|
|
27
|
+
# @param end_period [Integer] the ending period
|
|
28
|
+
# @param client [Client] the API client to use
|
|
29
|
+
# @return [Collection] a collection of player four factors stats
|
|
30
|
+
def self.player_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
|
|
31
|
+
game_id = Utils.extract_id(game)
|
|
32
|
+
response = client.get(build_path(game_id, start_period, end_period))
|
|
33
|
+
parse_player_response(response, game_id)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Retrieves four factors team box score stats for a game
|
|
37
|
+
#
|
|
38
|
+
# @api public
|
|
39
|
+
# @example
|
|
40
|
+
# stats = NBA::BoxScoreFourFactorsV3.team_stats(game: "0022400001")
|
|
41
|
+
# stats.each { |stat| puts "#{stat.team_abbreviation}: #{stat.efg_pct}" }
|
|
42
|
+
# @param game [String, Integer] the game ID
|
|
43
|
+
# @param start_period [Integer] the starting period
|
|
44
|
+
# @param end_period [Integer] the ending period
|
|
45
|
+
# @param client [Client] the API client to use
|
|
46
|
+
# @return [Collection] a collection of team four factors stats
|
|
47
|
+
def self.team_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
|
|
48
|
+
game_id = Utils.extract_id(game)
|
|
49
|
+
response = client.get(build_path(game_id, start_period, end_period))
|
|
50
|
+
parse_team_response(response, game_id)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Builds the API request path
|
|
54
|
+
# @api private
|
|
55
|
+
# @return [String] the request path
|
|
56
|
+
def self.build_path(game_id, start_period, end_period)
|
|
57
|
+
"boxscorefourfactorsv3?GameID=#{game_id}&StartPeriod=#{start_period}" \
|
|
58
|
+
"&EndPeriod=#{end_period}&StartRange=0&EndRange=0&RangeType=0"
|
|
59
|
+
end
|
|
60
|
+
private_class_method :build_path
|
|
61
|
+
|
|
62
|
+
# Parses the API response into player stat objects
|
|
63
|
+
# @api private
|
|
64
|
+
# @return [Collection] collection of player stats
|
|
65
|
+
def self.parse_player_response(response, game_id)
|
|
66
|
+
return Collection.new unless response
|
|
67
|
+
|
|
68
|
+
data = JSON.parse(response)
|
|
69
|
+
players = BoxScoreV3Helpers.extract_players(data, BOX_SCORE_KEY)
|
|
70
|
+
return Collection.new unless players
|
|
71
|
+
|
|
72
|
+
Collection.new(players.map { |p| build_player_stat(p, game_id) })
|
|
73
|
+
end
|
|
74
|
+
private_class_method :parse_player_response
|
|
75
|
+
|
|
76
|
+
# Parses the API response into team stat objects
|
|
77
|
+
# @api private
|
|
78
|
+
# @return [Collection] collection of team stats
|
|
79
|
+
def self.parse_team_response(response, game_id)
|
|
80
|
+
return Collection.new unless response
|
|
81
|
+
|
|
82
|
+
data = JSON.parse(response)
|
|
83
|
+
teams = BoxScoreV3Helpers.extract_teams(data, BOX_SCORE_KEY)
|
|
84
|
+
return Collection.new unless teams
|
|
85
|
+
|
|
86
|
+
Collection.new(teams.map { |t| build_team_stat(t, game_id) })
|
|
87
|
+
end
|
|
88
|
+
private_class_method :parse_team_response
|
|
89
|
+
|
|
90
|
+
# Builds a player stat object from raw data
|
|
91
|
+
# @api private
|
|
92
|
+
# @return [BoxScoreFourFactorsPlayerStat] the player stat object
|
|
93
|
+
def self.build_player_stat(player, game_id)
|
|
94
|
+
stats = player.fetch("statistics", {})
|
|
95
|
+
BoxScoreFourFactorsPlayerStat.new(
|
|
96
|
+
**BoxScoreV3Helpers.player_identity(player, game_id),
|
|
97
|
+
min: stats["minutes"],
|
|
98
|
+
**four_factors_stats(stats)
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
private_class_method :build_player_stat
|
|
102
|
+
|
|
103
|
+
# Builds a team stat object from raw data
|
|
104
|
+
# @api private
|
|
105
|
+
# @return [BoxScoreFourFactorsTeamStat] the team stat object
|
|
106
|
+
def self.build_team_stat(team, game_id)
|
|
107
|
+
stats = team.fetch("statistics", {})
|
|
108
|
+
BoxScoreFourFactorsTeamStat.new(
|
|
109
|
+
**BoxScoreV3Helpers.team_identity(team, game_id),
|
|
110
|
+
min: stats["minutes"],
|
|
111
|
+
**four_factors_stats(stats)
|
|
112
|
+
)
|
|
113
|
+
end
|
|
114
|
+
private_class_method :build_team_stat
|
|
115
|
+
|
|
116
|
+
# Extracts four factors statistics from raw data
|
|
117
|
+
# @api private
|
|
118
|
+
# @return [Hash] four factors statistics
|
|
119
|
+
def self.four_factors_stats(stats)
|
|
120
|
+
{
|
|
121
|
+
efg_pct: stats["effectiveFieldGoalPercentage"],
|
|
122
|
+
fta_rate: stats["freeThrowAttemptRate"],
|
|
123
|
+
tov_pct: stats["teamTurnoverPercentage"],
|
|
124
|
+
oreb_pct: stats["offensiveReboundPercentage"],
|
|
125
|
+
opp_efg_pct: stats["oppEffectiveFieldGoalPercentage"],
|
|
126
|
+
opp_fta_rate: stats["oppFreeThrowAttemptRate"],
|
|
127
|
+
opp_tov_pct: stats["oppTurnoverPercentage"],
|
|
128
|
+
opp_oreb_pct: stats["oppOffensiveReboundPercentage"]
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
private_class_method :four_factors_stats
|
|
132
|
+
end
|
|
133
|
+
end
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "box_score_hustle_player_stat"
|
|
5
|
+
require_relative "box_score_hustle_team_stat"
|
|
6
|
+
require_relative "utils"
|
|
7
|
+
|
|
8
|
+
module NBA
|
|
9
|
+
# Provides methods to retrieve hustle statistics for a game
|
|
10
|
+
module BoxScoreHustle
|
|
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 hustle statistics for players in a game
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# stats = NBA::BoxScoreHustle.player_stats(game: "0022400001")
|
|
24
|
+
# stats.each { |s| puts "#{s.player_name}: #{s.deflections} deflections" }
|
|
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 hustle stats
|
|
28
|
+
def self.player_stats(game:, client: CLIENT)
|
|
29
|
+
game_id = Utils.extract_id(game)
|
|
30
|
+
path = "boxscorehustlev2?GameID=#{game_id}"
|
|
31
|
+
response = client.get(path)
|
|
32
|
+
parse_player_response(response, game_id)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Retrieves hustle statistics for teams in a game
|
|
36
|
+
#
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# stats = NBA::BoxScoreHustle.team_stats(game: "0022400001")
|
|
40
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.deflections} deflections" }
|
|
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 hustle stats
|
|
44
|
+
def self.team_stats(game:, client: CLIENT)
|
|
45
|
+
game_id = Utils.extract_id(game)
|
|
46
|
+
path = "boxscorehustlev2?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
|
+
# @param headers [Array<String>] the headers
|
|
129
|
+
# @param row [Array] the row data
|
|
130
|
+
# @param game_id [String] the game ID
|
|
131
|
+
# @return [BoxScoreHustlePlayerStat] the player stat
|
|
132
|
+
def self.build_player_stat(headers, row, game_id)
|
|
133
|
+
data = headers.zip(row).to_h
|
|
134
|
+
BoxScoreHustlePlayerStat.new(**player_stat_attributes(data, game_id))
|
|
135
|
+
end
|
|
136
|
+
private_class_method :build_player_stat
|
|
137
|
+
|
|
138
|
+
# Builds a team stat
|
|
139
|
+
# @api private
|
|
140
|
+
# @param headers [Array<String>] the headers
|
|
141
|
+
# @param row [Array] the row data
|
|
142
|
+
# @param game_id [String] the game ID
|
|
143
|
+
# @return [BoxScoreHustleTeamStat] the team stat
|
|
144
|
+
def self.build_team_stat(headers, row, game_id)
|
|
145
|
+
data = headers.zip(row).to_h
|
|
146
|
+
BoxScoreHustleTeamStat.new(**team_stat_attributes(data, game_id))
|
|
147
|
+
end
|
|
148
|
+
private_class_method :build_team_stat
|
|
149
|
+
|
|
150
|
+
# Combines player stat attributes
|
|
151
|
+
# @api private
|
|
152
|
+
# @param data [Hash] the raw data
|
|
153
|
+
# @param game_id [String] the game ID
|
|
154
|
+
# @return [Hash] the combined attributes
|
|
155
|
+
def self.player_stat_attributes(data, game_id)
|
|
156
|
+
player_identity(data, game_id).merge(hustle_stats(data), loose_ball_stats(data), box_out_stats(data))
|
|
157
|
+
end
|
|
158
|
+
private_class_method :player_stat_attributes
|
|
159
|
+
|
|
160
|
+
# Combines team stat attributes
|
|
161
|
+
# @api private
|
|
162
|
+
# @param data [Hash] the raw data
|
|
163
|
+
# @param game_id [String] the game ID
|
|
164
|
+
# @return [Hash] the combined attributes
|
|
165
|
+
def self.team_stat_attributes(data, game_id)
|
|
166
|
+
team_identity(data, game_id).merge(hustle_stats(data), loose_ball_stats(data), box_out_stats(data))
|
|
167
|
+
end
|
|
168
|
+
private_class_method :team_stat_attributes
|
|
169
|
+
|
|
170
|
+
# Extracts player identity attributes
|
|
171
|
+
# @api private
|
|
172
|
+
# @param data [Hash] the raw data
|
|
173
|
+
# @param game_id [String] the game ID
|
|
174
|
+
# @return [Hash] identity attributes
|
|
175
|
+
def self.player_identity(data, game_id)
|
|
176
|
+
{game_id: game_id, team_id: data.fetch("TEAM_ID"), team_abbreviation: data.fetch("TEAM_ABBREVIATION"),
|
|
177
|
+
team_city: data.fetch("TEAM_CITY"), player_id: data.fetch("PLAYER_ID"), player_name: data.fetch("PLAYER_NAME"),
|
|
178
|
+
start_position: data.fetch("START_POSITION"), comment: data.fetch("COMMENT"), min: data.fetch("MIN"), pts: data.fetch("PTS")}
|
|
179
|
+
end
|
|
180
|
+
private_class_method :player_identity
|
|
181
|
+
|
|
182
|
+
# Extracts team identity attributes
|
|
183
|
+
# @api private
|
|
184
|
+
# @param data [Hash] the raw data
|
|
185
|
+
# @param game_id [String] the game ID
|
|
186
|
+
# @return [Hash] identity attributes
|
|
187
|
+
def self.team_identity(data, game_id)
|
|
188
|
+
{game_id: game_id, team_id: data.fetch("TEAM_ID"), team_name: data.fetch("TEAM_NAME"),
|
|
189
|
+
team_abbreviation: data.fetch("TEAM_ABBREVIATION"), team_city: data.fetch("TEAM_CITY"),
|
|
190
|
+
min: data.fetch("MIN"), pts: data.fetch("PTS")}
|
|
191
|
+
end
|
|
192
|
+
private_class_method :team_identity
|
|
193
|
+
|
|
194
|
+
# Extracts hustle stats
|
|
195
|
+
# @api private
|
|
196
|
+
# @param data [Hash] the raw data
|
|
197
|
+
# @return [Hash] hustle stats
|
|
198
|
+
def self.hustle_stats(data)
|
|
199
|
+
{contested_shots: data.fetch("CONTESTED_SHOTS"), contested_shots_2pt: data.fetch("CONTESTED_SHOTS_2PT"),
|
|
200
|
+
contested_shots_3pt: data.fetch("CONTESTED_SHOTS_3PT"), deflections: data.fetch("DEFLECTIONS"),
|
|
201
|
+
charges_drawn: data.fetch("CHARGES_DRAWN"), screen_assists: data.fetch("SCREEN_ASSISTS"),
|
|
202
|
+
screen_ast_pts: data.fetch("SCREEN_AST_PTS")}
|
|
203
|
+
end
|
|
204
|
+
private_class_method :hustle_stats
|
|
205
|
+
|
|
206
|
+
# Extracts loose ball stats
|
|
207
|
+
# @api private
|
|
208
|
+
# @param data [Hash] the raw data
|
|
209
|
+
# @return [Hash] loose ball stats
|
|
210
|
+
def self.loose_ball_stats(data)
|
|
211
|
+
{loose_balls_recovered: data.fetch("LOOSE_BALLS_RECOVERED"),
|
|
212
|
+
off_loose_balls_recovered: data.fetch("OFF_LOOSE_BALLS_RECOVERED"),
|
|
213
|
+
def_loose_balls_recovered: data.fetch("DEF_LOOSE_BALLS_RECOVERED")}
|
|
214
|
+
end
|
|
215
|
+
private_class_method :loose_ball_stats
|
|
216
|
+
|
|
217
|
+
# Extracts box out stats
|
|
218
|
+
# @api private
|
|
219
|
+
# @param data [Hash] the raw data
|
|
220
|
+
# @return [Hash] box out stats
|
|
221
|
+
def self.box_out_stats(data)
|
|
222
|
+
{box_outs: data.fetch("BOX_OUTS"), off_box_outs: data.fetch("OFF_BOX_OUTS"), def_box_outs: data.fetch("DEF_BOX_OUTS")}
|
|
223
|
+
end
|
|
224
|
+
private_class_method :box_out_stats
|
|
225
|
+
end
|
|
226
|
+
end
|