Решение на Втора задача от Нели Хатева

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

Към профила на Нели Хатева

Резултати

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

Код

class Collection
include Enumerable
attr_reader :songs_array
def self.parse(text)
lines_as_array = (text.lines.map { |song| song.split("\n") }).flatten
collection = Collection.new(lines_as_array)
end
def initialize(lines_as_array)
@songs_array = []
lines_as_array.each_slice(3) do |song|
@songs_array << Song.new(song[0], song[1], song[2])
end
end
def each
@songs_array.each { |song| yield song }
end
def names
names = []
each { |song| names << song.name }
names.uniq
end
def artists
artists = []
each { |song| artists << song.artist }
artists.uniq
end
def albums
albums = []
each { |song| albums << song.album }
albums.uniq
end
def filter(criteria)
filtered_songs = (@songs_array.select { |song| criteria.match?(song) }).uniq
sub_collection = SubCollection.new(filtered_songs)
end
end
class SubCollection < Collection
def initialize(songs_array)
@songs_array = songs_array
end
def adjoin(other)
unite_collection = SubCollection.new((@songs_array+other.songs_array).uniq)
end
end
class Song
include Comparable
attr_reader :name, :artist, :album
def initialize(name,artist,album)
@name, @artist, @album = name, artist, album
end
def hash
(name+artist+album).hash
end
def eql?(other)
self == other
end
def ==(other)
name == other.name and artist == other.artist and album == other.album
end
end
class Criteria
attr_reader :type, :value
def self.name(song_name)
criteria = Criteria.new(:name,song_name)
end
def self.artist(artist_name)
criteria = Criteria.new(:artist,artist_name)
end
def self.album(album_name)
criteria = Criteria.new(:album,album_name)
end
def initialize(type, value)
@type, @value = type, value
end
def match?(song)
if @type == :name then song.name == @value
elsif @type == :artist then song.artist == @value
else song.album == @value
end
end
def &(other)
criteria = ConjunctionCriteria.new(@type, other.type, @value, other.value)
end
def |(other)
criteria = DisjunctionCriteria.new(@type, other.type, @value, other.value)
end
def !
criteria = NegationCriteria.new(@type, @value)
end
end
class ConjunctionCriteria
def initialize(type1, type2, value1, value2)
@type1, @type2, @value1, @value2 = type1, type2, value1, value2
end
def match?(song)
Criteria.new(@type1, @value1).match?(song) and
Criteria.new(@type2, @value2).match?(song)
end
end
class DisjunctionCriteria
def initialize(type1, type2, value1, value2)
@type1, @type2, @value1, @value2 = type1, type2, value1, value2
end
def match?(song)
Criteria.new(@type1, @value1).match?(song) or
Criteria.new(@type2, @value2).match?(song)
end
end
class NegationCriteria
def initialize(type, value)
@type, @value = type, value
end
def match?(song)
not Criteria.new(@type, @value).match?(song)
end
def match?(song)
not Criteria.new(@type, @value).match?(song)
end
end

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

.........F.

Failures:

  1) Collection supports negation of filters
     Failure/Error: filtered = collection.filter Criteria.artist('Sting') & !Criteria.name('Fields of Gold')
     NoMethodError:
       undefined method `type' for #<NegationCriteria:0x99113c0>
     # /tmp/d20130203-23049-1m3hbbj/solution.rb:105:in `&'
     # /tmp/d20130203-23049-1m3hbbj/spec.rb:78: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.01093 seconds
11 examples, 1 failure

Failed examples:

rspec /tmp/d20130203-23049-1m3hbbj/spec.rb:77 # Collection supports negation of filters

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

Нели обнови решението на 25.10.2012 21:54 (преди около 12 години)

+class Collection
+ include Enumerable
+
+ def self.parse(text)
+ collection = Collection.new(text)
+ end
+
+ def initialize(text)
+ @text = text
+ end
+
+ def each
+ array_with_lines = []
+ @text.each_line { |line| array_with_lines << line.chop }
+ array_with_lines.each_slice(4) { |song| yield song[0..2] }
+ end
+
+ def names
+ names = []
+ each { |song| names << song[0] }
+ names.uniq!
+ end
+
+ def artists
+ artists = []
+ each { |song| artists << song[1] }
+ artists.uniq!
+ end
+
+ def albums
+ albums = []
+ each { |song| albums << song[2] }
+ albums.uniq!
+ end
+end

Нели обнови решението на 25.10.2012 23:55 (преди около 12 години)

