Решение на Втора задача от Габриела Лухова

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

Към профила на Габриела Лухова

Резултати

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

Код

class NumberSet
include Enumerable
def initialize
@numbers = []
end
def each(&block)
@numbers.each(&block)
end
def <<(number)
@numbers << number unless @numbers.include?(number)
end
def size
@numbers.size
end
def empty?
@numbers.empty?
end
def [](filter)
filtered_numbers = NumberSet.new
array = @numbers.select { |number| filter.matches? number }
array.each { |number| filtered_numbers << number }
filtered_numbers
end
end
class Filter
def initialize(&block)
@filter = block
end
def matches?(numbers)
@filter.(numbers)
end
def |(filter)
Filter.new { |number| matches? number or filter.matches? number }
end
def &(filter)
Filter.new { |number| matches? number and filter.matches? number }
end
end
class TypeFilter < Filter
def initialize(type)
if type == :integer
@filter = super() { |number| number.is_a? Integer }
elsif type == :real
@filter = super() { |number| number.is_a? Rational or number.is_a? Float}
else
@filter = super() { |number| number.is_a? Complex }
end
end
end
class SignFilter < Filter
def initialize(sign)
case
when sign == :positive
@filter = super() { |number| number > 0 }
when sign == :non_positive
@filter = super { |number| number <= 0 }
when sign == :negative
@filter = super() { |number| number < 0 }
when sign == :non_negative
@filter = super() { |number| number >= 0 }
end
end
end

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

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

Failures:

  1) NumberSet can filter non-positive numbers
     Failure/Error: can_filter [Rational(-5, 2), 7.6, 0], using: SignFilter.new(:non_positive),
     ArgumentError:
       wrong number of arguments (1 for 0)
     # /tmp/d20141028-18133-2nduxd/solution.rb:33:in `initialize'
     # /tmp/d20141028-18133-2nduxd/solution.rb:68:in `initialize'
     # /tmp/d20141028-18133-2nduxd/spec.rb:73:in `new'
     # /tmp/d20141028-18133-2nduxd/spec.rb:73: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.02244 seconds
24 examples, 1 failure

Failed examples:

rspec /tmp/d20141028-18133-2nduxd/spec.rb:72 # NumberSet can filter non-positive numbers

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

Габриела обнови решението на 25.10.2014 10:43 (преди над 9 години)

+class NumberSet
+ include Enumerable
+
+ attr_accessor :numbers
+
+ def initialize
+ @numbers = []
+ end
+
+ def each(&block)
+ @numbers.each(&block)
+ end
+
+ def <<(element)
+ @numbers << element unless @numbers.include?(element)
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def empty?
+ return true if @numbers.size == 0
+ false
+ end
+
+ def [](filter)
+ filtered_numbers = NumberSet.new
+ array = @numbers.select { |number| filter.matches? number }
+ array.each { |number| numbers << number }
+ filtered_numbers
+ end
+end
+
+class Filter
+ attr_accessor :filter
+
+ def initialize(&block)
+ @filter = block
+ end
+
+ def matches?(numbers)
+ @filter.(numbers)
+ end
+
+ def |(filter)
+ Filter.new { |number| matches? number or filter.matches? number }
+ end
+
+ def &(filter)
+ Filter.new { |number| matches? number and filter.matches? number }
+ end
+end
+
+class TypeFilter < Filter
+ attr_accessor :filter
+
+ def initialize(type)
+ if type == :integer
+ @filter = lambda { |number| number.is_a? Integer }
+ elsif type == :real
+ @filter = lambda { |number| number.is_a? Rational or number.is_a? Float}
+ else
+ @filter = lambda { |number| number.is_a? Complex }
+ end
+ end
+
+ def matches?(numbers)
+ @filter.(numbers)
+ end
+end
+
+class SignFilter < Filter
+ attr_accessor :filter
+
+ def initialize(sign)
+ @filter = lambda { |number| number > 0 } if sign == :positive
+ @filter = lambda { |number| number <= 0 } if sign == :non_positive
+ @filter = lambda { |number| number < 0 } if sign == :negative
+ @filter = lambda { |number| number >= 0 } if sign == :non_negative
+ end
+
+ def matches?(numbers)
+ @filter.(numbers)
+ end
+end

Здрасти,

Ето няколко неща, върху които можеш да помислиш:

  • Защо параметъра на NumberSet#<< се казва element при положение, че навсякъде си ползвала по-ясното number?
  • attr_accessor-ите не са ти нужни.
  • return true if @numbers.size == 0; false е еквивалентно на @numbers.size == 0, което е еквивалентно на @numbers.empty?. Кой според теб е по-четимия вариант от трите? :)
  • Имаш typo в NumberSet#[]. filtered_numbers седи празен. Можеш да погледнеш Enumerable#each_with_object.
  • TypeFilter наследява Filter. Можеш да се възползваш от това и да напишеш super() { |number| number.is_a? Integer }. Това ще подаде блок на конструктора на Filter и ще има същия ефект. Също така можеш да пробваш case вместо if/elsif/else. Същите неща важат за SignFilter.
  • Filter#matches?, TypeFIlter#matches? и SignFilter#matches? много си приличат. Кои два от тях можеш да махнеш без нещата да се счупят? :))

Габриела обнови решението на 25.10.2014 10:50 (преди над 9 години)

