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

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

Към профила на Радослав Върбанов

Резултати

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

Код

class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name = name
@artist = artist
@album = album
end
end
module FilterHelper
def meets_criterium(crit, song)
c1 = (crit[:names].empty? or crit[:names].include? song.name)
c2 = (crit[:arts].empty? or crit[:arts].include? song.artist)
c3 = (crit[:albs].empty? or crit[:albs].include? song.album)
c1 and c2 and c3
end
end
class Collection
attr_accessor :song_array, :name_list, :artist_list, :album_list
include Enumerable
include FilterHelper
def initialize(text)
self.song_array, self.name_list = [], []
self.artist_list, self.album_list = [], []
text.split("\n").each_slice(4) do |name, artist, album|
self.song_array << Song.new(name, artist, album)
end
end
def self.parse(text)
Collection.new(text)
end
def each
song_array.each do |song|
yield song
end
end
def filter(criterium)
coll = Collection.new("")
coll.song_array = self.song_array.select do |song|
meets_criterium(criterium, song)
end
coll
end
def adjoin(other_coll)
new_coll = self
new_coll.song_array |= other_coll.song_array
new_coll
end
def names
@song_array.each do |song|
@name_list << song.name
end
@name_list.uniq
end
def artists
@song_array.each do |song|
@artist_list << song.artist
end
@artist_list.uniq
end
def albums
@song_array.each do |song|
@album_list << song.album
end
@album_list.uniq
end
end
class Criteria
class << self
attr_accessor :criteria_hash
end
@criteria_hash = Hash.new
def initialize
self.class.criteria_hash = { names: [], arts: [], albs: [] }
end
def self.name(song_name)
self.criteria_hash[:names] << song_name
self.criteria_hash[:arts] = []
self.criteria_hash[:albs] = []
self.criteria_hash
end
def self.artist(song_artist)
self.criteria_hash[:names] = []
self.criteria_hash[:arts] << song_artist
self.criteria_hash[:albs] = []
self.criteria_hash
end
def self.album(song_album)
self.criteria_hash[:names] = []
self.criteria_hash[:arts] = []
self.criteria_hash[:albs] << song_album
self.criteria_hash
end
def & (other_crit)
@m_names = criteria_hash[:names].merge(other.crit.criteria_hash[:names])
@m_arts = criteria_hash[:arts].merge(other.crit.criteria_hash[:arts])
@m_albs = criteria_hash[:albs].merge(other.crit.criteria_hash[:albs])
Hash.new({ names: @m_names, arts: @m_arts, albs: @m_albs })
end
end

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

...FFFFFFF.

