Решение на Втора задача от Георги Костов

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

Към профила на Георги Костов

Резултати

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

Код

class Array
def unique_values
unique_elements = []
each do |element|
unique_elements << element unless unique_elements.include?(element)
end
unique_elements
end
end
class NumberSet
include Enumerable
def initialize
@elements = []
end
def size
@elements.size
end
def empty?
@elements.empty?
end
def <<(new_number)
@elements.push(new_number)
@elements = @elements.unique_values #uniq
self
end
def to_a
@elements
end
def each
@elements.each do |element|
yield(element)
end
self
end
def [](filter)
result = NumberSet.new
filter.each(@elements) { |element| result << element }
result
end
end
module SharedMethods
attr_reader :block
def each(elements)
@filtered = []
elements.each do |elem|
if block.call(elem) == true & not(@filtered.include?(elem))
yield(elem)
end
end
@filtered
end
def &(filter)
Filter.new { |n| self.block.call(n) and filter.block.call(n) }
end
def |(filter)
Filter.new { |n| self.block.call(n) or filter.block.call(n) }
end
end
class Filter
include SharedMethods
def initialize(&block)
@block = block
@filtered = []
@input = []
end
end
class SignFilter
include SharedMethods
def initialize(polarity)
@block = case polarity
when :positive then ->(n) { n > 0 }
when :non_positive then ->(n) { n <= 0 }
when :negative then ->(n) { n < 0 }
when :non_negative then ->(n) { n >= 0 }
end
@filtered = []
@input = []
end
end
class TypeFilter
include SharedMethods
def initialize(type)
@block = case type
when :integer then ->(n) { n.integer? }
when :real then ->(n) { n.real? and not(n.integer?) }
when :complex then ->(n) { n.is_a?(Complex) }
end
@input = []
@filtered = []
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-1hmdbup/solution.rb:40:in `block in each'
     # /tmp/d20141028-18133-1hmdbup/solution.rb:39:in `each'
     # /tmp/d20141028-18133-1hmdbup/solution.rb:39:in `each'
     # /tmp/d20141028-18133-1hmdbup/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.02323 seconds
24 examples, 1 failure

Failed examples:

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

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

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

+class Array
+
+ def unique_values
+ reversed = self.reverse
+ result = []
+ k = true
+ while k
+ k = reversed.pop
+ result << k unless result.include? k
+ end
+ result.pop
+ result
+ end
+
+end
+
+class NumberSet
+
+ include Enumerable
+
+ attr_writer :set
+ attr_reader :set
+
+ def initialize
+ @set = []
+ end
+
+ def size
+ @set.size
+ end
+
+ def empty?
+ return true if @set.size == 0
+ false
+ end
+
+ def <<(new)
+ @set.push(new)
+ @set = @set.unique_values
+ self
+ end
+
+ def to_a
+ @set
+ end
+
+ def each
+
+ k = @set.dup.reverse
+ l = k.pop
+ while l
+ yield l
+ l = k.pop
+ end
+ self
+ end
+
+ def [](filter)
+ filter.insert = @set
+ result = NumberSet.new
+ filter.to_a.each { |element| result << element }
+ result
+ end
+
+public
+ def print
+ puts "----NumberSet----"
+ puts "Content: #{set.to_s}"
+ puts "Size: #{size}"
+ puts "Empty? #{empty?}"
+ puts '-' * 30
+ end
+end
+
+module SharedMethods
+
+ def filtrate
+ @input.each do |element|
+ if @block.call element and not(@filtered.include? element)
+ @filtered << element
+ end
+ end
+ @filtered
+ end
+
+ def to_a
+ self.filtrate
+ end
+
+ def insert= set
+ if set.class.to_s == "Array"
+ @input = set
+ elsif set.class.to_s == "NumberSet"
+ @input = set.to_a
+ end
+ end
+
+ def print
+ puts '-' * 25
+ puts "Input: #{@input}"
+ puts "Filtered: #{filtrate}"
+ puts '-' * 25
+ end
+
+ def & filter
+ new_filter = Filter.new { |n| self.block.call n and filter.block.call n }
+ new_filter
+ end
+
+ def | filter
+ new_filter = Filter.new { |n| self.block.call n or filter.block.call n }
+ new_filter
+ end
+
+ def block
+ @block
+ end
+
+ def block= new_block
+ @block = block
+ end
+end
+
+class Filter
+
+ include SharedMethods
+
+ def initialize(&block)
+ @block = block
+ @filtered = []
+ @input = []
+ end
+
+end
+
+module NumberChecks
+
+ def positive?
+ return true if self > 0
+ false
+ end
+
+ def negative?
+ return true if self < 0
+ false
+ end
+
+ def non_positive?
+ return true if self <= 0
+ false
+ end
+
+ def non_negative?
+ return true if self >= 0
+ false
+ end
+
+end
+
+class Integer
+ include NumberChecks
+end
+
+class Float
+ include NumberChecks
+end
+
+class SignFilter
+
+# include Operators
+ include SharedMethods
+
+ def initialize polarity
+ @block = lambda { |n| (polarity.to_s + "?").to_sym.to_proc.call n }
+ @filtered = []
+ @input = []
+ end
+
+end
+
+class Numeric
+ def complex?
+ return true if self.class.to_s == "Complex"
+ false
+ end
+end
+
+class TypeFilter
+
+ #include Operators
+ include SharedMethods
+
+ def initialize(type)
+ case type
+ when :integer then @block = lambda { |n| n.integer? }
+ when :real then @block = lambda { |n| n.real? and not(n.integer?) }
+ when :complex then @block = lambda { |n| n.complex? }
+ end
+ @input = []
+ @filtered = []
+ end
+end

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