class Collection
include Enumerable
def self.parse(text)
collection = Collection.new(text)
end
def initialize(text)
@text = text
end
def each
array_with_lines = []
@text.each_line { |line| array_with_lines << line.chop }
- array_with_lines.each_slice(4) { |song| yield song[0..2] }
+ array_with_lines.each_slice(4) do |song|
+ name, artist, album = song[0], song[1], song[2]
+ #yield Song.new(name, artist, album)
+ end
end
def names
names = []
- each { |song| names << song[0] }
+ each { |song| names << song.name }
names.uniq!
end
def artists
artists = []
- each { |song| artists << song[1] }
+ each { |song| artists << song.artist }
artists.uniq!
end
def albums
albums = []
- each { |song| albums << song[2] }
+ each { |song| albums << song.album }
albums.uniq!
+ end
+end
+
+class Song
+ attr_reader :name, :artist, :album
+
+ def initialize(name,artist,album)
+ @name, @artist, @album = name, artist, album
end
end

Нели обнови решението на 26.10.2012 20:42 (преди около 12 години)

class Collection
include Enumerable
def self.parse(text)
collection = Collection.new(text)
end
def initialize(text)
@text = text
end
def each
- array_with_lines = []
- @text.each_line { |line| array_with_lines << line.chop }
- array_with_lines.each_slice(4) do |song|
+ array_with_lines = (@text.lines.map { |song| song.split("\n") }).flatten
+ array_with_lines.each_slice(3) do |song|
name, artist, album = song[0], song[1], song[2]
- #yield Song.new(name, artist, album)
- end
+ yield Song.new(name, artist, album)
+ end
end
def names
names = []
each { |song| names << song.name }
- names.uniq!
+ names.uniq
end
def artists
artists = []
each { |song| artists << song.artist }
- artists.uniq!
+ artists.uniq
end
def albums
albums = []
each { |song| albums << song.album }
- albums.uniq!
+ albums.uniq
end
+
+ def filter(criteria)
+ select { |song| song.match?(criteria) }
+ end
end
class Song
attr_reader :name, :artist, :album
def initialize(name,artist,album)
@name, @artist, @album = name, artist, album
+ end
+
+ def match?(criteria)
+ end
+end
+
+class Criteria
+ attr_reader :type, :value, :operation
+
+ def self.name(song_name)
+ criteria = Criteria.new(:name,song_name)
+ end
+
+ def self.artist(artist_name)
+ criteria = Criteria.new(:artist,artist_name)
+ end
+
+ def self.album(album_name)
+ criteria = Criteria.new(:album,album_name)
+ end
+
+ def initialize(type, value)
+ @type, @value = type, value
+ end
+
+ def &(other)
end
end

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

class Collection
include Enumerable
+ attr_reader :songs_array
+
def self.parse(text)
- collection = Collection.new(text)
+ lines_as_array = (text.lines.map { |song| song.split("\n") }).flatten
+ collection = Collection.new(lines_as_array)
end
- def initialize(text)
- @text = text
+ def initialize(lines_as_array)
+ @songs_array = []
+ lines_as_array.each_slice(3) do |song|
+ @songs_array << Song.new(song[0], song[1], song[2])
+ end
end
def each
- array_with_lines = (@text.lines.map { |song| song.split("\n") }).flatten
- array_with_lines.each_slice(3) do |song|
- name, artist, album = song[0], song[1], song[2]
- yield Song.new(name, artist, album)
- end
+ @songs_array.each { |song| yield song }
end
def names
names = []
each { |song| names << song.name }
names.uniq
end
def artists
artists = []
each { |song| artists << song.artist }
artists.uniq
end
def albums
albums = []
each { |song| albums << song.album }
albums.uniq
end
def filter(criteria)
- select { |song| song.match?(criteria) }
+ filtered_songs = (@songs_array.select { |song| criteria.match?(song) }).uniq
+ sub_collection = SubCollection.new(filtered_songs)
end
end
+class SubCollection < Collection
+ def initialize(songs_array)
+ @songs_array = songs_array
+ end
+
+ def adjoin(other)
+ unite_collection = SubCollection.new((@songs_array+other.songs_array).uniq)
+ end
+end
+
class Song
+ include Comparable
+
attr_reader :name, :artist, :album
def initialize(name,artist,album)
@name, @artist, @album = name, artist, album
end
-
- def match?(criteria)
- end
end
class Criteria
- attr_reader :type, :value, :operation
+ attr_reader :type, :value
def self.name(song_name)
criteria = Criteria.new(:name,song_name)
end
def self.artist(artist_name)
criteria = Criteria.new(:artist,artist_name)
end
def self.album(album_name)
criteria = Criteria.new(:album,album_name)
end
def initialize(type, value)
@type, @value = type, value
end
+ def match?(song)
+ if @type == :name then song.name == @value
+ elsif @type == :artist then song.artist == @value
+ else song.album == @value
+ end
+ end
+
def &(other)
+ criteria = ConjunctionCriteria.new(@type, other.type, @value, other.value)
+ end
+
+ def |(other)
+ criteria = DisjunctionCriteria.new(@type, other.type, @value, other.value)
+ end
+
+ def !
+ criteria = NegationCriteria.new(@type, @value)
+ end
+end
+
+class ConjunctionCriteria
+ def initialize(type1, type2, value1, value2)
+ @type1, @type2, @value1, @value2 = type1, type2, value1, value2
+ end
+
+ def match?(song)
+ Criteria.new(@type1, @value1).match?(song) and
+ Criteria.new(@type2, @value2).match?(song)
+ end
+end
+
+class DisjunctionCriteria
+ def initialize(type1, type2, value1, value2)
+ @type1, @type2, @value1, @value2 = type1, type2, value1, value2
+ end
+
+ def match?(song)
+ Criteria.new(@type1, @value1).match?(song) or
+ Criteria.new(@type2, @value2).match?(song)
+ end
+end
+
+class NegationCriteria
+ def initialize(type, value)
+ @type, @value = type, value
+ end
+
+ def match?(song)
+ not Criteria.new(@type, @value).match?(song)
+ end
+
+ def match?(song)
+ not Criteria.new(@type, @value).match?(song)
end
end

