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,241 @@
1
+ require "shale"
2
+ require "equalizer"
3
+
4
+ module NBA
5
+ # Represents a player's scoring box score statistics for a game
6
+ class BoxScoreScoringPlayerStat < 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 #=> "0022400565"
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 #=> "35:24"
78
+ # @return [String] the minutes played
79
+ attribute :min, Shale::Type::String
80
+
81
+ # @!attribute [rw] pct_fga_2pt
82
+ # Returns percentage of field goals from 2-point range
83
+ # @api public
84
+ # @example
85
+ # stat.pct_fga_2pt #=> 0.45
86
+ # @return [Float] the percentage
87
+ attribute :pct_fga_2pt, Shale::Type::Float
88
+
89
+ # @!attribute [rw] pct_fga_3pt
90
+ # Returns percentage of field goals from 3-point range
91
+ # @api public
92
+ # @example
93
+ # stat.pct_fga_3pt #=> 0.55
94
+ # @return [Float] the percentage
95
+ attribute :pct_fga_3pt, Shale::Type::Float
96
+
97
+ # @!attribute [rw] pct_pts_2pt
98
+ # Returns percentage of points from 2-point shots
99
+ # @api public
100
+ # @example
101
+ # stat.pct_pts_2pt #=> 0.40
102
+ # @return [Float] the percentage
103
+ attribute :pct_pts_2pt, Shale::Type::Float
104
+
105
+ # @!attribute [rw] pct_pts_2pt_mr
106
+ # Returns percentage of points from mid-range 2-point shots
107
+ # @api public
108
+ # @example
109
+ # stat.pct_pts_2pt_mr #=> 0.15
110
+ # @return [Float] the percentage
111
+ attribute :pct_pts_2pt_mr, Shale::Type::Float
112
+
113
+ # @!attribute [rw] pct_pts_3pt
114
+ # Returns percentage of points from 3-point shots
115
+ # @api public
116
+ # @example
117
+ # stat.pct_pts_3pt #=> 0.50
118
+ # @return [Float] the percentage
119
+ attribute :pct_pts_3pt, Shale::Type::Float
120
+
121
+ # @!attribute [rw] pct_pts_fb
122
+ # Returns percentage of points from fast break
123
+ # @api public
124
+ # @example
125
+ # stat.pct_pts_fb #=> 0.12
126
+ # @return [Float] the percentage
127
+ attribute :pct_pts_fb, Shale::Type::Float
128
+
129
+ # @!attribute [rw] pct_pts_ft
130
+ # Returns percentage of points from free throws
131
+ # @api public
132
+ # @example
133
+ # stat.pct_pts_ft #=> 0.10
134
+ # @return [Float] the percentage
135
+ attribute :pct_pts_ft, Shale::Type::Float
136
+
137
+ # @!attribute [rw] pct_pts_off_tov
138
+ # Returns percentage of points off turnovers
139
+ # @api public
140
+ # @example
141
+ # stat.pct_pts_off_tov #=> 0.18
142
+ # @return [Float] the percentage
143
+ attribute :pct_pts_off_tov, Shale::Type::Float
144
+
145
+ # @!attribute [rw] pct_pts_paint
146
+ # Returns percentage of points in the paint
147
+ # @api public
148
+ # @example
149
+ # stat.pct_pts_paint #=> 0.35
150
+ # @return [Float] the percentage
151
+ attribute :pct_pts_paint, Shale::Type::Float
152
+
153
+ # @!attribute [rw] pct_ast_2pm
154
+ # Returns percentage of 2-point makes that were assisted
155
+ # @api public
156
+ # @example
157
+ # stat.pct_ast_2pm #=> 0.65
158
+ # @return [Float] the percentage
159
+ attribute :pct_ast_2pm, Shale::Type::Float
160
+
161
+ # @!attribute [rw] pct_uast_2pm
162
+ # Returns percentage of 2-point makes that were unassisted
163
+ # @api public
164
+ # @example
165
+ # stat.pct_uast_2pm #=> 0.35
166
+ # @return [Float] the percentage
167
+ attribute :pct_uast_2pm, Shale::Type::Float
168
+
169
+ # @!attribute [rw] pct_ast_3pm
170
+ # Returns percentage of 3-point makes that were assisted
171
+ # @api public
172
+ # @example
173
+ # stat.pct_ast_3pm #=> 0.85
174
+ # @return [Float] the percentage
175
+ attribute :pct_ast_3pm, Shale::Type::Float
176
+
177
+ # @!attribute [rw] pct_uast_3pm
178
+ # Returns percentage of 3-point makes that were unassisted
179
+ # @api public
180
+ # @example
181
+ # stat.pct_uast_3pm #=> 0.15
182
+ # @return [Float] the percentage
183
+ attribute :pct_uast_3pm, Shale::Type::Float
184
+
185
+ # @!attribute [rw] pct_ast_fgm
186
+ # Returns percentage of field goal makes that were assisted
187
+ # @api public
188
+ # @example
189
+ # stat.pct_ast_fgm #=> 0.75
190
+ # @return [Float] the percentage
191
+ attribute :pct_ast_fgm, Shale::Type::Float
192
+
193
+ # @!attribute [rw] pct_uast_fgm
194
+ # Returns percentage of field goal makes that were unassisted
195
+ # @api public
196
+ # @example
197
+ # stat.pct_uast_fgm #=> 0.25
198
+ # @return [Float] the percentage
199
+ attribute :pct_uast_fgm, Shale::Type::Float
200
+
201
+ # Returns the player object
202
+ #
203
+ # @api public
204
+ # @example
205
+ # stat.player #=> #<NBA::Player>
206
+ # @return [Player, nil] the player object
207
+ def player
208
+ Players.find(player_id)
209
+ end
210
+
211
+ # Returns the team object
212
+ #
213
+ # @api public
214
+ # @example
215
+ # stat.team #=> #<NBA::Team>
216
+ # @return [Team, nil] the team object
217
+ def team
218
+ Teams.find(team_id)
219
+ end
220
+
221
+ # Returns whether the player started the game
222
+ #
223
+ # @api public
224
+ # @example
225
+ # stat.starter? #=> true
226
+ # @return [Boolean] true if the player started
227
+ def starter?
228
+ !start_position.nil? && !start_position.empty?
229
+ end
230
+
231
+ # Returns the game object for this box score
232
+ #
233
+ # @api public
234
+ # @example
235
+ # stat.game #=> #<NBA::Game>
236
+ # @return [Game, nil] the game object
237
+ def game
238
+ Games.find(game_id)
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,197 @@
1
+ require "shale"
2
+ require "equalizer"
3
+
4
+ module NBA
5
+ # Represents a team's scoring box score statistics for a game
6
+ class BoxScoreScoringTeamStat < 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 #=> "0022400565"
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] pct_fga_2pt
58
+ # Returns percentage of field goals from 2-point range
59
+ # @api public
60
+ # @example
61
+ # stat.pct_fga_2pt #=> 0.52
62
+ # @return [Float] the percentage
63
+ attribute :pct_fga_2pt, Shale::Type::Float
64
+
65
+ # @!attribute [rw] pct_fga_3pt
66
+ # Returns percentage of field goals from 3-point range
67
+ # @api public
68
+ # @example
69
+ # stat.pct_fga_3pt #=> 0.48
70
+ # @return [Float] the percentage
71
+ attribute :pct_fga_3pt, Shale::Type::Float
72
+
73
+ # @!attribute [rw] pct_pts_2pt
74
+ # Returns percentage of points from 2-point shots
75
+ # @api public
76
+ # @example
77
+ # stat.pct_pts_2pt #=> 0.42
78
+ # @return [Float] the percentage
79
+ attribute :pct_pts_2pt, Shale::Type::Float
80
+
81
+ # @!attribute [rw] pct_pts_2pt_mr
82
+ # Returns percentage of points from mid-range 2-point shots
83
+ # @api public
84
+ # @example
85
+ # stat.pct_pts_2pt_mr #=> 0.18
86
+ # @return [Float] the percentage
87
+ attribute :pct_pts_2pt_mr, Shale::Type::Float
88
+
89
+ # @!attribute [rw] pct_pts_3pt
90
+ # Returns percentage of points from 3-point shots
91
+ # @api public
92
+ # @example
93
+ # stat.pct_pts_3pt #=> 0.45
94
+ # @return [Float] the percentage
95
+ attribute :pct_pts_3pt, Shale::Type::Float
96
+
97
+ # @!attribute [rw] pct_pts_fb
98
+ # Returns percentage of points from fast break
99
+ # @api public
100
+ # @example
101
+ # stat.pct_pts_fb #=> 0.15
102
+ # @return [Float] the percentage
103
+ attribute :pct_pts_fb, Shale::Type::Float
104
+
105
+ # @!attribute [rw] pct_pts_ft
106
+ # Returns percentage of points from free throws
107
+ # @api public
108
+ # @example
109
+ # stat.pct_pts_ft #=> 0.13
110
+ # @return [Float] the percentage
111
+ attribute :pct_pts_ft, Shale::Type::Float
112
+
113
+ # @!attribute [rw] pct_pts_off_tov
114
+ # Returns percentage of points off turnovers
115
+ # @api public
116
+ # @example
117
+ # stat.pct_pts_off_tov #=> 0.16
118
+ # @return [Float] the percentage
119
+ attribute :pct_pts_off_tov, Shale::Type::Float
120
+
121
+ # @!attribute [rw] pct_pts_paint
122
+ # Returns percentage of points in the paint
123
+ # @api public
124
+ # @example
125
+ # stat.pct_pts_paint #=> 0.38
126
+ # @return [Float] the percentage
127
+ attribute :pct_pts_paint, Shale::Type::Float
128
+
129
+ # @!attribute [rw] pct_ast_2pm
130
+ # Returns percentage of 2-point makes that were assisted
131
+ # @api public
132
+ # @example
133
+ # stat.pct_ast_2pm #=> 0.70
134
+ # @return [Float] the percentage
135
+ attribute :pct_ast_2pm, Shale::Type::Float
136
+
137
+ # @!attribute [rw] pct_uast_2pm
138
+ # Returns percentage of 2-point makes that were unassisted
139
+ # @api public
140
+ # @example
141
+ # stat.pct_uast_2pm #=> 0.30
142
+ # @return [Float] the percentage
143
+ attribute :pct_uast_2pm, Shale::Type::Float
144
+
145
+ # @!attribute [rw] pct_ast_3pm
146
+ # Returns percentage of 3-point makes that were assisted
147
+ # @api public
148
+ # @example
149
+ # stat.pct_ast_3pm #=> 0.88
150
+ # @return [Float] the percentage
151
+ attribute :pct_ast_3pm, Shale::Type::Float
152
+
153
+ # @!attribute [rw] pct_uast_3pm
154
+ # Returns percentage of 3-point makes that were unassisted
155
+ # @api public
156
+ # @example
157
+ # stat.pct_uast_3pm #=> 0.12
158
+ # @return [Float] the percentage
159
+ attribute :pct_uast_3pm, Shale::Type::Float
160
+
161
+ # @!attribute [rw] pct_ast_fgm
162
+ # Returns percentage of field goal makes that were assisted
163
+ # @api public
164
+ # @example
165
+ # stat.pct_ast_fgm #=> 0.78
166
+ # @return [Float] the percentage
167
+ attribute :pct_ast_fgm, Shale::Type::Float
168
+
169
+ # @!attribute [rw] pct_uast_fgm
170
+ # Returns percentage of field goal makes that were unassisted
171
+ # @api public
172
+ # @example
173
+ # stat.pct_uast_fgm #=> 0.22
174
+ # @return [Float] the percentage
175
+ attribute :pct_uast_fgm, Shale::Type::Float
176
+
177
+ # Returns the team object
178
+ #
179
+ # @api public
180
+ # @example
181
+ # stat.team #=> #<NBA::Team>
182
+ # @return [Team, nil] the team object
183
+ def team
184
+ Teams.find(team_id)
185
+ end
186
+
187
+ # Returns the game object for this box score
188
+ #
189
+ # @api public
190
+ # @example
191
+ # stat.game #=> #<NBA::Game>
192
+ # @return [Game, nil] the game object
193
+ def game
194
+ Games.find(game_id)
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,170 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "box_score_scoring_player_stat"
5
+ require_relative "box_score_scoring_team_stat"
6
+ require_relative "box_score_v3_helpers"
7
+ require_relative "utils"
8
+
9
+ module NBA
10
+ # Provides methods to retrieve scoring box score statistics using V3 API
11
+ module BoxScoreScoringV3
12
+ # @return [String] JSON key for scoring box score data
13
+ BOX_SCORE_KEY = "boxScoreScoring".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 scoring player box score stats for a game
20
+ #
21
+ # @api public
22
+ # @example
23
+ # stats = NBA::BoxScoreScoringV3.player_stats(game: "0022400001")
24
+ # stats.each { |stat| puts "#{stat.player_name}: #{stat.pct_pts_paint}" }
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 scoring 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 scoring team box score stats for a game
37
+ #
38
+ # @api public
39
+ # @example
40
+ # stats = NBA::BoxScoreScoringV3.team_stats(game: "0022400001")
41
+ # stats.each { |stat| puts "#{stat.team_abbreviation}: #{stat.pct_pts_paint}" }
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 scoring 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
+ "boxscorescoringv3?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 [BoxScoreScoringPlayerStat] the player stat object
93
+ def self.build_player_stat(player, game_id)
94
+ stats = player.fetch("statistics", {})
95
+ BoxScoreScoringPlayerStat.new(
96
+ **BoxScoreV3Helpers.player_identity(player, game_id),
97
+ min: stats["minutes"],
98
+ **scoring_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 [BoxScoreScoringTeamStat] the team stat object
106
+ def self.build_team_stat(team, game_id)
107
+ stats = team.fetch("statistics", {})
108
+ BoxScoreScoringTeamStat.new(
109
+ **BoxScoreV3Helpers.team_identity(team, game_id),
110
+ min: stats["minutes"],
111
+ **scoring_stats(stats)
112
+ )
113
+ end
114
+ private_class_method :build_team_stat
115
+
116
+ # Extracts scoring statistics from raw data
117
+ # @api private
118
+ # @return [Hash] scoring statistics
119
+ def self.scoring_stats(stats)
120
+ shot_distribution(stats).merge(assist_distribution(stats))
121
+ end
122
+ private_class_method :scoring_stats
123
+
124
+ # Extracts shot distribution statistics from raw data
125
+ # @api private
126
+ # @return [Hash] shot distribution statistics
127
+ def self.shot_distribution(stats)
128
+ attempt_distribution(stats).merge(points_distribution(stats))
129
+ end
130
+ private_class_method :shot_distribution
131
+
132
+ # Extracts attempt distribution statistics from raw data
133
+ # @api private
134
+ # @return [Hash] attempt distribution statistics
135
+ def self.attempt_distribution(stats)
136
+ {pct_fga_2pt: stats["percentageFieldGoalsAttempted2pt"],
137
+ pct_fga_3pt: stats["percentageFieldGoalsAttempted3pt"],
138
+ pct_pts_2pt: stats["percentagePoints2pt"],
139
+ pct_pts_2pt_mr: stats["percentagePointsMidrange2pt"],
140
+ pct_pts_3pt: stats["percentagePoints3pt"]}
141
+ end
142
+ private_class_method :attempt_distribution
143
+
144
+ # Extracts points distribution statistics from raw data
145
+ # @api private
146
+ # @return [Hash] points distribution statistics
147
+ def self.points_distribution(stats)
148
+ {pct_pts_fb: stats["percentagePointsFastBreak"],
149
+ pct_pts_ft: stats["percentagePointsFreeThrow"],
150
+ pct_pts_off_tov: stats["percentagePointsOffTurnovers"],
151
+ pct_pts_paint: stats["percentagePointsPaint"]}
152
+ end
153
+ private_class_method :points_distribution
154
+
155
+ # Extracts assist distribution statistics from raw data
156
+ # @api private
157
+ # @return [Hash] assist distribution statistics
158
+ def self.assist_distribution(stats)
159
+ {
160
+ pct_ast_2pm: stats["percentageAssisted2pt"],
161
+ pct_uast_2pm: stats["percentageUnassisted2pt"],
162
+ pct_ast_3pm: stats["percentageAssisted3pt"],
163
+ pct_uast_3pm: stats["percentageUnassisted3pt"],
164
+ pct_ast_fgm: stats["percentageAssistedFieldGoals"],
165
+ pct_uast_fgm: stats["percentageUnassistedFieldGoals"]
166
+ }
167
+ end
168
+ private_class_method :assist_distribution
169
+ end
170
+ end