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,110 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
require_relative "teams"
|
|
4
|
+
|
|
5
|
+
module NBA
|
|
6
|
+
# Represents league-wide team defensive statistics
|
|
7
|
+
#
|
|
8
|
+
# @api public
|
|
9
|
+
class LeagueDashPtTeamDefendStat < Shale::Mapper
|
|
10
|
+
include Equalizer.new(:team_id)
|
|
11
|
+
|
|
12
|
+
# @!attribute [rw] team_id
|
|
13
|
+
# Returns the team ID
|
|
14
|
+
# @api public
|
|
15
|
+
# @example
|
|
16
|
+
# stat.team_id #=> 1610612744
|
|
17
|
+
# @return [Integer, nil] the team's ID
|
|
18
|
+
attribute :team_id, Shale::Type::Integer
|
|
19
|
+
|
|
20
|
+
# @!attribute [rw] team_name
|
|
21
|
+
# Returns the team name
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# stat.team_name #=> "Golden State Warriors"
|
|
25
|
+
# @return [String, nil] the team's name
|
|
26
|
+
attribute :team_name, Shale::Type::String
|
|
27
|
+
|
|
28
|
+
# @!attribute [rw] team_abbreviation
|
|
29
|
+
# Returns the team abbreviation
|
|
30
|
+
# @api public
|
|
31
|
+
# @example
|
|
32
|
+
# stat.team_abbreviation #=> "GSW"
|
|
33
|
+
# @return [String, nil] the team's abbreviation
|
|
34
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
35
|
+
|
|
36
|
+
# @!attribute [rw] gp
|
|
37
|
+
# Returns games played
|
|
38
|
+
# @api public
|
|
39
|
+
# @example
|
|
40
|
+
# stat.gp #=> 82
|
|
41
|
+
# @return [Integer, nil] games played
|
|
42
|
+
attribute :gp, Shale::Type::Integer
|
|
43
|
+
|
|
44
|
+
# @!attribute [rw] g
|
|
45
|
+
# Returns games (alias for games played)
|
|
46
|
+
# @api public
|
|
47
|
+
# @example
|
|
48
|
+
# stat.g #=> 82
|
|
49
|
+
# @return [Integer, nil] games
|
|
50
|
+
attribute :g, Shale::Type::Integer
|
|
51
|
+
|
|
52
|
+
# @!attribute [rw] freq
|
|
53
|
+
# Returns frequency percentage
|
|
54
|
+
# @api public
|
|
55
|
+
# @example
|
|
56
|
+
# stat.freq #=> 0.089
|
|
57
|
+
# @return [Float, nil] frequency percentage
|
|
58
|
+
attribute :freq, Shale::Type::Float
|
|
59
|
+
|
|
60
|
+
# @!attribute [rw] d_fgm
|
|
61
|
+
# Returns defended field goals made
|
|
62
|
+
# @api public
|
|
63
|
+
# @example
|
|
64
|
+
# stat.d_fgm #=> 245.0
|
|
65
|
+
# @return [Float, nil] defended field goals made
|
|
66
|
+
attribute :d_fgm, Shale::Type::Float
|
|
67
|
+
|
|
68
|
+
# @!attribute [rw] d_fga
|
|
69
|
+
# Returns defended field goals attempted
|
|
70
|
+
# @api public
|
|
71
|
+
# @example
|
|
72
|
+
# stat.d_fga #=> 612.0
|
|
73
|
+
# @return [Float, nil] defended field goals attempted
|
|
74
|
+
attribute :d_fga, Shale::Type::Float
|
|
75
|
+
|
|
76
|
+
# @!attribute [rw] d_fg_pct
|
|
77
|
+
# Returns defended field goal percentage
|
|
78
|
+
# @api public
|
|
79
|
+
# @example
|
|
80
|
+
# stat.d_fg_pct #=> 0.400
|
|
81
|
+
# @return [Float, nil] defended field goal percentage
|
|
82
|
+
attribute :d_fg_pct, Shale::Type::Float
|
|
83
|
+
|
|
84
|
+
# @!attribute [rw] normal_fg_pct
|
|
85
|
+
# Returns normal (uncontested) field goal percentage
|
|
86
|
+
# @api public
|
|
87
|
+
# @example
|
|
88
|
+
# stat.normal_fg_pct #=> 0.450
|
|
89
|
+
# @return [Float, nil] normal field goal percentage
|
|
90
|
+
attribute :normal_fg_pct, Shale::Type::Float
|
|
91
|
+
|
|
92
|
+
# @!attribute [rw] pct_plusminus
|
|
93
|
+
# Returns percentage plus/minus (difference from normal)
|
|
94
|
+
# @api public
|
|
95
|
+
# @example
|
|
96
|
+
# stat.pct_plusminus #=> -0.050
|
|
97
|
+
# @return [Float, nil] percentage plus/minus
|
|
98
|
+
attribute :pct_plusminus, Shale::Type::Float
|
|
99
|
+
|
|
100
|
+
# Returns the team
|
|
101
|
+
#
|
|
102
|
+
# @api public
|
|
103
|
+
# @example
|
|
104
|
+
# stat.team #=> #<NBA::Team id=1610612744 ...>
|
|
105
|
+
# @return [Team, nil] the team object
|
|
106
|
+
def team
|
|
107
|
+
Teams.find(team_id)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "league_dash_team_clutch_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve league-wide clutch team statistics
|
|
9
|
+
module LeagueDashTeamClutch
|
|
10
|
+
# Result set name for league dash team clutch
|
|
11
|
+
# @return [String] the result set name
|
|
12
|
+
LEAGUE_DASH_TEAM_CLUTCH = "LeagueDashTeamClutch".freeze
|
|
13
|
+
|
|
14
|
+
# Season type constant for regular season
|
|
15
|
+
# @return [String] the season type
|
|
16
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
17
|
+
|
|
18
|
+
# Season type constant for playoffs
|
|
19
|
+
# @return [String] the season type
|
|
20
|
+
PLAYOFFS = "Playoffs".freeze
|
|
21
|
+
|
|
22
|
+
# Per mode constant for per game stats
|
|
23
|
+
# @return [String] the per mode
|
|
24
|
+
PER_GAME = "PerGame".freeze
|
|
25
|
+
|
|
26
|
+
# Per mode constant for totals
|
|
27
|
+
# @return [String] the per mode
|
|
28
|
+
TOTALS = "Totals".freeze
|
|
29
|
+
|
|
30
|
+
# Per mode constant for per 100 possessions
|
|
31
|
+
# @return [String] the per mode
|
|
32
|
+
PER_100 = "Per100Possessions".freeze
|
|
33
|
+
|
|
34
|
+
# Clutch time constant for last 5 minutes
|
|
35
|
+
# @return [String] the clutch time
|
|
36
|
+
LAST_5_MINUTES = "Last 5 Minutes".freeze
|
|
37
|
+
|
|
38
|
+
# Clutch time constant for last 4 minutes
|
|
39
|
+
# @return [String] the clutch time
|
|
40
|
+
LAST_4_MINUTES = "Last 4 Minutes".freeze
|
|
41
|
+
|
|
42
|
+
# Clutch time constant for last 3 minutes
|
|
43
|
+
# @return [String] the clutch time
|
|
44
|
+
LAST_3_MINUTES = "Last 3 Minutes".freeze
|
|
45
|
+
|
|
46
|
+
# Clutch time constant for last 2 minutes
|
|
47
|
+
# @return [String] the clutch time
|
|
48
|
+
LAST_2_MINUTES = "Last 2 Minutes".freeze
|
|
49
|
+
|
|
50
|
+
# Clutch time constant for last 1 minute
|
|
51
|
+
# @return [String] the clutch time
|
|
52
|
+
LAST_1_MINUTE = "Last 1 Minute".freeze
|
|
53
|
+
|
|
54
|
+
# Ahead/behind constant for ahead or behind
|
|
55
|
+
# @return [String] the ahead/behind value
|
|
56
|
+
AHEAD_OR_BEHIND = "Ahead or Behind".freeze
|
|
57
|
+
|
|
58
|
+
# Ahead/behind constant for behind or tied
|
|
59
|
+
# @return [String] the ahead/behind value
|
|
60
|
+
BEHIND_OR_TIED = "Behind or Tied".freeze
|
|
61
|
+
|
|
62
|
+
# Ahead/behind constant for ahead or tied
|
|
63
|
+
# @return [String] the ahead/behind value
|
|
64
|
+
AHEAD_OR_TIED = "Ahead or Tied".freeze
|
|
65
|
+
|
|
66
|
+
# Retrieves league-wide clutch team statistics
|
|
67
|
+
#
|
|
68
|
+
# @api public
|
|
69
|
+
# @example
|
|
70
|
+
# stats = NBA::LeagueDashTeamClutch.all(season: 2024)
|
|
71
|
+
# stats.each { |s| puts "#{s.team_name}: #{s.pts} clutch PPG" }
|
|
72
|
+
# @param season [Integer] the season year
|
|
73
|
+
# @param season_type [String] the season type
|
|
74
|
+
# @param clutch_time [String] the clutch time definition
|
|
75
|
+
# @param ahead_behind [String] the ahead/behind filter
|
|
76
|
+
# @param point_diff [Integer] the point differential
|
|
77
|
+
# @param per_mode [String] the per mode
|
|
78
|
+
# @param client [Client] the API client to use
|
|
79
|
+
# @return [Collection] a collection of clutch team stats
|
|
80
|
+
def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, clutch_time: LAST_5_MINUTES,
|
|
81
|
+
ahead_behind: AHEAD_OR_BEHIND, point_diff: 5, per_mode: PER_GAME, client: CLIENT)
|
|
82
|
+
opts = {season_type: season_type, clutch_time: clutch_time, ahead_behind: ahead_behind,
|
|
83
|
+
point_diff: point_diff, per_mode: per_mode}
|
|
84
|
+
path = build_path(season, opts)
|
|
85
|
+
response = client.get(path)
|
|
86
|
+
parse_response(response, season)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Builds the API path
|
|
90
|
+
#
|
|
91
|
+
# @api private
|
|
92
|
+
# @param season [Integer] the season year
|
|
93
|
+
# @param opts [Hash] the request options
|
|
94
|
+
# @return [String] the API path
|
|
95
|
+
def self.build_path(season, opts)
|
|
96
|
+
season_str = Utils.format_season(season)
|
|
97
|
+
"leaguedashteamclutch?LeagueID=00&Season=#{season_str}&SeasonType=#{opts.fetch(:season_type)}" \
|
|
98
|
+
"&ClutchTime=#{opts.fetch(:clutch_time)}&AheadBehind=#{opts.fetch(:ahead_behind)}" \
|
|
99
|
+
"&PointDiff=#{opts.fetch(:point_diff)}&PerMode=#{opts.fetch(:per_mode)}&MeasureType=Base"
|
|
100
|
+
end
|
|
101
|
+
private_class_method :build_path
|
|
102
|
+
|
|
103
|
+
# Parses the API response
|
|
104
|
+
#
|
|
105
|
+
# @api private
|
|
106
|
+
# @param response [String, nil] the JSON response body
|
|
107
|
+
# @param season [Integer] the season year
|
|
108
|
+
# @return [Collection] a collection of clutch team stats
|
|
109
|
+
def self.parse_response(response, season)
|
|
110
|
+
return Collection.new unless response
|
|
111
|
+
|
|
112
|
+
data = JSON.parse(response)
|
|
113
|
+
result_set = find_result_set(data)
|
|
114
|
+
return Collection.new unless result_set
|
|
115
|
+
|
|
116
|
+
build_stats(result_set, Utils.format_season(season))
|
|
117
|
+
end
|
|
118
|
+
private_class_method :parse_response
|
|
119
|
+
|
|
120
|
+
# Finds the result set
|
|
121
|
+
#
|
|
122
|
+
# @api private
|
|
123
|
+
# @param data [Hash] the parsed JSON data
|
|
124
|
+
# @return [Hash, nil] the result set
|
|
125
|
+
def self.find_result_set(data)
|
|
126
|
+
result_sets = data["resultSets"]
|
|
127
|
+
return unless result_sets
|
|
128
|
+
|
|
129
|
+
result_sets.find { |rs| rs["name"].eql?(LEAGUE_DASH_TEAM_CLUTCH) }
|
|
130
|
+
end
|
|
131
|
+
private_class_method :find_result_set
|
|
132
|
+
|
|
133
|
+
# Builds stats collection from result set
|
|
134
|
+
#
|
|
135
|
+
# @api private
|
|
136
|
+
# @param result_set [Hash] the result set
|
|
137
|
+
# @param season_id [String] the season ID
|
|
138
|
+
# @return [Collection] collection of clutch team stats
|
|
139
|
+
def self.build_stats(result_set, season_id)
|
|
140
|
+
headers = result_set["headers"]
|
|
141
|
+
rows = result_set["rowSet"]
|
|
142
|
+
return Collection.new unless headers && rows
|
|
143
|
+
|
|
144
|
+
stats = rows.map { |row| build_stat(headers, row, season_id) }
|
|
145
|
+
Collection.new(stats)
|
|
146
|
+
end
|
|
147
|
+
private_class_method :build_stats
|
|
148
|
+
|
|
149
|
+
# Builds a single clutch team stat
|
|
150
|
+
#
|
|
151
|
+
# @api private
|
|
152
|
+
# @param headers [Array<String>] the column headers
|
|
153
|
+
# @param row [Array] the row data
|
|
154
|
+
# @param season_id [String] the season ID
|
|
155
|
+
# @return [LeagueDashTeamClutchStat] the clutch team stat
|
|
156
|
+
def self.build_stat(headers, row, season_id)
|
|
157
|
+
data = headers.zip(row).to_h
|
|
158
|
+
LeagueDashTeamClutchStat.new(**stat_attributes(data, season_id))
|
|
159
|
+
end
|
|
160
|
+
private_class_method :build_stat
|
|
161
|
+
|
|
162
|
+
# Extracts all stat attributes
|
|
163
|
+
#
|
|
164
|
+
# @api private
|
|
165
|
+
# @param data [Hash] the stat data
|
|
166
|
+
# @param season_id [String] the season ID
|
|
167
|
+
# @return [Hash] the stat attributes
|
|
168
|
+
def self.stat_attributes(data, season_id)
|
|
169
|
+
identity_attributes(data, season_id).merge(shooting_attributes(data), counting_attributes(data))
|
|
170
|
+
end
|
|
171
|
+
private_class_method :stat_attributes
|
|
172
|
+
|
|
173
|
+
# Extracts identity attributes
|
|
174
|
+
#
|
|
175
|
+
# @api private
|
|
176
|
+
# @param data [Hash] the stat data
|
|
177
|
+
# @param season_id [String] the season ID
|
|
178
|
+
# @return [Hash] the identity attributes
|
|
179
|
+
def self.identity_attributes(data, season_id)
|
|
180
|
+
{team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
|
|
181
|
+
gp: data["GP"], w: data["W"], l: data["L"],
|
|
182
|
+
w_pct: data["W_PCT"], min: data["MIN"], season_id: season_id}
|
|
183
|
+
end
|
|
184
|
+
private_class_method :identity_attributes
|
|
185
|
+
|
|
186
|
+
# Extracts shooting attributes
|
|
187
|
+
#
|
|
188
|
+
# @api private
|
|
189
|
+
# @param data [Hash] the stat data
|
|
190
|
+
# @return [Hash] the shooting attributes
|
|
191
|
+
def self.shooting_attributes(data)
|
|
192
|
+
{fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
|
|
193
|
+
fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
|
|
194
|
+
ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
|
|
195
|
+
end
|
|
196
|
+
private_class_method :shooting_attributes
|
|
197
|
+
|
|
198
|
+
# Extracts counting stats attributes
|
|
199
|
+
#
|
|
200
|
+
# @api private
|
|
201
|
+
# @param data [Hash] the stat data
|
|
202
|
+
# @return [Hash] the counting attributes
|
|
203
|
+
def self.counting_attributes(data)
|
|
204
|
+
{oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
|
|
205
|
+
ast: data["AST"], tov: data["TOV"], stl: data["STL"],
|
|
206
|
+
blk: data["BLK"], pf: data["PF"], pts: data["PTS"],
|
|
207
|
+
plus_minus: data["PLUS_MINUS"]}
|
|
208
|
+
end
|
|
209
|
+
private_class_method :counting_attributes
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents clutch-time team statistics
|
|
6
|
+
#
|
|
7
|
+
# @api public
|
|
8
|
+
class LeagueDashTeamClutchStat < Shale::Mapper
|
|
9
|
+
include Equalizer.new(:team_id, :season_id)
|
|
10
|
+
|
|
11
|
+
# @!attribute [rw] team_id
|
|
12
|
+
# Returns the team ID
|
|
13
|
+
# @api public
|
|
14
|
+
# @example
|
|
15
|
+
# stat.team_id #=> 1610612744
|
|
16
|
+
# @return [Integer, nil] the team ID
|
|
17
|
+
attribute :team_id, Shale::Type::Integer
|
|
18
|
+
|
|
19
|
+
# @!attribute [rw] team_name
|
|
20
|
+
# Returns the team name
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# stat.team_name #=> "Golden State Warriors"
|
|
24
|
+
# @return [String, nil] the team name
|
|
25
|
+
attribute :team_name, Shale::Type::String
|
|
26
|
+
|
|
27
|
+
# @!attribute [rw] season_id
|
|
28
|
+
# Returns the season ID
|
|
29
|
+
# @api public
|
|
30
|
+
# @example
|
|
31
|
+
# stat.season_id #=> "2024-25"
|
|
32
|
+
# @return [String, nil] the season ID
|
|
33
|
+
attribute :season_id, Shale::Type::String
|
|
34
|
+
|
|
35
|
+
# @!attribute [rw] gp
|
|
36
|
+
# Returns games played
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# stat.gp #=> 82
|
|
40
|
+
# @return [Integer, nil] games played
|
|
41
|
+
attribute :gp, Shale::Type::Integer
|
|
42
|
+
|
|
43
|
+
# @!attribute [rw] w
|
|
44
|
+
# Returns wins
|
|
45
|
+
# @api public
|
|
46
|
+
# @example
|
|
47
|
+
# stat.w #=> 46
|
|
48
|
+
# @return [Integer, nil] wins
|
|
49
|
+
attribute :w, Shale::Type::Integer
|
|
50
|
+
|
|
51
|
+
# @!attribute [rw] l
|
|
52
|
+
# Returns losses
|
|
53
|
+
# @api public
|
|
54
|
+
# @example
|
|
55
|
+
# stat.l #=> 36
|
|
56
|
+
# @return [Integer, nil] losses
|
|
57
|
+
attribute :l, Shale::Type::Integer
|
|
58
|
+
|
|
59
|
+
# @!attribute [rw] w_pct
|
|
60
|
+
# Returns win percentage
|
|
61
|
+
# @api public
|
|
62
|
+
# @example
|
|
63
|
+
# stat.w_pct #=> 0.561
|
|
64
|
+
# @return [Float, nil] win percentage
|
|
65
|
+
attribute :w_pct, Shale::Type::Float
|
|
66
|
+
|
|
67
|
+
# @!attribute [rw] min
|
|
68
|
+
# Returns minutes played
|
|
69
|
+
# @api public
|
|
70
|
+
# @example
|
|
71
|
+
# stat.min #=> 5.0
|
|
72
|
+
# @return [Float, nil] minutes played
|
|
73
|
+
attribute :min, Shale::Type::Float
|
|
74
|
+
|
|
75
|
+
# @!attribute [rw] fgm
|
|
76
|
+
# Returns field goals made
|
|
77
|
+
# @api public
|
|
78
|
+
# @example
|
|
79
|
+
# stat.fgm #=> 3.2
|
|
80
|
+
# @return [Float, nil] field goals made
|
|
81
|
+
attribute :fgm, Shale::Type::Float
|
|
82
|
+
|
|
83
|
+
# @!attribute [rw] fga
|
|
84
|
+
# Returns field goals attempted
|
|
85
|
+
# @api public
|
|
86
|
+
# @example
|
|
87
|
+
# stat.fga #=> 7.5
|
|
88
|
+
# @return [Float, nil] field goals attempted
|
|
89
|
+
attribute :fga, Shale::Type::Float
|
|
90
|
+
|
|
91
|
+
# @!attribute [rw] fg_pct
|
|
92
|
+
# Returns field goal percentage
|
|
93
|
+
# @api public
|
|
94
|
+
# @example
|
|
95
|
+
# stat.fg_pct #=> 0.427
|
|
96
|
+
# @return [Float, nil] field goal percentage
|
|
97
|
+
attribute :fg_pct, Shale::Type::Float
|
|
98
|
+
|
|
99
|
+
# @!attribute [rw] fg3m
|
|
100
|
+
# Returns three pointers made
|
|
101
|
+
# @api public
|
|
102
|
+
# @example
|
|
103
|
+
# stat.fg3m #=> 1.2
|
|
104
|
+
# @return [Float, nil] three pointers made
|
|
105
|
+
attribute :fg3m, Shale::Type::Float
|
|
106
|
+
|
|
107
|
+
# @!attribute [rw] fg3a
|
|
108
|
+
# Returns three pointers attempted
|
|
109
|
+
# @api public
|
|
110
|
+
# @example
|
|
111
|
+
# stat.fg3a #=> 3.5
|
|
112
|
+
# @return [Float, nil] three pointers attempted
|
|
113
|
+
attribute :fg3a, Shale::Type::Float
|
|
114
|
+
|
|
115
|
+
# @!attribute [rw] fg3_pct
|
|
116
|
+
# Returns three point percentage
|
|
117
|
+
# @api public
|
|
118
|
+
# @example
|
|
119
|
+
# stat.fg3_pct #=> 0.343
|
|
120
|
+
# @return [Float, nil] three point percentage
|
|
121
|
+
attribute :fg3_pct, Shale::Type::Float
|
|
122
|
+
|
|
123
|
+
# @!attribute [rw] ftm
|
|
124
|
+
# Returns free throws made
|
|
125
|
+
# @api public
|
|
126
|
+
# @example
|
|
127
|
+
# stat.ftm #=> 2.0
|
|
128
|
+
# @return [Float, nil] free throws made
|
|
129
|
+
attribute :ftm, Shale::Type::Float
|
|
130
|
+
|
|
131
|
+
# @!attribute [rw] fta
|
|
132
|
+
# Returns free throws attempted
|
|
133
|
+
# @api public
|
|
134
|
+
# @example
|
|
135
|
+
# stat.fta #=> 2.5
|
|
136
|
+
# @return [Float, nil] free throws attempted
|
|
137
|
+
attribute :fta, Shale::Type::Float
|
|
138
|
+
|
|
139
|
+
# @!attribute [rw] ft_pct
|
|
140
|
+
# Returns free throw percentage
|
|
141
|
+
# @api public
|
|
142
|
+
# @example
|
|
143
|
+
# stat.ft_pct #=> 0.800
|
|
144
|
+
# @return [Float, nil] free throw percentage
|
|
145
|
+
attribute :ft_pct, Shale::Type::Float
|
|
146
|
+
|
|
147
|
+
# @!attribute [rw] oreb
|
|
148
|
+
# Returns offensive rebounds
|
|
149
|
+
# @api public
|
|
150
|
+
# @example
|
|
151
|
+
# stat.oreb #=> 0.8
|
|
152
|
+
# @return [Float, nil] offensive rebounds
|
|
153
|
+
attribute :oreb, Shale::Type::Float
|
|
154
|
+
|
|
155
|
+
# @!attribute [rw] dreb
|
|
156
|
+
# Returns defensive rebounds
|
|
157
|
+
# @api public
|
|
158
|
+
# @example
|
|
159
|
+
# stat.dreb #=> 2.2
|
|
160
|
+
# @return [Float, nil] defensive rebounds
|
|
161
|
+
attribute :dreb, Shale::Type::Float
|
|
162
|
+
|
|
163
|
+
# @!attribute [rw] reb
|
|
164
|
+
# Returns total rebounds
|
|
165
|
+
# @api public
|
|
166
|
+
# @example
|
|
167
|
+
# stat.reb #=> 3.0
|
|
168
|
+
# @return [Float, nil] total rebounds
|
|
169
|
+
attribute :reb, Shale::Type::Float
|
|
170
|
+
|
|
171
|
+
# @!attribute [rw] ast
|
|
172
|
+
# Returns assists
|
|
173
|
+
# @api public
|
|
174
|
+
# @example
|
|
175
|
+
# stat.ast #=> 1.8
|
|
176
|
+
# @return [Float, nil] assists
|
|
177
|
+
attribute :ast, Shale::Type::Float
|
|
178
|
+
|
|
179
|
+
# @!attribute [rw] tov
|
|
180
|
+
# Returns turnovers
|
|
181
|
+
# @api public
|
|
182
|
+
# @example
|
|
183
|
+
# stat.tov #=> 1.2
|
|
184
|
+
# @return [Float, nil] turnovers
|
|
185
|
+
attribute :tov, Shale::Type::Float
|
|
186
|
+
|
|
187
|
+
# @!attribute [rw] stl
|
|
188
|
+
# Returns steals
|
|
189
|
+
# @api public
|
|
190
|
+
# @example
|
|
191
|
+
# stat.stl #=> 0.6
|
|
192
|
+
# @return [Float, nil] steals
|
|
193
|
+
attribute :stl, Shale::Type::Float
|
|
194
|
+
|
|
195
|
+
# @!attribute [rw] blk
|
|
196
|
+
# Returns blocks
|
|
197
|
+
# @api public
|
|
198
|
+
# @example
|
|
199
|
+
# stat.blk #=> 0.3
|
|
200
|
+
# @return [Float, nil] blocks
|
|
201
|
+
attribute :blk, Shale::Type::Float
|
|
202
|
+
|
|
203
|
+
# @!attribute [rw] pf
|
|
204
|
+
# Returns personal fouls
|
|
205
|
+
# @api public
|
|
206
|
+
# @example
|
|
207
|
+
# stat.pf #=> 1.5
|
|
208
|
+
# @return [Float, nil] personal fouls
|
|
209
|
+
attribute :pf, Shale::Type::Float
|
|
210
|
+
|
|
211
|
+
# @!attribute [rw] pts
|
|
212
|
+
# Returns points
|
|
213
|
+
# @api public
|
|
214
|
+
# @example
|
|
215
|
+
# stat.pts #=> 9.6
|
|
216
|
+
# @return [Float, nil] points
|
|
217
|
+
attribute :pts, Shale::Type::Float
|
|
218
|
+
|
|
219
|
+
# @!attribute [rw] plus_minus
|
|
220
|
+
# Returns plus/minus
|
|
221
|
+
# @api public
|
|
222
|
+
# @example
|
|
223
|
+
# stat.plus_minus #=> 0.8
|
|
224
|
+
# @return [Float, nil] plus/minus
|
|
225
|
+
attribute :plus_minus, Shale::Type::Float
|
|
226
|
+
|
|
227
|
+
# Returns the team object
|
|
228
|
+
#
|
|
229
|
+
# @api public
|
|
230
|
+
# @example
|
|
231
|
+
# stat.team #=> #<NBA::Team>
|
|
232
|
+
# @return [Team, nil] the team object
|
|
233
|
+
def team
|
|
234
|
+
Teams.find(team_id)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "league_dash_team_pt_shot_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve league-wide team tracking shot statistics
|
|
9
|
+
#
|
|
10
|
+
# @api public
|
|
11
|
+
module LeagueDashTeamPtShot
|
|
12
|
+
# Result set name for league dash team PT shots
|
|
13
|
+
# @return [String] the result set name
|
|
14
|
+
LEAGUE_DASH_PT_SHOTS = "LeagueDashPTShots".freeze
|
|
15
|
+
|
|
16
|
+
# Regular season type constant
|
|
17
|
+
# @return [String] the season type
|
|
18
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
19
|
+
|
|
20
|
+
# Playoffs season type constant
|
|
21
|
+
# @return [String] the season type
|
|
22
|
+
PLAYOFFS = "Playoffs".freeze
|
|
23
|
+
|
|
24
|
+
# Per game mode constant
|
|
25
|
+
# @return [String] the per mode
|
|
26
|
+
PER_GAME = "PerGame".freeze
|
|
27
|
+
|
|
28
|
+
# Totals mode constant
|
|
29
|
+
# @return [String] the per mode
|
|
30
|
+
TOTALS = "Totals".freeze
|
|
31
|
+
|
|
32
|
+
# Retrieves all league-wide team tracking shot statistics
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# stats = NBA::LeagueDashTeamPtShot.all(season: 2024)
|
|
37
|
+
# stats.first.fg_pct #=> 0.472
|
|
38
|
+
# @param season [Integer] the season year
|
|
39
|
+
# @param season_type [String] the season type
|
|
40
|
+
# @param per_mode [String] the per mode
|
|
41
|
+
# @param client [Client] the API client to use
|
|
42
|
+
# @return [Collection] a collection of team tracking shot statistics
|
|
43
|
+
def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
|
|
44
|
+
path = build_path(season, season_type: season_type, per_mode: per_mode)
|
|
45
|
+
response = client.get(path)
|
|
46
|
+
parse_response(response)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Builds the API request path
|
|
50
|
+
#
|
|
51
|
+
# @api private
|
|
52
|
+
# @return [String] the request path
|
|
53
|
+
def self.build_path(season, opts)
|
|
54
|
+
season_str = Utils.format_season(season)
|
|
55
|
+
"leaguedashteamptshot?LeagueID=00&Season=#{season_str}" \
|
|
56
|
+
"&SeasonType=#{opts.fetch(:season_type)}&PerMode=#{opts.fetch(:per_mode)}"
|
|
57
|
+
end
|
|
58
|
+
private_class_method :build_path
|
|
59
|
+
|
|
60
|
+
# Parses the API response into stat objects
|
|
61
|
+
#
|
|
62
|
+
# @api private
|
|
63
|
+
# @return [Collection] collection of team PT shot stats
|
|
64
|
+
def self.parse_response(response)
|
|
65
|
+
return Collection.new if response.nil? || response.empty?
|
|
66
|
+
|
|
67
|
+
data = JSON.parse(response)
|
|
68
|
+
result_set = find_result_set(data)
|
|
69
|
+
build_stats(result_set)
|
|
70
|
+
end
|
|
71
|
+
private_class_method :parse_response
|
|
72
|
+
|
|
73
|
+
# Finds the result set by name
|
|
74
|
+
#
|
|
75
|
+
# @api private
|
|
76
|
+
# @return [Hash, nil] the result set hash or nil if not found
|
|
77
|
+
def self.find_result_set(data)
|
|
78
|
+
result_sets = data["resultSets"]
|
|
79
|
+
return unless result_sets
|
|
80
|
+
|
|
81
|
+
result_sets.find { |rs| rs["name"].eql?(LEAGUE_DASH_PT_SHOTS) }
|
|
82
|
+
end
|
|
83
|
+
private_class_method :find_result_set
|
|
84
|
+
|
|
85
|
+
# Builds stats collection from result set
|
|
86
|
+
#
|
|
87
|
+
# @api private
|
|
88
|
+
# @return [Collection] the stats collection
|
|
89
|
+
def self.build_stats(result_set)
|
|
90
|
+
return Collection.new unless result_set
|
|
91
|
+
|
|
92
|
+
headers = result_set["headers"]
|
|
93
|
+
rows = result_set["rowSet"]
|
|
94
|
+
return Collection.new unless headers && rows
|
|
95
|
+
|
|
96
|
+
Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
|
|
97
|
+
end
|
|
98
|
+
private_class_method :build_stats
|
|
99
|
+
|
|
100
|
+
# Builds a single stat object from API data
|
|
101
|
+
#
|
|
102
|
+
# @api private
|
|
103
|
+
# @return [LeagueDashTeamPtShotStat] the stat object
|
|
104
|
+
def self.build_stat(data)
|
|
105
|
+
LeagueDashTeamPtShotStat.new(**identity_info(data), **shooting_info(data), **two_point_info(data),
|
|
106
|
+
**three_point_info(data))
|
|
107
|
+
end
|
|
108
|
+
private_class_method :build_stat
|
|
109
|
+
|
|
110
|
+
# Extracts identity information from data
|
|
111
|
+
#
|
|
112
|
+
# @api private
|
|
113
|
+
# @return [Hash] the identity information hash
|
|
114
|
+
def self.identity_info(data)
|
|
115
|
+
{team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
|
|
116
|
+
team_abbreviation: data["TEAM_ABBREVIATION"], gp: data["GP"], g: data["G"]}
|
|
117
|
+
end
|
|
118
|
+
private_class_method :identity_info
|
|
119
|
+
|
|
120
|
+
# Extracts shooting information from data
|
|
121
|
+
#
|
|
122
|
+
# @api private
|
|
123
|
+
# @return [Hash] the shooting information hash
|
|
124
|
+
def self.shooting_info(data)
|
|
125
|
+
{fga_frequency: data["FGA_FREQUENCY"], fgm: data["FGM"],
|
|
126
|
+
fga: data["FGA"], fg_pct: data["FG_PCT"], efg_pct: data["EFG_PCT"]}
|
|
127
|
+
end
|
|
128
|
+
private_class_method :shooting_info
|
|
129
|
+
|
|
130
|
+
# Extracts 2-point shooting information from data
|
|
131
|
+
#
|
|
132
|
+
# @api private
|
|
133
|
+
# @return [Hash] the 2-point shooting information hash
|
|
134
|
+
def self.two_point_info(data)
|
|
135
|
+
{fg2a_frequency: data["FG2A_FREQUENCY"], fg2m: data["FG2M"],
|
|
136
|
+
fg2a: data["FG2A"], fg2_pct: data["FG2_PCT"]}
|
|
137
|
+
end
|
|
138
|
+
private_class_method :two_point_info
|
|
139
|
+
|
|
140
|
+
# Extracts 3-point shooting information from data
|
|
141
|
+
#
|
|
142
|
+
# @api private
|
|
143
|
+
# @return [Hash] the 3-point shooting information hash
|
|
144
|
+
def self.three_point_info(data)
|
|
145
|
+
{fg3a_frequency: data["FG3A_FREQUENCY"], fg3m: data["FG3M"],
|
|
146
|
+
fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"]}
|
|
147
|
+
end
|
|
148
|
+
private_class_method :three_point_info
|
|
149
|
+
end
|
|
150
|
+
end
|