Решение на Втора задача от Ростислав Георгиев

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

Към профила на Ростислав Георгиев

Резултати

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

Код

class Song
attr_reader :name
attr_reader :artist
attr_reader :genre
attr_reader :subgenre
attr_reader :tags
def initialize(more_tags, *song_info)
@name = song_info[0]
@artist = song_info[1]
genre_pair = @song_info[2].split(',')
@genre = genre_pair[0].strip
@subgenre = genre_pair[1].strip if genre_pair[1]
@tags = []
unless song_info[3] == nil
song_info[3].split(',').each { |tag| @tags.push(tag.strip) }
end
@tags |= more_tags[artist] if more_tags.include? artist
end
def check_tag?(tag)
if tag.end_with? '!' then
return false if @tags.include? tag.chop
else
return false unless @tags.include? tag
end
return true
end
def check_tags?(tag_list)
tag_list.each do |tag|
return false unless check_tag? tag
end
return true
end
end
class Collection
def initialize(songdb, artist_tags)
@song_array = []
songdb.each_line do |song|
unless song.empty?
song_data = song.split '.'
song_data = song_data.each { |entry| entry.strip }
@song_array.push(Song.new(artist_tags, *song_data))
end
end
end
def find(crit = {})
songs = Array.new(@song_array)
songs = filter_by_name(songs, crit[:name]) if crit[:name]
songs = filter_by_artist(songs, crit[:artist]) if crit[:artist]
songs = filter_by_lambda(songs, crit[:filter]) if crit[:filter]
songs = filter_by_tags(songs, crit[:tags]) if crit[:tags]
songs
end
def filter_by_name(songs, name)
songs.select { |song| song.name == name }
end
def filter_by_artist(songs, artist)
songs.select { |song| song.artist == artist }
end
def filter_by_lambda(songs, filter)
songs.select(&filter)
end
def filter_by_tags(songs, tags)
if tags.class == String then
songs.select { |song| song.check_tag? tags }
else
songs.select { |song| song.check_tags? tags }
end
end
end

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

FFFFFFFFFFFF

Failures:

  1) Collection returns all entries if called without parameters
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:37: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 can look up songs by artist
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/spec.rb:41: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 can look up songs by name
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/spec.rb:45: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 uses the genre and subgenre as tags
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/spec.rb:100:in `song'
     # /tmp/d20111115-13548-aptmhs/spec.rb:49: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)>'

  5) Collection can find songs by tag
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/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)>'

  6) Collection can find songs by multiple tags
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/spec.rb:57: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)>'

  7) Collection can find songs that don't have a tag
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/spec.rb:61: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)>'

  8) Collection can filter songs by a lambda
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/spec.rb:65: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)>'

  9) Collection adds the artist tags to the songs
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/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)>'

  10) Collection allows multiple criteria
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/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)>'

  11) Collection allows all criteria
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:96:in `songs'
     # /tmp/d20111115-13548-aptmhs/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)>'

  12) Collection constructs an object for each song
     Failure/Error: let(:collection) { Collection.new input, additional_tags }
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111115-13548-aptmhs/solution.rb:13:in `initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `new'
     # /tmp/d20111115-13548-aptmhs/solution.rb:51:in `block in initialize'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `each_line'
     # /tmp/d20111115-13548-aptmhs/solution.rb:47:in `initialize'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `new'
     # /tmp/d20111115-13548-aptmhs/spec.rb:34:in `block (2 levels) in <top (required)>'
     # /tmp/d20111115-13548-aptmhs/spec.rb:86: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.5356 seconds
12 examples, 12 failures

Failed examples:

rspec /tmp/d20111115-13548-aptmhs/spec.rb:36 # Collection returns all entries if called without parameters
rspec /tmp/d20111115-13548-aptmhs/spec.rb:40 # Collection can look up songs by artist
rspec /tmp/d20111115-13548-aptmhs/spec.rb:44 # Collection can look up songs by name
rspec /tmp/d20111115-13548-aptmhs/spec.rb:48 # Collection uses the genre and subgenre as tags
rspec /tmp/d20111115-13548-aptmhs/spec.rb:52 # Collection can find songs by tag
rspec /tmp/d20111115-13548-aptmhs/spec.rb:56 # Collection can find songs by multiple tags
rspec /tmp/d20111115-13548-aptmhs/spec.rb:60 # Collection can find songs that don't have a tag
rspec /tmp/d20111115-13548-aptmhs/spec.rb:64 # Collection can filter songs by a lambda
rspec /tmp/d20111115-13548-aptmhs/spec.rb:68 # Collection adds the artist tags to the songs
rspec /tmp/d20111115-13548-aptmhs/spec.rb:72 # Collection allows multiple criteria
rspec /tmp/d20111115-13548-aptmhs/spec.rb:76 # Collection allows all criteria
rspec /tmp/d20111115-13548-aptmhs/spec.rb:85 # Collection constructs an object for each song

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

Ростислав обнови решението на 30.10.2011 01:26 (преди над 12 години)

+class Song
+
+ attr_reader :name
+ attr_reader :artist
+ attr_reader :genre
+ attr_reader :subgenre
+ attr_reader :tags
+
+ def initialize(more_tags, *song_info)
+ @name = song_info[0]
+ @artist = song_info[1]
+
+ genre_pair = @song_info[2].split(',')
+ @genre = genre_pair[0].strip
+ @subgenre = genre_pair[1].strip if genre_pair[1]
+
+ @tags = []
+ unless song_info[3] == nil
+ song_info[3].split(',').each { |tag| @tags.push(tag.strip) }
+ end
+ @tags |= more_tags[artist] if more_tags.include? artist
+ end
+
+ def check_tag?(tag)
+ if tag.end_with? '!' then
+ return false if @tags.include? tag.chop
+ else
+ return false unless @tags.include? tag
+ end
+
+ return true
+ end
+
+ def check_tags?(tag_list)
+ tag_list.each do |tag|
+ return false unless check_tag? tag
+ end
+
+ return true
+ end
+
+end
+
+class Collection
+ def initialize(songdb, artist_tags)
+ @song_array = []
+ songdb.each_line do |song|
+ unless song.empty?
+ song_data = song.split '.'
+ song_data = song_data.each { |entry| entry.strip }
+ @song_array.push(Song.new(artist_tags, *song_data))
+ end
+ end
+ end
+
+ def find(crit = {})
+ songs = Array.new(@song_array)
+ songs = filter_by_name(songs, crit[:name]) if crit[:name]
+ songs = filter_by_artist(songs, crit[:artist]) if crit[:artist]
+ songs = filter_by_lambda(songs, crit[:filter]) if crit[:filter]
+ songs = filter_by_tags(songs, crit[:tags]) if crit[:tags]
+ songs
+ end
+
+ def filter_by_name(songs, name)
+ songs.select { |song| song.name == name }
+ end
+
+ def filter_by_artist(songs, artist)
+ songs.select { |song| song.artist == artist }
+ end
+
+ def filter_by_lambda(songs, filter)
+ songs.select(&filter)
+ end
+
+ def filter_by_tags(songs, tags)
+ if tags.class == String then
+ songs.select { |song| song.check_tag? tags }
+ else
+ songs.select { |song| song.check_tags? tags }
+ end
+ end
+
+end

Имаш само четири малки проблема.

  • then-а е напълно излишен
  • tags.class == Array се прави така: tags.kind_of? Array
  • В Song#initialize правиш push в масив, вместо далеч по-приятното @tags = song_info[3].split(',').map(&:strip)
  • В Song#check_tags? не ползваш Enumerable#all?

Иначе, браво, много добро решение. Печелиш две бонус точки за него.