class Array
def unique_values
reversed = self.reverse
result = []
k = true
while k
k = reversed.pop
result << k unless result.include? k
end
result.pop
result
end
end
class NumberSet
include Enumerable
attr_writer :set
attr_reader :set
def initialize
@set = []
end
def size
@set.size
end
def empty?
return true if @set.size == 0
false
end
def <<(new)
@set.push(new)
@set = @set.unique_values
self
end
def to_a
@set
end
def each
k = @set.dup.reverse
l = k.pop
while l
yield l
l = k.pop
end
self
end
def [](filter)
filter.insert = @set
result = NumberSet.new
filter.to_a.each { |element| result << element }
result
end
public
def print
puts "----NumberSet----"
puts "Content: #{set.to_s}"
puts "Size: #{size}"
puts "Empty? #{empty?}"
puts '-' * 30
end
end
module SharedMethods
def filtrate
@input.each do |element|
if @block.call element and not(@filtered.include? element)
@filtered << element
end
end
@filtered
end
def to_a
self.filtrate
end
def insert= set
if set.class.to_s == "Array"
@input = set
elsif set.class.to_s == "NumberSet"
@input = set.to_a
end
end
def print
puts '-' * 25
puts "Input: #{@input}"
puts "Filtered: #{filtrate}"
puts '-' * 25
end
def & filter
new_filter = Filter.new { |n| self.block.call n and filter.block.call n }
new_filter
end
def | filter
new_filter = Filter.new { |n| self.block.call n or filter.block.call n }
new_filter
end
def block
@block
end
def block= new_block
@block = block
end
end
class Filter
include SharedMethods
def initialize(&block)
@block = block
@filtered = []
@input = []
end
end
module NumberChecks
def positive?
return true if self > 0
false
end
def negative?
return true if self < 0
false
end
def non_positive?
return true if self <= 0
false
end
def non_negative?
return true if self >= 0
false
end
end
class Integer
include NumberChecks
end
class Float
include NumberChecks
end
class SignFilter
-# include Operators
include SharedMethods
def initialize polarity
@block = lambda { |n| (polarity.to_s + "?").to_sym.to_proc.call n }
@filtered = []
@input = []
end
end
class Numeric
def complex?
return true if self.class.to_s == "Complex"
false
end
end
class TypeFilter
- #include Operators
include SharedMethods
def initialize(type)
case type
when :integer then @block = lambda { |n| n.integer? }
when :real then @block = lambda { |n| n.real? and not(n.integer?) }
when :complex then @block = lambda { |n| n.complex? }
end
@input = []
@filtered = []
end
end

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

