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.
- checksums.yaml +5 -5
- data/AGENTS.md +362 -0
- data/CHANGELOG.md +169 -0
- data/CLAUDE.md +1 -0
- data/LICENSE +21 -0
- data/README.md +501 -101
- data/bin/console +10 -0
- data/bin/setup +6 -0
- data/exe/nba +8 -0
- data/lib/nba/all_time_leader.rb +77 -0
- data/lib/nba/all_time_leaders.rb +185 -0
- data/lib/nba/assist_leader.rb +92 -0
- data/lib/nba/assist_leaders.rb +64 -0
- data/lib/nba/assist_tracker.rb +108 -0
- data/lib/nba/assist_tracker_entry.rb +206 -0
- data/lib/nba/award.rb +128 -0
- data/lib/nba/box_score.rb +2 -0
- data/lib/nba/box_score_advanced.rb +114 -0
- data/lib/nba/box_score_advanced_player_stat.rb +297 -0
- data/lib/nba/box_score_advanced_team_stat.rb +237 -0
- data/lib/nba/box_score_advanced_v3.rb +124 -0
- data/lib/nba/box_score_defensive_player_stat.rb +281 -0
- data/lib/nba/box_score_defensive_team_stat.rb +85 -0
- data/lib/nba/box_score_defensive_v2.rb +190 -0
- data/lib/nba/box_score_four_factors.rb +91 -0
- data/lib/nba/box_score_four_factors_player_stat.rb +185 -0
- data/lib/nba/box_score_four_factors_team_stat.rb +141 -0
- data/lib/nba/box_score_four_factors_v3.rb +133 -0
- data/lib/nba/box_score_hustle.rb +226 -0
- data/lib/nba/box_score_hustle_player_stat.rb +233 -0
- data/lib/nba/box_score_hustle_team_stat.rb +189 -0
- data/lib/nba/box_score_matchup_stat.rb +417 -0
- data/lib/nba/box_score_matchups_v3.rb +184 -0
- data/lib/nba/box_score_misc.rb +100 -0
- data/lib/nba/box_score_misc_player_stat.rb +217 -0
- data/lib/nba/box_score_misc_team_stat.rb +173 -0
- data/lib/nba/box_score_misc_v3.rb +163 -0
- data/lib/nba/box_score_player_stat.rb +273 -0
- data/lib/nba/box_score_player_track.rb +223 -0
- data/lib/nba/box_score_player_track_stat.rb +273 -0
- data/lib/nba/box_score_player_track_team_stat.rb +229 -0
- data/lib/nba/box_score_scoring.rb +103 -0
- data/lib/nba/box_score_scoring_player_stat.rb +241 -0
- data/lib/nba/box_score_scoring_team_stat.rb +197 -0
- data/lib/nba/box_score_scoring_v3.rb +170 -0
- data/lib/nba/box_score_similarity_score.rb +119 -0
- data/lib/nba/box_score_similarity_stat.rb +76 -0
- data/lib/nba/box_score_starter_bench_stat.rb +257 -0
- data/lib/nba/box_score_summary.rb +285 -0
- data/lib/nba/box_score_summary_v2.rb +202 -0
- data/lib/nba/box_score_summary_v3.rb +120 -0
- data/lib/nba/box_score_summary_v3_data.rb +419 -0
- data/lib/nba/box_score_team_stat.rb +229 -0
- data/lib/nba/box_score_traditional.rb +101 -0
- data/lib/nba/box_score_traditional_v3.rb +195 -0
- data/lib/nba/box_score_usage.rb +102 -0
- data/lib/nba/box_score_usage_player_stat.rb +265 -0
- data/lib/nba/box_score_usage_team_stat.rb +221 -0
- data/lib/nba/box_score_usage_v3.rb +169 -0
- data/lib/nba/box_score_v3_helpers.rb +144 -0
- data/lib/nba/career_stats.rb +217 -0
- data/lib/nba/cli/display/player_display.rb +98 -0
- data/lib/nba/cli/display.rb +178 -0
- data/lib/nba/cli/formatters/game_formatters.rb +86 -0
- data/lib/nba/cli/formatters/leaders_formatters.rb +26 -0
- data/lib/nba/cli/formatters/player_formatters.rb +52 -0
- data/lib/nba/cli/formatters/standings_formatters.rb +26 -0
- data/lib/nba/cli/formatters/team_formatters.rb +67 -0
- data/lib/nba/cli/formatters/time_formatters.rb +82 -0
- data/lib/nba/cli/formatters.rb +56 -0
- data/lib/nba/cli/helpers.rb +135 -0
- data/lib/nba/cli.rb +171 -20
- data/lib/nba/client.rb +35 -0
- data/lib/nba/collection.rb +89 -0
- data/lib/nba/college_player_stat.rb +200 -0
- data/lib/nba/common_player_info.rb +142 -0
- data/lib/nba/common_playoff_series.rb +90 -0
- data/lib/nba/common_team_years.rb +113 -0
- data/lib/nba/conference.rb +39 -0
- data/lib/nba/connection.rb +84 -0
- data/lib/nba/cume_stats_player.rb +358 -0
- data/lib/nba/cume_stats_player_game.rb +217 -0
- data/lib/nba/cume_stats_player_games.rb +99 -0
- data/lib/nba/cume_stats_player_games_entry.rb +25 -0
- data/lib/nba/cume_stats_player_total.rb +481 -0
- data/lib/nba/cume_stats_team.rb +349 -0
- data/lib/nba/cume_stats_team_games.rb +145 -0
- data/lib/nba/cume_stats_team_games_entry.rb +25 -0
- data/lib/nba/cume_stats_team_player.rb +485 -0
- data/lib/nba/cume_stats_team_total.rb +267 -0
- data/lib/nba/data.rb +73 -0
- data/lib/nba/defense_hub.rb +109 -0
- data/lib/nba/defense_hub_stat.rb +57 -0
- data/lib/nba/defensive_shot_stat.rb +102 -0
- data/lib/nba/division.rb +49 -0
- data/lib/nba/draft_board.rb +126 -0
- data/lib/nba/draft_board_pick.rb +173 -0
- data/lib/nba/draft_combine_anthro_measurement.rb +163 -0
- data/lib/nba/draft_combine_drill_result.rb +115 -0
- data/lib/nba/draft_combine_drill_results.rb +112 -0
- data/lib/nba/draft_combine_non_stationary_shooting.rb +268 -0
- data/lib/nba/draft_combine_non_stationary_shooting_result.rb +355 -0
- data/lib/nba/draft_combine_player_anthro.rb +133 -0
- data/lib/nba/draft_combine_spot_shooting.rb +243 -0
- data/lib/nba/draft_combine_spot_shooting_result.rb +419 -0
- data/lib/nba/draft_combine_stat.rb +211 -0
- data/lib/nba/draft_combine_stats.rb +160 -0
- data/lib/nba/draft_history.rb +142 -0
- data/lib/nba/draft_pick.rb +154 -0
- data/lib/nba/dunk_score_leader.rb +93 -0
- data/lib/nba/dunk_score_leaders.rb +77 -0
- data/lib/nba/estimated_metrics_stat.rb +152 -0
- data/lib/nba/fantasy_profile_stat.rb +142 -0
- data/lib/nba/fantasy_widget.rb +72 -0
- data/lib/nba/fantasy_widget_player.rb +98 -0
- data/lib/nba/found_game.rb +260 -0
- data/lib/nba/franchise.rb +136 -0
- data/lib/nba/franchise_history.rb +142 -0
- data/lib/nba/franchise_leader.rb +147 -0
- data/lib/nba/franchise_leaders.rb +162 -0
- data/lib/nba/franchise_player.rb +224 -0
- data/lib/nba/franchise_players.rb +147 -0
- data/lib/nba/game.rb +80 -64
- data/lib/nba/game_log.rb +349 -0
- data/lib/nba/game_rotation.rb +152 -0
- data/lib/nba/game_streak.rb +102 -0
- data/lib/nba/games.rb +46 -0
- data/lib/nba/home_page_leader.rb +99 -0
- data/lib/nba/home_page_leaders.rb +75 -0
- data/lib/nba/home_page_stat.rb +57 -0
- data/lib/nba/home_page_v2.rb +110 -0
- data/lib/nba/hustle_stats_box_score.rb +182 -0
- data/lib/nba/infographic_fan_duel_player.rb +139 -0
- data/lib/nba/infographic_fan_duel_player_stat.rb +311 -0
- data/lib/nba/ist_standing.rb +167 -0
- data/lib/nba/ist_standings.rb +81 -0
- data/lib/nba/leader.rb +103 -0
- data/lib/nba/leaders.rb +110 -0
- data/lib/nba/leaders_tile.rb +57 -0
- data/lib/nba/leaders_tiles.rb +90 -0
- data/lib/nba/league.rb +37 -0
- data/lib/nba/league_dash_lineup_stat.rb +270 -0
- data/lib/nba/league_dash_lineups.rb +177 -0
- data/lib/nba/league_dash_opp_pt_shot.rb +150 -0
- data/lib/nba/league_dash_player_bio_stat.rb +217 -0
- data/lib/nba/league_dash_player_bio_stats.rb +164 -0
- data/lib/nba/league_dash_player_clutch.rb +212 -0
- data/lib/nba/league_dash_player_clutch_stat.rb +271 -0
- data/lib/nba/league_dash_player_pt_shot.rb +152 -0
- data/lib/nba/league_dash_player_pt_shot_stat.rb +193 -0
- data/lib/nba/league_dash_player_shot_location_stat.rb +265 -0
- data/lib/nba/league_dash_player_shot_locations.rb +210 -0
- data/lib/nba/league_dash_player_stat.rb +306 -0
- data/lib/nba/league_dash_player_stats.rb +176 -0
- data/lib/nba/league_dash_pt_defend.rb +160 -0
- data/lib/nba/league_dash_pt_defend_stat.rb +145 -0
- data/lib/nba/league_dash_pt_stats.rb +152 -0
- data/lib/nba/league_dash_pt_stats_stat.rb +169 -0
- data/lib/nba/league_dash_pt_team_defend.rb +158 -0
- data/lib/nba/league_dash_pt_team_defend_stat.rb +110 -0
- data/lib/nba/league_dash_team_clutch.rb +211 -0
- data/lib/nba/league_dash_team_clutch_stat.rb +237 -0
- data/lib/nba/league_dash_team_pt_shot.rb +150 -0
- data/lib/nba/league_dash_team_pt_shot_stat.rb +166 -0
- data/lib/nba/league_dash_team_shot_location_stat.rb +230 -0
- data/lib/nba/league_dash_team_shot_locations.rb +208 -0
- data/lib/nba/league_dash_team_stat.rb +275 -0
- data/lib/nba/league_dash_team_stats.rb +172 -0
- data/lib/nba/league_game_finder.rb +170 -0
- data/lib/nba/league_game_log.rb +224 -0
- data/lib/nba/league_hustle_stats_player.rb +161 -0
- data/lib/nba/league_hustle_stats_player_stat.rb +253 -0
- data/lib/nba/league_hustle_stats_team.rb +157 -0
- data/lib/nba/league_hustle_stats_team_stat.rb +179 -0
- data/lib/nba/league_lineup_viz.rb +184 -0
- data/lib/nba/league_lineup_viz_stat.rb +214 -0
- data/lib/nba/league_player_on_details.rb +175 -0
- data/lib/nba/league_player_on_details_stat.rb +313 -0
- data/lib/nba/league_season_matchup_stat.rb +241 -0
- data/lib/nba/league_season_matchups.rb +181 -0
- data/lib/nba/league_standing.rb +284 -0
- data/lib/nba/league_standings.rb +159 -0
- data/lib/nba/league_wide_shot_stat.rb +62 -0
- data/lib/nba/live_action.rb +240 -0
- data/lib/nba/live_box_score.rb +143 -0
- data/lib/nba/live_connection.rb +84 -0
- data/lib/nba/live_game.rb +230 -0
- data/lib/nba/live_play_by_play.rb +120 -0
- data/lib/nba/live_player_stat.rb +276 -0
- data/lib/nba/live_scoreboard.rb +102 -0
- data/lib/nba/matchup_rollup.rb +98 -0
- data/lib/nba/matchups_rollup.rb +81 -0
- data/lib/nba/pass_stat.rb +209 -0
- data/lib/nba/play.rb +258 -0
- data/lib/nba/play_by_play.rb +85 -0
- data/lib/nba/play_by_play_v3.rb +91 -0
- data/lib/nba/play_type_stat.rb +206 -0
- data/lib/nba/player.rb +242 -24
- data/lib/nba/player_awards.rb +110 -0
- data/lib/nba/player_career_by_college.rb +86 -0
- data/lib/nba/player_career_by_college_rollup.rb +143 -0
- data/lib/nba/player_career_stats.rb +77 -0
- data/lib/nba/player_compare.rb +156 -0
- data/lib/nba/player_comparison_stat.rb +242 -0
- data/lib/nba/player_dash_pt_pass.rb +164 -0
- data/lib/nba/player_dash_pt_reb.rb +235 -0
- data/lib/nba/player_dash_pt_shot_defend.rb +119 -0
- data/lib/nba/player_dash_pt_shots.rb +279 -0
- data/lib/nba/player_dashboard.rb +259 -0
- data/lib/nba/player_dashboard_stat.rb +248 -0
- data/lib/nba/player_estimated_metrics.rb +84 -0
- data/lib/nba/player_fantasy_profile_bar_graph.rb +147 -0
- data/lib/nba/player_game_log.rb +72 -0
- data/lib/nba/player_game_logs.rb +117 -0
- data/lib/nba/player_game_streak_finder.rb +108 -0
- data/lib/nba/player_index.rb +135 -0
- data/lib/nba/player_index_entry.rb +266 -0
- data/lib/nba/player_info.rb +225 -0
- data/lib/nba/player_next_n_games.rb +64 -0
- data/lib/nba/player_profile_v2.rb +169 -0
- data/lib/nba/player_vs_player.rb +153 -0
- data/lib/nba/players.rb +107 -0
- data/lib/nba/playoff_matchup.rb +84 -0
- data/lib/nba/playoff_picture.rb +98 -0
- data/lib/nba/playoff_series.rb +76 -0
- data/lib/nba/position.rb +48 -0
- data/lib/nba/rebound_stat.rb +189 -0
- data/lib/nba/response_parser.rb +116 -0
- data/lib/nba/roster.rb +74 -0
- data/lib/nba/rotation_entry.rb +154 -0
- data/lib/nba/schedule.rb +183 -0
- data/lib/nba/schedule_international.rb +182 -0
- data/lib/nba/scheduled_game.rb +240 -0
- data/lib/nba/scoreboard.rb +183 -0
- data/lib/nba/scoreboard_v3.rb +104 -0
- data/lib/nba/shot.rb +208 -0
- data/lib/nba/shot_chart.rb +75 -0
- data/lib/nba/shot_chart_league_wide.rb +102 -0
- data/lib/nba/shot_chart_lineup_detail.rb +109 -0
- data/lib/nba/shot_stat.rb +174 -0
- data/lib/nba/standing.rb +129 -0
- data/lib/nba/standings.rb +75 -0
- data/lib/nba/static.rb +107 -0
- data/lib/nba/synergy_play_types.rb +211 -0
- data/lib/nba/team.rb +203 -127
- data/lib/nba/team_and_players_vs_players.rb +227 -0
- data/lib/nba/team_and_players_vs_players_stat.rb +155 -0
- data/lib/nba/team_dash_pt_pass.rb +157 -0
- data/lib/nba/team_dash_pt_reb.rb +216 -0
- data/lib/nba/team_dash_pt_shots.rb +244 -0
- data/lib/nba/team_dashboard.rb +275 -0
- data/lib/nba/team_dashboard_stat.rb +248 -0
- data/lib/nba/team_detail.rb +117 -0
- data/lib/nba/team_details.rb +173 -0
- data/lib/nba/team_estimated_metrics.rb +91 -0
- data/lib/nba/team_estimated_metrics_stat.rb +146 -0
- data/lib/nba/team_game_log.rb +143 -0
- data/lib/nba/team_game_log_entry.rb +246 -0
- data/lib/nba/team_game_log_stat.rb +275 -0
- data/lib/nba/team_game_logs.rb +163 -0
- data/lib/nba/team_game_streak.rb +111 -0
- data/lib/nba/team_game_streak_finder.rb +109 -0
- data/lib/nba/team_historical_leader.rb +207 -0
- data/lib/nba/team_historical_leaders.rb +98 -0
- data/lib/nba/team_historical_record.rb +139 -0
- data/lib/nba/team_info.rb +150 -0
- data/lib/nba/team_info_common.rb +177 -0
- data/lib/nba/team_on_off_overall_stat.rb +477 -0
- data/lib/nba/team_on_off_player_stat.rb +523 -0
- data/lib/nba/team_on_off_player_summary.rb +135 -0
- data/lib/nba/team_pass_stat.rb +183 -0
- data/lib/nba/team_player_dashboard.rb +212 -0
- data/lib/nba/team_player_on_off_details.rb +218 -0
- data/lib/nba/team_player_on_off_summary.rb +214 -0
- data/lib/nba/team_player_stat.rb +275 -0
- data/lib/nba/team_rebound_stat.rb +189 -0
- data/lib/nba/team_season_rank.rb +110 -0
- data/lib/nba/team_shot_stat.rb +173 -0
- data/lib/nba/team_vs_player.rb +151 -0
- data/lib/nba/team_vs_player_stat.rb +157 -0
- data/lib/nba/team_year.rb +55 -0
- data/lib/nba/team_year_by_year_stats.rb +152 -0
- data/lib/nba/team_year_stat.rb +282 -0
- data/lib/nba/teams.rb +33 -0
- data/lib/nba/upcoming_game.rb +115 -0
- data/lib/nba/utils.rb +94 -0
- data/lib/nba/version.rb +5 -2
- data/lib/nba/video_detail.rb +103 -0
- data/lib/nba/video_details.rb +118 -0
- data/lib/nba/video_details_asset.rb +115 -0
- data/lib/nba/video_details_asset_entry.rb +91 -0
- data/lib/nba/video_event.rb +83 -0
- data/lib/nba/video_event_asset.rb +91 -0
- data/lib/nba/video_events.rb +106 -0
- data/lib/nba/video_events_asset.rb +107 -0
- data/lib/nba/video_status.rb +129 -0
- data/lib/nba/video_status_entry.rb +161 -0
- data/lib/nba/vs_player_stat.rb +156 -0
- data/lib/nba/win_probability.rb +117 -0
- data/lib/nba/win_probability_point.rb +140 -0
- data/lib/nba.rb +249 -5
- data/sig/equalizer.rbs +3 -0
- data/sig/nba.rbs +7297 -0
- data/sig/shale.rbs +24 -0
- data/sig/thor.rbs +19 -0
- metadata +324 -95
- data/.gitignore +0 -18
- data/.travis.yml +0 -22
- data/Gemfile +0 -23
- data/LICENSE.md +0 -22
- data/Rakefile +0 -18
- data/bin/nba +0 -7
- data/cache/teams.json +0 -16529
- data/lib/faraday_middleware/scrape_game.rb +0 -41
- data/lib/nba/request.rb +0 -37
- data/nba.gemspec +0 -28
- data/spec/fixtures/games.html +0 -785
- data/spec/fixtures/teams.json +0 -16529
- data/spec/game_spec.rb +0 -40
- data/spec/spec_helper.rb +0 -25
- 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
|