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

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

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

Резултати

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

Код

class Criteria
def initialize(&condition)
@condition = condition
end
def meets?(song)
@condition.(song)
end
def !
Criteria.new { |song| !meets? song }
end
def |(criteria)
Criteria.new { |song| meets? song or criteria.meets? song }
end
def &(criteria)
Criteria.new { |song| meets? song and criteria.meets? song }
end
def Criteria.name(name)
Criteria.new { |song| song.name == name }
end
def Criteria.artist(artist)
Criteria.new { |song| song.artist == artist }
end
def Criteria.album(album)
Criteria.new { |song| song.album == album }
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Collection
include Enumerable
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.lines.each_slice(4).map do |name, artist, album|
Song.new name.chomp, artist.chomp, album.chomp
end
Collection.new songs
end
def each
@songs.each { |song| yield song }
end
def names
@songs.map(&:name).uniq
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def filter(criteria)
Collection.new @songs.select { |song| criteria.meets? song }
end
def adjoin(collection)
Collection.new @songs + collection.to_a
end
end

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

...........

Finished in 0.01007 seconds
11 examples, 0 failures

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

Станислав обнови решението на 26.10.2012 10:00 (преди над 11 години)

+class Criteria
+ attr_reader :condition
+
+ def initialize(condition)
+ @condition = condition
+ end
+
+ def check(song)
+ @condition.(song)
+ end
+
+ def !
+ Criteria.new(lambda { |song| !condition.(song) })
+ end
+
+ def |(other)
+ Criteria.new(lambda { |song| other.condition.(song) or @condition.(song) })
+ end
+
+ def &(other)
+ Criteria.new(lambda { |song| other.condition.(song) and @condition.(song) })
+ end
+
+ def Criteria.name(name)
+ Criteria.new(lambda { |song| song.name == name })
+ end
+
+ def Criteria.artist(artist)
+ Criteria.new(lambda { |song| song.artist == artist })
+ end
+
+ def Criteria.album(album)
+ Criteria.new(lambda { |song| song.album == album })
+ end
+end
+
+class Song
+ attr_accessor :name, :artist, :album
+
+ def initialize(name, artist, album)
+ @name, @artist, @album = name, artist, album
+ end
+end
+
+class Collection
+ include Enumerable
+
+ attr_accessor :songs
+
+ def initialize
+ @songs = []
+ yield self
+ end
+
+ def Collection.parse(text)
+ new { |result| result.fill(text) }
+ end
+
+ def fill(text)
+ text.lines.each_slice(4) do |name, artist, album|
+ @songs << Song.new(name.chomp, artist.chomp, album.chomp)
+ end
+ end
+
+ def each
+ @songs.each { |song| yield song }
+ end
+
+ def names
+ @songs.map { |song| song.name }.uniq
+ end
+
+ def artists
+ @songs.map { |song| song.artist }.uniq
+ end
+
+ def albums
+ @songs.map { |song| song.album }.uniq
+ end
+
+ def filter(criteria)
+ filtered_songs = @songs.select { |song| criteria.check song }
+ Collection.new { |result| result.songs = filtered_songs }
+ end
+
+ def adjoin(other)
+ Collection.new { |result| result.songs.concat(songs + other.songs) }
+ end
+end

Станислав обнови решението на 26.10.2012 10:02 (преди над 11 години)

class Criteria
attr_reader :condition
def initialize(condition)
@condition = condition
end
def check(song)
@condition.(song)
end
def !
Criteria.new(lambda { |song| !condition.(song) })
end
def |(other)
Criteria.new(lambda { |song| other.condition.(song) or @condition.(song) })
end
def &(other)
Criteria.new(lambda { |song| other.condition.(song) and @condition.(song) })
end
def Criteria.name(name)
Criteria.new(lambda { |song| song.name == name })
end
def Criteria.artist(artist)
Criteria.new(lambda { |song| song.artist == artist })
end
def Criteria.album(album)
Criteria.new(lambda { |song| song.album == album })
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
- @name, @artist, @album = name, artist, album
+ @name, @artist, @album = name, artist, album
end
end
class Collection
include Enumerable
attr_accessor :songs
def initialize
@songs = []
- yield self
+ yield self
end
def Collection.parse(text)
- new { |result| result.fill(text) }
+ new { |result| result.fill(text) }
end
def fill(text)
text.lines.each_slice(4) do |name, artist, album|
@songs << Song.new(name.chomp, artist.chomp, album.chomp)
end
end
def each
- @songs.each { |song| yield song }
+ @songs.each { |song| yield song }
end
def names
@songs.map { |song| song.name }.uniq
end
def artists
@songs.map { |song| song.artist }.uniq
end
def albums
@songs.map { |song| song.album }.uniq
end
def filter(criteria)
- filtered_songs = @songs.select { |song| criteria.check song }
+ filtered_songs = @songs.select { |song| criteria.check song }
Collection.new { |result| result.songs = filtered_songs }
end
def adjoin(other)
Collection.new { |result| result.songs.concat(songs + other.songs) }
end
end