Нели обнови решението на 31.10.2012 14:14 (преди около 12 години)

class Collection
include Enumerable
attr_reader :songs_array
def self.parse(text)
lines_as_array = (text.lines.map { |song| song.split("\n") }).flatten
collection = Collection.new(lines_as_array)
end
def initialize(lines_as_array)
@songs_array = []
lines_as_array.each_slice(3) do |song|
@songs_array << Song.new(song[0], song[1], song[2])
end
end
def each
@songs_array.each { |song| yield song }
end
def names
names = []
each { |song| names << song.name }
names.uniq
end
def artists
artists = []
each { |song| artists << song.artist }
artists.uniq
end
def albums
albums = []
each { |song| albums << song.album }
albums.uniq
end
def filter(criteria)
filtered_songs = (@songs_array.select { |song| criteria.match?(song) }).uniq
sub_collection = SubCollection.new(filtered_songs)
end
end
class SubCollection < Collection
def initialize(songs_array)
@songs_array = songs_array
end
def adjoin(other)
unite_collection = SubCollection.new((@songs_array+other.songs_array).uniq)
end
end
class Song
include Comparable
attr_reader :name, :artist, :album
def initialize(name,artist,album)
@name, @artist, @album = name, artist, album
end
+
+ def hash
+ (name+artist+album).hash
+ end
+
+ def eql?(other)
+ self == other
+ end
+
+ def ==(other)
+ name == other.name and artist == other.artist and album == other.album
+ end
end
class Criteria
attr_reader :type, :value
def self.name(song_name)
criteria = Criteria.new(:name,song_name)
end
def self.artist(artist_name)
criteria = Criteria.new(:artist,artist_name)
end
def self.album(album_name)
criteria = Criteria.new(:album,album_name)
end
def initialize(type, value)
@type, @value = type, value
end
def match?(song)
if @type == :name then song.name == @value
elsif @type == :artist then song.artist == @value
else song.album == @value
end
end
def &(other)
criteria = ConjunctionCriteria.new(@type, other.type, @value, other.value)
end
def |(other)
criteria = DisjunctionCriteria.new(@type, other.type, @value, other.value)
end
def !
criteria = NegationCriteria.new(@type, @value)
end
end
class ConjunctionCriteria
def initialize(type1, type2, value1, value2)
@type1, @type2, @value1, @value2 = type1, type2, value1, value2
end
def match?(song)
Criteria.new(@type1, @value1).match?(song) and
Criteria.new(@type2, @value2).match?(song)
end
end
class DisjunctionCriteria
def initialize(type1, type2, value1, value2)
@type1, @type2, @value1, @value2 = type1, type2, value1, value2
end
def match?(song)
Criteria.new(@type1, @value1).match?(song) or
Criteria.new(@type2, @value2).match?(song)
end
end
class NegationCriteria
def initialize(type, value)
@type, @value = type, value
end
def match?(song)
not Criteria.new(@type, @value).match?(song)
end
def match?(song)
not Criteria.new(@type, @value).match?(song)
end
end

it "supports a negation of filters" do filtered = collection.filter !Criteria.artist('Sting') filtered.map(&:album).should eq ["Live at Blues Alley", "Portrait in Jazz", "Yield", "Ten", "One", "A Love Supreme", "Mysterioso"] end

Ето при този тест проблемът е, че разултата ми е ["Live at Blues Alley", "Live at Blues Alley", "Portrait in Jazz", "Yield", "Ten", "One", "A Love Supreme", "Mysterioso"]. Как трябва да премахна повторенията. Мислех , че с uniq и предефиниране на hash и equ? за Songs ще се изчистят повторенията, но сега осъзнавам, че няма да стане така.