Решение на Втора задача от Людмила Савова

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

Към профила на Людмила Савова

Резултати

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

Код

class Filter
attr_accessor :block
def initialize(&block)
@block = block
end
def &(filter)
new_block = proc { |number| filter.block.call(number) &&
@block.call(number)}
Filter.new(&new_block)
end
def |(filter)
new_block = proc { |number| filter.block.call(number) ||
@block.call(number)}
Filter.new(&new_block)
end
def number_comply?(number)
@block.call number
end
end
class TypeFilter < Filter
def initialize(filter_type)
case filter_type
when :integer then block = proc { |number| number.instance_of?(Integer) }
when :real then block = proc { |number| number.instance_of?(Float) ||
number.instance_of?(Rational)}
when :complex then block = proc { |number| number.instance_of?(Complex) }
end
super(&block)
end
end
class SignFilter < Filter
def initialize(filter_type)
case filter_type
when :positive then block = proc { |number| number > 0 }
when :non_positive then block = proc { |number| number <= 0 }
when :negative then block = proc { |number| number < 0 }
when :non_negative then block = proc { |number| number >= 0 }
end
super(&block)
end
end
class NumberSet
include Enumerable
def initialize
@elements = []
end
def each
@elements.each
end
def include?(number)
@elements.include?(number)
end
def <<(new_element)
@elements << new_element unless @elements.include? new_element
end
def [](filter)
filtered_set = NumberSet.new
@elements.each {|number| if filter.number_comply?(number)
filtered_set << number
end }
filtered_set
end
def size
@elements.length
end
def empty?
@elements.empty?
end
def to_a
@elements
end
end

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

.........F............F.