Станислав обнови решението на 26.10.2012 14:33 (преди над 11 години)

class Criteria
attr_reader :condition
def initialize(condition)
@condition = condition
end
def check(song)
@condition.(song)
end
def !
Criteria.new(lambda { |song| !condition.(song) })
end
def |(other)
Criteria.new(lambda { |song| other.condition.(song) or @condition.(song) })
end
def &(other)
Criteria.new(lambda { |song| other.condition.(song) and @condition.(song) })
end
def Criteria.name(name)
Criteria.new(lambda { |song| song.name == name })
end
def Criteria.artist(artist)
Criteria.new(lambda { |song| song.artist == artist })
end
def Criteria.album(album)
Criteria.new(lambda { |song| song.album == album })
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Collection
include Enumerable
- attr_accessor :songs
-
- def initialize
- @songs = []
- yield self
+ def initialize(songs)
+ @songs = songs
end
def Collection.parse(text)
- new { |result| result.fill(text) }
- end
-
- def fill(text)
- text.lines.each_slice(4) do |name, artist, album|
- @songs << Song.new(name.chomp, artist.chomp, album.chomp)
+ songs = text.lines.each_slice(4).map do |name, artist, album|
+ Song.new name.chomp, artist.chomp, album.chomp
end
+ Collection.new songs
end
def each
@songs.each { |song| yield song }
end
def names
@songs.map { |song| song.name }.uniq
end
def artists
@songs.map { |song| song.artist }.uniq
end
def albums
@songs.map { |song| song.album }.uniq
end
def filter(criteria)
- filtered_songs = @songs.select { |song| criteria.check song }
- Collection.new { |result| result.songs = filtered_songs }
+ Collection.new @songs.select { |song| criteria.check song }
end
def adjoin(other)
- Collection.new { |result| result.songs.concat(songs + other.songs) }
+ Collection.new @songs + other.to_a
end
end

Станислав обнови решението на 26.10.2012 16:34 (преди над 11 години)

class Criteria
- attr_reader :condition
-
def initialize(condition)
@condition = condition
end
def check(song)
@condition.(song)
end
def !
- Criteria.new(lambda { |song| !condition.(song) })
+ Criteria.new lambda { |song| !check song }
end
def |(other)
- Criteria.new(lambda { |song| other.condition.(song) or @condition.(song) })
+ Criteria.new lambda { |song| check song or other.check song }
end
def &(other)
- Criteria.new(lambda { |song| other.condition.(song) and @condition.(song) })
+ Criteria.new lambda { |song| check song and other.check song }
end
def Criteria.name(name)
- Criteria.new(lambda { |song| song.name == name })
+ Criteria.new lambda { |song| song.name == name }
end
def Criteria.artist(artist)
- Criteria.new(lambda { |song| song.artist == artist })
+ Criteria.new lambda { |song| song.artist == artist }
end
def Criteria.album(album)
- Criteria.new(lambda { |song| song.album == album })
+ Criteria.new lambda { |song| song.album == album }
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Collection
include Enumerable
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.lines.each_slice(4).map do |name, artist, album|
- Song.new name.chomp, artist.chomp, album.chomp
- end
+ Song.new name.chomp, artist.chomp, album.chomp
+ end
Collection.new songs
end
def each
@songs.each { |song| yield song }
end
def names
@songs.map { |song| song.name }.uniq
end
def artists
@songs.map { |song| song.artist }.uniq
end
def albums
@songs.map { |song| song.album }.uniq
end
def filter(criteria)
Collection.new @songs.select { |song| criteria.check song }
end
def adjoin(other)
Collection.new @songs + other.to_a
end
end

