Решение на Втора задача от Йоан Динков

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

Към профила на Йоан Динков

Резултати

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

Код

module OverwriteOperators
def &(other)
Filter.new {|x| self.match?(x) && other.match?(x)}
end
def |(other)
Filter.new {|x| self.match?(x) || other.match?(x)}
end
end
class Filter
include OverwriteOperators
def initialize(&block)
@block = block
end
def match?(number)
@block.call(number)
end
end
class TypeFilter
include OverwriteOperators
def initialize(type)
@type = type
end
def match?(number)
case number
when Integer then @type == :integer
when Rational, Float then @type == :real
when Complex then @type == :complex
end
end
end
class SignFilter
include OverwriteOperators
def initialize(sign)
@sign = sign
end
def match?(number)
case @sign
when :positive then number > 0
when :non_positive then number <= 0
when :negative then number < 0
when :non_negative then number >= 0
end
end
end
class NumberSet
include Enumerable
def initialize
@values = []
end
def << (number)
@values << number unless @values.include? number
end
def each
@values.each do |value|
yield value
end
end
def size
@values.size
end
def empty?
@values.empty?
end
def [](filter)
@values.select{|x| filter.match?(x)}
end
end

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

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

Failures:

  1) NumberSet returns enumerable of set's contents if no block is given to each
     Failure/Error: expect(numbers.each.to_a.size).to eq [1, 3, 5].size
     LocalJumpError:
       no block given (yield)
     # /tmp/d20141028-18133-b80zqq/solution.rb:69:in `block in each'
     # /tmp/d20141028-18133-b80zqq/solution.rb:68:in `each'
     # /tmp/d20141028-18133-b80zqq/solution.rb:68:in `each'
     # /tmp/d20141028-18133-b80zqq/spec.rb:164: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.02162 seconds
24 examples, 1 failure

Failed examples:

rspec /tmp/d20141028-18133-b80zqq/spec.rb:159 # NumberSet returns enumerable of set's contents if no block is given to each

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

Йоан обнови решението на 26.10.2014 01:16 (преди около 10 години)

+module OverwriteOperators
+ attr_accessor :second_filter_type
+ attr_accessor :second_filter
+
+ def &(other)
+ puts(other.method(:filter))
+ self.second_filter_type = :and
+ self.second_filter = other
+ self
+ end
+
+ def |(other)
+ self.second_filter_type = :or
+ self.second_filter = other
+ self
+ end
+end
+
+class Filter
+ include OverwriteOperators
+ @block
+
+ def initialize (&block)
+ @block = block if block_given?
+ end
+
+ def filter(number)
+ @block.call(number)
+ end
+end
+
+class TypeFilter
+ include OverwriteOperators
+ @type
+ @number
+
+ def initialize (type)
+ @type = type
+ end
+
+ def filter (number)
+ case number
+ when Integer then @type == :integer
+ when Rational, Float then @type == :real
+ when Complex then @type == :complex
+ end
+ end
+end
+
+class SignFilter
+ include OverwriteOperators
+ @sign
+
+ def initialize (sign)
+ @sign = sign
+ end
+
+ def filter (number)
+ case @sign
+ when :positive then number > 0
+ when :non_positive then number <= 0
+ when :negative then number < 0
+ when :non_negative then number >= 0
+ end
+ end
+end
+
+class NumberSet
+ include Enumerable
+
+ def initialize
+ @values = []
+ end
+
+ def << (number)
+ case number
+ when Rational, Float then number = to_integer_from_rational(number)
+ when Complex then number = to_integer_from_complex(number)
+ end
+
+ @values.push(number) unless @values.include? number
+ end
+
+ def to_integer_from_rational(number)
+ integer, float = number.to_i, number.to_f
+ integer == float ? integer : float
+ end
+
+ def to_integer_from_complex(number)
+ Complex(number).abs
+ end
+
+ def size
+ @values.size
+ end
+
+ def empty?
+ @values.empty?
+ end
+
+ def each (&block)
+ @values.each
+ end
+
+ def [](filter)
+ case filter.second_filter_type
+ when :or
+ @values.select{|x| filter.filter(x) || filter.second_filter.filter(x)}
+ when :and
+ @values.select{|x| filter.filter(x) && filter.second_filter.filter(x)}
+ else
+ @values.select{|x| filter.filter(x)}
+ end
+ end
+end

Здрасти,

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

  • Пробвай да изпълниш някой от методите на Enumerable, примерно include? върху твоя NumberSet. :) Ще видиш нуждата от коректно имплементиран NumberSet#each.
  • С каква цел пишеш @block в тялото на класа?
  • Не оставяй празно място между името на метод и параметрите му при дефиниция.
  • Filter#filter името не ми харесва. До колкото разбирам метода връща истина/лъжа. Имаме конвенция за подобни методи.
  • Защо са ти необходими to_integer_from_... методите? Според мен не са.
  • Предпочитай << за добавяне на елемент в масив пред push.
  • Не ми харесва как си реализирал Filter#& и Filter#|. Защо не пробваш да ги реализираш връщайки нов Filter обект. Filter#filter връща булева стойност, така че не би трябвало да имаш проблем да комбинираш резултатите от две извиквания на този метод с правилния логически оператор. Това ще направи NumberSet#[] метода ти значително по-прост.

