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.
Files changed (321) hide show
  1. checksums.yaml +5 -5
  2. data/AGENTS.md +362 -0
  3. data/CHANGELOG.md +169 -0
  4. data/CLAUDE.md +1 -0
  5. data/LICENSE +21 -0
  6. data/README.md +501 -101
  7. data/bin/console +10 -0
  8. data/bin/setup +6 -0
  9. data/exe/nba +8 -0
  10. data/lib/nba/all_time_leader.rb +77 -0
  11. data/lib/nba/all_time_leaders.rb +185 -0
  12. data/lib/nba/assist_leader.rb +92 -0
  13. data/lib/nba/assist_leaders.rb +64 -0
  14. data/lib/nba/assist_tracker.rb +108 -0
  15. data/lib/nba/assist_tracker_entry.rb +206 -0
  16. data/lib/nba/award.rb +128 -0
  17. data/lib/nba/box_score.rb +2 -0
  18. data/lib/nba/box_score_advanced.rb +114 -0
  19. data/lib/nba/box_score_advanced_player_stat.rb +297 -0
  20. data/lib/nba/box_score_advanced_team_stat.rb +237 -0
  21. data/lib/nba/box_score_advanced_v3.rb +124 -0
  22. data/lib/nba/box_score_defensive_player_stat.rb +281 -0
  23. data/lib/nba/box_score_defensive_team_stat.rb +85 -0
  24. data/lib/nba/box_score_defensive_v2.rb +190 -0
  25. data/lib/nba/box_score_four_factors.rb +91 -0
  26. data/lib/nba/box_score_four_factors_player_stat.rb +185 -0
  27. data/lib/nba/box_score_four_factors_team_stat.rb +141 -0
  28. data/lib/nba/box_score_four_factors_v3.rb +133 -0
  29. data/lib/nba/box_score_hustle.rb +226 -0
  30. data/lib/nba/box_score_hustle_player_stat.rb +233 -0
  31. data/lib/nba/box_score_hustle_team_stat.rb +189 -0
  32. data/lib/nba/box_score_matchup_stat.rb +417 -0
  33. data/lib/nba/box_score_matchups_v3.rb +184 -0
  34. data/lib/nba/box_score_misc.rb +100 -0
  35. data/lib/nba/box_score_misc_player_stat.rb +217 -0
  36. data/lib/nba/box_score_misc_team_stat.rb +173 -0
  37. data/lib/nba/box_score_misc_v3.rb +163 -0
  38. data/lib/nba/box_score_player_stat.rb +273 -0
  39. data/lib/nba/box_score_player_track.rb +223 -0
  40. data/lib/nba/box_score_player_track_stat.rb +273 -0
  41. data/lib/nba/box_score_player_track_team_stat.rb +229 -0
  42. data/lib/nba/box_score_scoring.rb +103 -0
  43. data/lib/nba/box_score_scoring_player_stat.rb +241 -0
  44. data/lib/nba/box_score_scoring_team_stat.rb +197 -0
  45. data/lib/nba/box_score_scoring_v3.rb +170 -0
  46. data/lib/nba/box_score_similarity_score.rb +119 -0
  47. data/lib/nba/box_score_similarity_stat.rb +76 -0
  48. data/lib/nba/box_score_starter_bench_stat.rb +257 -0
  49. data/lib/nba/box_score_summary.rb +285 -0
  50. data/lib/nba/box_score_summary_v2.rb +202 -0
  51. data/lib/nba/box_score_summary_v3.rb +120 -0
  52. data/lib/nba/box_score_summary_v3_data.rb +419 -0
  53. data/lib/nba/box_score_team_stat.rb +229 -0
  54. data/lib/nba/box_score_traditional.rb +101 -0
  55. data/lib/nba/box_score_traditional_v3.rb +195 -0
  56. data/lib/nba/box_score_usage.rb +102 -0
  57. data/lib/nba/box_score_usage_player_stat.rb +265 -0
  58. data/lib/nba/box_score_usage_team_stat.rb +221 -0
  59. data/lib/nba/box_score_usage_v3.rb +169 -0
  60. data/lib/nba/box_score_v3_helpers.rb +144 -0
  61. data/lib/nba/career_stats.rb +217 -0
  62. data/lib/nba/cli/display/player_display.rb +98 -0
  63. data/lib/nba/cli/display.rb +178 -0
  64. data/lib/nba/cli/formatters/game_formatters.rb +86 -0
  65. data/lib/nba/cli/formatters/leaders_formatters.rb +26 -0
  66. data/lib/nba/cli/formatters/player_formatters.rb +52 -0
  67. data/lib/nba/cli/formatters/standings_formatters.rb +26 -0
  68. data/lib/nba/cli/formatters/team_formatters.rb +67 -0
  69. data/lib/nba/cli/formatters/time_formatters.rb +82 -0
  70. data/lib/nba/cli/formatters.rb +56 -0
  71. data/lib/nba/cli/helpers.rb +135 -0
  72. data/lib/nba/cli.rb +171 -20
  73. data/lib/nba/client.rb +35 -0
  74. data/lib/nba/collection.rb +89 -0
  75. data/lib/nba/college_player_stat.rb +200 -0
  76. data/lib/nba/common_player_info.rb +142 -0
  77. data/lib/nba/common_playoff_series.rb +90 -0
  78. data/lib/nba/common_team_years.rb +113 -0
  79. data/lib/nba/conference.rb +39 -0
  80. data/lib/nba/connection.rb +84 -0
  81. data/lib/nba/cume_stats_player.rb +358 -0
  82. data/lib/nba/cume_stats_player_game.rb +217 -0
  83. data/lib/nba/cume_stats_player_games.rb +99 -0
  84. data/lib/nba/cume_stats_player_games_entry.rb +25 -0
  85. data/lib/nba/cume_stats_player_total.rb +481 -0
  86. data/lib/nba/cume_stats_team.rb +349 -0
  87. data/lib/nba/cume_stats_team_games.rb +145 -0
  88. data/lib/nba/cume_stats_team_games_entry.rb +25 -0
  89. data/lib/nba/cume_stats_team_player.rb +485 -0
  90. data/lib/nba/cume_stats_team_total.rb +267 -0
  91. data/lib/nba/data.rb +73 -0
  92. data/lib/nba/defense_hub.rb +109 -0
  93. data/lib/nba/defense_hub_stat.rb +57 -0
  94. data/lib/nba/defensive_shot_stat.rb +102 -0
  95. data/lib/nba/division.rb +49 -0
  96. data/lib/nba/draft_board.rb +126 -0
  97. data/lib/nba/draft_board_pick.rb +173 -0
  98. data/lib/nba/draft_combine_anthro_measurement.rb +163 -0
  99. data/lib/nba/draft_combine_drill_result.rb +115 -0
  100. data/lib/nba/draft_combine_drill_results.rb +112 -0
  101. data/lib/nba/draft_combine_non_stationary_shooting.rb +268 -0
  102. data/lib/nba/draft_combine_non_stationary_shooting_result.rb +355 -0
  103. data/lib/nba/draft_combine_player_anthro.rb +133 -0
  104. data/lib/nba/draft_combine_spot_shooting.rb +243 -0
  105. data/lib/nba/draft_combine_spot_shooting_result.rb +419 -0
  106. data/lib/nba/draft_combine_stat.rb +211 -0
  107. data/lib/nba/draft_combine_stats.rb +160 -0
  108. data/lib/nba/draft_history.rb +142 -0
  109. data/lib/nba/draft_pick.rb +154 -0
  110. data/lib/nba/dunk_score_leader.rb +93 -0
  111. data/lib/nba/dunk_score_leaders.rb +77 -0
  112. data/lib/nba/estimated_metrics_stat.rb +152 -0
  113. data/lib/nba/fantasy_profile_stat.rb +142 -0
  114. data/lib/nba/fantasy_widget.rb +72 -0
  115. data/lib/nba/fantasy_widget_player.rb +98 -0
  116. data/lib/nba/found_game.rb +260 -0
  117. data/lib/nba/franchise.rb +136 -0
  118. data/lib/nba/franchise_history.rb +142 -0
  119. data/lib/nba/franchise_leader.rb +147 -0
  120. data/lib/nba/franchise_leaders.rb +162 -0
  121. data/lib/nba/franchise_player.rb +224 -0
  122. data/lib/nba/franchise_players.rb +147 -0
  123. data/lib/nba/game.rb +80 -64
  124. data/lib/nba/game_log.rb +349 -0
  125. data/lib/nba/game_rotation.rb +152 -0
  126. data/lib/nba/game_streak.rb +102 -0
  127. data/lib/nba/games.rb +46 -0
  128. data/lib/nba/home_page_leader.rb +99 -0
  129. data/lib/nba/home_page_leaders.rb +75 -0
  130. data/lib/nba/home_page_stat.rb +57 -0
  131. data/lib/nba/home_page_v2.rb +110 -0
  132. data/lib/nba/hustle_stats_box_score.rb +182 -0
  133. data/lib/nba/infographic_fan_duel_player.rb +139 -0
  134. data/lib/nba/infographic_fan_duel_player_stat.rb +311 -0
  135. data/lib/nba/ist_standing.rb +167 -0
  136. data/lib/nba/ist_standings.rb +81 -0
  137. data/lib/nba/leader.rb +103 -0
  138. data/lib/nba/leaders.rb +110 -0
  139. data/lib/nba/leaders_tile.rb +57 -0
  140. data/lib/nba/leaders_tiles.rb +90 -0
  141. data/lib/nba/league.rb +37 -0
  142. data/lib/nba/league_dash_lineup_stat.rb +270 -0
  143. data/lib/nba/league_dash_lineups.rb +177 -0
  144. data/lib/nba/league_dash_opp_pt_shot.rb +150 -0
  145. data/lib/nba/league_dash_player_bio_stat.rb +217 -0
  146. data/lib/nba/league_dash_player_bio_stats.rb +164 -0
  147. data/lib/nba/league_dash_player_clutch.rb +212 -0
  148. data/lib/nba/league_dash_player_clutch_stat.rb +271 -0
  149. data/lib/nba/league_dash_player_pt_shot.rb +152 -0
  150. data/lib/nba/league_dash_player_pt_shot_stat.rb +193 -0
  151. data/lib/nba/league_dash_player_shot_location_stat.rb +265 -0
  152. data/lib/nba/league_dash_player_shot_locations.rb +210 -0
  153. data/lib/nba/league_dash_player_stat.rb +306 -0
  154. data/lib/nba/league_dash_player_stats.rb +176 -0
  155. data/lib/nba/league_dash_pt_defend.rb +160 -0
  156. data/lib/nba/league_dash_pt_defend_stat.rb +145 -0
  157. data/lib/nba/league_dash_pt_stats.rb +152 -0
  158. data/lib/nba/league_dash_pt_stats_stat.rb +169 -0
  159. data/lib/nba/league_dash_pt_team_defend.rb +158 -0
  160. data/lib/nba/league_dash_pt_team_defend_stat.rb +110 -0
  161. data/lib/nba/league_dash_team_clutch.rb +211 -0
  162. data/lib/nba/league_dash_team_clutch_stat.rb +237 -0
  163. data/lib/nba/league_dash_team_pt_shot.rb +150 -0
  164. data/lib/nba/league_dash_team_pt_shot_stat.rb +166 -0
  165. data/lib/nba/league_dash_team_shot_location_stat.rb +230 -0
  166. data/lib/nba/league_dash_team_shot_locations.rb +208 -0
  167. data/lib/nba/league_dash_team_stat.rb +275 -0
  168. data/lib/nba/league_dash_team_stats.rb +172 -0
  169. data/lib/nba/league_game_finder.rb +170 -0
  170. data/lib/nba/league_game_log.rb +224 -0
  171. data/lib/nba/league_hustle_stats_player.rb +161 -0
  172. data/lib/nba/league_hustle_stats_player_stat.rb +253 -0
  173. data/lib/nba/league_hustle_stats_team.rb +157 -0
  174. data/lib/nba/league_hustle_stats_team_stat.rb +179 -0
  175. data/lib/nba/league_lineup_viz.rb +184 -0
  176. data/lib/nba/league_lineup_viz_stat.rb +214 -0
  177. data/lib/nba/league_player_on_details.rb +175 -0
  178. data/lib/nba/league_player_on_details_stat.rb +313 -0
  179. data/lib/nba/league_season_matchup_stat.rb +241 -0
  180. data/lib/nba/league_season_matchups.rb +181 -0
  181. data/lib/nba/league_standing.rb +284 -0
  182. data/lib/nba/league_standings.rb +159 -0
  183. data/lib/nba/league_wide_shot_stat.rb +62 -0
  184. data/lib/nba/live_action.rb +240 -0
  185. data/lib/nba/live_box_score.rb +143 -0
  186. data/lib/nba/live_connection.rb +84 -0
  187. data/lib/nba/live_game.rb +230 -0
  188. data/lib/nba/live_play_by_play.rb +120 -0
  189. data/lib/nba/live_player_stat.rb +276 -0
  190. data/lib/nba/live_scoreboard.rb +102 -0
  191. data/lib/nba/matchup_rollup.rb +98 -0
  192. data/lib/nba/matchups_rollup.rb +81 -0
  193. data/lib/nba/pass_stat.rb +209 -0
  194. data/lib/nba/play.rb +258 -0
  195. data/lib/nba/play_by_play.rb +85 -0
  196. data/lib/nba/play_by_play_v3.rb +91 -0
  197. data/lib/nba/play_type_stat.rb +206 -0
  198. data/lib/nba/player.rb +242 -24
  199. data/lib/nba/player_awards.rb +110 -0
  200. data/lib/nba/player_career_by_college.rb +86 -0
  201. data/lib/nba/player_career_by_college_rollup.rb +143 -0
  202. data/lib/nba/player_career_stats.rb +77 -0
  203. data/lib/nba/player_compare.rb +156 -0
  204. data/lib/nba/player_comparison_stat.rb +242 -0
  205. data/lib/nba/player_dash_pt_pass.rb +164 -0
  206. data/lib/nba/player_dash_pt_reb.rb +235 -0
  207. data/lib/nba/player_dash_pt_shot_defend.rb +119 -0
  208. data/lib/nba/player_dash_pt_shots.rb +279 -0
  209. data/lib/nba/player_dashboard.rb +259 -0
  210. data/lib/nba/player_dashboard_stat.rb +248 -0
  211. data/lib/nba/player_estimated_metrics.rb +84 -0
  212. data/lib/nba/player_fantasy_profile_bar_graph.rb +147 -0
  213. data/lib/nba/player_game_log.rb +72 -0
  214. data/lib/nba/player_game_logs.rb +117 -0
  215. data/lib/nba/player_game_streak_finder.rb +108 -0
  216. data/lib/nba/player_index.rb +135 -0
  217. data/lib/nba/player_index_entry.rb +266 -0
  218. data/lib/nba/player_info.rb +225 -0
  219. data/lib/nba/player_next_n_games.rb +64 -0
  220. data/lib/nba/player_profile_v2.rb +169 -0
  221. data/lib/nba/player_vs_player.rb +153 -0
  222. data/lib/nba/players.rb +107 -0
  223. data/lib/nba/playoff_matchup.rb +84 -0
  224. data/lib/nba/playoff_picture.rb +98 -0
  225. data/lib/nba/playoff_series.rb +76 -0
  226. data/lib/nba/position.rb +48 -0
  227. data/lib/nba/rebound_stat.rb +189 -0
  228. data/lib/nba/response_parser.rb +116 -0
  229. data/lib/nba/roster.rb +74 -0
  230. data/lib/nba/rotation_entry.rb +154 -0
  231. data/lib/nba/schedule.rb +183 -0
  232. data/lib/nba/schedule_international.rb +182 -0
  233. data/lib/nba/scheduled_game.rb +240 -0
  234. data/lib/nba/scoreboard.rb +183 -0
  235. data/lib/nba/scoreboard_v3.rb +104 -0
  236. data/lib/nba/shot.rb +208 -0
  237. data/lib/nba/shot_chart.rb +75 -0
  238. data/lib/nba/shot_chart_league_wide.rb +102 -0
  239. data/lib/nba/shot_chart_lineup_detail.rb +109 -0
  240. data/lib/nba/shot_stat.rb +174 -0
  241. data/lib/nba/standing.rb +129 -0
  242. data/lib/nba/standings.rb +75 -0
  243. data/lib/nba/static.rb +107 -0
  244. data/lib/nba/synergy_play_types.rb +211 -0
  245. data/lib/nba/team.rb +203 -127
  246. data/lib/nba/team_and_players_vs_players.rb +227 -0
  247. data/lib/nba/team_and_players_vs_players_stat.rb +155 -0
  248. data/lib/nba/team_dash_pt_pass.rb +157 -0
  249. data/lib/nba/team_dash_pt_reb.rb +216 -0
  250. data/lib/nba/team_dash_pt_shots.rb +244 -0
  251. data/lib/nba/team_dashboard.rb +275 -0
  252. data/lib/nba/team_dashboard_stat.rb +248 -0
  253. data/lib/nba/team_detail.rb +117 -0
  254. data/lib/nba/team_details.rb +173 -0
  255. data/lib/nba/team_estimated_metrics.rb +91 -0
  256. data/lib/nba/team_estimated_metrics_stat.rb +146 -0
  257. data/lib/nba/team_game_log.rb +143 -0
  258. data/lib/nba/team_game_log_entry.rb +246 -0
  259. data/lib/nba/team_game_log_stat.rb +275 -0
  260. data/lib/nba/team_game_logs.rb +163 -0
  261. data/lib/nba/team_game_streak.rb +111 -0
  262. data/lib/nba/team_game_streak_finder.rb +109 -0
  263. data/lib/nba/team_historical_leader.rb +207 -0
  264. data/lib/nba/team_historical_leaders.rb +98 -0
  265. data/lib/nba/team_historical_record.rb +139 -0
  266. data/lib/nba/team_info.rb +150 -0
  267. data/lib/nba/team_info_common.rb +177 -0
  268. data/lib/nba/team_on_off_overall_stat.rb +477 -0
  269. data/lib/nba/team_on_off_player_stat.rb +523 -0
  270. data/lib/nba/team_on_off_player_summary.rb +135 -0
  271. data/lib/nba/team_pass_stat.rb +183 -0
  272. data/lib/nba/team_player_dashboard.rb +212 -0
  273. data/lib/nba/team_player_on_off_details.rb +218 -0
  274. data/lib/nba/team_player_on_off_summary.rb +214 -0
  275. data/lib/nba/team_player_stat.rb +275 -0
  276. data/lib/nba/team_rebound_stat.rb +189 -0
  277. data/lib/nba/team_season_rank.rb +110 -0
  278. data/lib/nba/team_shot_stat.rb +173 -0
  279. data/lib/nba/team_vs_player.rb +151 -0
  280. data/lib/nba/team_vs_player_stat.rb +157 -0
  281. data/lib/nba/team_year.rb +55 -0
  282. data/lib/nba/team_year_by_year_stats.rb +152 -0
  283. data/lib/nba/team_year_stat.rb +282 -0
  284. data/lib/nba/teams.rb +33 -0
  285. data/lib/nba/upcoming_game.rb +115 -0
  286. data/lib/nba/utils.rb +94 -0
  287. data/lib/nba/version.rb +5 -2
  288. data/lib/nba/video_detail.rb +103 -0
  289. data/lib/nba/video_details.rb +118 -0
  290. data/lib/nba/video_details_asset.rb +115 -0
  291. data/lib/nba/video_details_asset_entry.rb +91 -0
  292. data/lib/nba/video_event.rb +83 -0
  293. data/lib/nba/video_event_asset.rb +91 -0
  294. data/lib/nba/video_events.rb +106 -0
  295. data/lib/nba/video_events_asset.rb +107 -0
  296. data/lib/nba/video_status.rb +129 -0
  297. data/lib/nba/video_status_entry.rb +161 -0
  298. data/lib/nba/vs_player_stat.rb +156 -0
  299. data/lib/nba/win_probability.rb +117 -0
  300. data/lib/nba/win_probability_point.rb +140 -0
  301. data/lib/nba.rb +249 -5
  302. data/sig/equalizer.rbs +3 -0
  303. data/sig/nba.rbs +7297 -0
  304. data/sig/shale.rbs +24 -0
  305. data/sig/thor.rbs +19 -0
  306. metadata +324 -95
  307. data/.gitignore +0 -18
  308. data/.travis.yml +0 -22
  309. data/Gemfile +0 -23
  310. data/LICENSE.md +0 -22
  311. data/Rakefile +0 -18
  312. data/bin/nba +0 -7
  313. data/cache/teams.json +0 -16529
  314. data/lib/faraday_middleware/scrape_game.rb +0 -41
  315. data/lib/nba/request.rb +0 -37
  316. data/nba.gemspec +0 -28
  317. data/spec/fixtures/games.html +0 -785
  318. data/spec/fixtures/teams.json +0 -16529
  319. data/spec/game_spec.rb +0 -40
  320. data/spec/spec_helper.rb +0 -25
  321. 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