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,259 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "utils"
5
+
6
+ require_relative "player_dashboard_stat"
7
+
8
+ module NBA
9
+ # Provides methods to retrieve player dashboard data with various splits
10
+ module PlayerDashboard
11
+ # Season type constant for regular season
12
+ # @return [String] the season type
13
+ REGULAR_SEASON = "Regular Season".freeze
14
+
15
+ # Season type constant for playoffs
16
+ # @return [String] the season type
17
+ PLAYOFFS = "Playoffs".freeze
18
+
19
+ # Per mode constant for per game stats
20
+ # @return [String] the per mode
21
+ PER_GAME = "PerGame".freeze
22
+
23
+ # Per mode constant for totals
24
+ # @return [String] the per mode
25
+ TOTALS = "Totals".freeze
26
+
27
+ # Per mode constant for per 36 minutes
28
+ # @return [String] the per mode
29
+ PER_36 = "Per36".freeze
30
+
31
+ # Retrieves player dashboard by general splits
32
+ #
33
+ # @api public
34
+ # @example
35
+ # stats = NBA::PlayerDashboard.general_splits(player: 201939)
36
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
37
+ # @param player [Integer, Player] the player ID or Player object
38
+ # @param season [Integer] the season year
39
+ # @param season_type [String] the season type
40
+ # @param per_mode [String] the per mode
41
+ # @param client [Client] the API client to use
42
+ # @return [Collection] a collection of dashboard stats
43
+ def self.general_splits(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
44
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbygeneralsplits", client: client)
45
+ end
46
+
47
+ # Retrieves player dashboard by clutch splits
48
+ #
49
+ # @api public
50
+ # @example
51
+ # stats = NBA::PlayerDashboard.clutch_splits(player: 201939)
52
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
53
+ # @param player [Integer, Player] the player ID or Player object
54
+ # @param season [Integer] the season year
55
+ # @param season_type [String] the season type
56
+ # @param per_mode [String] the per mode
57
+ # @param client [Client] the API client to use
58
+ # @return [Collection] a collection of dashboard stats
59
+ def self.clutch_splits(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
60
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbyclutch", client: client)
61
+ end
62
+
63
+ # Retrieves player dashboard by shooting splits
64
+ #
65
+ # @api public
66
+ # @example
67
+ # stats = NBA::PlayerDashboard.shooting_splits(player: 201939)
68
+ # stats.each { |s| puts "#{s.group_value}: #{s.fg_pct}" }
69
+ # @param player [Integer, Player] the player ID or Player object
70
+ # @param season [Integer] the season year
71
+ # @param season_type [String] the season type
72
+ # @param per_mode [String] the per mode
73
+ # @param client [Client] the API client to use
74
+ # @return [Collection] a collection of dashboard stats
75
+ def self.shooting_splits(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
76
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbyshootingsplits", client: client)
77
+ end
78
+
79
+ # Retrieves player dashboard by game splits
80
+ #
81
+ # @api public
82
+ # @example
83
+ # stats = NBA::PlayerDashboard.game_splits(player: 201939)
84
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
85
+ # @param player [Integer, Player] the player ID or Player object
86
+ # @param season [Integer] the season year
87
+ # @param season_type [String] the season type
88
+ # @param per_mode [String] the per mode
89
+ # @param client [Client] the API client to use
90
+ # @return [Collection] a collection of dashboard stats
91
+ def self.game_splits(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
92
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbygamesplits", client: client)
93
+ end
94
+
95
+ # Retrieves player dashboard by last N games
96
+ #
97
+ # @api public
98
+ # @example
99
+ # stats = NBA::PlayerDashboard.last_n_games(player: 201939)
100
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
101
+ # @param player [Integer, Player] the player ID or Player object
102
+ # @param season [Integer] the season year
103
+ # @param season_type [String] the season type
104
+ # @param per_mode [String] the per mode
105
+ # @param client [Client] the API client to use
106
+ # @return [Collection] a collection of dashboard stats
107
+ def self.last_n_games(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
108
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbylastngames", client: client)
109
+ end
110
+
111
+ # Retrieves player dashboard by year over year
112
+ #
113
+ # @api public
114
+ # @example
115
+ # stats = NBA::PlayerDashboard.year_over_year(player: 201939)
116
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
117
+ # @param player [Integer, Player] the player ID or Player object
118
+ # @param season [Integer] the season year
119
+ # @param season_type [String] the season type
120
+ # @param per_mode [String] the per mode
121
+ # @param client [Client] the API client to use
122
+ # @return [Collection] a collection of dashboard stats
123
+ def self.year_over_year(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
124
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbyyearoveryear", client: client)
125
+ end
126
+
127
+ # Retrieves player dashboard by team performance
128
+ #
129
+ # @api public
130
+ # @example
131
+ # stats = NBA::PlayerDashboard.team_performance(player: 201939)
132
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
133
+ # @param player [Integer, Player] the player ID or Player object
134
+ # @param season [Integer] the season year
135
+ # @param season_type [String] the season type
136
+ # @param per_mode [String] the per mode
137
+ # @param client [Client] the API client to use
138
+ # @return [Collection] a collection of dashboard stats
139
+ def self.team_performance(player:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
140
+ fetch_dashboard(player, season, season_type, per_mode, "playerdashboardbyteamperformance", client: client)
141
+ end
142
+
143
+ # Fetches dashboard data from the API
144
+ #
145
+ # @api private
146
+ # @return [Collection] collection of dashboard stats
147
+ def self.fetch_dashboard(player, season, season_type, per_mode, endpoint, client:)
148
+ player_id = Utils.extract_id(player)
149
+ path = build_path(player_id, season, season_type, per_mode, endpoint)
150
+ response = client.get(path)
151
+ parse_response(response, player_id)
152
+ end
153
+ private_class_method :fetch_dashboard
154
+
155
+ # Builds the API path
156
+ #
157
+ # @api private
158
+ # @return [String] the request path
159
+ def self.build_path(player_id, season, season_type, per_mode, endpoint)
160
+ season_str = Utils.format_season(season)
161
+ "#{endpoint}?PlayerID=#{player_id}&Season=#{season_str}&SeasonType=#{season_type}&PerMode=#{per_mode}&LeagueID=00"
162
+ end
163
+ private_class_method :build_path
164
+
165
+ # Parses the API response into dashboard stat objects
166
+ #
167
+ # @api private
168
+ # @return [Collection] collection of dashboard stats
169
+ def self.parse_response(response, player_id)
170
+ return Collection.new unless response
171
+
172
+ data = JSON.parse(response)
173
+ result_sets = data["resultSets"]
174
+ return Collection.new unless result_sets
175
+
176
+ all_stats = result_sets.flat_map { |rs| parse_result_set(rs, player_id) }
177
+ Collection.new(all_stats)
178
+ end
179
+ private_class_method :parse_response
180
+
181
+ # Parses a result set into stat objects
182
+ #
183
+ # @api private
184
+ # @return [Array<PlayerDashboardStat>] array of stats
185
+ def self.parse_result_set(result_set, player_id)
186
+ headers = result_set["headers"]
187
+ rows = result_set["rowSet"]
188
+ group_set = result_set["name"]
189
+ return [] unless headers && rows
190
+
191
+ rows.map { |row| build_dashboard_stat(headers, row, group_set, player_id) }
192
+ end
193
+ private_class_method :parse_result_set
194
+
195
+ # Builds a PlayerDashboardStat object from raw data
196
+ #
197
+ # @api private
198
+ # @return [PlayerDashboardStat] the dashboard stat object
199
+ def self.build_dashboard_stat(headers, row, group_set, player_id)
200
+ data = headers.zip(row).to_h
201
+ PlayerDashboardStat.new(**dashboard_attributes(data, group_set, player_id))
202
+ end
203
+ private_class_method :build_dashboard_stat
204
+
205
+ # Combines all dashboard attributes
206
+ #
207
+ # @api private
208
+ # @return [Hash] the combined attributes
209
+ def self.dashboard_attributes(data, group_set, player_id)
210
+ identity_attributes(data, group_set, player_id)
211
+ .merge(record_attributes(data))
212
+ .merge(shooting_attributes(data))
213
+ .merge(counting_attributes(data))
214
+ end
215
+ private_class_method :dashboard_attributes
216
+
217
+ # Extracts identity attributes from data
218
+ #
219
+ # @api private
220
+ # @return [Hash] identity attributes
221
+ def self.identity_attributes(data, group_set, player_id)
222
+ {group_set: group_set, group_value: data["GROUP_VALUE"],
223
+ player_id: player_id, gp: data["GP"], min: data["MIN"]}
224
+ end
225
+ private_class_method :identity_attributes
226
+
227
+ # Extracts record attributes from data
228
+ #
229
+ # @api private
230
+ # @return [Hash] record attributes
231
+ def self.record_attributes(data)
232
+ {w: data["W"], l: data["L"], w_pct: data["W_PCT"]}
233
+ end
234
+ private_class_method :record_attributes
235
+
236
+ # Extracts shooting attributes from data
237
+ #
238
+ # @api private
239
+ # @return [Hash] shooting attributes
240
+ def self.shooting_attributes(data)
241
+ {fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
242
+ fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
243
+ ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
244
+ end
245
+ private_class_method :shooting_attributes
246
+
247
+ # Extracts counting stats attributes from data
248
+ #
249
+ # @api private
250
+ # @return [Hash] counting attributes
251
+ def self.counting_attributes(data)
252
+ {oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
253
+ ast: data["AST"], tov: data["TOV"], stl: data["STL"], blk: data["BLK"],
254
+ blka: data["BLKA"], pf: data["PF"], pfd: data["PFD"],
255
+ pts: data["PTS"], plus_minus: data["PLUS_MINUS"]}
256
+ end
257
+ private_class_method :counting_attributes
258
+ end
259
+ end
@@ -0,0 +1,248 @@
1
+ module NBA
2
+ # Represents player dashboard split statistics
3
+ class PlayerDashboardStat < Shale::Mapper
4
+ include Equalizer.new(:player_id, :group_value)
5
+
6
+ # @!attribute [rw] group_set
7
+ # Returns the group set name
8
+ # @api public
9
+ # @example
10
+ # stat.group_set #=> "Overall"
11
+ # @return [String] the group set
12
+ attribute :group_set, Shale::Type::String
13
+
14
+ # @!attribute [rw] group_value
15
+ # Returns the group value
16
+ # @api public
17
+ # @example
18
+ # stat.group_value #=> "2023-24"
19
+ # @return [String] the group value
20
+ attribute :group_value, Shale::Type::String
21
+
22
+ # @!attribute [rw] player_id
23
+ # Returns the player ID
24
+ # @api public
25
+ # @example
26
+ # stat.player_id #=> 201939
27
+ # @return [Integer] the player ID
28
+ attribute :player_id, Shale::Type::Integer
29
+
30
+ # @!attribute [rw] gp
31
+ # Returns games played
32
+ # @api public
33
+ # @example
34
+ # stat.gp #=> 74
35
+ # @return [Integer] games played
36
+ attribute :gp, Shale::Type::Integer
37
+
38
+ # @!attribute [rw] w
39
+ # Returns wins
40
+ # @api public
41
+ # @example
42
+ # stat.w #=> 46
43
+ # @return [Integer] wins
44
+ attribute :w, Shale::Type::Integer
45
+
46
+ # @!attribute [rw] l
47
+ # Returns losses
48
+ # @api public
49
+ # @example
50
+ # stat.l #=> 28
51
+ # @return [Integer] losses
52
+ attribute :l, Shale::Type::Integer
53
+
54
+ # @!attribute [rw] w_pct
55
+ # Returns win percentage
56
+ # @api public
57
+ # @example
58
+ # stat.w_pct #=> 0.622
59
+ # @return [Float] win percentage
60
+ attribute :w_pct, Shale::Type::Float
61
+
62
+ # @!attribute [rw] min
63
+ # Returns minutes per game
64
+ # @api public
65
+ # @example
66
+ # stat.min #=> 32.7
67
+ # @return [Float] minutes
68
+ attribute :min, Shale::Type::Float
69
+
70
+ # @!attribute [rw] fgm
71
+ # Returns field goals made per game
72
+ # @api public
73
+ # @example
74
+ # stat.fgm #=> 10.0
75
+ # @return [Float] field goals made
76
+ attribute :fgm, Shale::Type::Float
77
+
78
+ # @!attribute [rw] fga
79
+ # Returns field goals attempted per game
80
+ # @api public
81
+ # @example
82
+ # stat.fga #=> 19.6
83
+ # @return [Float] field goals attempted
84
+ attribute :fga, Shale::Type::Float
85
+
86
+ # @!attribute [rw] fg_pct
87
+ # Returns field goal percentage
88
+ # @api public
89
+ # @example
90
+ # stat.fg_pct #=> 0.451
91
+ # @return [Float] field goal percentage
92
+ attribute :fg_pct, Shale::Type::Float
93
+
94
+ # @!attribute [rw] fg3m
95
+ # Returns three-pointers made per game
96
+ # @api public
97
+ # @example
98
+ # stat.fg3m #=> 4.8
99
+ # @return [Float] three-pointers made
100
+ attribute :fg3m, Shale::Type::Float
101
+
102
+ # @!attribute [rw] fg3a
103
+ # Returns three-pointers attempted per game
104
+ # @api public
105
+ # @example
106
+ # stat.fg3a #=> 11.7
107
+ # @return [Float] three-pointers attempted
108
+ attribute :fg3a, Shale::Type::Float
109
+
110
+ # @!attribute [rw] fg3_pct
111
+ # Returns three-point percentage
112
+ # @api public
113
+ # @example
114
+ # stat.fg3_pct #=> 0.408
115
+ # @return [Float] three-point percentage
116
+ attribute :fg3_pct, Shale::Type::Float
117
+
118
+ # @!attribute [rw] ftm
119
+ # Returns free throws made per game
120
+ # @api public
121
+ # @example
122
+ # stat.ftm #=> 4.8
123
+ # @return [Float] free throws made
124
+ attribute :ftm, Shale::Type::Float
125
+
126
+ # @!attribute [rw] fta
127
+ # Returns free throws attempted per game
128
+ # @api public
129
+ # @example
130
+ # stat.fta #=> 5.1
131
+ # @return [Float] free throws attempted
132
+ attribute :fta, Shale::Type::Float
133
+
134
+ # @!attribute [rw] ft_pct
135
+ # Returns free throw percentage
136
+ # @api public
137
+ # @example
138
+ # stat.ft_pct #=> 0.921
139
+ # @return [Float] free throw percentage
140
+ attribute :ft_pct, Shale::Type::Float
141
+
142
+ # @!attribute [rw] oreb
143
+ # Returns offensive rebounds per game
144
+ # @api public
145
+ # @example
146
+ # stat.oreb #=> 0.7
147
+ # @return [Float] offensive rebounds
148
+ attribute :oreb, Shale::Type::Float
149
+
150
+ # @!attribute [rw] dreb
151
+ # Returns defensive rebounds per game
152
+ # @api public
153
+ # @example
154
+ # stat.dreb #=> 4.5
155
+ # @return [Float] defensive rebounds
156
+ attribute :dreb, Shale::Type::Float
157
+
158
+ # @!attribute [rw] reb
159
+ # Returns total rebounds per game
160
+ # @api public
161
+ # @example
162
+ # stat.reb #=> 5.1
163
+ # @return [Float] total rebounds
164
+ attribute :reb, Shale::Type::Float
165
+
166
+ # @!attribute [rw] ast
167
+ # Returns assists per game
168
+ # @api public
169
+ # @example
170
+ # stat.ast #=> 5.1
171
+ # @return [Float] assists
172
+ attribute :ast, Shale::Type::Float
173
+
174
+ # @!attribute [rw] tov
175
+ # Returns turnovers per game
176
+ # @api public
177
+ # @example
178
+ # stat.tov #=> 2.8
179
+ # @return [Float] turnovers
180
+ attribute :tov, Shale::Type::Float
181
+
182
+ # @!attribute [rw] stl
183
+ # Returns steals per game
184
+ # @api public
185
+ # @example
186
+ # stat.stl #=> 0.7
187
+ # @return [Float] steals
188
+ attribute :stl, Shale::Type::Float
189
+
190
+ # @!attribute [rw] blk
191
+ # Returns blocks per game
192
+ # @api public
193
+ # @example
194
+ # stat.blk #=> 0.4
195
+ # @return [Float] blocks
196
+ attribute :blk, Shale::Type::Float
197
+
198
+ # @!attribute [rw] blka
199
+ # Returns blocked attempts per game
200
+ # @api public
201
+ # @example
202
+ # stat.blka #=> 0.3
203
+ # @return [Float] blocked attempts
204
+ attribute :blka, Shale::Type::Float
205
+
206
+ # @!attribute [rw] pf
207
+ # Returns personal fouls per game
208
+ # @api public
209
+ # @example
210
+ # stat.pf #=> 1.6
211
+ # @return [Float] personal fouls
212
+ attribute :pf, Shale::Type::Float
213
+
214
+ # @!attribute [rw] pfd
215
+ # Returns personal fouls drawn per game
216
+ # @api public
217
+ # @example
218
+ # stat.pfd #=> 1.9
219
+ # @return [Float] personal fouls drawn
220
+ attribute :pfd, Shale::Type::Float
221
+
222
+ # @!attribute [rw] pts
223
+ # Returns points per game
224
+ # @api public
225
+ # @example
226
+ # stat.pts #=> 26.4
227
+ # @return [Float] points
228
+ attribute :pts, Shale::Type::Float
229
+
230
+ # @!attribute [rw] plus_minus
231
+ # Returns plus/minus per game
232
+ # @api public
233
+ # @example
234
+ # stat.plus_minus #=> 7.8
235
+ # @return [Float] plus/minus
236
+ attribute :plus_minus, Shale::Type::Float
237
+
238
+ # Returns the player object
239
+ #
240
+ # @api public
241
+ # @example
242
+ # stat.player #=> #<NBA::Player>
243
+ # @return [Player, nil] the player object
244
+ def player
245
+ Players.find(player_id)
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,84 @@
1
+ require_relative "client"
2
+ require_relative "response_parser"
3
+ require_relative "utils"
4
+
5
+ require_relative "estimated_metrics_stat"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve player estimated metrics
9
+ module PlayerEstimatedMetrics
10
+ # Season type constant for regular season
11
+ # @return [String] the season type
12
+ REGULAR_SEASON = "Regular Season".freeze
13
+
14
+ # Season type constant for playoffs
15
+ # @return [String] the season type
16
+ PLAYOFFS = "Playoffs".freeze
17
+
18
+ # Result set name for player estimated metrics
19
+ # @return [String] the result set name
20
+ RESULT_SET_NAME = "PlayerEstimatedMetrics".freeze
21
+
22
+ # Retrieves estimated metrics for all players
23
+ #
24
+ # @api public
25
+ # @example
26
+ # stats = NBA::PlayerEstimatedMetrics.all
27
+ # stats.each { |s| puts "#{s.player_name}: #{s.e_net_rating} net rating" }
28
+ #
29
+ # @param season [Integer] the season year
30
+ # @param season_type [String] the season type
31
+ # @param client [Client] the API client to use
32
+ # @return [Collection] a collection of estimated metrics stats
33
+ def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, client: CLIENT)
34
+ path = build_path(season, season_type)
35
+ ResponseParser.parse(client.get(path), result_set: RESULT_SET_NAME) { |data| build_stat(data) }
36
+ end
37
+
38
+ # Builds the API request path
39
+ # @api private
40
+ # @return [String] the request path
41
+ def self.build_path(season, season_type)
42
+ season_str = Utils.format_season(season)
43
+ "playerestimatedmetrics?LeagueID=00&Season=#{season_str}&SeasonType=#{season_type}"
44
+ end
45
+ private_class_method :build_path
46
+
47
+ # Builds an estimated metrics stat from API data
48
+ # @api private
49
+ # @return [EstimatedMetricsStat]
50
+ def self.build_stat(data)
51
+ EstimatedMetricsStat.new(**identity_info(data), **rating_info(data), **percentage_info(data))
52
+ end
53
+ private_class_method :build_stat
54
+
55
+ # Extracts identity information from data
56
+ # @api private
57
+ # @return [Hash]
58
+ def self.identity_info(data)
59
+ {player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
60
+ gp: data["GP"], w: data["W"], l: data["L"],
61
+ w_pct: data["W_PCT"], min: data["MIN"]}
62
+ end
63
+ private_class_method :identity_info
64
+
65
+ # Extracts rating information from data
66
+ # @api private
67
+ # @return [Hash]
68
+ def self.rating_info(data)
69
+ {e_off_rating: data["E_OFF_RATING"], e_def_rating: data["E_DEF_RATING"],
70
+ e_net_rating: data["E_NET_RATING"], e_ast_ratio: data["E_AST_RATIO"]}
71
+ end
72
+ private_class_method :rating_info
73
+
74
+ # Extracts percentage information from data
75
+ # @api private
76
+ # @return [Hash]
77
+ def self.percentage_info(data)
78
+ {e_oreb_pct: data["E_OREB_PCT"], e_dreb_pct: data["E_DREB_PCT"],
79
+ e_reb_pct: data["E_REB_PCT"], e_tov_pct: data["E_TOV_PCT"],
80
+ e_usg_pct: data["E_USG_PCT"], e_pace: data["E_PACE"]}
81
+ end
82
+ private_class_method :percentage_info
83
+ end
84
+ end