Решение на Втора задача от Мая Лекова

Обратно към всички решения

Към профила на Мая Лекова

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 8 успешни тест(а)
  • 4 неуспешни тест(а)

Код

class Song
def initialize(spec)
@name, @artist, genre_spec, tag_spec = spec.split('.').map { |s| s.strip }
@genre, @subgenre = genre_spec.split(',').map { |s| s.strip }
@tags = [@genre.downcase()]
@subgenre and @tags.push(@subgenre.downcase())
tag_spec and tag_spec.lines(',') { |tag| @tags.push(tag.strip.delete(',')) }
end
def add_tags(tags)
@tags.concat(tags).uniq!
end
attr_accessor :name
attr_accessor :artist
attr_accessor :genre
attr_accessor :subgenre
attr_accessor :tags
def matches?(criteria)
match_tags(criteria[:tags]) and
match_name(criteria[:name]) and
match_artist(criteria[:artist]) and
match_filter(criteria[:filter])
end
def match_tags(tags)
return true unless tags
negative = tags.select { |tag| tag.end_with?('!') }
positive = tags - negative
negative = negative.map{ |str| str.delete('!') }
return false unless (@tags & negative).empty?()
(@tags & positive).eql? positive
end
def match_name(name)
!name or @name.eql? name
end
def match_artist(artist)
!artist or @artist.eql? artist
end
def match_filter(pred)
!pred or pred.call(self)
end
end
class Collection
def initialize(songs_as_string, artist_tags)
@songs = []
songs_as_string.lines { |line| @songs.push(Song.new(line)) }
artist_tags.map { |entry| add_to_songs(entry) }
end
def add_to_songs(tags)
matching_songs = @songs.select { |song| song.artist.eql? tags[0] }
matching_songs.map { |song| song.add_tags(tags[1]) }
end
def find(criteria)
@songs.select { |s| s.matches?(criteria) }
end
end

Лог от изпълнението

....F...FFF.

Failures:

  1) Collection can find songs by tag
     Failure/Error: collection.find(options)
     NoMethodError:
       private method `select' called for "baroque":String
     # /tmp/d20111115-13548-1irymn0/solution.rb:30:in `match_tags'
     # /tmp/d20111115-13548-1irymn0/solution.rb:21:in `matches?'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `block in find'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `select'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `find'
     # /tmp/d20111115-13548-1irymn0/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-1irymn0/spec.rb:53:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) Collection adds the artist tags to the songs
     Failure/Error: collection.find(options)
     NoMethodError:
       private method `select' called for "polyphone":String
     # /tmp/d20111115-13548-1irymn0/solution.rb:30:in `match_tags'
     # /tmp/d20111115-13548-1irymn0/solution.rb:21:in `matches?'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `block in find'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `select'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `find'
     # /tmp/d20111115-13548-1irymn0/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-1irymn0/spec.rb:69:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) Collection allows multiple criteria
     Failure/Error: collection.find(options)
     NoMethodError:
       private method `select' called for "bebop":String
     # /tmp/d20111115-13548-1irymn0/solution.rb:30:in `match_tags'
     # /tmp/d20111115-13548-1irymn0/solution.rb:21:in `matches?'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `block in find'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `select'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `find'
     # /tmp/d20111115-13548-1irymn0/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-1irymn0/spec.rb:73:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) Collection allows all criteria
     Failure/Error: collection.find(options)
     NoMethodError:
       private method `select' called for "bebop":String
     # /tmp/d20111115-13548-1irymn0/solution.rb:30:in `match_tags'
     # /tmp/d20111115-13548-1irymn0/solution.rb:21:in `matches?'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `block in find'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `select'
     # /tmp/d20111115-13548-1irymn0/solution.rb:65:in `find'
     # /tmp/d20111115-13548-1irymn0/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-1irymn0/spec.rb:82:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.54324 seconds
12 examples, 4 failures

Failed examples:

rspec /tmp/d20111115-13548-1irymn0/spec.rb:52 # Collection can find songs by tag
rspec /tmp/d20111115-13548-1irymn0/spec.rb:68 # Collection adds the artist tags to the songs
rspec /tmp/d20111115-13548-1irymn0/spec.rb:72 # Collection allows multiple criteria
rspec /tmp/d20111115-13548-1irymn0/spec.rb:76 # Collection allows all criteria

История (1 версия и 0 коментара)

Мая обнови решението на 30.10.2011 23:44 (преди над 12 години)

+class Song
+ def initialize(spec)
+ @name, @artist, genre_spec, tag_spec = spec.split('.').map { |s| s.strip }
+ @genre, @subgenre = genre_spec.split(',').map { |s| s.strip }
+ @tags = [@genre.downcase()]
+ @subgenre and @tags.push(@subgenre.downcase())
+ tag_spec and tag_spec.lines(',') { |tag| @tags.push(tag.strip.delete(',')) }
+ end
+
+ def add_tags(tags)
+ @tags.concat(tags).uniq!
+ end
+
+ attr_accessor :name
+ attr_accessor :artist
+ attr_accessor :genre
+ attr_accessor :subgenre
+ attr_accessor :tags
+
+ def matches?(criteria)
+ match_tags(criteria[:tags]) and
+ match_name(criteria[:name]) and
+ match_artist(criteria[:artist]) and
+ match_filter(criteria[:filter])
+ end
+
+ def match_tags(tags)
+ return true unless tags
+
+ negative = tags.select { |tag| tag.end_with?('!') }
+ positive = tags - negative
+
+ negative = negative.map{ |str| str.delete('!') }
+ return false unless (@tags & negative).empty?()
+
+ (@tags & positive).eql? positive
+ end
+
+ def match_name(name)
+ !name or @name.eql? name
+ end
+
+ def match_artist(artist)
+ !artist or @artist.eql? artist
+ end
+
+ def match_filter(pred)
+ !pred or pred.call(self)
+ end
+end
+
+class Collection
+ def initialize(songs_as_string, artist_tags)
+ @songs = []
+ songs_as_string.lines { |line| @songs.push(Song.new(line)) }
+ artist_tags.map { |entry| add_to_songs(entry) }
+ end
+
+ def add_to_songs(tags)
+ matching_songs = @songs.select { |song| song.artist.eql? tags[0] }
+ matching_songs.map { |song| song.add_tags(tags[1]) }
+ end
+
+ def find(criteria)
+ @songs.select { |s| s.matches?(criteria) }
+ end
+end