Решение на Втора задача от Георги Урумов

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

Към профила на Георги Урумов

Резултати

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

Код

class Item
attr_reader :status, :description, :priority, :tags
def initialize(status, description, priority, tags)
@status = status.downcase.to_sym
@description = description
@priority = priority.downcase.to_sym
@tags = tags.split(", ")
end
def ==(other)
@status == other.status and
@description == other.description and
@priority == other.priority and
@tags == other.tags
end
alias eql? ==
def hash
[@status, @description, @priority, @tags].hash
end
end
class TodoList
include Enumerable
attr_reader :tasks
def initialize(tasks)
@tasks = tasks
end
def self.parse(text)
tasks = text.lines.each.map do |l|
Item.new l.split('|')[0].strip, l.split('|')[1].strip,
l.split('|')[2].strip, l.split('|')[3].strip
end
TodoList.new tasks
end
def each(&block)
@tasks.each(&block)
end
def filter(criteria)
TodoList.new @tasks.select { |task| criteria.is_like? task }
end
def adjoin(other)
adjoinedList = (@tasks + other.tasks).uniq
TodoList.new adjoinedList
end
def tasks_todo
self.filter(Criteria.status(:todo)).tasks.size
end
def tasks_in_progress
self.filter(Criteria.status(:current)).tasks.size
end
def tasks_completed
self.filter(Criteria.status(:done)).tasks.size
end
def completed?
@tasks.size == tasks_completed
end
end
class Criteria
def self.status(status)
Matcher.new :status, status.downcase
end
def self.priority(priority)
Matcher.new :priority, priority.downcase
end
def self.tags(tags)
Matcher.new :tags, tags
end
end
class Matcher
def initialize(attr, value)
@attr = attr
@value = value
end
def is_like?(other)
attr = other.send(@attr)
return attr == @value unless attr.is_a? Enumerable
return @value.all? { |a| attr.member? a }
end
def &(other)
ComboMatcher.new "and", self, other
end
def |(other)
ComboMatcher.new "or", self, other
end
def !
ComboMatcher.new "not", self, nil
end
end
class ComboMatcher
def initialize(operation, left_matcher, right_matcher)
@operation = operation
@left = left_matcher
@right = right_matcher
end
def is_like?(other)
case @operation
when "or" then @left.is_like?(other) or @right.is_like?(other)
when "and" then @left.is_like?(other) and @right.is_like?(other)
when "not" then not @left.is_like?(other)
end
end
end

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

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

