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,227 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "team_and_players_vs_players_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve team and players vs players statistics
9
+ #
10
+ # @api public
11
+ module TeamAndPlayersVsPlayers
12
+ # Result set name for players vs players
13
+ # @return [String] the result set name
14
+ PLAYERS_VS_PLAYERS = "PlayersVsPlayers".freeze
15
+
16
+ # Result set name for team players vs players off court
17
+ # @return [String] the result set name
18
+ TEAM_PLAYERS_VS_PLAYERS_OFF = "TeamPlayersVsPlayersOff".freeze
19
+
20
+ # Result set name for team players vs players on court
21
+ # @return [String] the result set name
22
+ TEAM_PLAYERS_VS_PLAYERS_ON = "TeamPlayersVsPlayersOn".freeze
23
+
24
+ # Result set name for team vs players
25
+ # @return [String] the result set name
26
+ TEAM_VS_PLAYERS = "TeamVsPlayers".freeze
27
+
28
+ # Retrieves players vs players comparison statistics
29
+ #
30
+ # @api public
31
+ # @example
32
+ # stats = NBA::TeamAndPlayersVsPlayers.players_vs_players(
33
+ # team: 1610612744, vs_team: 1610612747, players: [201939], vs_players: [2544]
34
+ # )
35
+ # stats.first.pts #=> 26.4
36
+ # @param team [Integer, Team] the team ID or Team object
37
+ # @param vs_team [Integer, Team] the vs team ID or Team object
38
+ # @param players [Array<Integer, Player>] array of player IDs or Player objects
39
+ # @param vs_players [Array<Integer, Player>] array of vs player IDs or Player objects
40
+ # @param season [Integer] the season year
41
+ # @param season_type [String] the season type
42
+ # @param per_mode [String] the per mode
43
+ # @param client [Client] the API client to use
44
+ # @return [Collection] a collection of player vs player statistics
45
+ def self.players_vs_players(team:, vs_team:, players:, vs_players:, season: Utils.current_season,
46
+ season_type: "Regular Season", per_mode: "PerGame", client: CLIENT)
47
+ opts = {season: season, season_type: season_type, per_mode: per_mode, result_set: PLAYERS_VS_PLAYERS}
48
+ fetch_stats(team, vs_team, players, vs_players, opts, client: client)
49
+ end
50
+
51
+ # Retrieves team players vs players off court statistics
52
+ #
53
+ # @api public
54
+ # @example
55
+ # stats = NBA::TeamAndPlayersVsPlayers.team_players_vs_players_off(
56
+ # team: 1610612744, vs_team: 1610612747, players: [201939], vs_players: [2544]
57
+ # )
58
+ # stats.first.pts #=> 22.1
59
+ # @param team [Integer, Team] the team ID or Team object
60
+ # @param vs_team [Integer, Team] the vs team ID or Team object
61
+ # @param players [Array<Integer, Player>] array of player IDs or Player objects
62
+ # @param vs_players [Array<Integer, Player>] array of vs player IDs or Player objects
63
+ # @param season [Integer] the season year
64
+ # @param season_type [String] the season type
65
+ # @param per_mode [String] the per mode
66
+ # @param client [Client] the API client to use
67
+ # @return [Collection] a collection of team player statistics
68
+ def self.team_players_vs_players_off(team:, vs_team:, players:, vs_players:, season: Utils.current_season,
69
+ season_type: "Regular Season", per_mode: "PerGame", client: CLIENT)
70
+ opts = {season: season, season_type: season_type, per_mode: per_mode, result_set: TEAM_PLAYERS_VS_PLAYERS_OFF}
71
+ fetch_stats(team, vs_team, players, vs_players, opts, client: client)
72
+ end
73
+
74
+ # Retrieves team players vs players on court statistics
75
+ #
76
+ # @api public
77
+ # @example
78
+ # stats = NBA::TeamAndPlayersVsPlayers.team_players_vs_players_on(
79
+ # team: 1610612744, vs_team: 1610612747, players: [201939], vs_players: [2544]
80
+ # )
81
+ # stats.first.pts #=> 28.3
82
+ # @param team [Integer, Team] the team ID or Team object
83
+ # @param vs_team [Integer, Team] the vs team ID or Team object
84
+ # @param players [Array<Integer, Player>] array of player IDs or Player objects
85
+ # @param vs_players [Array<Integer, Player>] array of vs player IDs or Player objects
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 team player statistics
91
+ def self.team_players_vs_players_on(team:, vs_team:, players:, vs_players:, season: Utils.current_season,
92
+ season_type: "Regular Season", per_mode: "PerGame", client: CLIENT)
93
+ opts = {season: season, season_type: season_type, per_mode: per_mode, result_set: TEAM_PLAYERS_VS_PLAYERS_ON}
94
+ fetch_stats(team, vs_team, players, vs_players, opts, client: client)
95
+ end
96
+
97
+ # Retrieves team vs players statistics
98
+ #
99
+ # @api public
100
+ # @example
101
+ # stats = NBA::TeamAndPlayersVsPlayers.team_vs_players(
102
+ # team: 1610612744, vs_team: 1610612747, players: [201939], vs_players: [2544]
103
+ # )
104
+ # stats.first.pts #=> 112.4
105
+ # @param team [Integer, Team] the team ID or Team object
106
+ # @param vs_team [Integer, Team] the vs team ID or Team object
107
+ # @param players [Array<Integer, Player>] array of player IDs or Player objects
108
+ # @param vs_players [Array<Integer, Player>] array of vs player IDs or Player objects
109
+ # @param season [Integer] the season year
110
+ # @param season_type [String] the season type
111
+ # @param per_mode [String] the per mode
112
+ # @param client [Client] the API client to use
113
+ # @return [Collection] a collection of team statistics
114
+ def self.team_vs_players(team:, vs_team:, players:, vs_players:, season: Utils.current_season,
115
+ season_type: "Regular Season", per_mode: "PerGame", client: CLIENT)
116
+ opts = {season: season, season_type: season_type, per_mode: per_mode, result_set: TEAM_VS_PLAYERS}
117
+ fetch_stats(team, vs_team, players, vs_players, opts, client: client)
118
+ end
119
+
120
+ # Fetches team and players vs players statistics from the API
121
+ #
122
+ # @api private
123
+ # @return [Collection] the collection of statistics
124
+ def self.fetch_stats(team, vs_team, players, vs_players, opts, client:)
125
+ path = build_path(team, vs_team, players, vs_players, opts)
126
+ response = client.get(path)
127
+ parse_response(response, opts.fetch(:result_set))
128
+ end
129
+ private_class_method :fetch_stats
130
+
131
+ # Builds the API request path with all parameters
132
+ #
133
+ # @api private
134
+ # @return [String] the API request path
135
+ def self.build_path(team, vs_team, players, vs_players, opts)
136
+ team_id = Utils.extract_id(team)
137
+ vs_team_id = Utils.extract_id(vs_team)
138
+ season_str = Utils.format_season(opts.fetch(:season))
139
+ player_params = build_player_params(players, "PlayerID")
140
+ vs_player_params = build_player_params(vs_players, "VsPlayerID")
141
+ "teamandplayersvsplayers?TeamID=#{team_id}&VsTeamID=#{vs_team_id}&Season=#{season_str}" \
142
+ "&SeasonType=#{opts.fetch(:season_type)}&PerMode=#{opts.fetch(:per_mode)}" \
143
+ "&LeagueID=00#{player_params}#{vs_player_params}"
144
+ end
145
+ private_class_method :build_path
146
+
147
+ # Builds player parameter string for API request
148
+ #
149
+ # @api private
150
+ # @return [String] the player parameters string
151
+ def self.build_player_params(players, param_prefix)
152
+ ids = players.map { |p| Utils.extract_id(p) }
153
+ (1..5).map { |i| "&#{param_prefix}#{i}=#{ids.at(i - 1) || 0}" }.join
154
+ end
155
+ private_class_method :build_player_params
156
+
157
+ # Parses the API response and extracts the result set
158
+ #
159
+ # @api private
160
+ # @return [Collection] the collection of statistics
161
+ def self.parse_response(response, result_set_name)
162
+ return Collection.new if response.nil? || response.empty?
163
+
164
+ data = JSON.parse(response)
165
+ result_set = find_result_set(data, result_set_name)
166
+ build_collection(result_set)
167
+ end
168
+ private_class_method :parse_response
169
+
170
+ # Finds the result set matching the given name
171
+ #
172
+ # @api private
173
+ # @return [Hash, nil] the result set hash or nil
174
+ def self.find_result_set(data, result_set_name)
175
+ result_sets = data["resultSets"]
176
+ return unless result_sets
177
+
178
+ result_sets.find { |rs| rs["name"].eql?(result_set_name) }
179
+ end
180
+ private_class_method :find_result_set
181
+
182
+ # Builds a collection from the result set data
183
+ #
184
+ # @api private
185
+ # @return [Collection] the collection of statistics
186
+ def self.build_collection(result_set)
187
+ return Collection.new unless result_set
188
+
189
+ headers = result_set["headers"]
190
+ rows = result_set["rowSet"]
191
+ return Collection.new unless headers && rows
192
+
193
+ Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
194
+ end
195
+ private_class_method :build_collection
196
+
197
+ # Builds a stat object from the data hash
198
+ #
199
+ # @api private
200
+ # @return [TeamAndPlayersVsPlayersStat] the stat object
201
+ def self.build_stat(data)
202
+ TeamAndPlayersVsPlayersStat.new(**identity_info(data), **stat_info(data))
203
+ end
204
+ private_class_method :build_stat
205
+
206
+ # Extracts identity information from the data hash
207
+ #
208
+ # @api private
209
+ # @return [Hash] the identity attributes
210
+ def self.identity_info(data)
211
+ {team_id: data["TEAM_ID"], player_id: data["PLAYER_ID"],
212
+ vs_player_id: data["VS_PLAYER_ID"], player_name: data["PLAYER_NAME"],
213
+ gp: data["GP"], min: data["MIN"]}
214
+ end
215
+ private_class_method :identity_info
216
+
217
+ # Extracts stat information from the data hash
218
+ #
219
+ # @api private
220
+ # @return [Hash] the stat attributes
221
+ def self.stat_info(data)
222
+ {pts: data["PTS"], reb: data["REB"], ast: data["AST"], stl: data["STL"],
223
+ blk: data["BLK"], tov: data["TOV"], fg_pct: data["FG_PCT"], plus_minus: data["PLUS_MINUS"]}
224
+ end
225
+ private_class_method :stat_info
226
+ end
227
+ end
@@ -0,0 +1,155 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "players"
4
+ require_relative "teams"
5
+
6
+ module NBA
7
+ # Represents team and players vs players comparison statistics
8
+ #
9
+ # @api public
10
+ class TeamAndPlayersVsPlayersStat < Shale::Mapper
11
+ include Equalizer.new(:team_id, :player_id, :vs_player_id)
12
+
13
+ # @!attribute [rw] team_id
14
+ # Returns the team ID
15
+ # @api public
16
+ # @example
17
+ # stat.team_id #=> 1610612744
18
+ # @return [Integer, nil] the team's ID
19
+ attribute :team_id, Shale::Type::Integer
20
+
21
+ # @!attribute [rw] player_id
22
+ # Returns the player ID
23
+ # @api public
24
+ # @example
25
+ # stat.player_id #=> 201939
26
+ # @return [Integer, nil] the player's ID
27
+ attribute :player_id, Shale::Type::Integer
28
+
29
+ # @!attribute [rw] vs_player_id
30
+ # Returns the vs player ID
31
+ # @api public
32
+ # @example
33
+ # stat.vs_player_id #=> 201566
34
+ # @return [Integer, nil] the vs player's ID
35
+ attribute :vs_player_id, Shale::Type::Integer
36
+
37
+ # @!attribute [rw] player_name
38
+ # Returns the player name
39
+ # @api public
40
+ # @example
41
+ # stat.player_name #=> "Stephen Curry"
42
+ # @return [String, nil] the player's name
43
+ attribute :player_name, Shale::Type::String
44
+
45
+ # @!attribute [rw] gp
46
+ # Returns games played
47
+ # @api public
48
+ # @example
49
+ # stat.gp #=> 24
50
+ # @return [Integer, nil] games played
51
+ attribute :gp, Shale::Type::Integer
52
+
53
+ # @!attribute [rw] min
54
+ # Returns minutes played
55
+ # @api public
56
+ # @example
57
+ # stat.min #=> 32.5
58
+ # @return [Float, nil] minutes played
59
+ attribute :min, Shale::Type::Float
60
+
61
+ # @!attribute [rw] pts
62
+ # Returns points
63
+ # @api public
64
+ # @example
65
+ # stat.pts #=> 26.4
66
+ # @return [Float, nil] points
67
+ attribute :pts, Shale::Type::Float
68
+
69
+ # @!attribute [rw] reb
70
+ # Returns rebounds
71
+ # @api public
72
+ # @example
73
+ # stat.reb #=> 5.7
74
+ # @return [Float, nil] rebounds
75
+ attribute :reb, Shale::Type::Float
76
+
77
+ # @!attribute [rw] ast
78
+ # Returns assists
79
+ # @api public
80
+ # @example
81
+ # stat.ast #=> 6.1
82
+ # @return [Float, nil] assists
83
+ attribute :ast, Shale::Type::Float
84
+
85
+ # @!attribute [rw] stl
86
+ # Returns steals
87
+ # @api public
88
+ # @example
89
+ # stat.stl #=> 1.2
90
+ # @return [Float, nil] steals
91
+ attribute :stl, Shale::Type::Float
92
+
93
+ # @!attribute [rw] blk
94
+ # Returns blocks
95
+ # @api public
96
+ # @example
97
+ # stat.blk #=> 0.3
98
+ # @return [Float, nil] blocks
99
+ attribute :blk, Shale::Type::Float
100
+
101
+ # @!attribute [rw] tov
102
+ # Returns turnovers
103
+ # @api public
104
+ # @example
105
+ # stat.tov #=> 3.1
106
+ # @return [Float, nil] turnovers
107
+ attribute :tov, Shale::Type::Float
108
+
109
+ # @!attribute [rw] fg_pct
110
+ # Returns field goal percentage
111
+ # @api public
112
+ # @example
113
+ # stat.fg_pct #=> 0.467
114
+ # @return [Float, nil] field goal percentage
115
+ attribute :fg_pct, Shale::Type::Float
116
+
117
+ # @!attribute [rw] plus_minus
118
+ # Returns plus/minus
119
+ # @api public
120
+ # @example
121
+ # stat.plus_minus #=> 8.5
122
+ # @return [Float, nil] plus/minus
123
+ attribute :plus_minus, Shale::Type::Float
124
+
125
+ # Returns the team
126
+ #
127
+ # @api public
128
+ # @example
129
+ # stat.team #=> #<NBA::Team id=1610612744 ...>
130
+ # @return [Team, nil] the team object
131
+ def team
132
+ Teams.find(team_id)
133
+ end
134
+
135
+ # Returns the player
136
+ #
137
+ # @api public
138
+ # @example
139
+ # stat.player #=> #<NBA::Player id=201939 ...>
140
+ # @return [Player, nil] the player object
141
+ def player
142
+ Players.find(player_id)
143
+ end
144
+
145
+ # Returns the vs player
146
+ #
147
+ # @api public
148
+ # @example
149
+ # stat.vs_player #=> #<NBA::Player id=201566 ...>
150
+ # @return [Player, nil] the vs player object
151
+ def vs_player
152
+ Players.find(vs_player_id)
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,157 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "team_pass_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve team tracking pass statistics
9
+ #
10
+ # @api public
11
+ module TeamDashPtPass
12
+ # Result set name for passes made
13
+ # @return [String] the result set name
14
+ PASSES_MADE = "PassesMade".freeze
15
+
16
+ # Result set name for passes received
17
+ # @return [String] the result set name
18
+ PASSES_RECEIVED = "PassesReceived".freeze
19
+
20
+ # Retrieves passes made statistics for a team
21
+ #
22
+ # @api public
23
+ # @example
24
+ # stats = NBA::TeamDashPtPass.passes_made(team: 1610612744)
25
+ # stats.each { |s| puts "#{s.pass_from}: #{s.ast} assists" }
26
+ # @param team [Integer, Team] the team ID or Team object
27
+ # @param season [Integer] the season year
28
+ # @param season_type [String] the season type
29
+ # @param per_mode [String] the per mode
30
+ # @param client [Client] the API client to use
31
+ # @return [Collection] a collection of pass statistics
32
+ def self.passes_made(team:, season: Utils.current_season, season_type: "Regular Season",
33
+ per_mode: "PerGame", client: CLIENT)
34
+ fetch_stats(team, season, season_type, per_mode, PASSES_MADE, client: client)
35
+ end
36
+
37
+ # Retrieves passes received statistics for a team
38
+ #
39
+ # @api public
40
+ # @example
41
+ # stats = NBA::TeamDashPtPass.passes_received(team: 1610612744)
42
+ # stats.each { |s| puts "#{s.pass_to}: #{s.pass} passes" }
43
+ # @param team [Integer, Team] the team ID or Team object
44
+ # @param season [Integer] the season year
45
+ # @param season_type [String] the season type
46
+ # @param per_mode [String] the per mode
47
+ # @param client [Client] the API client to use
48
+ # @return [Collection] a collection of pass statistics
49
+ def self.passes_received(team:, season: Utils.current_season, season_type: "Regular Season",
50
+ per_mode: "PerGame", client: CLIENT)
51
+ fetch_stats(team, season, season_type, per_mode, PASSES_RECEIVED, client: client)
52
+ end
53
+
54
+ # Fetches pass stats from the API
55
+ #
56
+ # @api private
57
+ # @return [Collection] collection of pass stats
58
+ def self.fetch_stats(team, season, season_type, per_mode, result_set_name, client:)
59
+ path = build_path(team, season, season_type, per_mode)
60
+ response = client.get(path)
61
+ parse_response(response, result_set_name)
62
+ end
63
+ private_class_method :fetch_stats
64
+
65
+ # Builds the API path
66
+ #
67
+ # @api private
68
+ # @return [String] the request path
69
+ def self.build_path(team, season, season_type, per_mode)
70
+ team_id = Utils.extract_id(team)
71
+ season_str = Utils.format_season(season)
72
+ "teamdashptpass?TeamID=#{team_id}&Season=#{season_str}" \
73
+ "&SeasonType=#{season_type}&PerMode=#{per_mode}&LeagueID=00"
74
+ end
75
+ private_class_method :build_path
76
+
77
+ # Parses the API response into pass stat objects
78
+ #
79
+ # @api private
80
+ # @return [Collection] collection of pass stats
81
+ def self.parse_response(response, result_set_name)
82
+ return Collection.new if response.nil? || response.empty?
83
+
84
+ data = JSON.parse(response)
85
+ result_set = find_result_set(data, result_set_name)
86
+ build_collection(result_set)
87
+ end
88
+ private_class_method :parse_response
89
+
90
+ # Finds a result set by name
91
+ #
92
+ # @api private
93
+ # @return [Hash, nil] the result set hash or nil if not found
94
+ def self.find_result_set(data, result_set_name)
95
+ result_sets = data["resultSets"]
96
+ return unless result_sets
97
+
98
+ result_sets.find { |rs| rs["name"].eql?(result_set_name) }
99
+ end
100
+ private_class_method :find_result_set
101
+
102
+ # Builds a collection from a result set
103
+ #
104
+ # @api private
105
+ # @return [Collection] the stats collection
106
+ def self.build_collection(result_set)
107
+ return Collection.new unless result_set
108
+
109
+ headers = result_set["headers"]
110
+ rows = result_set["rowSet"]
111
+ return Collection.new unless headers && rows
112
+
113
+ Collection.new(rows.map { |row| build_pass_stat(headers.zip(row).to_h) })
114
+ end
115
+ private_class_method :build_collection
116
+
117
+ # Builds a pass stat from API data
118
+ #
119
+ # @api private
120
+ # @return [TeamPassStat] the pass stat object
121
+ def self.build_pass_stat(data)
122
+ TeamPassStat.new(**identity_info(data), **pass_info(data), **shooting_info(data))
123
+ end
124
+ private_class_method :build_pass_stat
125
+
126
+ # Extracts identity information from data
127
+ #
128
+ # @api private
129
+ # @return [Hash] the identity information hash
130
+ def self.identity_info(data)
131
+ {team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"], pass_type: data["PASS_TYPE"],
132
+ g: data["G"], pass_teammate_player_id: data["PASS_TEAMMATE_PLAYER_ID"]}
133
+ end
134
+ private_class_method :identity_info
135
+
136
+ # Extracts pass information from data
137
+ #
138
+ # @api private
139
+ # @return [Hash] the pass information hash
140
+ def self.pass_info(data)
141
+ {pass_from: data["PASS_FROM"], pass_to: data["PASS_TO"], frequency: data["FREQUENCY"],
142
+ pass: data["PASS"], ast: data["AST"]}
143
+ end
144
+ private_class_method :pass_info
145
+
146
+ # Extracts shooting information from data
147
+ #
148
+ # @api private
149
+ # @return [Hash] the shooting information hash
150
+ def self.shooting_info(data)
151
+ {fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
152
+ fg2m: data["FG2M"], fg2a: data["FG2A"], fg2_pct: data["FG2_PCT"],
153
+ fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"]}
154
+ end
155
+ private_class_method :shooting_info
156
+ end
157
+ end