Решение на Втора задача от Иван Кавалджиев

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

Към профила на Иван Кавалджиев

Резултати

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

Код

class NumberSet
include Enumerable
def initialize
@number_set = []
end
def each(&block)
@number_set.each &block
end
def <<(number)
@number_set << number unless @number_set.include?(number)
end
def size
@number_set.size
end
def empty?
@number_set.size == 0
end
def [](filter)
@number_set = @number_set.select { |number| filter.filtered?(number) }
end
end
class Filter
def initialize(&block)
@block = block
end
def filtered?(number)
@block.call(number)
end
def &(filter)
Filter.new{ |number| filtered?(number) and filter.filtered?(number) }
end
def |(&filter)
Filter.new{ |number| filtered?(number) or filter.filtered?(number) }
end
end
class TypeFilter < Filter
def initialize(type)
@type = type
end
def filtered?(number)
case @type
when :integer then number.integer?
when :real then number.real?
when :complex then number.complex?
end
end
end
class SignFilter < Filter
def initialize(sign)
@sign = sign
end
def filtered?(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

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

........F.F......F.FFF..

Failures:

  1) NumberSet can filter by complex type
     Failure/Error: filtered_numbers = numbers[using]
     NoMethodError:
       undefined method `complex?' for (0.3+2i):Complex
     # /tmp/d20141028-18133-a21xvf/solution.rb:56:in `filtered?'
     # /tmp/d20141028-18133-a21xvf/solution.rb:25:in `block in []'
     # /tmp/d20141028-18133-a21xvf/solution.rb:25:in `select'
     # /tmp/d20141028-18133-a21xvf/solution.rb:25:in `[]'
     # /tmp/d20141028-18133-a21xvf/spec.rb:179:in `can_filter'
     # /tmp/d20141028-18133-a21xvf/spec.rb:43: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 can filter by real type
     Failure/Error: expect(filtered_numbers.size).to eq expecting.size
       
       expected: 2
            got: 3
       
       (compared using ==)
     # /tmp/d20141028-18133-a21xvf/spec.rb:180:in `can_filter'
     # /tmp/d20141028-18133-a21xvf/spec.rb:55: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)>'

  3) NumberSet can combine two filters with "or" rule
     Failure/Error: filter = Filter.new { |number| number % 2 == 0 } | Filter.new { |number| number > 5 }
     ArgumentError:
       wrong number of arguments (1 for 0)
     # /tmp/d20141028-18133-a21xvf/solution.rb:42:in `|'
     # /tmp/d20141028-18133-a21xvf/spec.rb:98: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)>'

  4) NumberSet can combine multiple filters with "or" rule
     Failure/Error: filter        = even | negative | more_than_100
     ArgumentError:
       wrong number of arguments (1 for 0)
     # /tmp/d20141028-18133-a21xvf/solution.rb:42:in `|'
     # /tmp/d20141028-18133-a21xvf/spec.rb:118: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)>'

  5) NumberSet can combine multiple filters with "and" and "or" rules
     Failure/Error: filter        = even & negative | mod_3_is_zero
     ArgumentError:
       wrong number of arguments (1 for 0)
     # /tmp/d20141028-18133-a21xvf/solution.rb:42:in `|'
     # /tmp/d20141028-18133-a21xvf/spec.rb:128: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)>'

  6) NumberSet can combine multiple filters with "and", "or" and parenthesis
     Failure/Error: filter        = even & (negative | mod_3_is_zero)
     ArgumentError:
       wrong number of arguments (1 for 0)
     # /tmp/d20141028-18133-a21xvf/solution.rb:42:in `|'
     # /tmp/d20141028-18133-a21xvf/spec.rb:138: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.02209 seconds
24 examples, 6 failures

Failed examples:

rspec /tmp/d20141028-18133-a21xvf/spec.rb:42 # NumberSet can filter by complex type
rspec /tmp/d20141028-18133-a21xvf/spec.rb:54 # NumberSet can filter by real type
rspec /tmp/d20141028-18133-a21xvf/spec.rb:97 # NumberSet can combine two filters with "or" rule
rspec /tmp/d20141028-18133-a21xvf/spec.rb:114 # NumberSet can combine multiple filters with "or" rule
rspec /tmp/d20141028-18133-a21xvf/spec.rb:124 # NumberSet can combine multiple filters with "and" and "or" rules
rspec /tmp/d20141028-18133-a21xvf/spec.rb:134 # NumberSet can combine multiple filters with "and", "or" and parenthesis

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

Иван обнови решението на 26.10.2014 00:21 (преди около 10 години)

