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,214 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "teams"
4
+
5
+ module NBA
6
+ # Represents a lineup visualization statistic
7
+ #
8
+ # @api public
9
+ class LeagueLineupVizStat < Shale::Mapper
10
+ include Equalizer.new(:group_id, :team_id)
11
+
12
+ # @!attribute [rw] group_id
13
+ # Returns the lineup group ID
14
+ # @api public
15
+ # @example
16
+ # stat.group_id #=> "201939-203110-1628369"
17
+ # @return [String, nil] the group ID
18
+ attribute :group_id, Shale::Type::String
19
+
20
+ # @!attribute [rw] group_name
21
+ # Returns the lineup group name (player names)
22
+ # @api public
23
+ # @example
24
+ # stat.group_name #=> "S. Curry - K. Thompson - A. Wiggins"
25
+ # @return [String, nil] the group name
26
+ attribute :group_name, Shale::Type::String
27
+
28
+ # @!attribute [rw] team_id
29
+ # Returns the team ID
30
+ # @api public
31
+ # @example
32
+ # stat.team_id #=> 1610612744
33
+ # @return [Integer, nil] the team ID
34
+ attribute :team_id, Shale::Type::Integer
35
+
36
+ # @!attribute [rw] team_abbreviation
37
+ # Returns the team abbreviation
38
+ # @api public
39
+ # @example
40
+ # stat.team_abbreviation #=> "GSW"
41
+ # @return [String, nil] the team abbreviation
42
+ attribute :team_abbreviation, Shale::Type::String
43
+
44
+ # @!attribute [rw] min
45
+ # Returns minutes played
46
+ # @api public
47
+ # @example
48
+ # stat.min #=> 245.5
49
+ # @return [Float, nil] minutes played
50
+ attribute :min, Shale::Type::Float
51
+
52
+ # @!attribute [rw] off_rating
53
+ # Returns offensive rating
54
+ # @api public
55
+ # @example
56
+ # stat.off_rating #=> 115.3
57
+ # @return [Float, nil] offensive rating
58
+ attribute :off_rating, Shale::Type::Float
59
+
60
+ # @!attribute [rw] def_rating
61
+ # Returns defensive rating
62
+ # @api public
63
+ # @example
64
+ # stat.def_rating #=> 108.5
65
+ # @return [Float, nil] defensive rating
66
+ attribute :def_rating, Shale::Type::Float
67
+
68
+ # @!attribute [rw] net_rating
69
+ # Returns net rating
70
+ # @api public
71
+ # @example
72
+ # stat.net_rating #=> 6.8
73
+ # @return [Float, nil] net rating
74
+ attribute :net_rating, Shale::Type::Float
75
+
76
+ # @!attribute [rw] pace
77
+ # Returns pace
78
+ # @api public
79
+ # @example
80
+ # stat.pace #=> 101.2
81
+ # @return [Float, nil] pace
82
+ attribute :pace, Shale::Type::Float
83
+
84
+ # @!attribute [rw] ts_pct
85
+ # Returns true shooting percentage
86
+ # @api public
87
+ # @example
88
+ # stat.ts_pct #=> 0.612
89
+ # @return [Float, nil] true shooting percentage
90
+ attribute :ts_pct, Shale::Type::Float
91
+
92
+ # @!attribute [rw] fta_rate
93
+ # Returns free throw attempt rate
94
+ # @api public
95
+ # @example
96
+ # stat.fta_rate #=> 0.285
97
+ # @return [Float, nil] free throw attempt rate
98
+ attribute :fta_rate, Shale::Type::Float
99
+
100
+ # @!attribute [rw] tm_ast_pct
101
+ # Returns team assist percentage
102
+ # @api public
103
+ # @example
104
+ # stat.tm_ast_pct #=> 0.652
105
+ # @return [Float, nil] team assist percentage
106
+ attribute :tm_ast_pct, Shale::Type::Float
107
+
108
+ # @!attribute [rw] pct_fga_2pt
109
+ # Returns percentage of FGA that are 2-pointers
110
+ # @api public
111
+ # @example
112
+ # stat.pct_fga_2pt #=> 0.545
113
+ # @return [Float, nil] percentage of FGA that are 2-pointers
114
+ attribute :pct_fga_2pt, Shale::Type::Float
115
+
116
+ # @!attribute [rw] pct_fga_3pt
117
+ # Returns percentage of FGA that are 3-pointers
118
+ # @api public
119
+ # @example
120
+ # stat.pct_fga_3pt #=> 0.455
121
+ # @return [Float, nil] percentage of FGA that are 3-pointers
122
+ attribute :pct_fga_3pt, Shale::Type::Float
123
+
124
+ # @!attribute [rw] pct_pts_2pt_mr
125
+ # Returns percentage of points from mid-range 2s
126
+ # @api public
127
+ # @example
128
+ # stat.pct_pts_2pt_mr #=> 0.125
129
+ # @return [Float, nil] percentage of points from mid-range 2s
130
+ attribute :pct_pts_2pt_mr, Shale::Type::Float
131
+
132
+ # @!attribute [rw] pct_pts_fb
133
+ # Returns percentage of points from fast breaks
134
+ # @api public
135
+ # @example
136
+ # stat.pct_pts_fb #=> 0.152
137
+ # @return [Float, nil] percentage of points from fast breaks
138
+ attribute :pct_pts_fb, Shale::Type::Float
139
+
140
+ # @!attribute [rw] pct_pts_ft
141
+ # Returns percentage of points from free throws
142
+ # @api public
143
+ # @example
144
+ # stat.pct_pts_ft #=> 0.185
145
+ # @return [Float, nil] percentage of points from free throws
146
+ attribute :pct_pts_ft, Shale::Type::Float
147
+
148
+ # @!attribute [rw] pct_pts_paint
149
+ # Returns percentage of points in paint
150
+ # @api public
151
+ # @example
152
+ # stat.pct_pts_paint #=> 0.425
153
+ # @return [Float, nil] percentage of points in paint
154
+ attribute :pct_pts_paint, Shale::Type::Float
155
+
156
+ # @!attribute [rw] pct_ast_fgm
157
+ # Returns percentage of FGM that were assisted
158
+ # @api public
159
+ # @example
160
+ # stat.pct_ast_fgm #=> 0.652
161
+ # @return [Float, nil] percentage of FGM that were assisted
162
+ attribute :pct_ast_fgm, Shale::Type::Float
163
+
164
+ # @!attribute [rw] pct_uast_fgm
165
+ # Returns percentage of FGM that were unassisted
166
+ # @api public
167
+ # @example
168
+ # stat.pct_uast_fgm #=> 0.348
169
+ # @return [Float, nil] percentage of FGM that were unassisted
170
+ attribute :pct_uast_fgm, Shale::Type::Float
171
+
172
+ # @!attribute [rw] opp_fg3_pct
173
+ # Returns opponent 3-point percentage
174
+ # @api public
175
+ # @example
176
+ # stat.opp_fg3_pct #=> 0.352
177
+ # @return [Float, nil] opponent 3-point percentage
178
+ attribute :opp_fg3_pct, Shale::Type::Float
179
+
180
+ # @!attribute [rw] opp_efg_pct
181
+ # Returns opponent effective FG percentage
182
+ # @api public
183
+ # @example
184
+ # stat.opp_efg_pct #=> 0.512
185
+ # @return [Float, nil] opponent effective FG percentage
186
+ attribute :opp_efg_pct, Shale::Type::Float
187
+
188
+ # @!attribute [rw] opp_fta_rate
189
+ # Returns opponent FTA rate
190
+ # @api public
191
+ # @example
192
+ # stat.opp_fta_rate #=> 0.275
193
+ # @return [Float, nil] opponent FTA rate
194
+ attribute :opp_fta_rate, Shale::Type::Float
195
+
196
+ # @!attribute [rw] opp_tov_pct
197
+ # Returns opponent turnover percentage
198
+ # @api public
199
+ # @example
200
+ # stat.opp_tov_pct #=> 0.132
201
+ # @return [Float, nil] opponent turnover percentage
202
+ attribute :opp_tov_pct, Shale::Type::Float
203
+
204
+ # Returns the team
205
+ #
206
+ # @api public
207
+ # @example
208
+ # stat.team #=> #<NBA::Team id=1610612744 ...>
209
+ # @return [Team, nil] the team object
210
+ def team
211
+ Teams.find(team_id)
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,175 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "league_player_on_details_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve league-wide player on court details
9
+ module LeaguePlayerOnDetails
10
+ # Result set name for players on court stats
11
+ # @return [String] the result set name
12
+ PLAYERS_ON_COURT = "PlayersOnCourtLeaguePlayerDetails".freeze
13
+
14
+ # Regular season type
15
+ # @return [String] the season type
16
+ REGULAR_SEASON = "Regular Season".freeze
17
+
18
+ # Playoffs season type
19
+ # @return [String] the season type
20
+ PLAYOFFS = "Playoffs".freeze
21
+
22
+ # Per game mode
23
+ # @return [String] the per mode
24
+ PER_GAME = "PerGame".freeze
25
+
26
+ # Totals mode
27
+ # @return [String] the per mode
28
+ TOTALS = "Totals".freeze
29
+
30
+ # Base measure type
31
+ # @return [String] the measure type
32
+ BASE = "Base".freeze
33
+
34
+ # Retrieves league-wide player on court details for a team
35
+ #
36
+ # @api public
37
+ # @example
38
+ # stats = NBA::LeaguePlayerOnDetails.all(team: NBA::Team::GSW)
39
+ # stats.each { |s| puts "#{s.vs_player_name}: #{s.pts} pts" }
40
+ # @param team [Integer, Team] the team ID or Team object
41
+ # @param season [Integer] the season year (defaults to current season)
42
+ # @param season_type [String] the season type (Regular Season, Playoffs)
43
+ # @param per_mode [String] the per mode (PerGame, Totals)
44
+ # @param measure_type [String] the measure type (Base)
45
+ # @param client [Client] the API client to use
46
+ # @return [Collection] a collection of player on court stats
47
+ def self.all(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, measure_type: BASE, client: CLIENT)
48
+ team_id = Utils.extract_id(team)
49
+ path = build_path(team_id, season, season_type, per_mode, measure_type)
50
+ response = client.get(path)
51
+ parse_response(response)
52
+ end
53
+
54
+ # Builds the API path
55
+ # @api private
56
+ # @param team_id [Integer] the team ID
57
+ # @param season [Integer] the season
58
+ # @param season_type [String] the season type
59
+ # @param per_mode [String] the per mode
60
+ # @param measure_type [String] the measure type
61
+ # @return [String] the path
62
+ def self.build_path(team_id, season, season_type, per_mode, measure_type)
63
+ "leagueplayerondetails?LeagueID=00&Season=#{Utils.format_season(season)}&SeasonType=#{season_type}&" \
64
+ "PerMode=#{per_mode}&MeasureType=#{measure_type}&TeamID=#{team_id}&PaceAdjust=N&PlusMinus=N&Rank=N&" \
65
+ "LastNGames=0&Month=0&OpponentTeamID=0&Period=0"
66
+ end
67
+ private_class_method :build_path
68
+
69
+ # Parses the API response
70
+ # @api private
71
+ # @param response [String, nil] the JSON response
72
+ # @return [Collection] collection of player on court stats
73
+ def self.parse_response(response)
74
+ return Collection.new unless response
75
+
76
+ data = JSON.parse(response)
77
+ result_set = find_result_set(data)
78
+ return Collection.new unless result_set
79
+
80
+ build_stats(result_set)
81
+ end
82
+ private_class_method :parse_response
83
+
84
+ # Finds the result set
85
+ # @api private
86
+ # @param data [Hash] the parsed JSON
87
+ # @return [Hash, nil] the result set
88
+ def self.find_result_set(data)
89
+ result_sets = data["resultSets"]
90
+ return unless result_sets
91
+
92
+ result_sets.find { |rs| rs.fetch("name").eql?(PLAYERS_ON_COURT) }
93
+ end
94
+ private_class_method :find_result_set
95
+
96
+ # Builds stats collection
97
+ # @api private
98
+ # @param result_set [Hash] the result set
99
+ # @return [Collection] collection of player on court stats
100
+ def self.build_stats(result_set)
101
+ headers = result_set["headers"]
102
+ rows = result_set["rowSet"]
103
+ return Collection.new unless headers && rows
104
+
105
+ stats = rows.map { |row| build_stat(headers, row) }
106
+ Collection.new(stats)
107
+ end
108
+ private_class_method :build_stats
109
+
110
+ # Builds a single stat
111
+ # @api private
112
+ # @param headers [Array<String>] the headers
113
+ # @param row [Array] the row data
114
+ # @return [LeaguePlayerOnDetailsStat] the stat
115
+ def self.build_stat(headers, row)
116
+ data = headers.zip(row).to_h
117
+ LeaguePlayerOnDetailsStat.new(**stat_attributes(data))
118
+ end
119
+ private_class_method :build_stat
120
+
121
+ # Combines all stat attributes
122
+ # @api private
123
+ # @param data [Hash] the raw data
124
+ # @return [Hash] the combined attributes
125
+ def self.stat_attributes(data)
126
+ identity_info(data).merge(record_info(data), shooting_info(data), counting_info(data))
127
+ end
128
+ private_class_method :stat_attributes
129
+
130
+ # Extracts identity attributes
131
+ # @api private
132
+ # @param data [Hash] the raw data
133
+ # @return [Hash] identity attributes
134
+ def self.identity_info(data)
135
+ {group_set: data.fetch("GROUP_SET"), team_id: data.fetch("TEAM_ID"),
136
+ team_abbreviation: data.fetch("TEAM_ABBREVIATION"), team_name: data.fetch("TEAM_NAME"),
137
+ vs_player_id: data.fetch("VS_PLAYER_ID"), vs_player_name: data.fetch("VS_PLAYER_NAME"),
138
+ court_status: data.fetch("COURT_STATUS")}
139
+ end
140
+ private_class_method :identity_info
141
+
142
+ # Extracts record attributes
143
+ # @api private
144
+ # @param data [Hash] the raw data
145
+ # @return [Hash] record attributes
146
+ def self.record_info(data)
147
+ {gp: data.fetch("GP"), w: data.fetch("W"), l: data.fetch("L"),
148
+ w_pct: data.fetch("W_PCT"), min: data.fetch("MIN")}
149
+ end
150
+ private_class_method :record_info
151
+
152
+ # Extracts shooting attributes
153
+ # @api private
154
+ # @param data [Hash] the raw data
155
+ # @return [Hash] shooting attributes
156
+ def self.shooting_info(data)
157
+ {fgm: data.fetch("FGM"), fga: data.fetch("FGA"), fg_pct: data.fetch("FG_PCT"),
158
+ fg3m: data.fetch("FG3M"), fg3a: data.fetch("FG3A"), fg3_pct: data.fetch("FG3_PCT"),
159
+ ftm: data.fetch("FTM"), fta: data.fetch("FTA"), ft_pct: data.fetch("FT_PCT")}
160
+ end
161
+ private_class_method :shooting_info
162
+
163
+ # Extracts counting attributes
164
+ # @api private
165
+ # @param data [Hash] the raw data
166
+ # @return [Hash] counting attributes
167
+ def self.counting_info(data)
168
+ {oreb: data.fetch("OREB"), dreb: data.fetch("DREB"), reb: data.fetch("REB"),
169
+ ast: data.fetch("AST"), tov: data.fetch("TOV"), stl: data.fetch("STL"),
170
+ blk: data.fetch("BLK"), blka: data.fetch("BLKA"), pf: data.fetch("PF"),
171
+ pfd: data.fetch("PFD"), pts: data.fetch("PTS"), plus_minus: data.fetch("PLUS_MINUS")}
172
+ end
173
+ private_class_method :counting_info
174
+ end
175
+ end
@@ -0,0 +1,313 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents league-wide player on/off court statistics
6
+ class LeaguePlayerOnDetailsStat < Shale::Mapper
7
+ include Equalizer.new(:team_id, :vs_player_id)
8
+
9
+ # @!attribute [rw] group_set
10
+ # Returns the group set
11
+ # @api public
12
+ # @example
13
+ # stat.group_set #=> "Overall"
14
+ # @return [String] the group set
15
+ attribute :group_set, 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_name
34
+ # Returns the team name
35
+ # @api public
36
+ # @example
37
+ # stat.team_name #=> "Golden State Warriors"
38
+ # @return [String] the team name
39
+ attribute :team_name, Shale::Type::String
40
+
41
+ # @!attribute [rw] vs_player_id
42
+ # Returns the player ID
43
+ # @api public
44
+ # @example
45
+ # stat.vs_player_id #=> 201939
46
+ # @return [Integer] the player ID
47
+ attribute :vs_player_id, Shale::Type::Integer
48
+
49
+ # @!attribute [rw] vs_player_name
50
+ # Returns the player name
51
+ # @api public
52
+ # @example
53
+ # stat.vs_player_name #=> "Stephen Curry"
54
+ # @return [String] the player name
55
+ attribute :vs_player_name, Shale::Type::String
56
+
57
+ # @!attribute [rw] court_status
58
+ # Returns the court status (On or Off)
59
+ # @api public
60
+ # @example
61
+ # stat.court_status #=> "On"
62
+ # @return [String] the court status
63
+ attribute :court_status, Shale::Type::String
64
+
65
+ # @!attribute [rw] gp
66
+ # Returns games played
67
+ # @api public
68
+ # @example
69
+ # stat.gp #=> 74
70
+ # @return [Integer] games played
71
+ attribute :gp, Shale::Type::Integer
72
+
73
+ # @!attribute [rw] w
74
+ # Returns wins
75
+ # @api public
76
+ # @example
77
+ # stat.w #=> 46
78
+ # @return [Integer] wins
79
+ attribute :w, Shale::Type::Integer
80
+
81
+ # @!attribute [rw] l
82
+ # Returns losses
83
+ # @api public
84
+ # @example
85
+ # stat.l #=> 28
86
+ # @return [Integer] losses
87
+ attribute :l, Shale::Type::Integer
88
+
89
+ # @!attribute [rw] w_pct
90
+ # Returns win percentage
91
+ # @api public
92
+ # @example
93
+ # stat.w_pct #=> 0.622
94
+ # @return [Float] win percentage
95
+ attribute :w_pct, Shale::Type::Float
96
+
97
+ # @!attribute [rw] min
98
+ # Returns minutes
99
+ # @api public
100
+ # @example
101
+ # stat.min #=> 32.5
102
+ # @return [Float] minutes
103
+ attribute :min, Shale::Type::Float
104
+
105
+ # @!attribute [rw] fgm
106
+ # Returns field goals made
107
+ # @api public
108
+ # @example
109
+ # stat.fgm #=> 9.8
110
+ # @return [Float] field goals made
111
+ attribute :fgm, Shale::Type::Float
112
+
113
+ # @!attribute [rw] fga
114
+ # Returns field goals attempted
115
+ # @api public
116
+ # @example
117
+ # stat.fga #=> 20.2
118
+ # @return [Float] field goals attempted
119
+ attribute :fga, Shale::Type::Float
120
+
121
+ # @!attribute [rw] fg_pct
122
+ # Returns field goal percentage
123
+ # @api public
124
+ # @example
125
+ # stat.fg_pct #=> 0.485
126
+ # @return [Float] field goal percentage
127
+ attribute :fg_pct, Shale::Type::Float
128
+
129
+ # @!attribute [rw] fg3m
130
+ # Returns three pointers made
131
+ # @api public
132
+ # @example
133
+ # stat.fg3m #=> 4.8
134
+ # @return [Float] three pointers made
135
+ attribute :fg3m, Shale::Type::Float
136
+
137
+ # @!attribute [rw] fg3a
138
+ # Returns three pointers attempted
139
+ # @api public
140
+ # @example
141
+ # stat.fg3a #=> 11.7
142
+ # @return [Float] three pointers attempted
143
+ attribute :fg3a, Shale::Type::Float
144
+
145
+ # @!attribute [rw] fg3_pct
146
+ # Returns three point percentage
147
+ # @api public
148
+ # @example
149
+ # stat.fg3_pct #=> 0.411
150
+ # @return [Float] three point percentage
151
+ attribute :fg3_pct, Shale::Type::Float
152
+
153
+ # @!attribute [rw] ftm
154
+ # Returns free throws made
155
+ # @api public
156
+ # @example
157
+ # stat.ftm #=> 4.2
158
+ # @return [Float] free throws made
159
+ attribute :ftm, Shale::Type::Float
160
+
161
+ # @!attribute [rw] fta
162
+ # Returns free throws attempted
163
+ # @api public
164
+ # @example
165
+ # stat.fta #=> 4.6
166
+ # @return [Float] free throws attempted
167
+ attribute :fta, Shale::Type::Float
168
+
169
+ # @!attribute [rw] ft_pct
170
+ # Returns free throw percentage
171
+ # @api public
172
+ # @example
173
+ # stat.ft_pct #=> 0.913
174
+ # @return [Float] free throw percentage
175
+ attribute :ft_pct, Shale::Type::Float
176
+
177
+ # @!attribute [rw] oreb
178
+ # Returns offensive rebounds
179
+ # @api public
180
+ # @example
181
+ # stat.oreb #=> 0.7
182
+ # @return [Float] offensive rebounds
183
+ attribute :oreb, Shale::Type::Float
184
+
185
+ # @!attribute [rw] dreb
186
+ # Returns defensive rebounds
187
+ # @api public
188
+ # @example
189
+ # stat.dreb #=> 5.4
190
+ # @return [Float] defensive rebounds
191
+ attribute :dreb, Shale::Type::Float
192
+
193
+ # @!attribute [rw] reb
194
+ # Returns total rebounds
195
+ # @api public
196
+ # @example
197
+ # stat.reb #=> 6.1
198
+ # @return [Float] total rebounds
199
+ attribute :reb, Shale::Type::Float
200
+
201
+ # @!attribute [rw] ast
202
+ # Returns assists
203
+ # @api public
204
+ # @example
205
+ # stat.ast #=> 6.3
206
+ # @return [Float] assists
207
+ attribute :ast, Shale::Type::Float
208
+
209
+ # @!attribute [rw] tov
210
+ # Returns turnovers
211
+ # @api public
212
+ # @example
213
+ # stat.tov #=> 3.2
214
+ # @return [Float] turnovers
215
+ attribute :tov, Shale::Type::Float
216
+
217
+ # @!attribute [rw] stl
218
+ # Returns steals
219
+ # @api public
220
+ # @example
221
+ # stat.stl #=> 0.9
222
+ # @return [Float] steals
223
+ attribute :stl, Shale::Type::Float
224
+
225
+ # @!attribute [rw] blk
226
+ # Returns blocks
227
+ # @api public
228
+ # @example
229
+ # stat.blk #=> 0.4
230
+ # @return [Float] blocks
231
+ attribute :blk, Shale::Type::Float
232
+
233
+ # @!attribute [rw] blka
234
+ # Returns blocked attempts
235
+ # @api public
236
+ # @example
237
+ # stat.blka #=> 0.3
238
+ # @return [Float] blocked attempts
239
+ attribute :blka, Shale::Type::Float
240
+
241
+ # @!attribute [rw] pf
242
+ # Returns personal fouls
243
+ # @api public
244
+ # @example
245
+ # stat.pf #=> 2.0
246
+ # @return [Float] personal fouls
247
+ attribute :pf, Shale::Type::Float
248
+
249
+ # @!attribute [rw] pfd
250
+ # Returns personal fouls drawn
251
+ # @api public
252
+ # @example
253
+ # stat.pfd #=> 3.8
254
+ # @return [Float] personal fouls drawn
255
+ attribute :pfd, Shale::Type::Float
256
+
257
+ # @!attribute [rw] pts
258
+ # Returns points
259
+ # @api public
260
+ # @example
261
+ # stat.pts #=> 28.6
262
+ # @return [Float] points
263
+ attribute :pts, Shale::Type::Float
264
+
265
+ # @!attribute [rw] plus_minus
266
+ # Returns plus/minus
267
+ # @api public
268
+ # @example
269
+ # stat.plus_minus #=> 7.4
270
+ # @return [Float] plus/minus
271
+ attribute :plus_minus, Shale::Type::Float
272
+
273
+ # Returns the player object
274
+ #
275
+ # @api public
276
+ # @example
277
+ # stat.player #=> #<NBA::Player>
278
+ # @return [Player, nil] the player object
279
+ def player
280
+ Players.find(vs_player_id)
281
+ end
282
+
283
+ # Returns the team object
284
+ #
285
+ # @api public
286
+ # @example
287
+ # stat.team #=> #<NBA::Team>
288
+ # @return [Team, nil] the team object
289
+ def team
290
+ Teams.find(team_id)
291
+ end
292
+
293
+ # Returns whether the player is on court
294
+ #
295
+ # @api public
296
+ # @example
297
+ # stat.on_court? #=> true
298
+ # @return [Boolean] true if player is on court
299
+ def on_court?
300
+ court_status.eql?("On")
301
+ end
302
+
303
+ # Returns whether the player is off court
304
+ #
305
+ # @api public
306
+ # @example
307
+ # stat.off_court? #=> true
308
+ # @return [Boolean] true if player is off court
309
+ def off_court?
310
+ court_status.eql?("Off")
311
+ end
312
+ end
313
+ end