Failures:

  1) Collection can be filtered by song name
     Failure/Error: filtered = collection.filter Criteria.name('Fields of Gold')
     NoMethodError:
       undefined method `<<' for nil:NilClass
     # /tmp/d20130203-23049-q35waz/solution.rb:93:in `name'
     # /tmp/d20130203-23049-q35waz/spec.rb:44: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 be filtered by song name
     Failure/Error: filtered = collection.filter Criteria.artist('Sting')
     NoMethodError:
       undefined method `<<' for nil:NilClass
     # /tmp/d20130203-23049-q35waz/solution.rb:101:in `artist'
     # /tmp/d20130203-23049-q35waz/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)>'

  3) Collection can be filtered by album
     Failure/Error: filtered = collection.filter Criteria.album('Live at Blues Alley')
     NoMethodError:
       undefined method `<<' for nil:NilClass
     # /tmp/d20130203-23049-q35waz/solution.rb:109:in `album'
     # /tmp/d20130203-23049-q35waz/spec.rb:54: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 can return an empty result
     Failure/Error: filtered = collection.filter Criteria.album('The Dark Side of the Moon')
     NoMethodError:
       undefined method `<<' for nil:NilClass
     # /tmp/d20130203-23049-q35waz/solution.rb:109:in `album'
     # /tmp/d20130203-23049-q35waz/spec.rb:59: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 supports a conjuction of filters
     Failure/Error: filtered = collection.filter Criteria.artist('Sting') & Criteria.name('Fields of Gold')
     NoMethodError:
       undefined method `&' for {:names=>[], :arts=>["Sting", "Eva Cassidy"], :albs=>[]}:Hash
     # /tmp/d20130203-23049-q35waz/spec.rb:64: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 supports a disjunction of filters
     Failure/Error: filtered = collection.filter Criteria.artist('Sting') | Criteria.name('Fields of Gold')
     NoMethodError:
       undefined method `|' for {:names=>[], :arts=>["Sting", "Eva Cassidy"], :albs=>[]}:Hash
     # /tmp/d20130203-23049-q35waz/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)>'

  7) Collection supports negation of filters
     Failure/Error: filtered = collection.filter Criteria.artist('Sting') & !Criteria.name('Fields of Gold')
     NoMethodError:
       undefined method `&' for {:names=>[], :arts=>["Sting", "Eva Cassidy"], :albs=>[]}:Hash
     # /tmp/d20130203-23049-q35waz/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.01029 seconds
11 examples, 7 failures

Failed examples:

rspec /tmp/d20130203-23049-q35waz/spec.rb:43 # Collection can be filtered by song name
rspec /tmp/d20130203-23049-q35waz/spec.rb:48 # Collection can be filtered by song name
rspec /tmp/d20130203-23049-q35waz/spec.rb:53 # Collection can be filtered by album
rspec /tmp/d20130203-23049-q35waz/spec.rb:58 # Collection can return an empty result
rspec /tmp/d20130203-23049-q35waz/spec.rb:63 # Collection supports a conjuction of filters
rspec /tmp/d20130203-23049-q35waz/spec.rb:68 # Collection supports a disjunction of filters
rspec /tmp/d20130203-23049-q35waz/spec.rb:77 # Collection supports negation of filters

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

Радослав обнови решението на 31.10.2012 11:51 (преди около 12 години)

+class Song
+ attr_accessor :name, :artist, :album
+
+ def initialize(name, artist, album)
+ @name = name
+ @artist = artist
+ @album = album
+ end
+end
+
+module FilterHelper
+ def meets_criterium(crit, song)
+ c1 = (crit[:names].empty? or crit[:names].include? song.name)
+ c2 = (crit[:arts].empty? or crit[:arts].include? song.artist)
+ c3 = (crit[:albs].empty? or crit[:albs].include? song.album)
+ c1 and c2 and c3
+ end
+end
+
+class Collection
+ attr_accessor :song_array, :name_list, :artist_list, :album_list
+
+ include Enumerable
+
+ include FilterHelper
+
+ def initialize(text)
+ self.song_array, self.name_list = [], []
+ self.artist_list, self.album_list = [], []
+ text.split("\n").each_slice(4) do |name, artist, album|
+ self.song_array << Song.new(name, artist, album)
+ end
+ end
+
+ def self.parse(text)
+ Collection.new(text)
+ end
+
+ def each
+ song_array.each do |song|
+ yield song
+ end
+ end
+
+ def filter(criterium)
+ coll = Collection.new("")
+ coll.song_array = self.song_array.select do |song|
+ meets_criterium(criterium, song)
+ end
+ coll
+ end
+
+ def adjoin(other_coll)
+ new_coll = self
+ new_coll.song_array |= other_coll.song_array
+ new_coll
+ end
+
+ def names
+ @song_array.each do |song|
+ @name_list << song.name
+ end
+ @name_list.uniq
+ end
+
+ def artists
+ @song_array.each do |song|
+ @artist_list << song.artist
+ end
+ @artist_list.uniq
+ end
+
+ def albums
+ @song_array.each do |song|
+ @album_list << song.album
+ end
+ @album_list.uniq
+ end
+end
+
+class Criteria
+ class << self
+ attr_accessor :criteria_hash
+ end
+
+ @criteria_hash = Hash.new
+
+ def initialize
+ self.class.criteria_hash = { names: [], arts: [], albs: [] }
+ end
+
+ def self.name(song_name)
+ self.criteria_hash[:names] << song_name
+ self.criteria_hash[:arts] = []
+ self.criteria_hash[:albs] = []
+ self.criteria_hash
+ end
+
+ def self.artist(song_artist)
+ self.criteria_hash[:names] =[]
+ self.criteria_hash[:arts] << song_artist
+ self.criteria_hash[:albs] = []
+ self.criteria_hash
+ end
+
+ def self.album(song_album)
+ self.criteria_hash[:names] =[]
+ self.criteria_hash[:arts] = []
+ self.criteria_hash[:albs] << song_album
+ self.criteria_hash
+ end
+
+ def & (other_crit)
+ @m_names = criteria_hash[:names].merge(other.crit.criteria_hash[:names])
+ @m_arts = criteria_hash[:arts].merge(other.crit.criteria_hash[:arts])
+ @m_albs = criteria_hash[:albs].merge(other.crit.criteria_hash[:albs])
+ Hash.new({ names: @m_names, arts: @m_arts, albs: @m_albs })
+ end
+end

Радослав обнови решението на 31.10.2012 11:57 (преди около 12 години)

class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name = name
@artist = artist
@album = album
end
end
module FilterHelper
def meets_criterium(crit, song)
c1 = (crit[:names].empty? or crit[:names].include? song.name)
c2 = (crit[:arts].empty? or crit[:arts].include? song.artist)
c3 = (crit[:albs].empty? or crit[:albs].include? song.album)
c1 and c2 and c3
end
end
class Collection
attr_accessor :song_array, :name_list, :artist_list, :album_list
include Enumerable
include FilterHelper
def initialize(text)
self.song_array, self.name_list = [], []
self.artist_list, self.album_list = [], []
text.split("\n").each_slice(4) do |name, artist, album|
self.song_array << Song.new(name, artist, album)
end
end
def self.parse(text)
Collection.new(text)
end
def each
song_array.each do |song|
yield song
end
end
def filter(criterium)
coll = Collection.new("")
coll.song_array = self.song_array.select do |song|
meets_criterium(criterium, song)
end
coll
end
def adjoin(other_coll)
new_coll = self
new_coll.song_array |= other_coll.song_array
new_coll
end
def names
@song_array.each do |song|
@name_list << song.name
end
@name_list.uniq
end
def artists
@song_array.each do |song|
@artist_list << song.artist
end
@artist_list.uniq
end
def albums
@song_array.each do |song|
@album_list << song.album
end
@album_list.uniq
end
end
class Criteria
class << self
attr_accessor :criteria_hash
end
@criteria_hash = Hash.new
def initialize
self.class.criteria_hash = { names: [], arts: [], albs: [] }
end
def self.name(song_name)
self.criteria_hash[:names] << song_name
self.criteria_hash[:arts] = []
self.criteria_hash[:albs] = []
self.criteria_hash
end
def self.artist(song_artist)
- self.criteria_hash[:names] =[]
+ self.criteria_hash[:names] = []
self.criteria_hash[:arts] << song_artist
self.criteria_hash[:albs] = []
self.criteria_hash
end
def self.album(song_album)
- self.criteria_hash[:names] =[]
+ self.criteria_hash[:names] = []
self.criteria_hash[:arts] = []
self.criteria_hash[:albs] << song_album
self.criteria_hash
end
def & (other_crit)
@m_names = criteria_hash[:names].merge(other.crit.criteria_hash[:names])
@m_arts = criteria_hash[:arts].merge(other.crit.criteria_hash[:arts])
@m_albs = criteria_hash[:albs].merge(other.crit.criteria_hash[:albs])
Hash.new({ names: @m_names, arts: @m_arts, albs: @m_albs })
end
end
  • albs, arts — не съкращавай така, гадно е; имаш и други променливи, които са именовани лошо; променливи с имена m_* са също зле именовани
  • Тия self. в тялото на клас-методите на Criteria могат да се разкарат, излишни са
  • Този class << self в Criteria не знам откъде го изрови, но определено не трябва да остава там; не сме го показвали и не трябва да го ползваш, понеже вероятно не знаеш какво точно прави; още повече, че не ти трявба
  • Допълнително, тези методи имат повторение на код и също променят състоянието на обекта по кофти начин; това не е правилният метод (фактически държиш някакъв глобален state в класа Criteria, което е ужасно зле)
  • Методите names, artists, albums на Collection могат просто да връщат нови списъци, а не да блъскат в инстанционни променливи и да променят state-а на обекта; пренапиши тези методи

Обезателно разгледай решенията на колеги, след като свърши крайния срок на задачата. Ако имаш каквито и да е въпроси или съмнения, ела да питаш в някоя почивка, че този коментар ми стана тесен... :smile: