Решение на Втора задача от Николай Константинов

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

Към профила на Николай Константинов

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 9 успешни тест(а)
  • 3 неуспешни тест(а)

Код

module AdditionalFunctions
def split_and_strip(list, split_char)
list.split(split_char).map(&:strip)
end
end
module SongFunctions
def find_songs_by_special_filter(songs, filter)
songs.select { |song| filter.(song) }
end
def find_songs_by_tags(songs, tags)
pos_tags = []
neg_tags = []
if not tags.instance_of?(Array)
tags.end_with?("!") ? neg_tags << tags.delete('!') : pos_tags << tags
else
tags.each do |tag|
tag.end_with?("!") ? neg_tags << tag.chop : pos_tags << tag
end
end
if pos_tags == []
songs.select { |song| !comm_elem(song.tags, neg_tags) }
else
songs.select do |song|
comm_elem(song.tags, pos_tags) and !comm_elem(song.tags, neg_tags)
end
end
end
def find_songs_by_name(songs, song_name)
songs.select { |song| song.name == song_name }
end
def find_songs_by_artist(songs, artist_name)
songs.select { |song| song.artist == artist_name }
end
end
class Song
include AdditionalFunctions
attr_accessor :name, :artist, :genre, :subgenre, :tags
def initialize(parsed_line)
@name, @artist, @genre = parsed_line[0..2]
@tags = []
if parsed_line[3] != nil
[split_and_strip(parsed_line[3], ',').each { |tag| tags << tag }]
end
parsed_line.each_with_index do |column, index|
if(column.include? "," and index == 2)
genres = split_and_strip(column, ",")
@genre = genres[0]
@subgenre = genres[1]
end
end
@tags << genre.downcase if not tags.include? genre
if not tags.include? subgenre and subgenre != nil
@tags << subgenre.downcase
end
end
end
class Collection
include AdditionalFunctions
include SongFunctions
attr_accessor :songs_as_string, :artist_tags, :songs
def initialize(songs_as_string, artist_tags)
@songs_as_string, @artist_tags = songs_as_string, artist_tags
create_songs
add_artist_tags
end
def create_songs()
songs = []
songs_as_string.lines do |line|
songs << Song.new(split_and_strip(line, "."))
end
@songs = songs
end
def add_artist_tags()
artist_tags.each do |key, value|
songs.select{ |song| song.artist == key}.each do |song|
song.tags << value if not comm_elem(song.tags, value)
song.tags = song.tags.flatten
end
end
end
def find(criteria)
found_songs = []
return songs if criteria == {}
criteria.each do |key, value|
if(key == :name)
found_songs = find_songs_by_name(songs, value)
elsif(key == :tags)
found_songs = find_songs_by_tags(songs, value)
elsif(key == :filter)
found_songs = find_songs_by_special_filter(songs, value)
elsif(key == :artist)
found_songs = find_songs_by_artist(songs, value)
end
end
found_songs
end
def comm_elem(first_list, second_list)
return first_list & second_list != []
end
end

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

.....F...FF.

Failures:

  1) Collection can find songs by multiple tags
     Failure/Error: songs(tags: %w[popular violin]).map(&:name).should eq ['Eine Kleine Nachtmusik']
       
       expected: ["Eine Kleine Nachtmusik"]
            got: ["My Favourite Things", "Greensleves", "My Funny Valentine", "Autumn Leaves", "Fur Elise", "Moonlight Sonata", "Toccata e Fuga", "Eine Kleine Nachtmusik"]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,9 @@
       -["Eine Kleine Nachtmusik"]
       +["My Favourite Things",
       + "Greensleves",
       + "My Funny Valentine",
       + "Autumn Leaves",
       + "Fur Elise",
       + "Moonlight Sonata",
       + "Toccata e Fuga",
       + "Eine Kleine Nachtmusik"]
     # /tmp/d20111115-13548-cmjn3n/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)>'

  2) Collection allows multiple criteria
     Failure/Error: songs(name: "'Round Midnight", tags: 'bebop').map(&:artist).should eq ['Thelonious Monk']
       
       expected: ["Thelonious Monk"]
            got: ["John Coltrane", "John Coltrane", "Miles Davis", "Thelonious Monk"]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -["Thelonious Monk"]
       +["John Coltrane", "John Coltrane", "Miles Davis", "Thelonious Monk"]
     # /tmp/d20111115-13548-cmjn3n/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)>'

  3) Collection allows all criteria
     Failure/Error: ).map(&:artist).should eq ['Thelonious Monk']
       
       expected: ["Thelonious Monk"]
            got: ["John Coltrane", "John Coltrane", "John Coltrane", "John Coltrane", "John Coltrane", "John Coltrane", "Miles Davis", "Miles Davis", "Miles Davis", "Miles Davis", "Bill Evans", "Bill Evans", "Thelonious Monk", "Thelonious Monk"]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,15 @@
       -["Thelonious Monk"]
       +["John Coltrane",
       + "John Coltrane",
       + "John Coltrane",
       + "John Coltrane",
       + "John Coltrane",
       + "John Coltrane",
       + "Miles Davis",
       + "Miles Davis",
       + "Miles Davis",
       + "Miles Davis",
       + "Bill Evans",
       + "Bill Evans",
       + "Thelonious Monk",
       + "Thelonious Monk"]
     # /tmp/d20111115-13548-cmjn3n/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.58218 seconds
