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,145 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "players"
4
+ require_relative "teams"
5
+
6
+ module NBA
7
+ # Represents league-wide player defensive statistics
8
+ #
9
+ # @api public
10
+ class LeagueDashPtDefendStat < Shale::Mapper
11
+ include Equalizer.new(:player_id, :team_id)
12
+
13
+ # @!attribute [rw] player_id
14
+ # Returns the player ID (close defender)
15
+ # @api public
16
+ # @example
17
+ # stat.player_id #=> 201939
18
+ # @return [Integer, nil] the player's ID
19
+ attribute :player_id, Shale::Type::Integer
20
+
21
+ # @!attribute [rw] player_name
22
+ # Returns the player name
23
+ # @api public
24
+ # @example
25
+ # stat.player_name #=> "Stephen Curry"
26
+ # @return [String, nil] the player's name
27
+ attribute :player_name, Shale::Type::String
28
+
29
+ # @!attribute [rw] team_id
30
+ # Returns the player's last team ID
31
+ # @api public
32
+ # @example
33
+ # stat.team_id #=> 1610612744
34
+ # @return [Integer, nil] the team's ID
35
+ attribute :team_id, Shale::Type::Integer
36
+
37
+ # @!attribute [rw] team_abbreviation
38
+ # Returns the player's last team abbreviation
39
+ # @api public
40
+ # @example
41
+ # stat.team_abbreviation #=> "GSW"
42
+ # @return [String, nil] the team's abbreviation
43
+ attribute :team_abbreviation, Shale::Type::String
44
+
45
+ # @!attribute [rw] player_position
46
+ # Returns the player's position
47
+ # @api public
48
+ # @example
49
+ # stat.player_position #=> "G"
50
+ # @return [String, nil] the player's position
51
+ attribute :player_position, Shale::Type::String
52
+
53
+ # @!attribute [rw] age
54
+ # Returns the player's age
55
+ # @api public
56
+ # @example
57
+ # stat.age #=> 36.0
58
+ # @return [Float, nil] the player's age
59
+ attribute :age, Shale::Type::Float
60
+
61
+ # @!attribute [rw] gp
62
+ # Returns games played
63
+ # @api public
64
+ # @example
65
+ # stat.gp #=> 82
66
+ # @return [Integer, nil] games played
67
+ attribute :gp, Shale::Type::Integer
68
+
69
+ # @!attribute [rw] g
70
+ # Returns games (alias for games played)
71
+ # @api public
72
+ # @example
73
+ # stat.g #=> 82
74
+ # @return [Integer, nil] games
75
+ attribute :g, Shale::Type::Integer
76
+
77
+ # @!attribute [rw] freq
78
+ # Returns frequency percentage
79
+ # @api public
80
+ # @example
81
+ # stat.freq #=> 0.089
82
+ # @return [Float, nil] frequency percentage
83
+ attribute :freq, Shale::Type::Float
84
+
85
+ # @!attribute [rw] d_fgm
86
+ # Returns defended field goals made
87
+ # @api public
88
+ # @example
89
+ # stat.d_fgm #=> 245
90
+ # @return [Float, nil] defended field goals made
91
+ attribute :d_fgm, Shale::Type::Float
92
+
93
+ # @!attribute [rw] d_fga
94
+ # Returns defended field goals attempted
95
+ # @api public
96
+ # @example
97
+ # stat.d_fga #=> 612
98
+ # @return [Float, nil] defended field goals attempted
99
+ attribute :d_fga, Shale::Type::Float
100
+
101
+ # @!attribute [rw] d_fg_pct
102
+ # Returns defended field goal percentage
103
+ # @api public
104
+ # @example
105
+ # stat.d_fg_pct #=> 0.400
106
+ # @return [Float, nil] defended field goal percentage
107
+ attribute :d_fg_pct, Shale::Type::Float
108
+
109
+ # @!attribute [rw] normal_fg_pct
110
+ # Returns normal (uncontested) field goal percentage
111
+ # @api public
112
+ # @example
113
+ # stat.normal_fg_pct #=> 0.450
114
+ # @return [Float, nil] normal field goal percentage
115
+ attribute :normal_fg_pct, Shale::Type::Float
116
+
117
+ # @!attribute [rw] pct_plusminus
118
+ # Returns percentage plus/minus (difference from normal)
119
+ # @api public
120
+ # @example
121
+ # stat.pct_plusminus #=> -0.050
122
+ # @return [Float, nil] percentage plus/minus
123
+ attribute :pct_plusminus, Shale::Type::Float
124
+
125
+ # Returns the player
126
+ #
127
+ # @api public
128
+ # @example
129
+ # stat.player #=> #<NBA::Player id=201939 ...>
130
+ # @return [Player, nil] the player object
131
+ def player
132
+ Players.find(player_id)
133
+ end
134
+
135
+ # Returns the team
136
+ #
137
+ # @api public
138
+ # @example
139
+ # stat.team #=> #<NBA::Team id=1610612744 ...>
140
+ # @return [Team, nil] the team object
141
+ def team
142
+ Teams.find(team_id)
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,152 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "league_dash_pt_stats_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve league-wide player and team tracking statistics
9
+ #
10
+ # @api public
11
+ module LeagueDashPtStats
12
+ # Result set name for league dash PT stats
13
+ # @return [String] the result set name
14
+ LEAGUE_DASH_PT_STATS = "LeagueDashPtStats".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
+ # Player mode constant
33
+ # @return [String] the player or team mode
34
+ PLAYER = "Player".freeze
35
+
36
+ # Team mode constant
37
+ # @return [String] the player or team mode
38
+ TEAM = "Team".freeze
39
+
40
+ # Speed and distance measure type constant
41
+ # @return [String] the PT measure type
42
+ SPEED_DISTANCE = "SpeedDistance".freeze
43
+
44
+ # Retrieves all league-wide player or team tracking statistics
45
+ #
46
+ # @api public
47
+ # @example
48
+ # stats = NBA::LeagueDashPtStats.all(season: 2024)
49
+ # stats.first.avg_speed #=> 4.25
50
+ # @param season [Integer] the season year
51
+ # @param season_type [String] the season type
52
+ # @param per_mode [String] the per mode
53
+ # @param player_or_team [String] whether to get player or team stats
54
+ # @param pt_measure_type [String] the PT measure type
55
+ # @param client [Client] the API client to use
56
+ # @return [Collection] a collection of tracking statistics
57
+ def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME,
58
+ player_or_team: PLAYER, pt_measure_type: SPEED_DISTANCE, client: CLIENT)
59
+ path = build_path(season, season_type: season_type, per_mode: per_mode,
60
+ player_or_team: player_or_team, pt_measure_type: pt_measure_type)
61
+ response = client.get(path)
62
+ parse_response(response)
63
+ end
64
+
65
+ # Builds the API request path
66
+ #
67
+ # @api private
68
+ # @return [String] the request path
69
+ def self.build_path(season, opts)
70
+ season_str = Utils.format_season(season)
71
+ "leaguedashptstats?LeagueID=00&Season=#{season_str}" \
72
+ "&SeasonType=#{opts.fetch(:season_type)}" \
73
+ "&PerMode=#{opts.fetch(:per_mode)}&PlayerOrTeam=#{opts.fetch(:player_or_team)}" \
74
+ "&PtMeasureType=#{opts.fetch(:pt_measure_type)}"
75
+ end
76
+ private_class_method :build_path
77
+
78
+ # Parses the API response into stat objects
79
+ #
80
+ # @api private
81
+ # @return [Collection] collection of PT stats
82
+ def self.parse_response(response)
83
+ return Collection.new if response.nil? || response.empty?
84
+
85
+ data = JSON.parse(response)
86
+ result_set = find_result_set(data)
87
+ build_stats(result_set)
88
+ end
89
+ private_class_method :parse_response
90
+
91
+ # Finds the result set by name
92
+ #
93
+ # @api private
94
+ # @return [Hash, nil] the result set hash or nil if not found
95
+ def self.find_result_set(data)
96
+ result_sets = data["resultSets"]
97
+ return unless result_sets
98
+
99
+ result_sets.find { |rs| rs["name"].eql?(LEAGUE_DASH_PT_STATS) }
100
+ end
101
+ private_class_method :find_result_set
102
+
103
+ # Builds stats collection from result set
104
+ #
105
+ # @api private
106
+ # @return [Collection] the stats collection
107
+ def self.build_stats(result_set)
108
+ return Collection.new unless result_set
109
+
110
+ headers = result_set["headers"]
111
+ rows = result_set["rowSet"]
112
+ return Collection.new unless headers && rows
113
+
114
+ Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
115
+ end
116
+ private_class_method :build_stats
117
+
118
+ # Builds a single stat object from API data
119
+ #
120
+ # @api private
121
+ # @return [LeagueDashPtStatsStat] the stat object
122
+ def self.build_stat(data)
123
+ LeagueDashPtStatsStat.new(**identity_info(data), **speed_info(data))
124
+ end
125
+ private_class_method :build_stat
126
+
127
+ # Extracts identity information from data
128
+ #
129
+ # @api private
130
+ # @return [Hash] the identity information hash
131
+ def self.identity_info(data)
132
+ {player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
133
+ team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
134
+ team_name: data["TEAM_NAME"], age: data["AGE"],
135
+ gp: data["GP"], w: data["W"], l: data["L"],
136
+ min: data["MIN"]}
137
+ end
138
+ private_class_method :identity_info
139
+
140
+ # Extracts speed and distance information from data
141
+ #
142
+ # @api private
143
+ # @return [Hash] the speed and distance statistics hash
144
+ def self.speed_info(data)
145
+ {dist_feet: data["DIST_FEET"], dist_miles: data["DIST_MILES"],
146
+ dist_miles_off: data["DIST_MILES_OFF"], dist_miles_def: data["DIST_MILES_DEF"],
147
+ avg_speed: data["AVG_SPEED"], avg_speed_off: data["AVG_SPEED_OFF"],
148
+ avg_speed_def: data["AVG_SPEED_DEF"]}
149
+ end
150
+ private_class_method :speed_info
151
+ end
152
+ end
@@ -0,0 +1,169 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "players"
4
+ require_relative "teams"
5
+
6
+ module NBA
7
+ # Represents league-wide player or team speed and distance tracking statistics
8
+ #
9
+ # @api public
10
+ class LeagueDashPtStatsStat < Shale::Mapper
11
+ include Equalizer.new(:player_id, :team_id)
12
+
13
+ # @!attribute [rw] player_id
14
+ # Returns the player ID (for player mode)
15
+ # @api public
16
+ # @example
17
+ # stat.player_id #=> 201939
18
+ # @return [Integer, nil] the player's ID
19
+ attribute :player_id, Shale::Type::Integer
20
+
21
+ # @!attribute [rw] player_name
22
+ # Returns the player name (for player mode)
23
+ # @api public
24
+ # @example
25
+ # stat.player_name #=> "Stephen Curry"
26
+ # @return [String, nil] the player's name
27
+ attribute :player_name, Shale::Type::String
28
+
29
+ # @!attribute [rw] team_id
30
+ # Returns the team ID
31
+ # @api public
32
+ # @example
33
+ # stat.team_id #=> 1610612744
34
+ # @return [Integer, nil] the team's ID
35
+ attribute :team_id, Shale::Type::Integer
36
+
37
+ # @!attribute [rw] team_abbreviation
38
+ # Returns the team abbreviation
39
+ # @api public
40
+ # @example
41
+ # stat.team_abbreviation #=> "GSW"
42
+ # @return [String, nil] the team's abbreviation
43
+ attribute :team_abbreviation, Shale::Type::String
44
+
45
+ # @!attribute [rw] team_name
46
+ # Returns the team name (for team mode)
47
+ # @api public
48
+ # @example
49
+ # stat.team_name #=> "Golden State Warriors"
50
+ # @return [String, nil] the team's name
51
+ attribute :team_name, Shale::Type::String
52
+
53
+ # @!attribute [rw] age
54
+ # Returns the player's age (for player mode)
55
+ # @api public
56
+ # @example
57
+ # stat.age #=> 36.0
58
+ # @return [Float, nil] the player's age
59
+ attribute :age, Shale::Type::Float
60
+
61
+ # @!attribute [rw] gp
62
+ # Returns games played
63
+ # @api public
64
+ # @example
65
+ # stat.gp #=> 82
66
+ # @return [Integer, nil] games played
67
+ attribute :gp, Shale::Type::Integer
68
+
69
+ # @!attribute [rw] w
70
+ # Returns wins
71
+ # @api public
72
+ # @example
73
+ # stat.w #=> 50
74
+ # @return [Integer, nil] wins
75
+ attribute :w, Shale::Type::Integer
76
+
77
+ # @!attribute [rw] l
78
+ # Returns losses
79
+ # @api public
80
+ # @example
81
+ # stat.l #=> 32
82
+ # @return [Integer, nil] losses
83
+ attribute :l, Shale::Type::Integer
84
+
85
+ # @!attribute [rw] min
86
+ # Returns minutes played
87
+ # @api public
88
+ # @example
89
+ # stat.min #=> 32.5
90
+ # @return [Float, nil] minutes played
91
+ attribute :min, Shale::Type::Float
92
+
93
+ # @!attribute [rw] dist_feet
94
+ # Returns distance traveled in feet
95
+ # @api public
96
+ # @example
97
+ # stat.dist_feet #=> 12500.5
98
+ # @return [Float, nil] distance in feet
99
+ attribute :dist_feet, Shale::Type::Float
100
+
101
+ # @!attribute [rw] dist_miles
102
+ # Returns distance traveled in miles
103
+ # @api public
104
+ # @example
105
+ # stat.dist_miles #=> 2.37
106
+ # @return [Float, nil] distance in miles
107
+ attribute :dist_miles, Shale::Type::Float
108
+
109
+ # @!attribute [rw] dist_miles_off
110
+ # Returns distance traveled on offense in miles
111
+ # @api public
112
+ # @example
113
+ # stat.dist_miles_off #=> 1.15
114
+ # @return [Float, nil] distance on offense in miles
115
+ attribute :dist_miles_off, Shale::Type::Float
116
+
117
+ # @!attribute [rw] dist_miles_def
118
+ # Returns distance traveled on defense in miles
119
+ # @api public
120
+ # @example
121
+ # stat.dist_miles_def #=> 1.22
122
+ # @return [Float, nil] distance on defense in miles
123
+ attribute :dist_miles_def, Shale::Type::Float
124
+
125
+ # @!attribute [rw] avg_speed
126
+ # Returns average speed
127
+ # @api public
128
+ # @example
129
+ # stat.avg_speed #=> 4.25
130
+ # @return [Float, nil] average speed
131
+ attribute :avg_speed, Shale::Type::Float
132
+
133
+ # @!attribute [rw] avg_speed_off
134
+ # Returns average speed on offense
135
+ # @api public
136
+ # @example
137
+ # stat.avg_speed_off #=> 4.15
138
+ # @return [Float, nil] average speed on offense
139
+ attribute :avg_speed_off, Shale::Type::Float
140
+
141
+ # @!attribute [rw] avg_speed_def
142
+ # Returns average speed on defense
143
+ # @api public
144
+ # @example
145
+ # stat.avg_speed_def #=> 4.35
146
+ # @return [Float, nil] average speed on defense
147
+ attribute :avg_speed_def, Shale::Type::Float
148
+
149
+ # Returns the player
150
+ #
151
+ # @api public
152
+ # @example
153
+ # stat.player #=> #<NBA::Player id=201939 ...>
154
+ # @return [Player, nil] the player object
155
+ def player
156
+ Players.find(player_id)
157
+ end
158
+
159
+ # Returns the team
160
+ #
161
+ # @api public
162
+ # @example
163
+ # stat.team #=> #<NBA::Team id=1610612744 ...>
164
+ # @return [Team, nil] the team object
165
+ def team
166
+ Teams.find(team_id)
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,158 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "league_dash_pt_team_defend_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve league-wide team defensive tracking statistics
9
+ #
10
+ # @api public
11
+ module LeagueDashPtTeamDefend
12
+ # Result set name for league dash PT team defend
13
+ # @return [String] the result set name
14
+ LEAGUE_DASH_PT_TEAM_DEFEND = "LeagueDashPtTeamDefend".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
+ # Overall defense category constant
33
+ # @return [String] the defense category
34
+ OVERALL = "Overall".freeze
35
+
36
+ # 3 Pointers defense category constant
37
+ # @return [String] the defense category
38
+ THREE_POINTERS = "3 Pointers".freeze
39
+
40
+ # 2 Pointers defense category constant
41
+ # @return [String] the defense category
42
+ TWO_POINTERS = "2 Pointers".freeze
43
+
44
+ # Less than 6ft defense category constant
45
+ # @return [String] the defense category
46
+ LESS_THAN_6FT = "Less Than 6Ft".freeze
47
+
48
+ # Less than 10ft defense category constant
49
+ # @return [String] the defense category
50
+ LESS_THAN_10FT = "Less Than 10Ft".freeze
51
+
52
+ # Greater than 15ft defense category constant
53
+ # @return [String] the defense category
54
+ GREATER_THAN_15FT = "Greater Than 15Ft".freeze
55
+
56
+ # Retrieves all league-wide team defensive tracking statistics
57
+ #
58
+ # @api public
59
+ # @example
60
+ # stats = NBA::LeagueDashPtTeamDefend.all(season: 2024)
61
+ # stats.first.d_fg_pct #=> 0.421
62
+ # @param season [Integer] the season year
63
+ # @param season_type [String] the season type
64
+ # @param per_mode [String] the per mode
65
+ # @param defense_category [String] the defense category
66
+ # @param client [Client] the API client to use
67
+ # @return [Collection] a collection of team defensive statistics
68
+ def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME,
69
+ defense_category: OVERALL, client: CLIENT)
70
+ path = build_path(season, season_type: season_type, per_mode: per_mode, defense_category: defense_category)
71
+ response = client.get(path)
72
+ parse_response(response)
73
+ end
74
+
75
+ # Builds the API request path
76
+ #
77
+ # @api private
78
+ # @return [String] the request path
79
+ def self.build_path(season, opts)
80
+ season_str = Utils.format_season(season)
81
+ "leaguedashptteamdefend?LeagueID=00&Season=#{season_str}" \
82
+ "&SeasonType=#{opts.fetch(:season_type)}" \
83
+ "&PerMode=#{opts.fetch(:per_mode)}&DefenseCategory=#{opts.fetch(:defense_category)}"
84
+ end
85
+ private_class_method :build_path
86
+
87
+ # Parses the API response into stat objects
88
+ #
89
+ # @api private
90
+ # @return [Collection] collection of PT team defend stats
91
+ def self.parse_response(response)
92
+ return Collection.new if response.nil? || response.empty?
93
+
94
+ data = JSON.parse(response)
95
+ result_set = find_result_set(data)
96
+ build_stats(result_set)
97
+ end
98
+ private_class_method :parse_response
99
+
100
+ # Finds the result set by name
101
+ #
102
+ # @api private
103
+ # @return [Hash, nil] the result set hash or nil if not found
104
+ def self.find_result_set(data)
105
+ result_sets = data["resultSets"]
106
+ return unless result_sets
107
+
108
+ result_sets.find { |rs| rs["name"].eql?(LEAGUE_DASH_PT_TEAM_DEFEND) }
109
+ end
110
+ private_class_method :find_result_set
111
+
112
+ # Builds stats collection from result set
113
+ #
114
+ # @api private
115
+ # @return [Collection] the stats collection
116
+ def self.build_stats(result_set)
117
+ return Collection.new unless result_set
118
+
119
+ headers = result_set["headers"]
120
+ rows = result_set["rowSet"]
121
+ return Collection.new unless headers && rows
122
+
123
+ Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
124
+ end
125
+ private_class_method :build_stats
126
+
127
+ # Builds a single stat object from API data
128
+ #
129
+ # @api private
130
+ # @return [LeagueDashPtTeamDefendStat] the stat object
131
+ def self.build_stat(data)
132
+ LeagueDashPtTeamDefendStat.new(**identity_info(data), **defensive_info(data))
133
+ end
134
+ private_class_method :build_stat
135
+
136
+ # Extracts identity information from data
137
+ #
138
+ # @api private
139
+ # @return [Hash] the identity information hash
140
+ def self.identity_info(data)
141
+ {team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
142
+ team_abbreviation: data["TEAM_ABBREVIATION"],
143
+ gp: data["GP"], g: data["G"]}
144
+ end
145
+ private_class_method :identity_info
146
+
147
+ # Extracts defensive statistics information from data
148
+ #
149
+ # @api private
150
+ # @return [Hash] the defensive statistics hash
151
+ def self.defensive_info(data)
152
+ {freq: data["FREQ"], d_fgm: data["D_FGM"], d_fga: data["D_FGA"],
153
+ d_fg_pct: data["D_FG_PCT"], normal_fg_pct: data["NORMAL_FG_PCT"],
154
+ pct_plusminus: data["PCT_PLUSMINUS"]}
155
+ end
156
+ private_class_method :defensive_info
157
+ end
158
+ end