class Array
def unique_values
reversed = self.reverse
result = []
k = true
while k
k = reversed.pop
result << k unless result.include? k
end
result.pop
result
end
end
class NumberSet
include Enumerable
attr_writer :set
attr_reader :set
def initialize
@set = []
end
def size
@set.size
end
def empty?
return true if @set.size == 0
false
end
def <<(new)
@set.push(new)
@set = @set.unique_values
self
end
def to_a
@set
end
def each
k = @set.dup.reverse
l = k.pop
while l
yield l
l = k.pop
end
self
end
def [](filter)
filter.insert = @set
result = NumberSet.new
filter.to_a.each { |element| result << element }
result
end
public
def print
puts "----NumberSet----"
puts "Content: #{set.to_s}"
puts "Size: #{size}"
puts "Empty? #{empty?}"
puts '-' * 30
end
end
module SharedMethods
def filtrate
@input.each do |element|
if @block.call element and not(@filtered.include? element)
@filtered << element
end
end
@filtered
end
def to_a
self.filtrate
end
def insert= set
if set.class.to_s == "Array"
@input = set
elsif set.class.to_s == "NumberSet"
@input = set.to_a
end
end
def print
puts '-' * 25
puts "Input: #{@input}"
puts "Filtered: #{filtrate}"
puts '-' * 25
end
def & filter
new_filter = Filter.new { |n| self.block.call n and filter.block.call n }
new_filter
end
def | filter
new_filter = Filter.new { |n| self.block.call n or filter.block.call n }
new_filter
end
def block
@block
end
def block= new_block
@block = block
end
end
class Filter
include SharedMethods
def initialize(&block)
@block = block
@filtered = []
@input = []
end
end
module NumberChecks
def positive?
return true if self > 0
false
end
def negative?
return true if self < 0
false
end
def non_positive?
return true if self <= 0
false
end
def non_negative?
return true if self >= 0
false
end
end
class Integer
include NumberChecks
end
class Float
include NumberChecks
end
+class Rational
+ include NumberChecks
+end
+
class SignFilter
include SharedMethods
def initialize polarity
@block = lambda { |n| (polarity.to_s + "?").to_sym.to_proc.call n }
@filtered = []
@input = []
end
end
class Numeric
def complex?
return true if self.class.to_s == "Complex"
false
end
end
class TypeFilter
include SharedMethods
def initialize(type)
case type
when :integer then @block = lambda { |n| n.integer? }
when :real then @block = lambda { |n| n.real? and not(n.integer?) }
when :complex then @block = lambda { |n| n.complex? }
end
@input = []
@filtered = []
end
end

Георги, коментари, бележки, напътствия, съвети, подредени не непременно по важност:

Проблеми с конвенциите

Като цяло си се придържал към конвенциите, споменати в нашето ръководство по стил, но на някои места имаш отклонения.

Например:

  • Не трябва да има празен ред веднага след началото на дефиниция на class Foo, както и непосредствено преди затварящия end.
  • Ред 11 и 12 не са правилно отместени навътре.
  • Дефиницията public на 65 ред трябва да е отместена едно ниво навътре, редом с def-овете и да има празен ред след нея. Освен това е безсмислена. Всички методи са public по подразбиране.
  • Имаш проблеми с отместването на filtrate метода.
  • На 87-ред по конвенция се изпуска self., защото няма смисъл от него.
  • Когато дефинираш методи, приемащи аргументи, се слагат кръгли скоби (напр. ред 105 и 110).
  • Хубаво е да има скоби около n на редове 106 и 111, защото е малко объркано иначе.