Failures:

  1) NumberSet can filter by integer type
     Failure/Error: expect(filtered_numbers.size).to eq expecting.size
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20141028-18133-16un0m9/spec.rb:180:in `can_filter'
     # /tmp/d20141028-18133-16un0m9/spec.rb:49:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) NumberSet is enumerable
     Failure/Error: expect(values.size).to eq [Rational(5, 2), 8, 7, 9].size
       
       expected: 4
            got: 0
       
       (compared using ==)
     # /tmp/d20141028-18133-16un0m9/spec.rb:155:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.02714 seconds
24 examples, 2 failures

Failed examples:

rspec /tmp/d20141028-18133-16un0m9/spec.rb:48 # NumberSet can filter by integer type
rspec /tmp/d20141028-18133-16un0m9/spec.rb:144 # NumberSet is enumerable

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

Людмила обнови решението на 25.10.2014 11:12 (преди над 9 години)

+class Filter
+
+ def initialize(&block)
+ @block = block
+ end
+ attr_accessor :block
+
+ def &(filter)
+ new_block = Proc.new { |number| filter.block.call(number) &&
+ @block.call(number)}
+ Filter.new(&new_block)
+ end
+end
+
+
+class TypeFilter
+
+ def initialize(filter_type)
+ @filter_type = filter_type
+ @block = self.set_filter
+ end
+ attr_accessor :block
+
+ def set_filter
+ case @filter_type
+ when :integer then
+ @block = Proc.new { |number| number.instance_of?(Integer) }
+ when :real then
+ @block = Proc.new { |number| number.instance_of?(Float) ||
+ number.instance_of?(Rational) }
+ when :complex then
+ @block = Proc.new { |number| number.instance_of?(Complex) }
+ end
+ end
+
+ def &(filter)
+ block = Proc.new { |number| filter.block.call(number) &&
+ @block.call(number)}
+ Filter.new(&block)
+ end
+end
+
+
+class SignFilter
+
+ def initialize(filter_type)
+ @filter_type = filter_type
+ @block = self.set_filter
+ end
+
+ attr_accessor :block
+
+ def set_filter
+ case @filter_type
+ when :positive then @block = Proc.new { |number| number > 0 }
+ when :non_positive then @block = Proc.new { |number| number <= 0 }
+ when :negative then @block = Proc.new { |number| number < 0 }
+ when :non_negative then @block = Proc.new { |number| number >= 0 }
+ end
+ end
+
+ def &(filter)
+ new_block = Proc.new { |number| filter.block.call(number) &&
+ @block.call(number)}
+ Filter.new(&new_block)
+ end
+end
+
+
+class NumberSet
+
+ def initialize
+ @elements = []
+ end
+
+ def <<(new_element)
+ @elements << new_element unless @elements.include? new_element
+ end
+
+ def [](filter)
+ filtered_set = NumberSet.new
+ (@elements.select(& filter.block)).each { |number| filtered_set << number }
+ end
+
+ def size
+ @elements.length
+ end
+
+ def empty?
+ @elements.empty?
+ end
+end

Знам, че мизерийката с (@elements.select(& filter.block)) е лош workaround за scepttic проблема, който имах, когато събмитвах, но за съжаление опитите ми да променя нещата и да не го достъпвам така блока не бяха успешни :D Ще се радвам на допълнителна помощ

Здрасти,

Ето няколко коментара по кода ти:

  • Не оставяй празен ред преди първия метод в клас.
  • attr_accessor-ите по принцип е добре да се пишат преди методите. Те също се разделят с празен ред. В случая attr_accessor-и не ти трябват, така че ги махни.
  • Относно проблема ти с filter.block. Защо не направиш метод във Filter, който да приема число и тялото му да е нещо като @block.call number? Така ще можеш да използваш този метод за проверка на число, а не да достъпваш анонимната функция, която пазиш във филтъра.
  • Имаш излишни скоби около @elements.select(...).
  • Помисли какъв резултат връщаш в NumberSet#[]. Ние очакваме NumberSet обратно.
  • Filter#&, TypeFilter#& и SignFilter#& много си приличат. Не може ли да reuse-неш по някакъв начин?
  • Във Filter#& според мен не ти е нужен Proc-а. Помисли си за блокове.

Струва ми се, че ти липсват някои неща. Прочети пак условието. :))

Людмила обнови решението на 25.10.2014 13:44 (преди над 9 години)

class Filter
-
+ attr_accessor :block
def initialize(&block)
@block = block
end
- attr_accessor :block
def &(filter)
- new_block = Proc.new { |number| filter.block.call(number) &&
+ new_block = proc { |number| filter.block.call(number) &&
@block.call(number)}
Filter.new(&new_block)
end
-end
-
-class TypeFilter
-
- def initialize(filter_type)
- @filter_type = filter_type
- @block = self.set_filter
+ def |(filter)
+ new_block = proc { |number| filter.block.call(number) ||
+ @block.call(number)}
+ Filter.new(&new_block)
end
- attr_accessor :block
- def set_filter
- case @filter_type
- when :integer then
- @block = Proc.new { |number| number.instance_of?(Integer) }
- when :real then
- @block = Proc.new { |number| number.instance_of?(Float) ||
- number.instance_of?(Rational) }
- when :complex then
- @block = Proc.new { |number| number.instance_of?(Complex) }
- end
+ def number_comply?(number)
+ @block.call number
end
-
- def &(filter)
- block = Proc.new { |number| filter.block.call(number) &&
- @block.call(number)}
- Filter.new(&block)
- end
end
-
-class SignFilter
-
+class TypeFilter < Filter
def initialize(filter_type)
- @filter_type = filter_type
- @block = self.set_filter
+ case filter_type
+ when :integer then block = proc { |number| number.instance_of?(Integer) }
+ when :real then block = proc { |number| number.instance_of?(Float) ||
+ number.instance_of?(Rational)}
+ when :complex then block = proc { |number| number.instance_of?(Complex) }
+ end
+ super(&block)
end
+end
- attr_accessor :block
-
- def set_filter
- case @filter_type
- when :positive then @block = Proc.new { |number| number > 0 }
- when :non_positive then @block = Proc.new { |number| number <= 0 }
- when :negative then @block = Proc.new { |number| number < 0 }
- when :non_negative then @block = Proc.new { |number| number >= 0 }
+class SignFilter < Filter
+ def initialize(filter_type)
+ case filter_type
+ when :positive then block = proc { |number| number > 0 }
+ when :non_positive then block = proc { |number| number <= 0 }
+ when :negative then block = proc { |number| number < 0 }
+ when :non_negative then block = proc { |number| number >= 0 }
end
+ super(&block)
end
-
- def &(filter)
- new_block = Proc.new { |number| filter.block.call(number) &&
- @block.call(number)}
- Filter.new(&new_block)
- end
end
-
class NumberSet
-
+ include Enumerable
def initialize
@elements = []
end
+ def each
+ @elements.each
+ end
+
+ def include?(number)
+ @elements.include?(number)
+ end
+
def <<(new_element)
@elements << new_element unless @elements.include? new_element
end
def [](filter)
filtered_set = NumberSet.new
- (@elements.select(& filter.block)).each { |number| filtered_set << number }
+ @elements.each {|number| if filter.number_comply?(number)
+ filtered_set << number
+ end }
+ filtered_set
end
def size
@elements.length
end
def empty?
@elements.empty?
+ end
+
+ def to_a
+ @elements
end
end