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

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

Към профила на Стилиян Стоянов

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 17 успешни тест(а)
  • 7 неуспешни тест(а)

Код

class NumberSet
include Enumerable
def initialize
@number_set = []
end
def <<( number )
unless @number_set.include? number
@number_set << number
end
end
def each
@number_set.each { |x| yield x }
end
def size
@number_set.length
end
def empty?
@number_set.empty?
end
def []( filter )
filter.filter_set_of_numbers @number_set
end
end
class SignFilter
def initialize number_sign_type
@sign = number_sign_type
end
def filter_set_of_numbers numbers
case @sign.to_s
when "negative"
numbers.select { |x| x.real < 0.0 }
when "positive"
numbers.select { |x| x.real > 0.0 }
when "non_positive"
numbers.select { |x| x.real <= 0.0 }
else
numbers.select { |x| x.real >= 0.0 }
end
end
end
class TypeFilter
def initialize number_type
@number_type = number_type
end
def filter_set_of_numbers numbers
case @number_type.to_s
when "complex"
numbers.select { |x| x.class.to_s == "Complex" }
when "real", "rational"
real_and_rational = numbers.select { |x| x.class.to_s == "Float" }
real_and_rational + numbers.select { |x| x.class.to_s == "Rational" }
when "integer"
numbers.select { |x| x.class.to_s == "Fixnum" }
end
end
end
class Filter
def initialize &block
@filter = block
end
def filter_set_of_numbers numbers
numbers.select { |x| @filter.call x.real.round }
end
end

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

................FFFFFF.F

Failures:

  1) NumberSet can combine two filters with "and" rule
     Failure/Error: filter = SignFilter.new(:non_negative) & Filter.new { |number| number != 0 }
     NoMethodError:
       undefined method `&' for #<SignFilter:0xb9368bc0 @sign=:non_negative>
     # /tmp/d20141028-18133-1a741i6/spec.rb:91: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 combine two filters with "or" rule
     Failure/Error: filter = Filter.new { |number| number % 2 == 0 } | Filter.new { |number| number > 5 }
     NoMethodError:
       undefined method `|' for #<Filter:0xb9368044>
     # /tmp/d20141028-18133-1a741i6/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)>'

  3) NumberSet can combine multiple filters with "and" rule
     Failure/Error: filter        = non_negative & non_zero & mod_3_is_zero
     NoMethodError:
       undefined method `&' for #<SignFilter:0xb92df6f4 @sign=:non_negative>
     # /tmp/d20141028-18133-1a741i6/spec.rb:108: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
     NoMethodError:
       undefined method `|' for #<Filter:0xb92debc8 @filter=#<Proc:0xb92dec04>>
     # /tmp/d20141028-18133-1a741i6/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
     NoMethodError:
       undefined method `&' for #<Filter:0xb92de0b0 @filter=#<Proc:0xb92dec04>>
     # /tmp/d20141028-18133-1a741i6/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)
     NoMethodError:
       undefined method `|' for #<SignFilter:0xb92dd584 @sign=:negative>
     # /tmp/d20141028-18133-1a741i6/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)>'

  7) 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-1a741i6/solution.rb:15:in `block in each'
     # /tmp/d20141028-18133-1a741i6/solution.rb:15:in `each'
     # /tmp/d20141028-18133-1a741i6/solution.rb:15:in `each'
     # /tmp/d20141028-18133-1a741i6/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.02104 seconds
24 examples, 7 failures

Failed examples:

rspec /tmp/d20141028-18133-1a741i6/spec.rb:90 # NumberSet can combine two filters with "and" rule
rspec /tmp/d20141028-18133-1a741i6/spec.rb:97 # NumberSet can combine two filters with "or" rule
rspec /tmp/d20141028-18133-1a741i6/spec.rb:104 # NumberSet can combine multiple filters with "and" rule
rspec /tmp/d20141028-18133-1a741i6/spec.rb:114 # NumberSet can combine multiple filters with "or" rule
rspec /tmp/d20141028-18133-1a741i6/spec.rb:124 # NumberSet can combine multiple filters with "and" and "or" rules
rspec /tmp/d20141028-18133-1a741i6/spec.rb:134 # NumberSet can combine multiple filters with "and", "or" and parenthesis
rspec /tmp/d20141028-18133-1a741i6/spec.rb:159 # NumberSet returns enumerable of set's contents if no block is given to each

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

Стилиян обнови решението на 27.10.2014 02:44 (преди около 10 години)

+class NumberSet
+ include Enumerable
+
+ def initialize
+ @number_set = []
+ end
+
+ def <<(number)
+ unless @number_set.include? number
+ @number_set << number
+ end
+ end
+
+ def each
+ @number_set.each { | x | yield x }
+ end
+
+ def size
+ @number_set.length
+ end
+
+ def empty?
+ @number_set.empty?
+ end
+
+ def type index
+ p @number_set[index].class
+ end
+end

В отговор на твоя имейл:

Здравейте, малко ми е трудно да асимилирам как точно трябва да реализирам метода each, за да активирам Enumerable.В моят клас съм го реализирал използвайки each на Аrray и yield.Ще може ли малко повече разяснение за този метод?

Да, тази имплементация на each не е далеч от истината. Покрива 90% от функционалността. Не е фатално да я оставиш и така.

И още един въпрос ако е възможно да ми отговорите.Методът [] ще приема един аргумент - име на филтър, което при мен ще се явява име на метод най-вероятно, а аргументите на филтрите като блок ли се очаква да се появят?В единият случай взима блок, а в другите по 1 символ.Или тези филтри са някакви отделни класове?

