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,221 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a team's usage box score statistics for a game
|
|
6
|
+
class BoxScoreUsageTeamStat < 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 #=> "0022400565"
|
|
14
|
+
# @return [String] the game ID
|
|
15
|
+
attribute :game_id, Shale::Type::String
|
|
16
|
+
|
|
17
|
+
# @!attribute [rw] team_id
|
|
18
|
+
# Returns the team ID
|
|
19
|
+
# @api public
|
|
20
|
+
# @example
|
|
21
|
+
# stat.team_id #=> 1610612744
|
|
22
|
+
# @return [Integer] the team ID
|
|
23
|
+
attribute :team_id, Shale::Type::Integer
|
|
24
|
+
|
|
25
|
+
# @!attribute [rw] team_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] usg_pct
|
|
58
|
+
# Returns usage percentage
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# stat.usg_pct #=> 1.0
|
|
62
|
+
# @return [Float] usage percentage
|
|
63
|
+
attribute :usg_pct, Shale::Type::Float
|
|
64
|
+
|
|
65
|
+
# @!attribute [rw] pct_fgm
|
|
66
|
+
# Returns percentage of field goals made
|
|
67
|
+
# @api public
|
|
68
|
+
# @example
|
|
69
|
+
# stat.pct_fgm #=> 1.0
|
|
70
|
+
# @return [Float] the percentage
|
|
71
|
+
attribute :pct_fgm, Shale::Type::Float
|
|
72
|
+
|
|
73
|
+
# @!attribute [rw] pct_fga
|
|
74
|
+
# Returns percentage of field goals attempted
|
|
75
|
+
# @api public
|
|
76
|
+
# @example
|
|
77
|
+
# stat.pct_fga #=> 1.0
|
|
78
|
+
# @return [Float] the percentage
|
|
79
|
+
attribute :pct_fga, Shale::Type::Float
|
|
80
|
+
|
|
81
|
+
# @!attribute [rw] pct_fg3m
|
|
82
|
+
# Returns percentage of 3-pointers made
|
|
83
|
+
# @api public
|
|
84
|
+
# @example
|
|
85
|
+
# stat.pct_fg3m #=> 1.0
|
|
86
|
+
# @return [Float] the percentage
|
|
87
|
+
attribute :pct_fg3m, Shale::Type::Float
|
|
88
|
+
|
|
89
|
+
# @!attribute [rw] pct_fg3a
|
|
90
|
+
# Returns percentage of 3-pointers attempted
|
|
91
|
+
# @api public
|
|
92
|
+
# @example
|
|
93
|
+
# stat.pct_fg3a #=> 1.0
|
|
94
|
+
# @return [Float] the percentage
|
|
95
|
+
attribute :pct_fg3a, Shale::Type::Float
|
|
96
|
+
|
|
97
|
+
# @!attribute [rw] pct_ftm
|
|
98
|
+
# Returns percentage of free throws made
|
|
99
|
+
# @api public
|
|
100
|
+
# @example
|
|
101
|
+
# stat.pct_ftm #=> 1.0
|
|
102
|
+
# @return [Float] the percentage
|
|
103
|
+
attribute :pct_ftm, Shale::Type::Float
|
|
104
|
+
|
|
105
|
+
# @!attribute [rw] pct_fta
|
|
106
|
+
# Returns percentage of free throws attempted
|
|
107
|
+
# @api public
|
|
108
|
+
# @example
|
|
109
|
+
# stat.pct_fta #=> 1.0
|
|
110
|
+
# @return [Float] the percentage
|
|
111
|
+
attribute :pct_fta, Shale::Type::Float
|
|
112
|
+
|
|
113
|
+
# @!attribute [rw] pct_oreb
|
|
114
|
+
# Returns percentage of offensive rebounds
|
|
115
|
+
# @api public
|
|
116
|
+
# @example
|
|
117
|
+
# stat.pct_oreb #=> 1.0
|
|
118
|
+
# @return [Float] the percentage
|
|
119
|
+
attribute :pct_oreb, Shale::Type::Float
|
|
120
|
+
|
|
121
|
+
# @!attribute [rw] pct_dreb
|
|
122
|
+
# Returns percentage of defensive rebounds
|
|
123
|
+
# @api public
|
|
124
|
+
# @example
|
|
125
|
+
# stat.pct_dreb #=> 1.0
|
|
126
|
+
# @return [Float] the percentage
|
|
127
|
+
attribute :pct_dreb, Shale::Type::Float
|
|
128
|
+
|
|
129
|
+
# @!attribute [rw] pct_reb
|
|
130
|
+
# Returns percentage of total rebounds
|
|
131
|
+
# @api public
|
|
132
|
+
# @example
|
|
133
|
+
# stat.pct_reb #=> 1.0
|
|
134
|
+
# @return [Float] the percentage
|
|
135
|
+
attribute :pct_reb, Shale::Type::Float
|
|
136
|
+
|
|
137
|
+
# @!attribute [rw] pct_ast
|
|
138
|
+
# Returns percentage of assists
|
|
139
|
+
# @api public
|
|
140
|
+
# @example
|
|
141
|
+
# stat.pct_ast #=> 1.0
|
|
142
|
+
# @return [Float] the percentage
|
|
143
|
+
attribute :pct_ast, Shale::Type::Float
|
|
144
|
+
|
|
145
|
+
# @!attribute [rw] pct_tov
|
|
146
|
+
# Returns percentage of turnovers
|
|
147
|
+
# @api public
|
|
148
|
+
# @example
|
|
149
|
+
# stat.pct_tov #=> 1.0
|
|
150
|
+
# @return [Float] the percentage
|
|
151
|
+
attribute :pct_tov, Shale::Type::Float
|
|
152
|
+
|
|
153
|
+
# @!attribute [rw] pct_stl
|
|
154
|
+
# Returns percentage of steals
|
|
155
|
+
# @api public
|
|
156
|
+
# @example
|
|
157
|
+
# stat.pct_stl #=> 1.0
|
|
158
|
+
# @return [Float] the percentage
|
|
159
|
+
attribute :pct_stl, Shale::Type::Float
|
|
160
|
+
|
|
161
|
+
# @!attribute [rw] pct_blk
|
|
162
|
+
# Returns percentage of blocks
|
|
163
|
+
# @api public
|
|
164
|
+
# @example
|
|
165
|
+
# stat.pct_blk #=> 1.0
|
|
166
|
+
# @return [Float] the percentage
|
|
167
|
+
attribute :pct_blk, Shale::Type::Float
|
|
168
|
+
|
|
169
|
+
# @!attribute [rw] pct_blka
|
|
170
|
+
# Returns percentage of blocked attempts
|
|
171
|
+
# @api public
|
|
172
|
+
# @example
|
|
173
|
+
# stat.pct_blka #=> 1.0
|
|
174
|
+
# @return [Float] the percentage
|
|
175
|
+
attribute :pct_blka, Shale::Type::Float
|
|
176
|
+
|
|
177
|
+
# @!attribute [rw] pct_pf
|
|
178
|
+
# Returns percentage of personal fouls
|
|
179
|
+
# @api public
|
|
180
|
+
# @example
|
|
181
|
+
# stat.pct_pf #=> 1.0
|
|
182
|
+
# @return [Float] the percentage
|
|
183
|
+
attribute :pct_pf, Shale::Type::Float
|
|
184
|
+
|
|
185
|
+
# @!attribute [rw] pct_pfd
|
|
186
|
+
# Returns percentage of personal fouls drawn
|
|
187
|
+
# @api public
|
|
188
|
+
# @example
|
|
189
|
+
# stat.pct_pfd #=> 1.0
|
|
190
|
+
# @return [Float] the percentage
|
|
191
|
+
attribute :pct_pfd, Shale::Type::Float
|
|
192
|
+
|
|
193
|
+
# @!attribute [rw] pct_pts
|
|
194
|
+
# Returns percentage of points
|
|
195
|
+
# @api public
|
|
196
|
+
# @example
|
|
197
|
+
# stat.pct_pts #=> 1.0
|
|
198
|
+
# @return [Float] the percentage
|
|
199
|
+
attribute :pct_pts, Shale::Type::Float
|
|
200
|
+
|
|
201
|
+
# Returns the team object
|
|
202
|
+
#
|
|
203
|
+
# @api public
|
|
204
|
+
# @example
|
|
205
|
+
# stat.team #=> #<NBA::Team>
|
|
206
|
+
# @return [Team, nil] the team object
|
|
207
|
+
def team
|
|
208
|
+
Teams.find(team_id)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Returns the game object for this box score
|
|
212
|
+
#
|
|
213
|
+
# @api public
|
|
214
|
+
# @example
|
|
215
|
+
# stat.game #=> #<NBA::Game>
|
|
216
|
+
# @return [Game, nil] the game object
|
|
217
|
+
def game
|
|
218
|
+
Games.find(game_id)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "box_score_usage_player_stat"
|
|
5
|
+
require_relative "box_score_usage_team_stat"
|
|
6
|
+
require_relative "box_score_v3_helpers"
|
|
7
|
+
require_relative "utils"
|
|
8
|
+
|
|
9
|
+
module NBA
|
|
10
|
+
# Provides methods to retrieve usage box score statistics using V3 API
|
|
11
|
+
module BoxScoreUsageV3
|
|
12
|
+
# @return [String] JSON key for usage box score data
|
|
13
|
+
BOX_SCORE_KEY = "boxScoreUsage".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 usage player box score stats for a game
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# stats = NBA::BoxScoreUsageV3.player_stats(game: "0022400001")
|
|
24
|
+
# stats.each { |stat| puts "#{stat.player_name}: #{stat.usg_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 usage 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 usage team box score stats for a game
|
|
37
|
+
#
|
|
38
|
+
# @api public
|
|
39
|
+
# @example
|
|
40
|
+
# stats = NBA::BoxScoreUsageV3.team_stats(game: "0022400001")
|
|
41
|
+
# stats.each { |stat| puts "#{stat.team_abbreviation}: #{stat.usg_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 usage 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
|
+
"boxscoreusagev3?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 [BoxScoreUsagePlayerStat] the player stat object
|
|
93
|
+
def self.build_player_stat(player, game_id)
|
|
94
|
+
stats = player.fetch("statistics", {})
|
|
95
|
+
BoxScoreUsagePlayerStat.new(
|
|
96
|
+
**BoxScoreV3Helpers.player_identity(player, game_id),
|
|
97
|
+
min: stats["minutes"],
|
|
98
|
+
**usage_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 [BoxScoreUsageTeamStat] the team stat object
|
|
106
|
+
def self.build_team_stat(team, game_id)
|
|
107
|
+
stats = team.fetch("statistics", {})
|
|
108
|
+
BoxScoreUsageTeamStat.new(
|
|
109
|
+
**BoxScoreV3Helpers.team_identity(team, game_id),
|
|
110
|
+
min: stats["minutes"],
|
|
111
|
+
**usage_stats(stats)
|
|
112
|
+
)
|
|
113
|
+
end
|
|
114
|
+
private_class_method :build_team_stat
|
|
115
|
+
|
|
116
|
+
# Extracts usage statistics from raw data
|
|
117
|
+
# @api private
|
|
118
|
+
# @return [Hash] usage statistics
|
|
119
|
+
def self.usage_stats(stats)
|
|
120
|
+
core_usage(stats).merge(shooting_usage(stats), other_usage(stats))
|
|
121
|
+
end
|
|
122
|
+
private_class_method :usage_stats
|
|
123
|
+
|
|
124
|
+
# Extracts core usage statistics from raw data
|
|
125
|
+
# @api private
|
|
126
|
+
# @return [Hash] core usage statistics
|
|
127
|
+
def self.core_usage(stats)
|
|
128
|
+
{
|
|
129
|
+
usg_pct: stats["usagePercentage"],
|
|
130
|
+
pct_fgm: stats["percentageFieldGoalsMade"],
|
|
131
|
+
pct_fga: stats["percentageFieldGoalsAttempted"],
|
|
132
|
+
pct_fg3m: stats["percentageThreePointersMade"],
|
|
133
|
+
pct_fg3a: stats["percentageThreePointersAttempted"],
|
|
134
|
+
pct_ftm: stats["percentageFreeThrowsMade"],
|
|
135
|
+
pct_fta: stats["percentageFreeThrowsAttempted"]
|
|
136
|
+
}
|
|
137
|
+
end
|
|
138
|
+
private_class_method :core_usage
|
|
139
|
+
|
|
140
|
+
# Extracts shooting usage statistics from raw data
|
|
141
|
+
# @api private
|
|
142
|
+
# @return [Hash] shooting usage statistics
|
|
143
|
+
def self.shooting_usage(stats)
|
|
144
|
+
{
|
|
145
|
+
pct_oreb: stats["percentageReboundsOffensive"],
|
|
146
|
+
pct_dreb: stats["percentageReboundsDefensive"],
|
|
147
|
+
pct_reb: stats["percentageReboundsTotal"],
|
|
148
|
+
pct_ast: stats["percentageAssists"],
|
|
149
|
+
pct_tov: stats["percentageTurnovers"]
|
|
150
|
+
}
|
|
151
|
+
end
|
|
152
|
+
private_class_method :shooting_usage
|
|
153
|
+
|
|
154
|
+
# Extracts other usage statistics from raw data
|
|
155
|
+
# @api private
|
|
156
|
+
# @return [Hash] other usage statistics
|
|
157
|
+
def self.other_usage(stats)
|
|
158
|
+
{
|
|
159
|
+
pct_stl: stats["percentageSteals"],
|
|
160
|
+
pct_blk: stats["percentageBlocks"],
|
|
161
|
+
pct_blka: stats["percentageBlocksAgainst"],
|
|
162
|
+
pct_pf: stats["percentageFoulsPersonal"],
|
|
163
|
+
pct_pfd: stats["percentageFoulsDrawn"],
|
|
164
|
+
pct_pts: stats["percentagePoints"]
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
private_class_method :other_usage
|
|
168
|
+
end
|
|
169
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
module NBA
|
|
2
|
+
# Shared helper methods for V3 box score modules
|
|
3
|
+
# @api private
|
|
4
|
+
module BoxScoreV3Helpers
|
|
5
|
+
# Extracts player identity attributes from V3 API format
|
|
6
|
+
# @api private
|
|
7
|
+
# @return [Hash] player identity attributes
|
|
8
|
+
def self.player_identity(player, game_id)
|
|
9
|
+
{game_id: game_id, team_id: player["teamId"],
|
|
10
|
+
team_abbreviation: player["teamTricode"],
|
|
11
|
+
team_city: player["teamCity"],
|
|
12
|
+
player_id: player["personId"],
|
|
13
|
+
player_name: build_player_name(player),
|
|
14
|
+
start_position: player["position"],
|
|
15
|
+
comment: player["comment"]}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Extracts team identity attributes from V3 API format
|
|
19
|
+
# @api private
|
|
20
|
+
# @return [Hash] team identity attributes
|
|
21
|
+
def self.team_identity(team, game_id)
|
|
22
|
+
{game_id: game_id, team_id: team["teamId"],
|
|
23
|
+
team_name: team["teamName"],
|
|
24
|
+
team_abbreviation: team["teamTricode"],
|
|
25
|
+
team_city: team["teamCity"]}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Builds player full name from first and family name
|
|
29
|
+
# @api private
|
|
30
|
+
# @param player [Hash] player data from V3 API
|
|
31
|
+
# @return [String] player full name
|
|
32
|
+
def self.build_player_name(player)
|
|
33
|
+
first = player["firstName"]
|
|
34
|
+
last = player["familyName"]
|
|
35
|
+
"#{first} #{last}".strip
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Extracts all players from box score data
|
|
39
|
+
# @api private
|
|
40
|
+
# @param data [Hash] parsed JSON response
|
|
41
|
+
# @param box_score_key [String] key to access box score data
|
|
42
|
+
# @return [Array, nil] array of player data or nil if not found
|
|
43
|
+
def self.extract_players(data, box_score_key)
|
|
44
|
+
box_score = data[box_score_key]
|
|
45
|
+
return unless box_score
|
|
46
|
+
|
|
47
|
+
home = box_score.dig("homeTeam", "players") || []
|
|
48
|
+
away = box_score.dig("awayTeam", "players") || []
|
|
49
|
+
home + away
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Extracts both teams from box score data
|
|
53
|
+
# @api private
|
|
54
|
+
# @param data [Hash] parsed JSON response
|
|
55
|
+
# @param box_score_key [String] key to access box score data
|
|
56
|
+
# @return [Array, nil] array of team data or nil if not found
|
|
57
|
+
def self.extract_teams(data, box_score_key)
|
|
58
|
+
box_score = data[box_score_key]
|
|
59
|
+
return unless box_score
|
|
60
|
+
|
|
61
|
+
[box_score["homeTeam"], box_score["awayTeam"]].compact
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Extracts shooting statistics from V3 API format
|
|
65
|
+
# @api private
|
|
66
|
+
# @return [Hash] shooting statistics
|
|
67
|
+
def self.shooting_stats(stats)
|
|
68
|
+
field_goal_stats(stats).merge(free_throw_stats(stats))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Extracts field goal statistics from V3 API format
|
|
72
|
+
# @api private
|
|
73
|
+
# @param stats [Hash] statistics data from V3 API
|
|
74
|
+
# @return [Hash] field goal statistics
|
|
75
|
+
def self.field_goal_stats(stats)
|
|
76
|
+
{fgm: stats["fieldGoalsMade"], fga: stats["fieldGoalsAttempted"],
|
|
77
|
+
fg_pct: stats["fieldGoalsPercentage"], fg3m: stats["threePointersMade"],
|
|
78
|
+
fg3a: stats["threePointersAttempted"], fg3_pct: stats["threePointersPercentage"]}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Extracts free throw statistics from V3 API format
|
|
82
|
+
# @api private
|
|
83
|
+
# @param stats [Hash] statistics data from V3 API
|
|
84
|
+
# @return [Hash] free throw statistics
|
|
85
|
+
def self.free_throw_stats(stats)
|
|
86
|
+
{ftm: stats["freeThrowsMade"], fta: stats["freeThrowsAttempted"],
|
|
87
|
+
ft_pct: stats["freeThrowsPercentage"]}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Extracts counting statistics from V3 API format
|
|
91
|
+
# @api private
|
|
92
|
+
# @return [Hash] counting statistics
|
|
93
|
+
def self.counting_stats(stats)
|
|
94
|
+
rebound_stats(stats).merge(other_counting_stats(stats))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Extracts rebound and assist statistics from V3 API format
|
|
98
|
+
# @api private
|
|
99
|
+
# @param stats [Hash] statistics data from V3 API
|
|
100
|
+
# @return [Hash] rebound and assist statistics
|
|
101
|
+
def self.rebound_stats(stats)
|
|
102
|
+
{oreb: stats["reboundsOffensive"], dreb: stats["reboundsDefensive"],
|
|
103
|
+
reb: stats["reboundsTotal"], ast: stats["assists"]}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Extracts other counting statistics from V3 API format
|
|
107
|
+
# @api private
|
|
108
|
+
# @param stats [Hash] statistics data from V3 API
|
|
109
|
+
# @return [Hash] steals, blocks, turnovers, fouls, points, plus/minus
|
|
110
|
+
def self.other_counting_stats(stats)
|
|
111
|
+
{stl: stats["steals"], blk: stats["blocks"],
|
|
112
|
+
tov: stats["turnovers"], pf: stats["foulsPersonal"],
|
|
113
|
+
pts: stats["points"], plus_minus: stats["plusMinusPoints"]}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Extracts advanced rating statistics from V3 API format
|
|
117
|
+
# @api private
|
|
118
|
+
# @return [Hash] rating statistics
|
|
119
|
+
def self.advanced_rating_stats(stats)
|
|
120
|
+
{e_off_rating: stats["estimatedOffensiveRating"], off_rating: stats["offensiveRating"],
|
|
121
|
+
e_def_rating: stats["estimatedDefensiveRating"], def_rating: stats["defensiveRating"],
|
|
122
|
+
e_net_rating: stats["estimatedNetRating"], net_rating: stats["netRating"]}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Extracts advanced efficiency statistics from V3 API format
|
|
126
|
+
# @api private
|
|
127
|
+
# @return [Hash] efficiency statistics
|
|
128
|
+
def self.advanced_efficiency_stats(stats)
|
|
129
|
+
{ast_pct: stats["assistPercentage"], ast_tov: stats["assistToTurnover"],
|
|
130
|
+
ast_ratio: stats["assistRatio"], oreb_pct: stats["reboundsOffensivePercentage"],
|
|
131
|
+
dreb_pct: stats["reboundsDefensivePercentage"], reb_pct: stats["reboundsPercentage"],
|
|
132
|
+
tov_pct: stats["turnoverPercentage"], efg_pct: stats["effectiveFieldGoalPercentage"],
|
|
133
|
+
ts_pct: stats["trueShootingPercentage"], pie: stats["playerImpactEstimate"]}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Extracts advanced tempo statistics from V3 API format
|
|
137
|
+
# @api private
|
|
138
|
+
# @return [Hash] tempo statistics
|
|
139
|
+
def self.advanced_tempo_stats(stats)
|
|
140
|
+
{e_pace: stats["estimatedPace"], pace: stats["pace"],
|
|
141
|
+
pace_per40: stats["pacePer40"], poss: stats["possessions"]}
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|