class NumberSet
include Enumerable
attr_accessor :numbers
def initialize
@numbers = []
end
def each(&block)
@numbers.each(&block)
end
def <<(element)
@numbers << element unless @numbers.include?(element)
end
def size
@numbers.size
end
def empty?
return true if @numbers.size == 0
false
end
def [](filter)
filtered_numbers = NumberSet.new
array = @numbers.select { |number| filter.matches? number }
- array.each { |number| numbers << number }
+ array.each { |number| filtered_numbers << number }
filtered_numbers
end
end
class Filter
attr_accessor :filter
def initialize(&block)
@filter = block
end
def matches?(numbers)
@filter.(numbers)
end
def |(filter)
Filter.new { |number| matches? number or filter.matches? number }
end
def &(filter)
Filter.new { |number| matches? number and filter.matches? number }
end
end
class TypeFilter < Filter
attr_accessor :filter
def initialize(type)
if type == :integer
@filter = lambda { |number| number.is_a? Integer }
elsif type == :real
@filter = lambda { |number| number.is_a? Rational or number.is_a? Float}
else
@filter = lambda { |number| number.is_a? Complex }
end
end
def matches?(numbers)
@filter.(numbers)
end
end
class SignFilter < Filter
attr_accessor :filter
def initialize(sign)
@filter = lambda { |number| number > 0 } if sign == :positive
@filter = lambda { |number| number <= 0 } if sign == :non_positive
@filter = lambda { |number| number < 0 } if sign == :negative
@filter = lambda { |number| number >= 0 } if sign == :non_negative
end
def matches?(numbers)
@filter.(numbers)
end
end

Габриела обнови решението на 25.10.2014 13:21 (преди над 9 години)

class NumberSet
include Enumerable
- attr_accessor :numbers
-
def initialize
@numbers = []
end
def each(&block)
@numbers.each(&block)
end
- def <<(element)
- @numbers << element unless @numbers.include?(element)
+ def <<(number)
+ @numbers << number unless @numbers.include?(number)
end
def size
@numbers.size
end
def empty?
- return true if @numbers.size == 0
- false
+ @numbers.empty?
end
def [](filter)
filtered_numbers = NumberSet.new
array = @numbers.select { |number| filter.matches? number }
array.each { |number| filtered_numbers << number }
filtered_numbers
end
end
class Filter
- attr_accessor :filter
-
def initialize(&block)
@filter = block
end
def matches?(numbers)
@filter.(numbers)
end
def |(filter)
Filter.new { |number| matches? number or filter.matches? number }
end
def &(filter)
Filter.new { |number| matches? number and filter.matches? number }
end
end
class TypeFilter < Filter
- attr_accessor :filter
-
def initialize(type)
if type == :integer
- @filter = lambda { |number| number.is_a? Integer }
+ @filter = super() { |number| number.is_a? Integer }
elsif type == :real
- @filter = lambda { |number| number.is_a? Rational or number.is_a? Float}
+ @filter = super() { |number| number.is_a? Rational or number.is_a? Float}
else
- @filter = lambda { |number| number.is_a? Complex }
+ @filter = super() { |number| number.is_a? Complex }
end
end
-
- def matches?(numbers)
- @filter.(numbers)
- end
end
class SignFilter < Filter
- attr_accessor :filter
-
def initialize(sign)
- @filter = lambda { |number| number > 0 } if sign == :positive
- @filter = lambda { |number| number <= 0 } if sign == :non_positive
- @filter = lambda { |number| number < 0 } if sign == :negative
- @filter = lambda { |number| number >= 0 } if sign == :non_negative
- end
-
- def matches?(numbers)
- @filter.(numbers)
+ case
+ when sign == :positive
+ @filter = super() { |number| number > 0 }
+ when sign == :non_positive
+ @filter = super { |number| number <= 0 }
+ when sign == :negative
+ @filter = super() { |number| number < 0 }
+ when sign == :non_negative
+ @filter = super() { |number| number >= 0 }
+ end
end
end

Габриела обнови решението на 25.10.2014 16:24 (преди над 9 години)

class NumberSet
include Enumerable
def initialize
@numbers = []
end
def each(&block)
@numbers.each(&block)
end
def <<(number)
@numbers << number unless @numbers.include?(number)
end
def size
@numbers.size
end
def empty?
@numbers.empty?
end
def [](filter)
filtered_numbers = NumberSet.new
array = @numbers.select { |number| filter.matches? number }
array.each { |number| filtered_numbers << number }
filtered_numbers
end
end
class Filter
def initialize(&block)
@filter = block
end
def matches?(numbers)
@filter.(numbers)
end
def |(filter)
Filter.new { |number| matches? number or filter.matches? number }
end
def &(filter)
Filter.new { |number| matches? number and filter.matches? number }
end
end
class TypeFilter < Filter
def initialize(type)
if type == :integer
@filter = super() { |number| number.is_a? Integer }
elsif type == :real
@filter = super() { |number| number.is_a? Rational or number.is_a? Float}
else
@filter = super() { |number| number.is_a? Complex }
end
end
end
class SignFilter < Filter
def initialize(sign)
case
when sign == :positive
@filter = super() { |number| number > 0 }
when sign == :non_positive
@filter = super { |number| number <= 0 }
when sign == :negative
@filter = super() { |number| number < 0 }
when sign == :non_negative
@filter = super() { |number| number >= 0 }
- end
+ end
end
end