12 examples, 3 failures

Failed examples:

rspec /tmp/d20111115-13548-cmjn3n/spec.rb:56 # Collection can find songs by multiple tags
rspec /tmp/d20111115-13548-cmjn3n/spec.rb:72 # Collection allows multiple criteria
rspec /tmp/d20111115-13548-cmjn3n/spec.rb:76 # Collection allows all criteria

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

Николай обнови решението на 31.10.2011 00:06 (преди над 12 години)

+module AdditionalFunctions
+ def split_and_strip(list, split_char)
+ list.split(split_char).map(&:strip)
+ end
+end
+
+module SongFunctions
+ def find_songs_by_special_filter(songs, filter)
+ songs.select { |song| filter.(song) }
+ end
+
+ def find_songs_by_tags(songs, tags)
+ pos_tags = []
+ neg_tags = []
+ if not tags.instance_of?(Array)
+ tags.end_with?("!") ? neg_tags << tags.delete('!') : pos_tags << tags
+ else
+ tags.each do |tag|
+ tag.end_with?("!") ? neg_tags << tag.chop : pos_tags << tag
+ end
+ end
+ if pos_tags == []
+ songs.select { |song| !comm_elem(song.tags, neg_tags) }
+ else
+ songs.select do |song|
+ comm_elem(song.tags, pos_tags) and !comm_elem(song.tags, neg_tags)
+ end
+ end
+ end
+
+ def find_songs_by_name(songs, song_name)
+ songs.select { |song| song.name == song_name }
+ end
+
+ def find_songs_by_artist(songs, artist_name)
+ songs.select { |song| song.artist == artist_name }
+ end
+
+end
+
+class Song
+ include AdditionalFunctions
+ attr_accessor :name, :artist, :genre, :subgenre, :tags
+
+ def initialize(parsed_line)
+ @name, @artist, @genre = parsed_line[0..2]
+ @tags = []
+ if parsed_line[3] != nil
+ [split_and_strip(parsed_line[3], ',').each { |tag| tags << tag }]
+ end
+ parsed_line.each_with_index do |column, index|
+ if(column.include? "," and index == 2)
+ genres = split_and_strip(column, ",")
+ @genre = genres[0]
+ @subgenre = genres[1]
+ end
+ end
+ @tags << genre.downcase if not tags.include? genre
+ if not tags.include? subgenre and subgenre != nil
+ @tags << subgenre.downcase
+ end
+ end
+end
+
+class Collection
+ include AdditionalFunctions
+ include SongFunctions
+ attr_accessor :songs_as_string, :artist_tags, :songs
+
+ def initialize(songs_as_string, artist_tags)
+ @songs_as_string, @artist_tags = songs_as_string, artist_tags
+ create_songs
+ add_artist_tags
+ end
+
+ def create_songs()
+ songs = []
+ songs_as_string.lines do |line|
+ songs << Song.new(split_and_strip(line, "."))
+ end
+ @songs = songs
+ end
+
+ def add_artist_tags()
+ artist_tags.each do |key, value|
+ songs.select{ |song| song.artist == key}.each do |song|
+ song.tags << value if not comm_elem(song.tags, value)
+ song.tags = song.tags.flatten
+ end
+ end
+ end
+
+ def find(criteria)
+ found_songs = []
+ return songs if criteria == {}
+ criteria.each do |key, value|
+ if(key == :name)
+ found_songs = find_songs_by_name(songs, value)
+ elsif(key == :tags)
+ found_songs = find_songs_by_tags(songs, value)
+ elsif(key == :filter)
+ found_songs = find_songs_by_special_filter(songs, value)
+ elsif(key == :artist)
+ found_songs = find_songs_by_artist(songs, value)
+ end
+ end
+ found_songs
+ end
+
+ def comm_elem(first_list, second_list)
+ return first_list & second_list != []
+ end
+
+end