За филтрите виж пак условието и примерните тестове. Там има примери как се ползва. Това, което си казал, че NumberSet#[] "ще приема един аргумент - име на филтър", не е вярно. Методът ще приема един обект. Този обект ще е или филтър, или нещо друго, което се получава при комбинация на два или повече филтъра. Какъв да е обектът във втория случай, си измисляш ти.

Но при всяко положение, [] примеа един-единствен аргумент, който е инстанция на клас-филтър. Тази инстанция носи със себе си информация как да се филтрира. Как да използваш тази информация в метода [], е твое решение.

Допълнително, имаш проблеми с идентацията, както и разни p неща, които са вероятно защото все още пишеш решението.

Стилиян обнови решението на 27.10.2014 11:46 (преди около 10 години)

class NumberSet
include Enumerable
def initialize
- @number_set = []
+ @number_set = []
end
- def <<(number)
+ def <<(number)
unless @number_set.include? number
- @number_set << number
+ @number_set << number
end
end
def each
- @number_set.each { | x | yield x }
+ @number_set.each { |x| yield x }
end
def size
@number_set.length
end
def empty?
@number_set.empty?
end
- def type index
- p @number_set[index].class
+ def []( filter )
+ p filter.filter_set_of_numbers @number_set
+ end
+end
+
+class SignFilter
+ def initialize number_sign_type
+ @sign = number_sign_type
+ end
+
+ def filter_set_of_numbers numbers
+ case @sign.to_s
+ when "negative"
+ numbers.select { |x| x.real < 0.0 }
+ when "positive"
+ numbers.select { |x| x.real > 0.0 }
+ when "non_positive"
+ numbers.select { |x| x.real <= 0.0 }
+ else
+ numbers.select { |x| x.real >= 0.0 }
+ end
+ end
+end
+
+class TypeFilter
+ def initialize number_type
+ @number_type = number_type
+ end
+ def filter_set_of_numbers numbers
+ case @number_type.to_s
+ when "complex"
+ numbers.select { |x| x.class.to_s == "Complex" }
+ when "real", "rational"
+ real_and_rational = numbers.select { |x| x.class.to_s == "Float" }
+ real_and_rational + numbers.select { |x| x.class.to_s == "Rational" }
+ when "integer"
+ numbers.select { |x| x.class.to_s == "Fixnum" }
+ end
end
end

Благодаря за бързия отговор по това време. :) Надявам се след крайния срок да ми обясните и за останалите 10%, които не хваща моя each. Не са финални версии решенията, които качвам, а просто за всеки случай, ако стане нещо с интернет връзката...

Стилиян обнови решението на 27.10.2014 14:07 (преди около 10 години)

class NumberSet
include Enumerable
def initialize
@number_set = []
end
- def <<(number)
+ def <<( number )
unless @number_set.include? number
@number_set << number
end
end
def each
@number_set.each { |x| yield x }
end
def size
@number_set.length
end
def empty?
@number_set.empty?
end
def []( filter )
p filter.filter_set_of_numbers @number_set
end
end
class SignFilter
def initialize number_sign_type
@sign = number_sign_type
end
def filter_set_of_numbers numbers
case @sign.to_s
when "negative"
numbers.select { |x| x.real < 0.0 }
when "positive"
numbers.select { |x| x.real > 0.0 }
when "non_positive"
numbers.select { |x| x.real <= 0.0 }
else
numbers.select { |x| x.real >= 0.0 }
end
end
end
class TypeFilter
def initialize number_type
@number_type = number_type
end
+
def filter_set_of_numbers numbers
case @number_type.to_s
when "complex"
numbers.select { |x| x.class.to_s == "Complex" }
when "real", "rational"
real_and_rational = numbers.select { |x| x.class.to_s == "Float" }
real_and_rational + numbers.select { |x| x.class.to_s == "Rational" }
when "integer"
numbers.select { |x| x.class.to_s == "Fixnum" }
end
+ end
+end
+
+class Filter
+ def initialize &block
+ @filter = block
+ end
+
+ def filter_set_of_numbers numbers
+ numbers.select { |x| @filter.call x.real.round }
end
end

Стилиян обнови решението на 27.10.2014 16:54 (преди около 10 години)

class NumberSet
include Enumerable
def initialize
@number_set = []
end
def <<( number )
unless @number_set.include? number
@number_set << number
end
end
def each
@number_set.each { |x| yield x }
end
def size
@number_set.length
end
def empty?
@number_set.empty?
end
def []( filter )
- p filter.filter_set_of_numbers @number_set
+ filter.filter_set_of_numbers @number_set
end
end
class SignFilter
def initialize number_sign_type
@sign = number_sign_type
end
def filter_set_of_numbers numbers
case @sign.to_s
when "negative"
numbers.select { |x| x.real < 0.0 }
when "positive"
numbers.select { |x| x.real > 0.0 }
when "non_positive"
numbers.select { |x| x.real <= 0.0 }
else
numbers.select { |x| x.real >= 0.0 }
end
end
end
class TypeFilter
def initialize number_type
@number_type = number_type
end
def filter_set_of_numbers numbers
case @number_type.to_s
when "complex"
numbers.select { |x| x.class.to_s == "Complex" }
when "real", "rational"
real_and_rational = numbers.select { |x| x.class.to_s == "Float" }
real_and_rational + numbers.select { |x| x.class.to_s == "Rational" }
when "integer"
numbers.select { |x| x.class.to_s == "Fixnum" }
end
end
end
class Filter
def initialize &block
@filter = block
end
def filter_set_of_numbers numbers
numbers.select { |x| @filter.call x.real.round }
end
end