-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
16,649 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
module Sportradar | ||
module Api | ||
module Baseball | ||
class Lineup < Data | ||
attr_reader :roster, :home, :away, :game | ||
def initialize(data, game: nil) | ||
@game = game | ||
end | ||
|
||
def update(data, source: nil) | ||
case source | ||
when :pbp | ||
when :summary | ||
@roster = (data.dig('home', 'roster') || []) + (data.dig('away', 'roster') || []) | ||
@home_team_lineup = data.dig('home', 'lineup') | ||
@away_team_lineup = data.dig('away', 'lineup') | ||
initialize_home | ||
initialize_away | ||
end | ||
end | ||
|
||
def update_from_lineup_event(data) | ||
if data.dig('lineup', 'team_id') == game.home_id | ||
update_home(find_player(data.dig('lineup', 'player_id')), data.dig('lineup', 'order')) | ||
elsif data.dig('lineup', 'team_id') == game.away_id | ||
update_away(find_player(data.dig('lineup', 'player_id')), data.dig('lineup', 'order')) | ||
end | ||
end | ||
|
||
def update_home(player, order) | ||
return if order == 0 | ||
idx = home.index do |h| | ||
h['order'] == order | ||
end | ||
home[idx] = { 'order' => order } | ||
home[idx].merge!(player) | ||
end | ||
|
||
def update_away(player, order) | ||
return if order == 0 | ||
idx = away.index do |h| | ||
h['order'] == order | ||
end | ||
away[idx] = { 'order' => order} | ||
away[idx].merge!(player) | ||
end | ||
|
||
def find_player(id) | ||
roster.detect do |player| | ||
player['id'] == id | ||
end | ||
end | ||
|
||
def initial_lineup | ||
[ | ||
{ 'order' => 1 }, | ||
{ 'order' => 2 }, | ||
{ 'order' => 3 }, | ||
{ 'order' => 4 }, | ||
{ 'order' => 5 }, | ||
{ 'order' => 6 }, | ||
{ 'order' => 7 }, | ||
{ 'order' => 8 }, | ||
{ 'order' => 9 }, | ||
] | ||
end | ||
|
||
def next_batters(team, number_of_upcoming_batters = 3) | ||
if team == 'home' | ||
last_at_bat = game.at_bats.select{|at_bat| at_bat.event.half_inning.half == 'B'}.last | ||
if last_at_bat # first inning | ||
last_position = @home_team_lineup.detect{|htl| htl['id'] == last_at_bat.hitter_id}&.dig('order') | ||
upcoming = home.rotate(last_position || 0) | ||
else | ||
upcoming = home | ||
end | ||
elsif team == 'away' | ||
last_at_bat = game.at_bats.select{|at_bat| at_bat.event.half_inning.half == 'T'}.last | ||
if last_at_bat # first inning | ||
last_position = @away_team_lineup.detect{|atl| atl['id'] == last_at_bat.hitter_id}&.dig('order') | ||
upcoming = away.rotate(last_position || 0) | ||
else | ||
upcoming = away | ||
end | ||
end | ||
upcoming[0..(number_of_upcoming_batters - 1)] | ||
end | ||
|
||
private | ||
|
||
def initialize_away | ||
@away = initial_lineup.dup | ||
@away_team_lineup.sort_by{|t| t['sequence']}.each do |al| | ||
# al.merge!(find_player(al['id'])) | ||
update_away(find_player(al['id']), al['order']) | ||
end.sort_by{|al| al['order']} | ||
end | ||
|
||
def initialize_home | ||
@home = initial_lineup.dup | ||
@home_team_lineup.sort_by{|t| t['sequence']}.each do |hl| | ||
# hl.merge!(find_player(hl['id'])) | ||
update_home(find_player(hl['id']), hl['order']) | ||
end.sort_by{|hl| hl['order']} | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
require 'test_helper' | ||
|
||
class Sportradar::Api::Baseball::Mlb::LineupTest < Minitest::Test | ||
describe "lineup" do | ||
describe "American" do | ||
let(:game) { Sportradar::Api::Baseball::Game.new('id' => "9d0fe41c-4e6b-4433-b376-2d09ed39d184") } | ||
let(:summary) { VCR.use_cassette('lineup game summary') { game.get_summary } } | ||
let(:pbp) { VCR.use_cassette('lineup game play by play') { game.get_pbp } } | ||
let(:lineup_update_hash) { {"lineup"=> | ||
{"description"=>"Robbie Ross Jr. (P) replaces Steven Wright (P).", | ||
"id"=>"912e171b-b906-4214-a420-c1ca512a71a6", | ||
"player_id"=>"7267e527-1ca0-4a94-b5a6-032e4769df48", | ||
"order"=>1, | ||
"position"=>1, | ||
"team_id"=>"93941372-eb4c-4c40-aced-fe3267174393", | ||
"last_name"=>"Ross Jr.", | ||
"first_name"=>"Robert", | ||
"preferred_name"=>"Robbie", | ||
"jersey_number"=>"28"}} } | ||
|
||
it "creates a lineup from a summary" do | ||
lineup = Sportradar::Api::Baseball::Lineup.new(nil, game: game) | ||
lineup.update(summary, source: :summary) | ||
assert_equal lineup.home.length, 9 | ||
assert_equal lineup.away.length, 9 | ||
assert_equal 'Dustin', lineup.home.first['preferred_name'] | ||
end | ||
|
||
it "creates a lineup from a pbp update" do | ||
lineup = Sportradar::Api::Baseball::Lineup.new(nil, game: game) | ||
lineup.update(summary, source: :summary) | ||
lineup.update_from_lineup_event(lineup_update_hash) | ||
assert_equal lineup.home.length, 9 | ||
assert_equal lineup.away.length, 9 | ||
assert_equal 'Robbie', lineup.home.first['preferred_name'] | ||
end | ||
|
||
it "sets the next upcoming batters" do | ||
lineup = Sportradar::Api::Baseball::Lineup.new(nil, game: game) | ||
lineup.update(summary, source: :summary) | ||
pbp | ||
next_batters = lineup.next_batters('home', 3) | ||
assert_equal next_batters.length, 3 | ||
assert_equal 'Marco', next_batters.first['preferred_name'] | ||
assert_equal 'Dustin', next_batters.second['preferred_name'] | ||
assert_equal 'Andrew', next_batters.third['preferred_name'] | ||
end | ||
end | ||
describe "National" do | ||
let(:game) { Sportradar::Api::Baseball::Game.new('id' => "1977122c-6e03-4668-ac96-d2ce670f3e55") } | ||
let(:summary) { VCR.use_cassette('lineup game national summary') { game.get_summary } } | ||
let(:pbp) { VCR.use_cassette('lineup game national play by play') { game.get_pbp } } | ||
let(:lineup_update_hash) { {"lineup"=> { | ||
"description"=>"Fernando Salas (P) replaces Tommy Milone (P), batting 9th.", | ||
"id"=>"6a962ba1-2bbb-4ec1-8f0c-1d05cb980e6a", | ||
"player_id"=>"e878885a-8e8f-4b50-a130-15a08748e99e", | ||
"order"=>9, | ||
"position"=>1, | ||
"team_id"=>"f246a5e5-afdb-479c-9aaa-c68beeda7af6", | ||
"last_name"=>"Salas", | ||
"first_name"=>"Noel", | ||
"preferred_name"=>"Fernando", | ||
"jersey_number"=>"59" } } } | ||
it "creates a lineup from a summary" do | ||
lineup = Sportradar::Api::Baseball::Lineup.new(nil, game: game) | ||
lineup.update(summary, source: :summary) | ||
pbp | ||
assert_equal lineup.home.length, 9 | ||
assert_equal lineup.away.length, 9 | ||
assert_equal lineup.home.first['preferred_name'], 'José' | ||
end | ||
|
||
it "creates a lineup from a pbp update" do | ||
lineup = Sportradar::Api::Baseball::Lineup.new(nil, game: game) | ||
lineup.update(summary, source: :summary) | ||
lineup.update_from_lineup_event(lineup_update_hash) | ||
assert_equal lineup.home.length, 9 | ||
assert_equal lineup.away.length, 9 | ||
assert_equal lineup.home[8]['preferred_name'], 'Fernando' | ||
end | ||
|
||
it "sets the next upcoming batters" do | ||
lineup = Sportradar::Api::Baseball::Lineup.new(nil, game: game) | ||
lineup.update(summary, source: :summary) | ||
pbp | ||
next_batters = lineup.next_batters('home', 3) | ||
assert_equal next_batters.length, 3 | ||
assert_equal 'Juan', next_batters.first['preferred_name'] | ||
assert_equal 'Rafael', next_batters.second['preferred_name'] | ||
assert_equal 'José', next_batters.third['preferred_name'] | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.