Станислав обнови решението на 26.10.2012 23:08 (преди над 11 години)

class Criteria
def initialize(condition)
@condition = condition
end
- def check(song)
+ def meets?(song)
@condition.(song)
end
def !
- Criteria.new lambda { |song| !check song }
+ Criteria.new lambda { |song| !meets? song }
end
- def |(other)
- Criteria.new lambda { |song| check song or other.check song }
+ def |(criteria)
+ Criteria.new lambda { |song| meets? song or criteria.meets? song }
end
- def &(other)
- Criteria.new lambda { |song| check song and other.check song }
+ def &(criteria)
+ Criteria.new lambda { |song| meets? song and criteria.meets? song }
end
def Criteria.name(name)
Criteria.new lambda { |song| song.name == name }
end
def Criteria.artist(artist)
Criteria.new lambda { |song| song.artist == artist }
end
def Criteria.album(album)
Criteria.new lambda { |song| song.album == album }
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Collection
include Enumerable
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.lines.each_slice(4).map do |name, artist, album|
Song.new name.chomp, artist.chomp, album.chomp
- end
+ end
Collection.new songs
end
def each
@songs.each { |song| yield song }
end
def names
- @songs.map { |song| song.name }.uniq
+ @songs.map(&:name).uniq
end
def artists
- @songs.map { |song| song.artist }.uniq
+ @songs.map(&:artist).uniq
end
def albums
- @songs.map { |song| song.album }.uniq
+ @songs.map(&:album).uniq
end
def filter(criteria)
- Collection.new @songs.select { |song| criteria.check song }
+ Collection.new @songs.select { |song| criteria.meets? song }
end
- def adjoin(other)
- Collection.new @songs + other.to_a
+ def adjoin(collection)
+ Collection.new @songs + collection.to_a
end
end

Станислав обнови решението на 29.10.2012 22:57 (преди над 11 години)

class Criteria
- def initialize(condition)
+ def initialize(&condition)
@condition = condition
end
def meets?(song)
@condition.(song)
end
def !
- Criteria.new lambda { |song| !meets? song }
+ Criteria.new { |song| !meets? song }
end
def |(criteria)
- Criteria.new lambda { |song| meets? song or criteria.meets? song }
+ Criteria.new { |song| meets? song or criteria.meets? song }
end
def &(criteria)
- Criteria.new lambda { |song| meets? song and criteria.meets? song }
+ Criteria.new { |song| meets? song and criteria.meets? song }
end
def Criteria.name(name)
- Criteria.new lambda { |song| song.name == name }
+ Criteria.new { |song| song.name == name }
end
def Criteria.artist(artist)
- Criteria.new lambda { |song| song.artist == artist }
+ Criteria.new { |song| song.artist == artist }
end
def Criteria.album(album)
- Criteria.new lambda { |song| song.album == album }
+ Criteria.new { |song| song.album == album }
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Collection
include Enumerable
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.lines.each_slice(4).map do |name, artist, album|
Song.new name.chomp, artist.chomp, album.chomp
end
Collection.new songs
end
def each
@songs.each { |song| yield song }
end
def names
@songs.map(&:name).uniq
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def filter(criteria)
Collection.new @songs.select { |song| criteria.meets? song }
end
def adjoin(collection)
Collection.new @songs + collection.to_a
end
end

Супер решение. Мога само да ти дам няколко идеи, които да позваш за вбъдеще.

  • Прието е клас методите да се дефинират преди другите, дори и initialize. За предпочитане е също да ползваш self.class_method_name при тяхната дефиниция, но сега е ОК, все пак не бяхме говорили за това.
  • Когато си вмъкнал Enumerable можеш да използваш map/collect направо върху себе си. Така @songs.map(&:name).uniq може да е map(&:name).uniq и т.н.

Според мен, заслужаваш бонус точка.

Всъщност, на лекцията казах, че аз предпочитам @songs.map(&:name).uniq пред map(&:name).uniq. Причината е, че първото зависи от instance променлива, докато второто - от публичен интерфейс и няколко слоя на абстракция (#map -> Enumerable -> @songs -> Array).