Дизайн, архитектура, стил, функционалност

  • Използвал си т. нар. "monkey patching" - добавяне/промяна на методи в съществуващи класове; в случая, Array#unique_values и промените в Integer, Float и Rational. Да, правят кода по-четим, но "замърсяват" всички класове с тези методи. Този тип monkey patching е много примамлива техника, но и същевременно нещо, с което много трябва да се внимава. Ако пишеш библиотека, е почти забранено. Ако пишеш твой проект, е донякъде окей (защото си мажеш твоите неща и твоето глобално пространство). Домашните принципно спадат към втората категория, но искаме да ви научим да внимавате с използването на monkey patching. Съвсем накратко, ако съществува достатъчно елегантно решение без monkey patching (каквото в случая - а и почти винаги - има), ще ви караме да не ползвате monkey patching. Така че съветът ми е да го премахнеш.
  • Допълнително за Array#unique_values - сигурен ли си, че няма такава вградена в Ruby функционалност? Провери ли документацията на Array, преди да го напишеш този метод, както сме казвали нееднократно на лекции?
  • Още повече, че по самата имплементация на гореописания метод имам много забележки. reverse е излишен; ако искаш да махаш елементи от единия край, няма значение кой край ползваш; а и има Array#shift, което е като pop, но от началото. k е лошо име на променлива; по-добре би било да се казва element, например. while и изобщо pop са излишни. Ето ти примерна имплементация на този метод (забележи идентацията ми и къде има нови редове):

      class Array
        def unique_values
          unique_elements = []
          each do |element|
            unique_elements << element unless unique_elements.include?(element)
          end
    
          unique_elements
        end
      end
    

    В Ruby има и клас Set, който би бил подходящ в случая. Но, пак, виж документацията на Array и прецени има ли смисъл ти да пишеш такъв метод.

  • attr_writer + attr_reader = attr_accessor

  • Защо на 25-ти ред кръщаваш променливата си @set, когато всъщност тя е списък? Защо не ползваш класа Set? :)
  • Има ли смисъл от return и if в empty?? Защо не просто @set.size == 0? А може би въпросният обект @set също има метод empty?, който би могъл да се ползва?
  • Ред 37 - какво е new? new_number, може би?
  • Ред 48 е празен и не трябва да го има.
  • В each на ред 47 - почти същите забележки имам като за unique_values - не ползвай еднобуквени имена като k, l; не ползвай while; не прави dup и reverse (още повече - dup би бил излишен, понеже reverse връща ново копие; което по случайност те е спасило от ужасна грешка в Array#unique_values, но явно е било случайно, понеже не си ползвал dup там, а тук си го ползвал); не ползвай pop.
  • Методите print не трябва да го има в окончателното ти решение. Ако трябваше да останат, щеше да е добре да ги кръстиш to_s или inspect, каквито са Ruby конвенциите в случая. Даже ако ги кръстиш inspect, irb ще ти показва този текст, когато резултатът от израз е NumberSet обект.
  • В метода NumberSet#[] на ред 58, дизайнът със setter-а insert= е лош. И защо изобщо се казва insert? Какво вмъква? Може да подходиш така - методът ти to_a на филтрите ми се струва излишен. Ползваш го само тук. На свой ред, filtrate се ползва само от to_a. Аз лично мисля, че filtrate спокойно може да се казва each и методът to_a да отпадне. Нещо повече, този метод filtrate (each) може да приема аргумент -- списъкът/нещото, по което да итерира (това, което сега подаваш през insert=). Така ще може да го ползваш по следния начин:

      def [](filter)
        result = NumberSet.new
        filter.each(@set) { |element| result << element }
        result
      end
    
  • За някои от методите в SharedMethods се разбрахме, че не са нужни. Другите може да ги сложиш в базов клас на филтрите, но тъй като не сме говорили за наследяване все още, и така е окей.

  • Променливата new_filter в методите & и | е напълно излишна. Трябва да се махне.
  • Няма причина да дефинираш ръчно getter и setter за @block. Ползвай клас-макросите attr_* за целта. Още повече, че да имаш setter за блок не е добра идея. И за капак - не мисля, че някъде изобщо ползваш този setter. Разкарай го.
  • Методите в модула NumberChecks според мен не трябва да ги има. Вж. бележката ми за monkey patching. Но ако ги имаше, щеше да е напълно окей да са само self > 0, например, без if, без return и без false на втори ред. Ако ползваш тези сравнения директно във филтрите си, няма да изгубиш четимост (нещо < 0 ми се струва достатъчно четимо), като същевременно ще спестиш 30-40 реда код и ще избегнеш monkey patching-а.
  • За да провериш от какъв клас е даден обект, няма нужда да обръщаш името на класа до низ. Може да ползваш само foo.class == Complex (например). Но най-добре ползвай foo.is_a?(Complex).
  • Аз бих подравнил вертикално then клаузите в case-а на ред 196. Освен това, може да е @block = case type ....

Твоето решение ме принуди да напиша 6к символа за коментар. Това е ако не рекорд, то поне в челната тройка :) Надявам се да ти е полезно.

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

