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,297 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents a player's advanced box score statistics for a game
6
+ class BoxScoreAdvancedPlayerStat < Shale::Mapper
7
+ include Equalizer.new(:game_id, :player_id)
8
+
9
+ # @!attribute [rw] game_id
10
+ # Returns the game ID
11
+ # @api public
12
+ # @example
13
+ # stat.game_id #=> "0022400350"
14
+ # @return [String] the game ID
15
+ attribute :game_id, Shale::Type::String
16
+
17
+ # @!attribute [rw] team_id
18
+ # Returns the team ID
19
+ # @api public
20
+ # @example
21
+ # stat.team_id #=> 1610612744
22
+ # @return [Integer] the team ID
23
+ attribute :team_id, Shale::Type::Integer
24
+
25
+ # @!attribute [rw] team_abbreviation
26
+ # Returns the team abbreviation
27
+ # @api public
28
+ # @example
29
+ # stat.team_abbreviation #=> "GSW"
30
+ # @return [String] the team abbreviation
31
+ attribute :team_abbreviation, Shale::Type::String
32
+
33
+ # @!attribute [rw] team_city
34
+ # Returns the team city
35
+ # @api public
36
+ # @example
37
+ # stat.team_city #=> "Golden State"
38
+ # @return [String] the team city
39
+ attribute :team_city, Shale::Type::String
40
+
41
+ # @!attribute [rw] player_id
42
+ # Returns the player ID
43
+ # @api public
44
+ # @example
45
+ # stat.player_id #=> 201939
46
+ # @return [Integer] the player ID
47
+ attribute :player_id, Shale::Type::Integer
48
+
49
+ # @!attribute [rw] player_name
50
+ # Returns the player name
51
+ # @api public
52
+ # @example
53
+ # stat.player_name #=> "Stephen Curry"
54
+ # @return [String] the player name
55
+ attribute :player_name, Shale::Type::String
56
+
57
+ # @!attribute [rw] start_position
58
+ # Returns the starting position
59
+ # @api public
60
+ # @example
61
+ # stat.start_position #=> "G"
62
+ # @return [String] the starting position
63
+ attribute :start_position, Shale::Type::String
64
+
65
+ # @!attribute [rw] comment
66
+ # Returns any comment (e.g., "DNP - Rest")
67
+ # @api public
68
+ # @example
69
+ # stat.comment #=> "DNP - Rest"
70
+ # @return [String] the comment
71
+ attribute :comment, Shale::Type::String
72
+
73
+ # @!attribute [rw] min
74
+ # Returns minutes played
75
+ # @api public
76
+ # @example
77
+ # stat.min #=> "32:45"
78
+ # @return [String] the minutes played
79
+ attribute :min, Shale::Type::String
80
+
81
+ # @!attribute [rw] e_off_rating
82
+ # Returns estimated offensive rating
83
+ # @api public
84
+ # @example
85
+ # stat.e_off_rating #=> 118.5
86
+ # @return [Float] the estimated offensive rating
87
+ attribute :e_off_rating, Shale::Type::Float
88
+
89
+ # @!attribute [rw] off_rating
90
+ # Returns offensive rating
91
+ # @api public
92
+ # @example
93
+ # stat.off_rating #=> 120.3
94
+ # @return [Float] the offensive rating
95
+ attribute :off_rating, Shale::Type::Float
96
+
97
+ # @!attribute [rw] e_def_rating
98
+ # Returns estimated defensive rating
99
+ # @api public
100
+ # @example
101
+ # stat.e_def_rating #=> 108.2
102
+ # @return [Float] the estimated defensive rating
103
+ attribute :e_def_rating, Shale::Type::Float
104
+
105
+ # @!attribute [rw] def_rating
106
+ # Returns defensive rating
107
+ # @api public
108
+ # @example
109
+ # stat.def_rating #=> 106.8
110
+ # @return [Float] the defensive rating
111
+ attribute :def_rating, Shale::Type::Float
112
+
113
+ # @!attribute [rw] e_net_rating
114
+ # Returns estimated net rating
115
+ # @api public
116
+ # @example
117
+ # stat.e_net_rating #=> 10.3
118
+ # @return [Float] the estimated net rating
119
+ attribute :e_net_rating, Shale::Type::Float
120
+
121
+ # @!attribute [rw] net_rating
122
+ # Returns net rating
123
+ # @api public
124
+ # @example
125
+ # stat.net_rating #=> 13.5
126
+ # @return [Float] the net rating
127
+ attribute :net_rating, Shale::Type::Float
128
+
129
+ # @!attribute [rw] ast_pct
130
+ # Returns assist percentage
131
+ # @api public
132
+ # @example
133
+ # stat.ast_pct #=> 45.2
134
+ # @return [Float] the assist percentage
135
+ attribute :ast_pct, Shale::Type::Float
136
+
137
+ # @!attribute [rw] ast_tov
138
+ # Returns assist to turnover ratio
139
+ # @api public
140
+ # @example
141
+ # stat.ast_tov #=> 2.75
142
+ # @return [Float] the assist to turnover ratio
143
+ attribute :ast_tov, Shale::Type::Float
144
+
145
+ # @!attribute [rw] ast_ratio
146
+ # Returns assist ratio
147
+ # @api public
148
+ # @example
149
+ # stat.ast_ratio #=> 28.5
150
+ # @return [Float] the assist ratio
151
+ attribute :ast_ratio, Shale::Type::Float
152
+
153
+ # @!attribute [rw] oreb_pct
154
+ # Returns offensive rebound percentage
155
+ # @api public
156
+ # @example
157
+ # stat.oreb_pct #=> 3.2
158
+ # @return [Float] the offensive rebound percentage
159
+ attribute :oreb_pct, Shale::Type::Float
160
+
161
+ # @!attribute [rw] dreb_pct
162
+ # Returns defensive rebound percentage
163
+ # @api public
164
+ # @example
165
+ # stat.dreb_pct #=> 18.6
166
+ # @return [Float] the defensive rebound percentage
167
+ attribute :dreb_pct, Shale::Type::Float
168
+
169
+ # @!attribute [rw] reb_pct
170
+ # Returns total rebound percentage
171
+ # @api public
172
+ # @example
173
+ # stat.reb_pct #=> 10.9
174
+ # @return [Float] the total rebound percentage
175
+ attribute :reb_pct, Shale::Type::Float
176
+
177
+ # @!attribute [rw] tov_pct
178
+ # Returns turnover percentage
179
+ # @api public
180
+ # @example
181
+ # stat.tov_pct #=> 12.3
182
+ # @return [Float] the turnover percentage
183
+ attribute :tov_pct, Shale::Type::Float
184
+
185
+ # @!attribute [rw] efg_pct
186
+ # Returns effective field goal percentage
187
+ # @api public
188
+ # @example
189
+ # stat.efg_pct #=> 0.625
190
+ # @return [Float] the effective field goal percentage
191
+ attribute :efg_pct, Shale::Type::Float
192
+
193
+ # @!attribute [rw] ts_pct
194
+ # Returns true shooting percentage
195
+ # @api public
196
+ # @example
197
+ # stat.ts_pct #=> 0.658
198
+ # @return [Float] the true shooting percentage
199
+ attribute :ts_pct, Shale::Type::Float
200
+
201
+ # @!attribute [rw] usg_pct
202
+ # Returns usage percentage
203
+ # @api public
204
+ # @example
205
+ # stat.usg_pct #=> 32.4
206
+ # @return [Float] the usage percentage
207
+ attribute :usg_pct, Shale::Type::Float
208
+
209
+ # @!attribute [rw] e_usg_pct
210
+ # Returns estimated usage percentage
211
+ # @api public
212
+ # @example
213
+ # stat.e_usg_pct #=> 31.8
214
+ # @return [Float] the estimated usage percentage
215
+ attribute :e_usg_pct, Shale::Type::Float
216
+
217
+ # @!attribute [rw] e_pace
218
+ # Returns estimated pace
219
+ # @api public
220
+ # @example
221
+ # stat.e_pace #=> 100.5
222
+ # @return [Float] the estimated pace
223
+ attribute :e_pace, Shale::Type::Float
224
+
225
+ # @!attribute [rw] pace
226
+ # Returns pace
227
+ # @api public
228
+ # @example
229
+ # stat.pace #=> 102.3
230
+ # @return [Float] the pace
231
+ attribute :pace, Shale::Type::Float
232
+
233
+ # @!attribute [rw] pace_per40
234
+ # Returns pace per 40 minutes
235
+ # @api public
236
+ # @example
237
+ # stat.pace_per40 #=> 101.8
238
+ # @return [Float] the pace per 40 minutes
239
+ attribute :pace_per40, Shale::Type::Float
240
+
241
+ # @!attribute [rw] poss
242
+ # Returns possessions
243
+ # @api public
244
+ # @example
245
+ # stat.poss #=> 65
246
+ # @return [Integer] the possessions
247
+ attribute :poss, Shale::Type::Integer
248
+
249
+ # @!attribute [rw] pie
250
+ # Returns player impact estimate
251
+ # @api public
252
+ # @example
253
+ # stat.pie #=> 18.4
254
+ # @return [Float] the player impact estimate
255
+ attribute :pie, Shale::Type::Float
256
+
257
+ # Returns the player object
258
+ #
259
+ # @api public
260
+ # @example
261
+ # stat.player #=> #<NBA::Player>
262
+ # @return [Player, nil] the player object
263
+ def player
264
+ Players.find(player_id)
265
+ end
266
+
267
+ # Returns the team object
268
+ #
269
+ # @api public
270
+ # @example
271
+ # stat.team #=> #<NBA::Team>
272
+ # @return [Team, nil] the team object
273
+ def team
274
+ Teams.find(team_id)
275
+ end
276
+
277
+ # Returns whether the player started the game
278
+ #
279
+ # @api public
280
+ # @example
281
+ # stat.starter? #=> true
282
+ # @return [Boolean] true if the player started
283
+ def starter?
284
+ !start_position.nil? && !start_position.empty?
285
+ end
286
+
287
+ # Returns the game object for this box score
288
+ #
289
+ # @api public
290
+ # @example
291
+ # stat.game #=> #<NBA::Game>
292
+ # @return [Game, nil] the game object
293
+ def game
294
+ Games.find(game_id)
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,237 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents a team's advanced box score statistics for a game
6
+ class BoxScoreAdvancedTeamStat < Shale::Mapper
7
+ include Equalizer.new(:game_id, :team_id)
8
+
9
+ # @!attribute [rw] game_id
10
+ # Returns the game ID
11
+ # @api public
12
+ # @example
13
+ # stat.game_id #=> "0022400350"
14
+ # @return [String] the game ID
15
+ attribute :game_id, Shale::Type::String
16
+
17
+ # @!attribute [rw] team_id
18
+ # Returns the team ID
19
+ # @api public
20
+ # @example
21
+ # stat.team_id #=> 1610612744
22
+ # @return [Integer] the team ID
23
+ attribute :team_id, Shale::Type::Integer
24
+
25
+ # @!attribute [rw] team_name
26
+ # Returns the team name
27
+ # @api public
28
+ # @example
29
+ # stat.team_name #=> "Warriors"
30
+ # @return [String] the team name
31
+ attribute :team_name, Shale::Type::String
32
+
33
+ # @!attribute [rw] team_abbreviation
34
+ # Returns the team abbreviation
35
+ # @api public
36
+ # @example
37
+ # stat.team_abbreviation #=> "GSW"
38
+ # @return [String] the team abbreviation
39
+ attribute :team_abbreviation, Shale::Type::String
40
+
41
+ # @!attribute [rw] team_city
42
+ # Returns the team city
43
+ # @api public
44
+ # @example
45
+ # stat.team_city #=> "Golden State"
46
+ # @return [String] the team city
47
+ attribute :team_city, Shale::Type::String
48
+
49
+ # @!attribute [rw] min
50
+ # Returns total minutes played
51
+ # @api public
52
+ # @example
53
+ # stat.min #=> "240:00"
54
+ # @return [String] the minutes
55
+ attribute :min, Shale::Type::String
56
+
57
+ # @!attribute [rw] e_off_rating
58
+ # Returns estimated offensive rating
59
+ # @api public
60
+ # @example
61
+ # stat.e_off_rating #=> 115.2
62
+ # @return [Float] the estimated offensive rating
63
+ attribute :e_off_rating, Shale::Type::Float
64
+
65
+ # @!attribute [rw] off_rating
66
+ # Returns offensive rating
67
+ # @api public
68
+ # @example
69
+ # stat.off_rating #=> 117.5
70
+ # @return [Float] the offensive rating
71
+ attribute :off_rating, Shale::Type::Float
72
+
73
+ # @!attribute [rw] e_def_rating
74
+ # Returns estimated defensive rating
75
+ # @api public
76
+ # @example
77
+ # stat.e_def_rating #=> 110.3
78
+ # @return [Float] the estimated defensive rating
79
+ attribute :e_def_rating, Shale::Type::Float
80
+
81
+ # @!attribute [rw] def_rating
82
+ # Returns defensive rating
83
+ # @api public
84
+ # @example
85
+ # stat.def_rating #=> 108.9
86
+ # @return [Float] the defensive rating
87
+ attribute :def_rating, Shale::Type::Float
88
+
89
+ # @!attribute [rw] e_net_rating
90
+ # Returns estimated net rating
91
+ # @api public
92
+ # @example
93
+ # stat.e_net_rating #=> 4.9
94
+ # @return [Float] the estimated net rating
95
+ attribute :e_net_rating, Shale::Type::Float
96
+
97
+ # @!attribute [rw] net_rating
98
+ # Returns net rating
99
+ # @api public
100
+ # @example
101
+ # stat.net_rating #=> 8.6
102
+ # @return [Float] the net rating
103
+ attribute :net_rating, Shale::Type::Float
104
+
105
+ # @!attribute [rw] ast_pct
106
+ # Returns assist percentage
107
+ # @api public
108
+ # @example
109
+ # stat.ast_pct #=> 66.7
110
+ # @return [Float] the assist percentage
111
+ attribute :ast_pct, Shale::Type::Float
112
+
113
+ # @!attribute [rw] ast_tov
114
+ # Returns assist to turnover ratio
115
+ # @api public
116
+ # @example
117
+ # stat.ast_tov #=> 2.0
118
+ # @return [Float] the assist to turnover ratio
119
+ attribute :ast_tov, Shale::Type::Float
120
+
121
+ # @!attribute [rw] ast_ratio
122
+ # Returns assist ratio
123
+ # @api public
124
+ # @example
125
+ # stat.ast_ratio #=> 19.8
126
+ # @return [Float] the assist ratio
127
+ attribute :ast_ratio, Shale::Type::Float
128
+
129
+ # @!attribute [rw] oreb_pct
130
+ # Returns offensive rebound percentage
131
+ # @api public
132
+ # @example
133
+ # stat.oreb_pct #=> 22.2
134
+ # @return [Float] the offensive rebound percentage
135
+ attribute :oreb_pct, Shale::Type::Float
136
+
137
+ # @!attribute [rw] dreb_pct
138
+ # Returns defensive rebound percentage
139
+ # @api public
140
+ # @example
141
+ # stat.dreb_pct #=> 77.8
142
+ # @return [Float] the defensive rebound percentage
143
+ attribute :dreb_pct, Shale::Type::Float
144
+
145
+ # @!attribute [rw] reb_pct
146
+ # Returns total rebound percentage
147
+ # @api public
148
+ # @example
149
+ # stat.reb_pct #=> 50.0
150
+ # @return [Float] the total rebound percentage
151
+ attribute :reb_pct, Shale::Type::Float
152
+
153
+ # @!attribute [rw] tov_pct
154
+ # Returns turnover percentage
155
+ # @api public
156
+ # @example
157
+ # stat.tov_pct #=> 14.5
158
+ # @return [Float] the turnover percentage
159
+ attribute :tov_pct, Shale::Type::Float
160
+
161
+ # @!attribute [rw] efg_pct
162
+ # Returns effective field goal percentage
163
+ # @api public
164
+ # @example
165
+ # stat.efg_pct #=> 0.562
166
+ # @return [Float] the effective field goal percentage
167
+ attribute :efg_pct, Shale::Type::Float
168
+
169
+ # @!attribute [rw] ts_pct
170
+ # Returns true shooting percentage
171
+ # @api public
172
+ # @example
173
+ # stat.ts_pct #=> 0.590
174
+ # @return [Float] the true shooting percentage
175
+ attribute :ts_pct, Shale::Type::Float
176
+
177
+ # @!attribute [rw] e_pace
178
+ # Returns estimated pace
179
+ # @api public
180
+ # @example
181
+ # stat.e_pace #=> 99.5
182
+ # @return [Float] the estimated pace
183
+ attribute :e_pace, Shale::Type::Float
184
+
185
+ # @!attribute [rw] pace
186
+ # Returns pace
187
+ # @api public
188
+ # @example
189
+ # stat.pace #=> 101.2
190
+ # @return [Float] the pace
191
+ attribute :pace, Shale::Type::Float
192
+
193
+ # @!attribute [rw] pace_per40
194
+ # Returns pace per 40 minutes
195
+ # @api public
196
+ # @example
197
+ # stat.pace_per40 #=> 100.8
198
+ # @return [Float] the pace per 40 minutes
199
+ attribute :pace_per40, Shale::Type::Float
200
+
201
+ # @!attribute [rw] poss
202
+ # Returns possessions
203
+ # @api public
204
+ # @example
205
+ # stat.poss #=> 98
206
+ # @return [Integer] the possessions
207
+ attribute :poss, Shale::Type::Integer
208
+
209
+ # @!attribute [rw] pie
210
+ # Returns player impact estimate
211
+ # @api public
212
+ # @example
213
+ # stat.pie #=> 52.3
214
+ # @return [Float] the player impact estimate
215
+ attribute :pie, Shale::Type::Float
216
+
217
+ # Returns the team object
218
+ #
219
+ # @api public
220
+ # @example
221
+ # stat.team #=> #<NBA::Team>
222
+ # @return [Team, nil] the team object
223
+ def team
224
+ Teams.find(team_id)
225
+ end
226
+
227
+ # Returns the game object for this box score
228
+ #
229
+ # @api public
230
+ # @example
231
+ # stat.game #=> #<NBA::Game>
232
+ # @return [Game, nil] the game object
233
+ def game
234
+ Games.find(game_id)
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,124 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "box_score_advanced_player_stat"
5
+ require_relative "box_score_advanced_team_stat"
6
+ require_relative "box_score_v3_helpers"
7
+ require_relative "utils"
8
+
9
+ module NBA
10
+ # Provides methods to retrieve advanced box score statistics using V3 API
11
+ module BoxScoreAdvancedV3
12
+ # @return [String] JSON key for advanced box score data
13
+ BOX_SCORE_KEY = "boxScoreAdvanced".freeze
14
+ # @return [String] JSON key for player statistics
15
+ PLAYER_STATS = "PlayerStats".freeze
16
+ # @return [String] JSON key for team statistics
17
+ TEAM_STATS = "TeamStats".freeze
18
+
19
+ # Retrieves advanced player box score stats for a game
20
+ #
21
+ # @api public
22
+ # @example
23
+ # stats = NBA::BoxScoreAdvancedV3.player_stats(game: "0022400001")
24
+ # stats.each { |stat| puts "#{stat.player_name}: #{stat.off_rating}" }
25
+ # @param game [String, Integer] the game ID
26
+ # @param start_period [Integer] the starting period
27
+ # @param end_period [Integer] the ending period
28
+ # @param client [Client] the API client to use
29
+ # @return [Collection] a collection of player advanced stats
30
+ def self.player_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
31
+ game_id = Utils.extract_id(game)
32
+ response = client.get(build_path(game_id, start_period, end_period))
33
+ parse_player_response(response, game_id)
34
+ end
35
+
36
+ # Retrieves advanced team box score stats for a game
37
+ #
38
+ # @api public
39
+ # @example
40
+ # stats = NBA::BoxScoreAdvancedV3.team_stats(game: "0022400001")
41
+ # stats.each { |stat| puts "#{stat.team_abbreviation}: #{stat.off_rating}" }
42
+ # @param game [String, Integer] the game ID
43
+ # @param start_period [Integer] the starting period
44
+ # @param end_period [Integer] the ending period
45
+ # @param client [Client] the API client to use
46
+ # @return [Collection] a collection of team advanced stats
47
+ def self.team_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
48
+ game_id = Utils.extract_id(game)
49
+ response = client.get(build_path(game_id, start_period, end_period))
50
+ parse_team_response(response, game_id)
51
+ end
52
+
53
+ # Builds the API request path
54
+ # @api private
55
+ # @return [String] the request path
56
+ def self.build_path(game_id, start_period, end_period)
57
+ "boxscoreadvancedv3?GameID=#{game_id}&StartPeriod=#{start_period}" \
58
+ "&EndPeriod=#{end_period}&StartRange=0&EndRange=0&RangeType=0"
59
+ end
60
+ private_class_method :build_path
61
+
62
+ # Parses the API response into player stat objects
63
+ # @api private
64
+ # @return [Collection] collection of player stats
65
+ def self.parse_player_response(response, game_id)
66
+ return Collection.new unless response
67
+
68
+ data = JSON.parse(response)
69
+ players = BoxScoreV3Helpers.extract_players(data, BOX_SCORE_KEY)
70
+ return Collection.new unless players
71
+
72
+ Collection.new(players.map { |p| build_player_stat(p, game_id) })
73
+ end
74
+ private_class_method :parse_player_response
75
+
76
+ # Parses the API response into team stat objects
77
+ # @api private
78
+ # @return [Collection] collection of team stats
79
+ def self.parse_team_response(response, game_id)
80
+ return Collection.new unless response
81
+
82
+ data = JSON.parse(response)
83
+ teams = BoxScoreV3Helpers.extract_teams(data, BOX_SCORE_KEY)
84
+ return Collection.new unless teams
85
+
86
+ Collection.new(teams.map { |t| build_team_stat(t, game_id) })
87
+ end
88
+ private_class_method :parse_team_response
89
+
90
+ # Builds a player stat object from raw data
91
+ # @api private
92
+ # @return [BoxScoreAdvancedPlayerStat] the player stat object
93
+ def self.build_player_stat(player, game_id)
94
+ stats = player.fetch("statistics", {})
95
+ BoxScoreAdvancedPlayerStat.new(
96
+ **BoxScoreV3Helpers.player_identity(player, game_id), min: stats["minutes"],
97
+ **BoxScoreV3Helpers.advanced_rating_stats(stats), **BoxScoreV3Helpers.advanced_efficiency_stats(stats),
98
+ **BoxScoreV3Helpers.advanced_tempo_stats(stats), **player_usage_stats(stats)
99
+ )
100
+ end
101
+ private_class_method :build_player_stat
102
+
103
+ # Builds a team stat object from raw data
104
+ # @api private
105
+ # @return [BoxScoreAdvancedTeamStat] the team stat object
106
+ def self.build_team_stat(team, game_id)
107
+ stats = team.fetch("statistics", {})
108
+ BoxScoreAdvancedTeamStat.new(
109
+ **BoxScoreV3Helpers.team_identity(team, game_id), min: stats["minutes"],
110
+ **BoxScoreV3Helpers.advanced_rating_stats(stats), **BoxScoreV3Helpers.advanced_efficiency_stats(stats),
111
+ **BoxScoreV3Helpers.advanced_tempo_stats(stats)
112
+ )
113
+ end
114
+ private_class_method :build_team_stat
115
+
116
+ # Extracts player usage statistics from raw data
117
+ # @api private
118
+ # @return [Hash] usage statistics
119
+ def self.player_usage_stats(stats)
120
+ {usg_pct: stats["usagePercentage"], e_usg_pct: stats["estimatedUsagePercentage"]}
121
+ end
122
+ private_class_method :player_usage_stats
123
+ end
124
+ end