+class NumberSet
+ include Enumerable
+
+ def initialize
+ @container = []
+ end
+
+ def each(&block)
+ @container.each &block
+ end
+
+ def << (number)
+ @container << number if no_repetition(number)
+ end
+
+ def no_repetition(number)
+ @container.each do |element|
+ if ((number <=> element) == 0)
+ return false
+ else
+ true
+ end
+ end
+ end
+
+ def size
+ @container.count
+ end
+
+ def empty?
+ @container.count == 0
+ end
+
+ def [] (filter)
+ @container.select { |number| filter.checker(number) }
+ end
+
+end
+
+class Sieve
+ def initialize(combination)
+ @combination = combination
+ end
+
+ def checker(number)
+ @combination.call(number)
+ end
+
+ def &(filter)
+ Sieve.new(Proc.new{ |number| checker(number) and filter.checker(number) })
+ end
+
+ def |(filter)
+ Sieve.new(Proc.new{ |number| checker(number) or filter.checker(number) })
+ end
+
+end
+
+class Filter < Sieve
+ def initialize(&block)
+ @block = block
+ end
+
+ def checker(number)
+ @block.call(number)
+ end
+
+end
+
+class TypeFilter < Sieve
+ def initialize(type)
+ @type = type
+ end
+
+ def checker(number)
+ case @type
+ when :integer then number.integer?
+ when :real then number.real?
+ when :complex then number.complex?
+ end
+ end
+
+end
+
+class SignFilter < Sieve
+ def initialize(sign)
+ @sign = sign
+ end
+
+ def checker(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

Иван обнови решението на 26.10.2014 11:59 (преди около 10 години)

class NumberSet
include Enumerable
- def initialize
- @container = []
- end
+ def initialize
+ @container = []
+ end
- def each(&block)
- @container.each &block
- end
+ def each(&block)
+ @container.each &block
+ end
- def << (number)
- @container << number if no_repetition(number)
- end
+ def << (number)
+ @container << number if no_repetition(number)
+ end
- def no_repetition(number)
- @container.each do |element|
- if ((number <=> element) == 0)
- return false
- else
- true
- end
- end
+ def no_repetition(number)
+ @container.each do |element|
+ if ((number <=> element) == 0)
+ return false
+ else
+ true
+ end
end
+ end
- def size
- @container.count
- end
+ def size
+ @container.count
+ end
- def empty?
- @container.count == 0
- end
+ def empty?
+ @container.count == 0
+ end
- def [] (filter)
- @container.select { |number| filter.checker(number) }
- end
+ def [] (filter)
+ @container.select { |number| filter.checker(number) }
+ end
end
class Sieve
def initialize(combination)
- @combination = combination
+ @combination = combination
end
def checker(number)
- @combination.call(number)
+ @combination.call(number)
end
def &(filter)
Sieve.new(Proc.new{ |number| checker(number) and filter.checker(number) })
end
def |(filter)
Sieve.new(Proc.new{ |number| checker(number) or filter.checker(number) })
end
end
class Filter < Sieve
def initialize(&block)
@block = block
end
def checker(number)
@block.call(number)
end
end
class TypeFilter < Sieve
def initialize(type)
@type = type
end
def checker(number)
case @type
when :integer then number.integer?
when :real then number.real?
when :complex then number.complex?
end
end
end
class SignFilter < Sieve
def initialize(sign)
@sign = sign
end
def checker(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

Здрасти,

Харесва ми решението ти. Имам няколко малки коментара по кода ти:

  • no_repetition also known as @container.include? :)
  • Измисли по-добри имена за container и Filter#checker. Първото е твърде абстрактно. Все пак работим в контекста на числа/множества... Второто пък е някак нелогично. Това е метод, който връща булева стойност до колкото виждам. Имаме конвенция за такива. Постарай се да уловиш точната му задача в името.
  • Не оставяй празен ред след последния метод в клас.
  • Защо ти е класа Sieve? Не може ли да са едно с Filter?
  • Предпочитай size пред count, ако е възможно. Можеш да им прегледаш документацията.
  • NumberSet#[] трябва да връща NumberSet обратно. В момента ми се струва, че връщаш Array.
  • Не оставяй празно място между името на метода и параметрите при дефинирането му.

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

class NumberSet
include Enumerable
def initialize
- @container = []
+ @number_set = []
end
def each(&block)
- @container.each &block
+ @number_set.each &block
end
- def << (number)
- @container << number if no_repetition(number)
+ def <<(number)
+ @number_set << number unless @number_set.include?(number)
end
- def no_repetition(number)
- @container.each do |element|
- if ((number <=> element) == 0)
- return false
- else
- true
- end
- end
- end
-
def size
- @container.count
+ @number_set.size
end
def empty?
- @container.count == 0
+ @number_set.size == 0
end
- def [] (filter)
- @container.select { |number| filter.checker(number) }
+ def [](filter)
+ @number_set = @number_set.select { |number| filter.filtered?(number) }
end
-
end
-class Sieve
- def initialize(combination)
- @combination = combination
+class Filter
+ def initialize(&block)
+ @block = block
end
- def checker(number)
- @combination.call(number)
+ def filtered?(number)
+ @block.call(number)
end
def &(filter)
- Sieve.new(Proc.new{ |number| checker(number) and filter.checker(number) })
+ Filter.new{ |number| filtered?(number) and filter.filtered?(number) }
end
- def |(filter)
- Sieve.new(Proc.new{ |number| checker(number) or filter.checker(number) })
+ def |(&filter)
+ Filter.new{ |number| filtered?(number) or filter.filtered?(number) }
end
-
end
-class Filter < Sieve
- def initialize(&block)
- @block = block
- end
-
- def checker(number)
- @block.call(number)
- end
-
-end
-
-class TypeFilter < Sieve
+class TypeFilter < Filter
def initialize(type)
@type = type
end
- def checker(number)
+ def filtered?(number)
case @type
- when :integer then number.integer?
- when :real then number.real?
- when :complex then number.complex?
+ when :integer then number.integer?
+ when :real then number.real?
+ when :complex then number.complex?
end
end
-
end
-class SignFilter < Sieve
+class SignFilter < Filter
def initialize(sign)
@sign = sign
end
- def checker(number)
+ def filtered?(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
+ 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