Йоан обнови решението на 26.10.2014 16:34 (преди около 10 години)

module OverwriteOperators
- attr_accessor :second_filter_type
- attr_accessor :second_filter
-
def &(other)
- puts(other.method(:filter))
- self.second_filter_type = :and
- self.second_filter = other
- self
+ Filter.new {|x| self.match?(x) && other.match?(x)}
end
def |(other)
- self.second_filter_type = :or
- self.second_filter = other
- self
+ Filter.new {|x| self.match?(x) || other.match?(x)}
end
end
class Filter
include OverwriteOperators
- @block
- def initialize (&block)
+ def initialize(&block)
@block = block if block_given?
end
- def filter(number)
+ def match?(number)
@block.call(number)
end
end
class TypeFilter
include OverwriteOperators
- @type
- @number
- def initialize (type)
+ def initialize(type)
@type = type
end
- def filter (number)
+ def match?(number)
case number
when Integer then @type == :integer
when Rational, Float then @type == :real
when Complex then @type == :complex
end
end
end
class SignFilter
include OverwriteOperators
- @sign
- def initialize (sign)
+ def initialize(sign)
@sign = sign
end
- def filter (number)
+ def match?(number)
case @sign
when :positive then number > 0
when :non_positive then number <= 0
when :negative then number < 0
when :non_negative then number >= 0
end
end
end
class NumberSet
include Enumerable
def initialize
@values = []
end
def << (number)
- case number
- when Rational, Float then number = to_integer_from_rational(number)
- when Complex then number = to_integer_from_complex(number)
- end
-
- @values.push(number) unless @values.include? number
+ @values << number unless @values.include? number
end
- def to_integer_from_rational(number)
- integer, float = number.to_i, number.to_f
- integer == float ? integer : float
+ def each(&block)
+ @values.each do |value|
+ yield value
+ end
end
- def to_integer_from_complex(number)
- Complex(number).abs
- end
-
def size
@values.size
end
def empty?
@values.empty?
end
- def each (&block)
- @values.each
- end
-
def [](filter)
- case filter.second_filter_type
- when :or
- @values.select{|x| filter.filter(x) || filter.second_filter.filter(x)}
- when :and
- @values.select{|x| filter.filter(x) && filter.second_filter.filter(x)}
- else
- @values.select{|x| filter.filter(x)}
- end
+ @values.select{|x| filter.match?(x)}
end
end

Йоан обнови решението на 26.10.2014 16:39 (преди около 10 години)

module OverwriteOperators
def &(other)
Filter.new {|x| self.match?(x) && other.match?(x)}
end
def |(other)
Filter.new {|x| self.match?(x) || other.match?(x)}
end
end
class Filter
include OverwriteOperators
def initialize(&block)
@block = block if block_given?
end
def match?(number)
@block.call(number)
end
end
class TypeFilter
include OverwriteOperators
def initialize(type)
@type = type
end
def match?(number)
case number
when Integer then @type == :integer
when Rational, Float then @type == :real
when Complex then @type == :complex
end
end
end
class SignFilter
include OverwriteOperators
def initialize(sign)
@sign = sign
end
def match?(number)
case @sign
when :positive then number > 0
when :non_positive then number <= 0
when :negative then number < 0
when :non_negative then number >= 0
end
end
end
class NumberSet
include Enumerable
def initialize
@values = []
end
def << (number)
@values << number unless @values.include? number
end
- def each(&block)
+ def each
@values.each do |value|
yield value
end
end
def size
@values.size
end
def empty?
@values.empty?
end
def [](filter)
@values.select{|x| filter.match?(x)}
end
end

Йоан обнови решението на 26.10.2014 19:46 (преди около 10 години)

module OverwriteOperators
def &(other)
Filter.new {|x| self.match?(x) && other.match?(x)}
end
def |(other)
Filter.new {|x| self.match?(x) || other.match?(x)}
end
end
class Filter
include OverwriteOperators
def initialize(&block)
- @block = block if block_given?
+ @block = block
end
def match?(number)
@block.call(number)
end
end
class TypeFilter
include OverwriteOperators
def initialize(type)
@type = type
end
def match?(number)
case number
when Integer then @type == :integer
when Rational, Float then @type == :real
when Complex then @type == :complex
end
end
end
class SignFilter
include OverwriteOperators
def initialize(sign)
@sign = sign
end
def match?(number)
case @sign
when :positive then number > 0
when :non_positive then number <= 0
when :negative then number < 0
when :non_negative then number >= 0
end
end
end
class NumberSet
include Enumerable
def initialize
@values = []
end
def << (number)
@values << number unless @values.include? number
end
def each
@values.each do |value|
yield value
end
end
def size
@values.size
end
def empty?
@values.empty?
end
def [](filter)
@values.select{|x| filter.match?(x)}
end
end