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,133 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "draft_combine_anthro_measurement"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve draft combine anthropometric data
|
|
8
|
+
module DraftCombinePlayerAnthro
|
|
9
|
+
# Result set name
|
|
10
|
+
# @return [String] the result set name
|
|
11
|
+
RESULTS = "Results".freeze
|
|
12
|
+
|
|
13
|
+
# Retrieves draft combine anthropometric measurements for a season
|
|
14
|
+
#
|
|
15
|
+
# @api public
|
|
16
|
+
# @example
|
|
17
|
+
# measurements = NBA::DraftCombinePlayerAnthro.all(season: 2019)
|
|
18
|
+
# measurements.each { |m| puts "#{m.player_name}: #{m.height_w_shoes_ft_in}" }
|
|
19
|
+
# @param season [Integer] the draft combine season year
|
|
20
|
+
# @param league [String, League] the league ID or League object (default NBA)
|
|
21
|
+
# @param client [Client] the API client to use
|
|
22
|
+
# @return [Collection] a collection of draft combine anthropometric measurements
|
|
23
|
+
def self.all(season:, league: League::NBA, client: CLIENT)
|
|
24
|
+
league_id = Utils.extract_league_id(league)
|
|
25
|
+
path = build_path(season, league_id)
|
|
26
|
+
response = client.get(path)
|
|
27
|
+
parse_response(response)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Builds the API request path
|
|
31
|
+
# @api private
|
|
32
|
+
# @return [String] the request path
|
|
33
|
+
def self.build_path(season, league_id)
|
|
34
|
+
"draftcombineplayeranthro?LeagueID=#{league_id}&SeasonYear=#{season}"
|
|
35
|
+
end
|
|
36
|
+
private_class_method :build_path
|
|
37
|
+
|
|
38
|
+
# Parses the API response into measurement objects
|
|
39
|
+
# @api private
|
|
40
|
+
# @return [Collection] collection of measurements
|
|
41
|
+
def self.parse_response(response)
|
|
42
|
+
return Collection.new unless response
|
|
43
|
+
|
|
44
|
+
data = JSON.parse(response)
|
|
45
|
+
result_set = find_result_set(data)
|
|
46
|
+
return Collection.new unless result_set
|
|
47
|
+
|
|
48
|
+
headers = result_set["headers"]
|
|
49
|
+
rows = result_set["rowSet"]
|
|
50
|
+
return Collection.new unless headers && rows
|
|
51
|
+
|
|
52
|
+
measurements = rows.map { |row| build_measurement(headers, row) }
|
|
53
|
+
Collection.new(measurements)
|
|
54
|
+
end
|
|
55
|
+
private_class_method :parse_response
|
|
56
|
+
|
|
57
|
+
# Finds the result set in the response
|
|
58
|
+
# @api private
|
|
59
|
+
# @return [Hash, nil] the result set hash
|
|
60
|
+
def self.find_result_set(data)
|
|
61
|
+
result_sets = data["resultSets"]
|
|
62
|
+
return unless result_sets
|
|
63
|
+
|
|
64
|
+
result_sets.find { |rs| rs["name"].eql?(RESULTS) }
|
|
65
|
+
end
|
|
66
|
+
private_class_method :find_result_set
|
|
67
|
+
|
|
68
|
+
# Builds a DraftCombineAnthroMeasurement object from raw data
|
|
69
|
+
# @api private
|
|
70
|
+
# @return [DraftCombineAnthroMeasurement] the measurement object
|
|
71
|
+
def self.build_measurement(headers, row)
|
|
72
|
+
data = headers.zip(row).to_h
|
|
73
|
+
DraftCombineAnthroMeasurement.new(**measurement_attributes(data))
|
|
74
|
+
end
|
|
75
|
+
private_class_method :build_measurement
|
|
76
|
+
|
|
77
|
+
# Extracts measurement attributes from data
|
|
78
|
+
# @api private
|
|
79
|
+
# @return [Hash] the measurement attributes
|
|
80
|
+
def self.measurement_attributes(data)
|
|
81
|
+
player_attributes(data).merge(
|
|
82
|
+
height_attributes(data),
|
|
83
|
+
physical_attributes(data)
|
|
84
|
+
)
|
|
85
|
+
end
|
|
86
|
+
private_class_method :measurement_attributes
|
|
87
|
+
|
|
88
|
+
# Extracts player attributes from data
|
|
89
|
+
# @api private
|
|
90
|
+
# @return [Hash] player attributes
|
|
91
|
+
def self.player_attributes(data)
|
|
92
|
+
{
|
|
93
|
+
temp_player_id: data["TEMP_PLAYER_ID"],
|
|
94
|
+
player_id: data["PLAYER_ID"],
|
|
95
|
+
first_name: data["FIRST_NAME"],
|
|
96
|
+
last_name: data["LAST_NAME"],
|
|
97
|
+
player_name: data["PLAYER_NAME"],
|
|
98
|
+
position: data["POSITION"]
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
private_class_method :player_attributes
|
|
102
|
+
|
|
103
|
+
# Extracts height attributes from data
|
|
104
|
+
# @api private
|
|
105
|
+
# @return [Hash] height attributes
|
|
106
|
+
def self.height_attributes(data)
|
|
107
|
+
{
|
|
108
|
+
height_wo_shoes: data["HEIGHT_WO_SHOES"],
|
|
109
|
+
height_wo_shoes_ft_in: data["HEIGHT_WO_SHOES_FT_IN"],
|
|
110
|
+
height_w_shoes: data["HEIGHT_W_SHOES"],
|
|
111
|
+
height_w_shoes_ft_in: data["HEIGHT_W_SHOES_FT_IN"]
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
private_class_method :height_attributes
|
|
115
|
+
|
|
116
|
+
# Extracts physical attributes from data
|
|
117
|
+
# @api private
|
|
118
|
+
# @return [Hash] physical attributes
|
|
119
|
+
def self.physical_attributes(data)
|
|
120
|
+
{
|
|
121
|
+
weight: data["WEIGHT"],
|
|
122
|
+
wingspan: data["WINGSPAN"],
|
|
123
|
+
wingspan_ft_in: data["WINGSPAN_FT_IN"],
|
|
124
|
+
standing_reach: data["STANDING_REACH"],
|
|
125
|
+
standing_reach_ft_in: data["STANDING_REACH_FT_IN"],
|
|
126
|
+
body_fat_pct: data["BODY_FAT_PCT"],
|
|
127
|
+
hand_length: data["HAND_LENGTH"],
|
|
128
|
+
hand_width: data["HAND_WIDTH"]
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
private_class_method :physical_attributes
|
|
132
|
+
end
|
|
133
|
+
end
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "draft_combine_spot_shooting_result"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve draft combine spot shooting data
|
|
8
|
+
module DraftCombineSpotShooting
|
|
9
|
+
# Result set name
|
|
10
|
+
# @return [String] the result set name
|
|
11
|
+
RESULTS = "Results".freeze
|
|
12
|
+
|
|
13
|
+
# Retrieves draft combine spot shooting results for a season
|
|
14
|
+
#
|
|
15
|
+
# @api public
|
|
16
|
+
# @example
|
|
17
|
+
# results = NBA::DraftCombineSpotShooting.all(season: 2019)
|
|
18
|
+
# results.each { |r| puts "#{r.player_name}: #{r.nba_corner_left_pct}" }
|
|
19
|
+
# @param season [Integer] the draft combine season year
|
|
20
|
+
# @param league [String, League] the league ID or League object (default NBA)
|
|
21
|
+
# @param client [Client] the API client to use
|
|
22
|
+
# @return [Collection] a collection of draft combine spot shooting results
|
|
23
|
+
def self.all(season:, league: League::NBA, client: CLIENT)
|
|
24
|
+
league_id = Utils.extract_league_id(league)
|
|
25
|
+
path = build_path(season, league_id)
|
|
26
|
+
response = client.get(path)
|
|
27
|
+
parse_response(response)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Builds the API request path
|
|
31
|
+
# @api private
|
|
32
|
+
# @return [String] the request path
|
|
33
|
+
def self.build_path(season, league_id)
|
|
34
|
+
"draftcombinespotshooting?LeagueID=#{league_id}&SeasonYear=#{season}"
|
|
35
|
+
end
|
|
36
|
+
private_class_method :build_path
|
|
37
|
+
|
|
38
|
+
# Parses the API response into result objects
|
|
39
|
+
# @api private
|
|
40
|
+
# @return [Collection] collection of results
|
|
41
|
+
def self.parse_response(response)
|
|
42
|
+
return Collection.new unless response
|
|
43
|
+
|
|
44
|
+
data = JSON.parse(response)
|
|
45
|
+
result_set = find_result_set(data)
|
|
46
|
+
return Collection.new unless result_set
|
|
47
|
+
|
|
48
|
+
headers = result_set["headers"]
|
|
49
|
+
rows = result_set["rowSet"]
|
|
50
|
+
return Collection.new unless headers && rows
|
|
51
|
+
|
|
52
|
+
results = rows.map { |row| build_result(headers, row) }
|
|
53
|
+
Collection.new(results)
|
|
54
|
+
end
|
|
55
|
+
private_class_method :parse_response
|
|
56
|
+
|
|
57
|
+
# Finds the result set in the response
|
|
58
|
+
# @api private
|
|
59
|
+
# @return [Hash, nil] the result set hash
|
|
60
|
+
def self.find_result_set(data)
|
|
61
|
+
result_sets = data["resultSets"]
|
|
62
|
+
return unless result_sets
|
|
63
|
+
|
|
64
|
+
result_sets.find { |rs| rs["name"].eql?(RESULTS) }
|
|
65
|
+
end
|
|
66
|
+
private_class_method :find_result_set
|
|
67
|
+
|
|
68
|
+
# Builds a DraftCombineSpotShootingResult object from raw data
|
|
69
|
+
# @api private
|
|
70
|
+
# @return [DraftCombineSpotShootingResult] the result object
|
|
71
|
+
def self.build_result(headers, row)
|
|
72
|
+
data = headers.zip(row).to_h
|
|
73
|
+
DraftCombineSpotShootingResult.new(**ResultAttributes.extract(data))
|
|
74
|
+
end
|
|
75
|
+
private_class_method :build_result
|
|
76
|
+
|
|
77
|
+
# Extracts result attributes from data
|
|
78
|
+
# @api private
|
|
79
|
+
module ResultAttributes
|
|
80
|
+
# Extracts all result attributes from data
|
|
81
|
+
# @api private
|
|
82
|
+
# @param data [Hash] the row data
|
|
83
|
+
# @return [Hash] extracted attributes
|
|
84
|
+
def self.extract(data)
|
|
85
|
+
player(data).merge(fifteen_foot(data)).merge(college_range(data)).merge(nba_range(data))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Extracts player attributes from data
|
|
89
|
+
# @api private
|
|
90
|
+
# @param data [Hash] the row data
|
|
91
|
+
# @return [Hash] player attributes
|
|
92
|
+
def self.player(data)
|
|
93
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
94
|
+
first_name: data["FIRST_NAME"], last_name: data["LAST_NAME"],
|
|
95
|
+
position: data["POSITION"]}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Extracts fifteen-foot range shot attributes from data
|
|
99
|
+
# @api private
|
|
100
|
+
# @param data [Hash] the row data
|
|
101
|
+
# @return [Hash] fifteen-foot range shot attributes
|
|
102
|
+
def self.fifteen_foot(data)
|
|
103
|
+
FifteenFoot.corners(data).merge(FifteenFoot.breaks(data)).merge(FifteenFoot.top(data))
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Extracts college range shot attributes from data
|
|
107
|
+
# @api private
|
|
108
|
+
# @param data [Hash] the row data
|
|
109
|
+
# @return [Hash] college range shot attributes
|
|
110
|
+
def self.college_range(data)
|
|
111
|
+
CollegeRange.corners(data).merge(CollegeRange.breaks(data)).merge(CollegeRange.top(data))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Extracts NBA range shot attributes from data
|
|
115
|
+
# @api private
|
|
116
|
+
# @param data [Hash] the row data
|
|
117
|
+
# @return [Hash] NBA range shot attributes
|
|
118
|
+
def self.nba_range(data)
|
|
119
|
+
NbaRange.corners(data).merge(NbaRange.breaks(data)).merge(NbaRange.top(data))
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Extracts fifteen-foot range shot attributes
|
|
124
|
+
# @api private
|
|
125
|
+
module FifteenFoot
|
|
126
|
+
# Extracts corner shot attributes from data
|
|
127
|
+
# @api private
|
|
128
|
+
# @param data [Hash] the row data
|
|
129
|
+
# @return [Hash] corner shot attributes
|
|
130
|
+
def self.corners(data)
|
|
131
|
+
{fifteen_corner_left_made: data["FIFTEEN_CORNER_LEFT_MADE"],
|
|
132
|
+
fifteen_corner_left_attempt: data["FIFTEEN_CORNER_LEFT_ATTEMPT"],
|
|
133
|
+
fifteen_corner_left_pct: data["FIFTEEN_CORNER_LEFT_PCT"],
|
|
134
|
+
fifteen_corner_right_made: data["FIFTEEN_CORNER_RIGHT_MADE"],
|
|
135
|
+
fifteen_corner_right_attempt: data["FIFTEEN_CORNER_RIGHT_ATTEMPT"],
|
|
136
|
+
fifteen_corner_right_pct: data["FIFTEEN_CORNER_RIGHT_PCT"]}
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Extracts break shot attributes from data
|
|
140
|
+
# @api private
|
|
141
|
+
# @param data [Hash] the row data
|
|
142
|
+
# @return [Hash] break shot attributes
|
|
143
|
+
def self.breaks(data)
|
|
144
|
+
{fifteen_break_left_made: data["FIFTEEN_BREAK_LEFT_MADE"],
|
|
145
|
+
fifteen_break_left_attempt: data["FIFTEEN_BREAK_LEFT_ATTEMPT"],
|
|
146
|
+
fifteen_break_left_pct: data["FIFTEEN_BREAK_LEFT_PCT"],
|
|
147
|
+
fifteen_break_right_made: data["FIFTEEN_BREAK_RIGHT_MADE"],
|
|
148
|
+
fifteen_break_right_attempt: data["FIFTEEN_BREAK_RIGHT_ATTEMPT"],
|
|
149
|
+
fifteen_break_right_pct: data["FIFTEEN_BREAK_RIGHT_PCT"]}
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Extracts top key shot attributes from data
|
|
153
|
+
# @api private
|
|
154
|
+
# @param data [Hash] the row data
|
|
155
|
+
# @return [Hash] top key shot attributes
|
|
156
|
+
def self.top(data)
|
|
157
|
+
{fifteen_top_key_made: data["FIFTEEN_TOP_KEY_MADE"],
|
|
158
|
+
fifteen_top_key_attempt: data["FIFTEEN_TOP_KEY_ATTEMPT"],
|
|
159
|
+
fifteen_top_key_pct: data["FIFTEEN_TOP_KEY_PCT"]}
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Extracts college range shot attributes
|
|
164
|
+
# @api private
|
|
165
|
+
module CollegeRange
|
|
166
|
+
# Extracts corner shot attributes from data
|
|
167
|
+
# @api private
|
|
168
|
+
# @param data [Hash] the row data
|
|
169
|
+
# @return [Hash] corner shot attributes
|
|
170
|
+
def self.corners(data)
|
|
171
|
+
{college_corner_left_made: data["COLLEGE_CORNER_LEFT_MADE"],
|
|
172
|
+
college_corner_left_attempt: data["COLLEGE_CORNER_LEFT_ATTEMPT"],
|
|
173
|
+
college_corner_left_pct: data["COLLEGE_CORNER_LEFT_PCT"],
|
|
174
|
+
college_corner_right_made: data["COLLEGE_CORNER_RIGHT_MADE"],
|
|
175
|
+
college_corner_right_attempt: data["COLLEGE_CORNER_RIGHT_ATTEMPT"],
|
|
176
|
+
college_corner_right_pct: data["COLLEGE_CORNER_RIGHT_PCT"]}
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Extracts break shot attributes from data
|
|
180
|
+
# @api private
|
|
181
|
+
# @param data [Hash] the row data
|
|
182
|
+
# @return [Hash] break shot attributes
|
|
183
|
+
def self.breaks(data)
|
|
184
|
+
{college_break_left_made: data["COLLEGE_BREAK_LEFT_MADE"],
|
|
185
|
+
college_break_left_attempt: data["COLLEGE_BREAK_LEFT_ATTEMPT"],
|
|
186
|
+
college_break_left_pct: data["COLLEGE_BREAK_LEFT_PCT"],
|
|
187
|
+
college_break_right_made: data["COLLEGE_BREAK_RIGHT_MADE"],
|
|
188
|
+
college_break_right_attempt: data["COLLEGE_BREAK_RIGHT_ATTEMPT"],
|
|
189
|
+
college_break_right_pct: data["COLLEGE_BREAK_RIGHT_PCT"]}
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Extracts top key shot attributes from data
|
|
193
|
+
# @api private
|
|
194
|
+
# @param data [Hash] the row data
|
|
195
|
+
# @return [Hash] top key shot attributes
|
|
196
|
+
def self.top(data)
|
|
197
|
+
{college_top_key_made: data["COLLEGE_TOP_KEY_MADE"],
|
|
198
|
+
college_top_key_attempt: data["COLLEGE_TOP_KEY_ATTEMPT"],
|
|
199
|
+
college_top_key_pct: data["COLLEGE_TOP_KEY_PCT"]}
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Extracts NBA range shot attributes
|
|
204
|
+
# @api private
|
|
205
|
+
module NbaRange
|
|
206
|
+
# Extracts corner shot attributes from data
|
|
207
|
+
# @api private
|
|
208
|
+
# @param data [Hash] the row data
|
|
209
|
+
# @return [Hash] corner shot attributes
|
|
210
|
+
def self.corners(data)
|
|
211
|
+
{nba_corner_left_made: data["NBA_CORNER_LEFT_MADE"],
|
|
212
|
+
nba_corner_left_attempt: data["NBA_CORNER_LEFT_ATTEMPT"],
|
|
213
|
+
nba_corner_left_pct: data["NBA_CORNER_LEFT_PCT"],
|
|
214
|
+
nba_corner_right_made: data["NBA_CORNER_RIGHT_MADE"],
|
|
215
|
+
nba_corner_right_attempt: data["NBA_CORNER_RIGHT_ATTEMPT"],
|
|
216
|
+
nba_corner_right_pct: data["NBA_CORNER_RIGHT_PCT"]}
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Extracts break shot attributes from data
|
|
220
|
+
# @api private
|
|
221
|
+
# @param data [Hash] the row data
|
|
222
|
+
# @return [Hash] break shot attributes
|
|
223
|
+
def self.breaks(data)
|
|
224
|
+
{nba_break_left_made: data["NBA_BREAK_LEFT_MADE"],
|
|
225
|
+
nba_break_left_attempt: data["NBA_BREAK_LEFT_ATTEMPT"],
|
|
226
|
+
nba_break_left_pct: data["NBA_BREAK_LEFT_PCT"],
|
|
227
|
+
nba_break_right_made: data["NBA_BREAK_RIGHT_MADE"],
|
|
228
|
+
nba_break_right_attempt: data["NBA_BREAK_RIGHT_ATTEMPT"],
|
|
229
|
+
nba_break_right_pct: data["NBA_BREAK_RIGHT_PCT"]}
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Extracts top key shot attributes from data
|
|
233
|
+
# @api private
|
|
234
|
+
# @param data [Hash] the row data
|
|
235
|
+
# @return [Hash] top key shot attributes
|
|
236
|
+
def self.top(data)
|
|
237
|
+
{nba_top_key_made: data["NBA_TOP_KEY_MADE"],
|
|
238
|
+
nba_top_key_attempt: data["NBA_TOP_KEY_ATTEMPT"],
|
|
239
|
+
nba_top_key_pct: data["NBA_TOP_KEY_PCT"]}
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|