class Array
-
def unique_values
- reversed = self.reverse
- result = []
- k = true
- while k
- k = reversed.pop
- result << k unless result.include? k
+ unique_elements = []
+ each do |element|
+ unique_elements << element unless unique_elements.include?(element)
end
- result.pop
- result
- end
+ unique_elements
+ end
end
class NumberSet
-
include Enumerable
- attr_writer :set
- attr_reader :set
-
def initialize
- @set = []
+ @elements = []
end
def size
- @set.size
+ @elements.size
end
def empty?
- return true if @set.size == 0
- false
+ @elements.empty?
end
- def <<(new)
- @set.push(new)
- @set = @set.unique_values
+ def <<(new_number)
+ @elements.push(new_number)
+ @elements = @elements.unique_values #
self
end
def to_a
- @set
+ @elements
end
def each
-
- k = @set.dup.reverse
- l = k.pop
- while l
- yield l
- l = k.pop
+ @elements.each do |element|
+ yield(element)
end
self
end
def [](filter)
- filter.insert = @set
result = NumberSet.new
- filter.to_a.each { |element| result << element }
+ filter.each(@elements) { |element| result << element }
result
end
-
-public
- def print
- puts "----NumberSet----"
- puts "Content: #{set.to_s}"
- puts "Size: #{size}"
- puts "Empty? #{empty?}"
- puts '-' * 30
- end
end
module SharedMethods
+ attr_reader :block
- def filtrate
- @input.each do |element|
- if @block.call element and not(@filtered.include? element)
- @filtered << element
- end
+ def each(elements)
+ @filtered = []
+ elements.each do |elem|
+ if block.call(elem) == true & not(@filtered.include?(elem))
+ yield(elem)
end
- @filtered
- end
-
- def to_a
- self.filtrate
- end
-
- def insert= set
- if set.class.to_s == "Array"
- @input = set
- elsif set.class.to_s == "NumberSet"
- @input = set.to_a
end
+ @filtered
end
- def print
- puts '-' * 25
- puts "Input: #{@input}"
- puts "Filtered: #{filtrate}"
- puts '-' * 25
+ def &(filter)
+ Filter.new { |n| self.block.call(n) and filter.block.call(n) }
end
- def & filter
- new_filter = Filter.new { |n| self.block.call n and filter.block.call n }
- new_filter
+ def |(filter)
+ Filter.new { |n| self.block.call(n) or filter.block.call(n) }
end
-
- def | filter
- new_filter = Filter.new { |n| self.block.call n or filter.block.call n }
- new_filter
- end
-
- def block
- @block
- end
-
- def block= new_block
- @block = block
- end
end
class Filter
-
include SharedMethods
def initialize(&block)
@block = block
@filtered = []
@input = []
end
-
end
-module NumberChecks
-
- def positive?
- return true if self > 0
- false
- end
-
- def negative?
- return true if self < 0
- false
- end
-
- def non_positive?
- return true if self <= 0
- false
- end
-
- def non_negative?
- return true if self >= 0
- false
- end
-
-end
-
-class Integer
- include NumberChecks
-end
-
-class Float
- include NumberChecks
-end
-
-class Rational
- include NumberChecks
-end
-
class SignFilter
-
include SharedMethods
- def initialize polarity
- @block = lambda { |n| (polarity.to_s + "?").to_sym.to_proc.call n }
+ def initialize(polarity)
+ @block = case polarity
+ when :positive then lambda { |n| n > 0 }
+ when :non_positive then lambda { |n| n <= 0 }
+ when :negative then lambda { |n| n < 0 }
+ when :non_negative then lambda { |n| n >= 0 }
+ end
@filtered = []
@input = []
end
-
end
class Numeric
def complex?
- return true if self.class.to_s == "Complex"
+ return true if self.is_a?(Complex)
false
end
end
class TypeFilter
-
include SharedMethods
def initialize(type)
- case type
- when :integer then @block = lambda { |n| n.integer? }
- when :real then @block = lambda { |n| n.real? and not(n.integer?) }
- when :complex then @block = lambda { |n| n.complex? }
+ @block = case type
+ when :integer then lambda { |n| n.integer? }
+ when :real then lambda { |n| n.real? and not(n.integer?) }
+ when :complex then lambda { |n| n.complex? }
end
@input = []
@filtered = []
end
end

Георги обнови решението на 27.10.2014 00:42 (преди около 10 години)