Failures:

  1) TodoList supports complex filters combination
     Failure/Error: !Criteria.tags(['development'])
     NoMethodError:
       undefined method `|' for #<ComboMatcher:0xb9e76c10>
     # /tmp/d20131107-4393-r42euc/spec.rb:84: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.04234 seconds
22 examples, 1 failure

Failed examples:

rspec /tmp/d20131107-4393-r42euc/spec.rb:80 # TodoList supports complex filters combination

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

Георги обнови решението на 06.11.2013 15:22 (преди около 11 години)

+class Item
+ attr_reader :status, :description, :priority, :tags
+
+ def initialize(status, description, priority, tags)
+ @status = status.downcase.to_sym
+ @description = description
+ @priority = priority.downcase.to_sym
+ @tags = tags.split(", ")
+ end
+
+ def ==(other)
+ @status == other.status and
+ @description == other.description and
+ @priority == other.priority and
+ @tags == other.tags
+ end
+
+ alias eql? ==
+
+ def hash
+ [@status, @description, @priority, @tags].hash
+ end
+end
+
+class TodoList
+ include Enumerable
+ attr_reader :tasks
+
+ def initialize(tasks)
+ @tasks = tasks
+ end
+
+ def self.parse(text)
+ tasks = text.lines.each.map do |l|
+ Item.new l.split('|')[0].strip, l.split('|')[1].strip,
+ l.split('|')[2].strip, l.split('|')[3].strip
+ end
+
+ TodoList.new tasks
+ end
+
+ def each(&block)
+ @tasks.each(&block)
+ end
+
+ def filter(criteria)
+ TodoList.new @tasks.select { |task| criteria.is_like? task }
+ end
+
+ def adjoin(other)
+ adjoinedList = (@tasks + other.tasks).uniq
+ TodoList.new adjoinedList
+ end
+
+ def tasks_todo
+ self.filter(Criteria.status(:todo)).tasks.size
+ end
+
+ def tasks_in_progress
+ self.filter(Criteria.status(:current)).tasks.size
+ end
+
+ def tasks_completed
+ self.filter(Criteria.status(:done)).tasks.size
+ end
+
+ def completed?
+ @tasks.size == tasks_completed
+ end
+end
+
+class Criteria
+ def self.status(status)
+ Matcher.new :status, status.downcase
+ end
+
+ def self.priority(priority)
+ Matcher.new :priority, priority.downcase
+ end
+
+ def self.tags(tags)
+ Matcher.new :tags, tags
+ end
+end
+
+class Matcher
+ def initialize(attr, value)
+ @attr = attr
+ @value = value
+ end
+
+ def is_like?(other)
+ attr = other.send(@attr)
+ return attr == @value unless attr.is_a? Enumerable
+ return value.all? { |a| attr.member? a }
+ end
+
+ def &(other)
+ ComboMatcher.new "and", self, other
+ end
+
+ def |(other)
+ ComboMatcher.new "or", self, other
+ end
+
+ def !
+ ComboMatcher.new "not", self, nil
+ end
+end
+
+class ComboMatcher
+ def initialize(operation, left_matcher, right_matcher)
+ @operation = operation
+ @left = left_matcher
+ @right = right_matcher
+ end
+
+ def is_like?(other)
+ case @operation
+ when "or" then @left.is_like?(other) or @right.is_like?(other)
+ when "and" then @left.is_like?(other) and @right.is_like?(other)
+ when "not" then not @left.is_like?(other)
+ end
+ end
+end

Георги обнови решението на 06.11.2013 17:29 (преди около 11 години)

class Item
attr_reader :status, :description, :priority, :tags
def initialize(status, description, priority, tags)
@status = status.downcase.to_sym
@description = description
@priority = priority.downcase.to_sym
@tags = tags.split(", ")
end
def ==(other)
@status == other.status and
@description == other.description and
@priority == other.priority and
@tags == other.tags
end
alias eql? ==
def hash
[@status, @description, @priority, @tags].hash
end
end
class TodoList
include Enumerable
attr_reader :tasks
def initialize(tasks)
@tasks = tasks
end
def self.parse(text)
tasks = text.lines.each.map do |l|
Item.new l.split('|')[0].strip, l.split('|')[1].strip,
l.split('|')[2].strip, l.split('|')[3].strip
end
TodoList.new tasks
end
def each(&block)
@tasks.each(&block)
end
def filter(criteria)
TodoList.new @tasks.select { |task| criteria.is_like? task }
end
def adjoin(other)
adjoinedList = (@tasks + other.tasks).uniq
TodoList.new adjoinedList
end
def tasks_todo
self.filter(Criteria.status(:todo)).tasks.size
end
def tasks_in_progress
self.filter(Criteria.status(:current)).tasks.size
end
def tasks_completed
self.filter(Criteria.status(:done)).tasks.size
end
def completed?
@tasks.size == tasks_completed
end
end
class Criteria
def self.status(status)
Matcher.new :status, status.downcase
end
def self.priority(priority)
Matcher.new :priority, priority.downcase
end
def self.tags(tags)
Matcher.new :tags, tags
end
end
class Matcher
def initialize(attr, value)
@attr = attr
@value = value
end
def is_like?(other)
attr = other.send(@attr)
return attr == @value unless attr.is_a? Enumerable
- return value.all? { |a| attr.member? a }
+ return @value.all? { |a| attr.member? a }
end
def &(other)
ComboMatcher.new "and", self, other
end
def |(other)
ComboMatcher.new "or", self, other
end
def !
ComboMatcher.new "not", self, nil
end
end
class ComboMatcher
def initialize(operation, left_matcher, right_matcher)
@operation = operation
@left = left_matcher
@right = right_matcher
end
def is_like?(other)
case @operation
when "or" then @left.is_like?(other) or @right.is_like?(other)
when "and" then @left.is_like?(other) and @right.is_like?(other)
when "not" then not @left.is_like?(other)
end
end
end