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,109 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "shot"
|
|
5
|
+
require_relative "league"
|
|
6
|
+
require_relative "response_parser"
|
|
7
|
+
require_relative "utils"
|
|
8
|
+
|
|
9
|
+
module NBA
|
|
10
|
+
# Provides methods to retrieve NBA shot chart lineup detail
|
|
11
|
+
module ShotChartLineupDetail
|
|
12
|
+
# Result set name for shot chart lineup detail
|
|
13
|
+
# @return [String] the result set name
|
|
14
|
+
DETAIL_SET = "ShotChartLineupDetail".freeze
|
|
15
|
+
|
|
16
|
+
# Result set name for league averages
|
|
17
|
+
# @return [String] the result set name
|
|
18
|
+
AVERAGE_SET = "ShotChartLineupLeagueAverage".freeze
|
|
19
|
+
|
|
20
|
+
# Retrieves shot chart lineup detail for a lineup group
|
|
21
|
+
#
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# shots = NBA::ShotChartLineupDetail.all(group_id: 12345, season: 2023)
|
|
25
|
+
# shots.each { |s| puts "#{s.player_name}: #{s.made? ? 'Made' : 'Missed'}" }
|
|
26
|
+
# @param group_id [Integer] the lineup group ID
|
|
27
|
+
# @param season [Integer] the season year (defaults to current season)
|
|
28
|
+
# @param season_type [String] the season type (Regular Season, Playoffs, etc.)
|
|
29
|
+
# @param context_measure [String] the context measure (FGA, FG3A, etc.)
|
|
30
|
+
# @param period [Integer] the period (0 for all periods)
|
|
31
|
+
# @param league [String, League] the league ID or League object
|
|
32
|
+
# @param client [Client] the API client to use
|
|
33
|
+
# @return [Collection] a collection of shots
|
|
34
|
+
def self.all(group_id:, season: Utils.current_season, season_type: "Regular Season",
|
|
35
|
+
context_measure: "FGA", period: 0, league: League::NBA, client: CLIENT)
|
|
36
|
+
league_id = Utils.extract_league_id(league)
|
|
37
|
+
opts = {group_id: group_id, season: season, season_type: season_type,
|
|
38
|
+
context_measure: context_measure, period: period, league_id: league_id}
|
|
39
|
+
ResponseParser.parse(client.get(build_path(opts)), result_set: DETAIL_SET) do |data|
|
|
40
|
+
build_shot(data)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Builds the API request path
|
|
45
|
+
# @api private
|
|
46
|
+
# @return [String] the request path
|
|
47
|
+
def self.build_path(opts)
|
|
48
|
+
"shotchartlineupdetail?ContextMeasure=#{opts[:context_measure]}" \
|
|
49
|
+
"&GROUP_ID=#{opts[:group_id]}&LeagueID=#{opts[:league_id]}&Period=#{opts[:period]}" \
|
|
50
|
+
"&Season=#{Utils.format_season(opts[:season])}&SeasonType=#{opts[:season_type]}"
|
|
51
|
+
end
|
|
52
|
+
private_class_method :build_path
|
|
53
|
+
|
|
54
|
+
# Builds a Shot object from raw data
|
|
55
|
+
# @api private
|
|
56
|
+
# @param data [Hash] the row data
|
|
57
|
+
# @return [Shot] the shot object
|
|
58
|
+
def self.build_shot(data)
|
|
59
|
+
Shot.new(**shot_attributes(data))
|
|
60
|
+
end
|
|
61
|
+
private_class_method :build_shot
|
|
62
|
+
|
|
63
|
+
# Extracts shot attributes from data
|
|
64
|
+
# @api private
|
|
65
|
+
# @param data [Hash] the row data
|
|
66
|
+
# @return [Hash] shot attributes
|
|
67
|
+
def self.shot_attributes(data)
|
|
68
|
+
game_attributes(data).merge(player_attributes(data)).merge(shot_info_attributes(data))
|
|
69
|
+
end
|
|
70
|
+
private_class_method :shot_attributes
|
|
71
|
+
|
|
72
|
+
# Extracts game-related attributes
|
|
73
|
+
# @api private
|
|
74
|
+
# @param data [Hash] the row data
|
|
75
|
+
# @return [Hash] game attributes
|
|
76
|
+
def self.game_attributes(data)
|
|
77
|
+
{game_id: data["GAME_ID"], game_event_id: data["GAME_EVENT_ID"],
|
|
78
|
+
period: data["PERIOD"], minutes_remaining: data["MINUTES_REMAINING"],
|
|
79
|
+
seconds_remaining: data["SECONDS_REMAINING"]}
|
|
80
|
+
end
|
|
81
|
+
private_class_method :game_attributes
|
|
82
|
+
|
|
83
|
+
# Extracts player-related attributes
|
|
84
|
+
# @api private
|
|
85
|
+
# @param data [Hash] the row data
|
|
86
|
+
# @return [Hash] player attributes
|
|
87
|
+
def self.player_attributes(data)
|
|
88
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
89
|
+
team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"]}
|
|
90
|
+
end
|
|
91
|
+
private_class_method :player_attributes
|
|
92
|
+
|
|
93
|
+
# Extracts shot info attributes
|
|
94
|
+
# @api private
|
|
95
|
+
# @param data [Hash] the row data
|
|
96
|
+
# @return [Hash] shot info attributes
|
|
97
|
+
def self.shot_info_attributes(data)
|
|
98
|
+
{action_type: data["ACTION_TYPE"], shot_type: data["SHOT_TYPE"],
|
|
99
|
+
shot_zone_basic: data["SHOT_ZONE_BASIC"],
|
|
100
|
+
shot_zone_area: data["SHOT_ZONE_AREA"],
|
|
101
|
+
shot_zone_range: data["SHOT_ZONE_RANGE"],
|
|
102
|
+
shot_distance: data["SHOT_DISTANCE"],
|
|
103
|
+
loc_x: data["LOC_X"], loc_y: data["LOC_Y"],
|
|
104
|
+
shot_attempted_flag: data["SHOT_ATTEMPTED_FLAG"],
|
|
105
|
+
shot_made_flag: data["SHOT_MADE_FLAG"]}
|
|
106
|
+
end
|
|
107
|
+
private_class_method :shot_info_attributes
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
require_relative "players"
|
|
4
|
+
|
|
5
|
+
module NBA
|
|
6
|
+
# Represents a player's shot statistics
|
|
7
|
+
#
|
|
8
|
+
# @api public
|
|
9
|
+
class ShotStat < Shale::Mapper
|
|
10
|
+
include Equalizer.new(:player_id, :shot_type, :g)
|
|
11
|
+
|
|
12
|
+
# @!attribute [rw] player_id
|
|
13
|
+
# Returns the player ID
|
|
14
|
+
# @api public
|
|
15
|
+
# @example
|
|
16
|
+
# stat.player_id #=> 201939
|
|
17
|
+
# @return [Integer, nil] the player's ID
|
|
18
|
+
attribute :player_id, Shale::Type::Integer
|
|
19
|
+
|
|
20
|
+
# @!attribute [rw] player_name_last_first
|
|
21
|
+
# Returns the player name in "Last, First" format
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# stat.player_name_last_first #=> "Curry, Stephen"
|
|
25
|
+
# @return [String, nil] the player's name (last, first)
|
|
26
|
+
attribute :player_name_last_first, Shale::Type::String
|
|
27
|
+
|
|
28
|
+
# @!attribute [rw] sort_order
|
|
29
|
+
# Returns the sort order
|
|
30
|
+
# @api public
|
|
31
|
+
# @example
|
|
32
|
+
# stat.sort_order #=> 1
|
|
33
|
+
# @return [Integer, nil] the sort order
|
|
34
|
+
attribute :sort_order, Shale::Type::Integer
|
|
35
|
+
|
|
36
|
+
# @!attribute [rw] gp
|
|
37
|
+
# Returns games played
|
|
38
|
+
# @api public
|
|
39
|
+
# @example
|
|
40
|
+
# stat.gp #=> 74
|
|
41
|
+
# @return [Integer, nil] games played
|
|
42
|
+
attribute :gp, Shale::Type::Integer
|
|
43
|
+
|
|
44
|
+
# @!attribute [rw] g
|
|
45
|
+
# Returns number of games
|
|
46
|
+
# @api public
|
|
47
|
+
# @example
|
|
48
|
+
# stat.g #=> 74
|
|
49
|
+
# @return [Integer, nil] games
|
|
50
|
+
attribute :g, Shale::Type::Integer
|
|
51
|
+
|
|
52
|
+
# @!attribute [rw] shot_type
|
|
53
|
+
# Returns the shot type or category
|
|
54
|
+
# @api public
|
|
55
|
+
# @example
|
|
56
|
+
# stat.shot_type #=> "Catch and Shoot"
|
|
57
|
+
# @return [String, nil] the shot type or category
|
|
58
|
+
attribute :shot_type, Shale::Type::String
|
|
59
|
+
|
|
60
|
+
# @!attribute [rw] fga_frequency
|
|
61
|
+
# Returns field goal attempt frequency
|
|
62
|
+
# @api public
|
|
63
|
+
# @example
|
|
64
|
+
# stat.fga_frequency #=> 0.35
|
|
65
|
+
# @return [Float, nil] field goal attempt frequency
|
|
66
|
+
attribute :fga_frequency, Shale::Type::Float
|
|
67
|
+
|
|
68
|
+
# @!attribute [rw] fgm
|
|
69
|
+
# Returns field goals made
|
|
70
|
+
# @api public
|
|
71
|
+
# @example
|
|
72
|
+
# stat.fgm #=> 7.2
|
|
73
|
+
# @return [Float, nil] field goals made
|
|
74
|
+
attribute :fgm, Shale::Type::Float
|
|
75
|
+
|
|
76
|
+
# @!attribute [rw] fga
|
|
77
|
+
# Returns field goals attempted
|
|
78
|
+
# @api public
|
|
79
|
+
# @example
|
|
80
|
+
# stat.fga #=> 15.3
|
|
81
|
+
# @return [Float, nil] field goals attempted
|
|
82
|
+
attribute :fga, Shale::Type::Float
|
|
83
|
+
|
|
84
|
+
# @!attribute [rw] fg_pct
|
|
85
|
+
# Returns field goal percentage
|
|
86
|
+
# @api public
|
|
87
|
+
# @example
|
|
88
|
+
# stat.fg_pct #=> 0.472
|
|
89
|
+
# @return [Float, nil] field goal percentage
|
|
90
|
+
attribute :fg_pct, Shale::Type::Float
|
|
91
|
+
|
|
92
|
+
# @!attribute [rw] efg_pct
|
|
93
|
+
# Returns effective field goal percentage
|
|
94
|
+
# @api public
|
|
95
|
+
# @example
|
|
96
|
+
# stat.efg_pct #=> 0.561
|
|
97
|
+
# @return [Float, nil] effective field goal percentage
|
|
98
|
+
attribute :efg_pct, Shale::Type::Float
|
|
99
|
+
|
|
100
|
+
# @!attribute [rw] fg2a_frequency
|
|
101
|
+
# Returns 2-point field goal attempt frequency
|
|
102
|
+
# @api public
|
|
103
|
+
# @example
|
|
104
|
+
# stat.fg2a_frequency #=> 0.45
|
|
105
|
+
# @return [Float, nil] 2-point field goal attempt frequency
|
|
106
|
+
attribute :fg2a_frequency, Shale::Type::Float
|
|
107
|
+
|
|
108
|
+
# @!attribute [rw] fg2m
|
|
109
|
+
# Returns 2-point field goals made
|
|
110
|
+
# @api public
|
|
111
|
+
# @example
|
|
112
|
+
# stat.fg2m #=> 4.1
|
|
113
|
+
# @return [Float, nil] 2-point field goals made
|
|
114
|
+
attribute :fg2m, Shale::Type::Float
|
|
115
|
+
|
|
116
|
+
# @!attribute [rw] fg2a
|
|
117
|
+
# Returns 2-point field goals attempted
|
|
118
|
+
# @api public
|
|
119
|
+
# @example
|
|
120
|
+
# stat.fg2a #=> 7.8
|
|
121
|
+
# @return [Float, nil] 2-point field goals attempted
|
|
122
|
+
attribute :fg2a, Shale::Type::Float
|
|
123
|
+
|
|
124
|
+
# @!attribute [rw] fg2_pct
|
|
125
|
+
# Returns 2-point field goal percentage
|
|
126
|
+
# @api public
|
|
127
|
+
# @example
|
|
128
|
+
# stat.fg2_pct #=> 0.526
|
|
129
|
+
# @return [Float, nil] 2-point field goal percentage
|
|
130
|
+
attribute :fg2_pct, Shale::Type::Float
|
|
131
|
+
|
|
132
|
+
# @!attribute [rw] fg3a_frequency
|
|
133
|
+
# Returns 3-point field goal attempt frequency
|
|
134
|
+
# @api public
|
|
135
|
+
# @example
|
|
136
|
+
# stat.fg3a_frequency #=> 0.55
|
|
137
|
+
# @return [Float, nil] 3-point field goal attempt frequency
|
|
138
|
+
attribute :fg3a_frequency, Shale::Type::Float
|
|
139
|
+
|
|
140
|
+
# @!attribute [rw] fg3m
|
|
141
|
+
# Returns 3-point field goals made
|
|
142
|
+
# @api public
|
|
143
|
+
# @example
|
|
144
|
+
# stat.fg3m #=> 4.8
|
|
145
|
+
# @return [Float, nil] 3-point field goals made
|
|
146
|
+
attribute :fg3m, Shale::Type::Float
|
|
147
|
+
|
|
148
|
+
# @!attribute [rw] fg3a
|
|
149
|
+
# Returns 3-point field goals attempted
|
|
150
|
+
# @api public
|
|
151
|
+
# @example
|
|
152
|
+
# stat.fg3a #=> 11.2
|
|
153
|
+
# @return [Float, nil] 3-point field goals attempted
|
|
154
|
+
attribute :fg3a, Shale::Type::Float
|
|
155
|
+
|
|
156
|
+
# @!attribute [rw] fg3_pct
|
|
157
|
+
# Returns 3-point field goal percentage
|
|
158
|
+
# @api public
|
|
159
|
+
# @example
|
|
160
|
+
# stat.fg3_pct #=> 0.428
|
|
161
|
+
# @return [Float, nil] 3-point field goal percentage
|
|
162
|
+
attribute :fg3_pct, Shale::Type::Float
|
|
163
|
+
|
|
164
|
+
# Returns the player who took the shots
|
|
165
|
+
#
|
|
166
|
+
# @api public
|
|
167
|
+
# @example
|
|
168
|
+
# stat.player #=> #<NBA::Player id=201939 ...>
|
|
169
|
+
# @return [Player, nil] the player object
|
|
170
|
+
def player
|
|
171
|
+
Players.find(player_id)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
data/lib/nba/standing.rb
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
require_relative "teams"
|
|
4
|
+
|
|
5
|
+
module NBA
|
|
6
|
+
# Represents a team's standing in the league
|
|
7
|
+
class Standing < Shale::Mapper
|
|
8
|
+
include Equalizer.new(:team_id)
|
|
9
|
+
|
|
10
|
+
# @!attribute [rw] team_id
|
|
11
|
+
# Returns the team ID
|
|
12
|
+
# @api public
|
|
13
|
+
# @example
|
|
14
|
+
# standing.team_id #=> 1610612744
|
|
15
|
+
# @return [Integer] the team ID
|
|
16
|
+
attribute :team_id, Shale::Type::Integer
|
|
17
|
+
|
|
18
|
+
# @!attribute [rw] team_name
|
|
19
|
+
# Returns the team name
|
|
20
|
+
# @api public
|
|
21
|
+
# @example
|
|
22
|
+
# standing.team_name #=> "Golden State Warriors"
|
|
23
|
+
# @return [String] the team name
|
|
24
|
+
attribute :team_name, Shale::Type::String
|
|
25
|
+
|
|
26
|
+
# @!attribute [rw] conference
|
|
27
|
+
# Returns the conference
|
|
28
|
+
# @api public
|
|
29
|
+
# @example
|
|
30
|
+
# standing.conference #=> "West"
|
|
31
|
+
# @return [String] the conference
|
|
32
|
+
attribute :conference, Shale::Type::String
|
|
33
|
+
|
|
34
|
+
# @!attribute [rw] division
|
|
35
|
+
# Returns the division
|
|
36
|
+
# @api public
|
|
37
|
+
# @example
|
|
38
|
+
# standing.division #=> "Pacific"
|
|
39
|
+
# @return [String] the division
|
|
40
|
+
attribute :division, Shale::Type::String
|
|
41
|
+
|
|
42
|
+
# @!attribute [rw] wins
|
|
43
|
+
# Returns the number of wins
|
|
44
|
+
# @api public
|
|
45
|
+
# @example
|
|
46
|
+
# standing.wins #=> 45
|
|
47
|
+
# @return [Integer] the number of wins
|
|
48
|
+
attribute :wins, Shale::Type::Integer
|
|
49
|
+
|
|
50
|
+
# @!attribute [rw] losses
|
|
51
|
+
# Returns the number of losses
|
|
52
|
+
# @api public
|
|
53
|
+
# @example
|
|
54
|
+
# standing.losses #=> 30
|
|
55
|
+
# @return [Integer] the number of losses
|
|
56
|
+
attribute :losses, Shale::Type::Integer
|
|
57
|
+
|
|
58
|
+
# @!attribute [rw] win_pct
|
|
59
|
+
# Returns the win percentage
|
|
60
|
+
# @api public
|
|
61
|
+
# @example
|
|
62
|
+
# standing.win_pct #=> 0.600
|
|
63
|
+
# @return [Float] the win percentage
|
|
64
|
+
attribute :win_pct, Shale::Type::Float
|
|
65
|
+
|
|
66
|
+
# @!attribute [rw] conference_rank
|
|
67
|
+
# Returns the conference rank
|
|
68
|
+
# @api public
|
|
69
|
+
# @example
|
|
70
|
+
# standing.conference_rank #=> 5
|
|
71
|
+
# @return [Integer] the conference rank
|
|
72
|
+
attribute :conference_rank, Shale::Type::Integer
|
|
73
|
+
|
|
74
|
+
# @!attribute [rw] home_record
|
|
75
|
+
# Returns the home record
|
|
76
|
+
# @api public
|
|
77
|
+
# @example
|
|
78
|
+
# standing.home_record #=> "25-12"
|
|
79
|
+
# @return [String] the home record
|
|
80
|
+
attribute :home_record, Shale::Type::String
|
|
81
|
+
|
|
82
|
+
# @!attribute [rw] road_record
|
|
83
|
+
# Returns the road record
|
|
84
|
+
# @api public
|
|
85
|
+
# @example
|
|
86
|
+
# standing.road_record #=> "20-18"
|
|
87
|
+
# @return [String] the road record
|
|
88
|
+
attribute :road_record, Shale::Type::String
|
|
89
|
+
|
|
90
|
+
# @!attribute [rw] streak
|
|
91
|
+
# Returns the current streak
|
|
92
|
+
# @api public
|
|
93
|
+
# @example
|
|
94
|
+
# standing.streak #=> "W3"
|
|
95
|
+
# @return [String] the current streak
|
|
96
|
+
attribute :streak, Shale::Type::String
|
|
97
|
+
|
|
98
|
+
# Returns the team object for this standing
|
|
99
|
+
#
|
|
100
|
+
# @api public
|
|
101
|
+
# @example
|
|
102
|
+
# standing.team #=> #<NBA::Team>
|
|
103
|
+
# standing.team.city #=> "San Francisco"
|
|
104
|
+
# @return [Team, nil] the team object
|
|
105
|
+
def team
|
|
106
|
+
Teams.find(team_id)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
json do
|
|
110
|
+
map "team_id", to: :team_id
|
|
111
|
+
map "teamId", to: :team_id
|
|
112
|
+
map "team_name", to: :team_name
|
|
113
|
+
map "teamName", to: :team_name
|
|
114
|
+
map "conference", to: :conference
|
|
115
|
+
map "division", to: :division
|
|
116
|
+
map "wins", to: :wins
|
|
117
|
+
map "losses", to: :losses
|
|
118
|
+
map "win_pct", to: :win_pct
|
|
119
|
+
map "winPct", to: :win_pct
|
|
120
|
+
map "conference_rank", to: :conference_rank
|
|
121
|
+
map "conferenceRank", to: :conference_rank
|
|
122
|
+
map "home_record", to: :home_record
|
|
123
|
+
map "homeRecord", to: :home_record
|
|
124
|
+
map "road_record", to: :road_record
|
|
125
|
+
map "roadRecord", to: :road_record
|
|
126
|
+
map "streak", to: :streak
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require_relative "client"
|
|
2
|
+
require_relative "response_parser"
|
|
3
|
+
require_relative "standing"
|
|
4
|
+
require_relative "utils"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve NBA standings
|
|
8
|
+
module Standings
|
|
9
|
+
# Retrieves all team standings
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# standings = NBA::Standings.all
|
|
14
|
+
# standings.each { |s| puts "#{s.conference_rank}. #{s.team_name}: #{s.wins}-#{s.losses}" }
|
|
15
|
+
# @param season [Integer] the season year (defaults to current season)
|
|
16
|
+
# @param client [Client] the API client to use
|
|
17
|
+
# @return [Collection] a collection of standings
|
|
18
|
+
def self.all(season: Utils.current_season, client: CLIENT)
|
|
19
|
+
path = "leaguestandings?LeagueID=00&Season=#{Utils.format_season(season)}&SeasonType=Regular+Season"
|
|
20
|
+
ResponseParser.parse(client.get(path)) { |data| build_standing(data) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Retrieves standings for a specific conference
|
|
24
|
+
#
|
|
25
|
+
# @api public
|
|
26
|
+
# @example
|
|
27
|
+
# western = NBA::Standings.conference("West")
|
|
28
|
+
# @param conference_name [String] the conference name (East or West)
|
|
29
|
+
# @param season [Integer] the season year
|
|
30
|
+
# @param client [Client] the API client to use
|
|
31
|
+
# @return [Collection] a collection of standings for the conference
|
|
32
|
+
def self.conference(conference_name, season: Utils.current_season, client: CLIENT)
|
|
33
|
+
Collection.new(all(season: season, client: client).select { |s| s.conference.eql?(conference_name) })
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Builds a standing from API data
|
|
37
|
+
# @api private
|
|
38
|
+
# @return [Standing]
|
|
39
|
+
def self.build_standing(data)
|
|
40
|
+
Standing.new(**team_info(data), **record_info(data))
|
|
41
|
+
end
|
|
42
|
+
private_class_method :build_standing
|
|
43
|
+
|
|
44
|
+
# Extracts team information from data
|
|
45
|
+
# @api private
|
|
46
|
+
# @return [Hash]
|
|
47
|
+
def self.team_info(data)
|
|
48
|
+
{team_id: data["TeamID"], team_name: data["TeamName"],
|
|
49
|
+
conference: data["Conference"], division: data["Division"]}
|
|
50
|
+
end
|
|
51
|
+
private_class_method :team_info
|
|
52
|
+
|
|
53
|
+
# Extracts record information from data
|
|
54
|
+
# @api private
|
|
55
|
+
# @return [Hash]
|
|
56
|
+
def self.record_info(data)
|
|
57
|
+
{wins: data["WINS"], losses: data["LOSSES"], win_pct: data["WinPCT"],
|
|
58
|
+
conference_rank: parse_conference_rank(data["ConferenceRecord"], data["PlayoffRank"]),
|
|
59
|
+
home_record: data["HOME"], road_record: data["ROAD"], streak: data["strCurrentStreak"]}
|
|
60
|
+
end
|
|
61
|
+
private_class_method :record_info
|
|
62
|
+
|
|
63
|
+
# Parses conference rank from conference record or playoff rank
|
|
64
|
+
#
|
|
65
|
+
# @api private
|
|
66
|
+
# @param conference_record [String, Integer, nil] the conference record
|
|
67
|
+
# @param playoff_rank [Integer, nil] the playoff rank
|
|
68
|
+
# @return [Integer, nil] the conference rank
|
|
69
|
+
def self.parse_conference_rank(conference_record, playoff_rank)
|
|
70
|
+
wins = conference_record.to_s.split("-").first
|
|
71
|
+
(wins.nil? || wins.empty?) ? playoff_rank : wins.to_i
|
|
72
|
+
end
|
|
73
|
+
private_class_method :parse_conference_rank
|
|
74
|
+
end
|
|
75
|
+
end
|
data/lib/nba/static.rb
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require_relative "data"
|
|
2
|
+
require_relative "team"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Provides static data lookup for teams without API calls
|
|
6
|
+
#
|
|
7
|
+
# @api public
|
|
8
|
+
module Static
|
|
9
|
+
# Retrieves all NBA teams
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# teams = NBA::Static.teams
|
|
14
|
+
# teams.size #=> 30
|
|
15
|
+
# @return [Array<Hash>] array of team hashes
|
|
16
|
+
def self.teams
|
|
17
|
+
Data::TEAMS
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Finds a team by ID
|
|
21
|
+
#
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# team = NBA::Static.find_team_by_id(1610612744)
|
|
25
|
+
# team[:full_name] #=> "Golden State Warriors"
|
|
26
|
+
# @param id [Integer] the team ID
|
|
27
|
+
# @return [Hash, nil] the team hash or nil if not found
|
|
28
|
+
def self.find_team_by_id(id)
|
|
29
|
+
Data::TEAMS.find { |t| t.fetch(:id).eql?(id) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Finds a team by abbreviation
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# team = NBA::Static.find_team_by_abbreviation("GSW")
|
|
37
|
+
# team[:full_name] #=> "Golden State Warriors"
|
|
38
|
+
# @param abbreviation [String] the team abbreviation
|
|
39
|
+
# @return [Hash, nil] the team hash or nil if not found
|
|
40
|
+
def self.find_team_by_abbreviation(abbreviation)
|
|
41
|
+
Data::TEAMS.find { |t| t.fetch(:abbreviation).casecmp?(abbreviation) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Finds teams by city name
|
|
45
|
+
#
|
|
46
|
+
# @api public
|
|
47
|
+
# @example
|
|
48
|
+
# teams = NBA::Static.find_teams_by_city("Los Angeles")
|
|
49
|
+
# teams.size #=> 2
|
|
50
|
+
# @param city [String] the city name (case-insensitive, partial match)
|
|
51
|
+
# @return [Array<Hash>] array of matching team hashes
|
|
52
|
+
def self.find_teams_by_city(city)
|
|
53
|
+
pattern = Regexp.new(Regexp.escape(city), Regexp::IGNORECASE)
|
|
54
|
+
Data::TEAMS.select { |t| pattern.match?(t.fetch(:city)) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Finds teams by state name
|
|
58
|
+
#
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# teams = NBA::Static.find_teams_by_state("California")
|
|
62
|
+
# teams.size #=> 4
|
|
63
|
+
# @param state [String] the state name (case-insensitive, partial match)
|
|
64
|
+
# @return [Array<Hash>] array of matching team hashes
|
|
65
|
+
def self.find_teams_by_state(state)
|
|
66
|
+
pattern = Regexp.new(Regexp.escape(state), Regexp::IGNORECASE)
|
|
67
|
+
Data::TEAMS.select { |t| pattern.match?(t.fetch(:state)) }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Finds teams by nickname
|
|
71
|
+
#
|
|
72
|
+
# @api public
|
|
73
|
+
# @example
|
|
74
|
+
# team = NBA::Static.find_team_by_nickname("Warriors")
|
|
75
|
+
# team[:city] #=> "San Francisco"
|
|
76
|
+
# @param nickname [String] the team nickname (case-insensitive)
|
|
77
|
+
# @return [Hash, nil] the team hash or nil if not found
|
|
78
|
+
def self.find_team_by_nickname(nickname)
|
|
79
|
+
Data::TEAMS.find { |t| t.fetch(:nickname).casecmp?(nickname) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Finds teams by full name
|
|
83
|
+
#
|
|
84
|
+
# @api public
|
|
85
|
+
# @example
|
|
86
|
+
# teams = NBA::Static.find_teams_by_full_name("Warriors")
|
|
87
|
+
# teams.first[:city] #=> "San Francisco"
|
|
88
|
+
# @param name [String] the name to search (case-insensitive, partial match)
|
|
89
|
+
# @return [Array<Hash>] array of matching team hashes
|
|
90
|
+
def self.find_teams_by_full_name(name)
|
|
91
|
+
pattern = Regexp.new(Regexp.escape(name), Regexp::IGNORECASE)
|
|
92
|
+
Data::TEAMS.select { |t| pattern.match?(t.fetch(:full_name)) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Finds teams by year founded
|
|
96
|
+
#
|
|
97
|
+
# @api public
|
|
98
|
+
# @example
|
|
99
|
+
# teams = NBA::Static.find_teams_by_year_founded(1946)
|
|
100
|
+
# teams.size #=> 4
|
|
101
|
+
# @param year [Integer] the founding year
|
|
102
|
+
# @return [Array<Hash>] array of matching team hashes
|
|
103
|
+
def self.find_teams_by_year_founded(year)
|
|
104
|
+
Data::TEAMS.select { |t| t.fetch(:year_founded).eql?(year) }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|