class Array
def unique_values
unique_elements = []
each do |element|
unique_elements << element unless unique_elements.include?(element)
end
unique_elements
end
end
class NumberSet
include Enumerable
def initialize
@elements = []
end
def size
@elements.size
end
def empty?
@elements.empty?
end
def <<(new_number)
@elements.push(new_number)
- @elements = @elements.unique_values #
+ @elements = @elements.unique_values #uniq
+
self
end
def to_a
@elements
end
def each
@elements.each do |element|
yield(element)
end
+
self
end
def [](filter)
result = NumberSet.new
filter.each(@elements) { |element| result << element }
+
result
end
end
module SharedMethods
attr_reader :block
def each(elements)
@filtered = []
elements.each do |elem|
if block.call(elem) == true & not(@filtered.include?(elem))
yield(elem)
end
end
+
@filtered
end
def &(filter)
Filter.new { |n| self.block.call(n) and filter.block.call(n) }
end
def |(filter)
Filter.new { |n| self.block.call(n) or filter.block.call(n) }
end
end
class Filter
include SharedMethods
def initialize(&block)
@block = block
@filtered = []
@input = []
end
end
class SignFilter
include SharedMethods
def initialize(polarity)
@block = case polarity
- when :positive then lambda { |n| n > 0 }
- when :non_positive then lambda { |n| n <= 0 }
- when :negative then lambda { |n| n < 0 }
- when :non_negative then lambda { |n| n >= 0 }
- end
+ when :positive then ->(n) { n > 0 }
+ when :non_positive then ->(n) { n <= 0 }
+ when :negative then ->(n) { n < 0 }
+ when :non_negative then ->(n) { n >= 0 }
+ end
@filtered = []
@input = []
end
end
class Numeric
def complex?
- return true if self.is_a?(Complex)
- false
+ self.is_a?(Complex)
end
end
class TypeFilter
include SharedMethods
def initialize(type)
@block = case type
- when :integer then lambda { |n| n.integer? }
- when :real then lambda { |n| n.real? and not(n.integer?) }
- when :complex then lambda { |n| n.complex? }
- end
+ when :integer then ->(n) { n.integer? }
+ when :real then ->(n) { n.real? and not(n.integer?) }
+ when :complex then ->(n) { n.complex? }
+ end
@input = []
@filtered = []
end
end

Георги обнови решението на 27.10.2014 01:27 (преди около 10 години)

class Array
def unique_values
unique_elements = []
each do |element|
unique_elements << element unless unique_elements.include?(element)
end
unique_elements
end
end
class NumberSet
include Enumerable
def initialize
@elements = []
end
def size
@elements.size
end
def empty?
@elements.empty?
end
def <<(new_number)
@elements.push(new_number)
@elements = @elements.unique_values #uniq
self
end
def to_a
@elements
end
def each
@elements.each do |element|
yield(element)
end
self
end
def [](filter)
result = NumberSet.new
filter.each(@elements) { |element| result << element }
result
end
end
module SharedMethods
attr_reader :block
def each(elements)
@filtered = []
elements.each do |elem|
if block.call(elem) == true & not(@filtered.include?(elem))
yield(elem)
end
end
@filtered
end
def &(filter)
Filter.new { |n| self.block.call(n) and filter.block.call(n) }
end
def |(filter)
Filter.new { |n| self.block.call(n) or filter.block.call(n) }
end
end
class Filter
include SharedMethods
def initialize(&block)
@block = block
@filtered = []
@input = []
end
end
class SignFilter
include SharedMethods
def initialize(polarity)
@block = case polarity
when :positive then ->(n) { n > 0 }
when :non_positive then ->(n) { n <= 0 }
when :negative then ->(n) { n < 0 }
when :non_negative then ->(n) { n >= 0 }
end
@filtered = []
@input = []
end
end
-class Numeric
- def complex?
- self.is_a?(Complex)
- end
-end
-
class TypeFilter
include SharedMethods
def initialize(type)
@block = case type
when :integer then ->(n) { n.integer? }
when :real then ->(n) { n.real? and not(n.integer?) }
- when :complex then ->(n) { n.complex? }
+ when :complex then ->(n) { n.is_a?(Complex) }
end
@input = []
@filtered = []
end
end