Решение на Втора задача от Никола Величков

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

Към профила на Никола Величков

Резултати

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

Код

class TodoList
include Enumerable
attr_reader :tasks
def self.parse text
self.new(Parser.to_array(text))
end
def filter criteria
#You can use Filter.display_all to print by passing TodoList
TodoList.new(Filter.filter(criteria,tasks))
end
def initialize tasks
@tasks = tasks
end
def adjoin todoList
TodoList.new(self.tasks | todoList.tasks)
end
def tasks_todo
tasks.map {|task| task.status == :todo }.count
end
def tasks_in_progress
tasks.map {|task| task.status == :current }.count
end
def tasks_completed
tasks.map {|task| task.status == :done }.count
end
def completed?
self.tasks_completed == tasks.count
end
end
class Filter
def self.filter criteria, tasks
criteria.criteria.call(tasks)
end
def self.display_all todoList
tasks = todoList.tasks
tasks.each_with_index.map {|t,i| display_task t,i}
end
def self.display_task t,num
print "Task " + num.to_s + p_status(t) + p_desc(t) + p_prior(t) + p_tags(t)
end
def self.p_status task
"\n" + 'status: ' + task.status.to_s + "\n"
end
def self.p_desc task
'description: ' + task.description + "\n"
end
def self.p_prior task
'priority: ' + task.priority.to_s + "\n"
end
def self.p_tags task
'hashtags: ' + task.tags.join(',') + "\n"
end
end
class Task
attr_reader :status, :description, :priority, :tags
def initialize(status,description,priority,tags)
@status = status
@description = description
@priority = priority
@tags = tags
end
end
class Parser
def self.to_array text
procedure = Proc.new {|item| item.strip! }
text.each_line.map {|line| parse_task line.split('|').map &procedure}
end
private
def self.parse_status text
text.downcase.to_sym
end
def self.parse_priority text
text.downcase.to_sym
end
def self.parse_tags text
text.split(',').map {|item| item.strip}
end
def self.parse_task text
status = parse_status text[0]
priority = parse_priority text[2]
tags = parse_tags text[3]
Task.new(status,text[1],priority,tags)
end
end
class Criteria
attr_reader :criteria
def initialize criteria
@criteria = criteria
end
def self.status status
procedure = Proc.new {|task| task.status == status}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def self.priority priority
procedure = Proc.new {|task| task.priority == priority}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def self.tags tags
procedure = Proc.new {|task| task.tags.each_cons(tags.size).include? tags}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def &(other)
Criteria.new Proc.new { |tasks| criteria.(tasks) & other.criteria.(tasks)}
end
def |(other)
Criteria.new Proc.new { |tasks| criteria.(tasks) | other.criteria.(tasks)}
end
def !
Criteria.new Proc.new { |tasks| tasks - criteria.(tasks)}
end
end

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

FFFFFFFFFFFFFFFFFFFFF.

Failures:

  1) TodoList filters tasks by status
     Failure/Error: todo_list.filter(Criteria.status :done).map(&:description).should =~ [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb955bf54>
     # /tmp/d20131107-4393-li3qcl/spec.rb:19:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:19: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) TodoList filters tasks by priority
     Failure/Error: todo_list.filter(Criteria.priority :high).map(&:description).should =~ [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb9559f9c>
     # /tmp/d20131107-4393-li3qcl/spec.rb:26:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:26: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) TodoList filters tasks by tag
     Failure/Error: todo_list.filter(Criteria.tags %w[food]).map(&:description).should =~ ['Eat spaghetti.']
     NoMethodError:
       undefined method `each' for #<TodoList:0xb954f628>
     # /tmp/d20131107-4393-li3qcl/spec.rb:36:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:36: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) TodoList filters tasks by multiple tags
     Failure/Error: todo_list.filter(Criteria.tags %w[development ruby]).map(&:description).should =~ [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb954cfa4>
     # /tmp/d20131107-4393-li3qcl/spec.rb:40:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:40: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) TodoList filtering by multiple tags matches only tasks with all the tags
     Failure/Error: todo_list.filter(Criteria.tags %w[development FMI]).map(&:description).should =~ ['Do the 5th Ruby challenge.']
     NoMethodError:
       undefined method `each' for #<TodoList:0xb95c1278 @tasks=[]>
     # /tmp/d20131107-4393-li3qcl/spec.rb:47:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:47: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) TodoList supports a conjuction of filters
     Failure/Error: filtered.map(&:description).should =~ ['Eat spaghetti.', 'Destroy Facebook and Google.', 'Occupy Sofia University.']
     NoMethodError:
       undefined method `each' for #<TodoList:0xb967a534>
     # /tmp/d20131107-4393-li3qcl/spec.rb:52:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:52: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) TodoList supports a disjunction of filters
     Failure/Error: filtered.map(&:description).should =~ [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb967848c>
     # /tmp/d20131107-4393-li3qcl/spec.rb:57:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:57: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)>'

  8) TodoList supports a negation of filters
     Failure/Error: filtered.map(&:description).should =~ [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb957a260>
     # /tmp/d20131107-4393-li3qcl/spec.rb:67:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:67: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)>'

  9) TodoList supports simple filters combination
     Failure/Error: filtered.map(&:description).should =~ ['Eat spaghetti.', 'Destroy Facebook and Google.', 'Occupy Sofia University.']
     NoMethodError:
       undefined method `each' for #<TodoList:0xb944ee68>
     # /tmp/d20131107-4393-li3qcl/spec.rb:77:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:77: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)>'

  10) TodoList supports complex filters combination
     Failure/Error: filtered.map(&:description).should =~ [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb94478e8>
     # /tmp/d20131107-4393-li3qcl/spec.rb:86:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:86: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)>'

  11) TodoList can be adjoined with another to-do list
     Failure/Error: adjoined.count.should eq 3
     NoMethodError:
       undefined method `each' for #<TodoList:0xb9444148>
     # /tmp/d20131107-4393-li3qcl/spec.rb:101:in `count'
     # /tmp/d20131107-4393-li3qcl/spec.rb:101: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)>'

  12) TodoList constructs an object for each task
     Failure/Error: task = todo_list.filter(Criteria.tags ['health']).first
     NoMethodError:
       undefined method `each' for #<TodoList:0xb944122c>
     # /tmp/d20131107-4393-li3qcl/spec.rb:110:in `first'
     # /tmp/d20131107-4393-li3qcl/spec.rb:110: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)>'

  13) TodoList returns the number of the tasks todo
     Failure/Error: todo_list.tasks_todo.should eq 5
       
       expected: 5
            got: 9
       
       (compared using ==)
     # /tmp/d20131107-4393-li3qcl/spec.rb:119: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)>'

  14) TodoList returns the number of the tasks in progress
     Failure/Error: todo_list.tasks_in_progress.should eq 2
       
       expected: 2
            got: 9
       
       (compared using ==)
     # /tmp/d20131107-4393-li3qcl/spec.rb:123: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)>'

  15) TodoList returns the number of the completed tasks
     Failure/Error: todo_list.tasks_completed.should eq 2
       
       expected: 2
            got: 9
       
       (compared using ==)
     # /tmp/d20131107-4393-li3qcl/spec.rb:127: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)>'

  16) TodoList checks if all tasks are completed
     Failure/Error: todo_list.completed?.should eq false
       
       expected: false
            got: true
       
       (compared using ==)
     # /tmp/d20131107-4393-li3qcl/spec.rb:131: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)>'

  17) TodoList doesn't modify the to-do list when filtering
     Failure/Error: todo_list.should have(text_input.lines.count).items
     NoMethodError:
       undefined method `each' for #<TodoList:0xb942cea8>
     # /tmp/d20131107-4393-li3qcl/spec.rb:137: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)>'

  18) TodoList implements Enumerable
     Failure/Error: todo_list.should respond_to :each
       expected #<TodoList:0xb9420fe0 @tasks=[#<Task:0xb9421e18 @status=:todo, @description="Eat spaghetti.", @priority=:high, @tags=["food", "happiness"]>, #<Task:0xb9421c88 @status=:todo, @description="Get 8 hours of sleep.", @priority=:low, @tags=["health"]>, #<Task:0xb9421a94 @status=:current, @description="Party animal.", @priority=:normal, @tags=["socialization"]>, #<Task:0xb94218f0 @status=:current, @description="Grok Ruby.", @priority=:high, @tags=["development", "ruby"]>, #<Task:0xb9421788 @status=:done, @description="Have some tea.", @priority=:normal, @tags=[]>, #<Task:0xb94215a8 @status=:todo, @description="Destroy Facebook and Google.", @priority=:high, @tags=["save humanity", "conspiracy"]>, #<Task:0xb942133c @status=:done, @description="Do the 5th Ruby challenge.", @priority=:high, @tags=["ruby course", "FMI", "development", "ruby"]>, #<Task:0xb94211e8 @status=:todo, @description="Find missing socks.", @priority=:low, @tags=[]>, #<Task:0xb9421008 @status=:todo, @description="Occupy Sofia University.", @priority=:high, @tags=["#ДАНСwithMe", "#occupysu", "#оставка"]>]> to respond to :each
     # /tmp/d20131107-4393-li3qcl/spec.rb:141: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)>'

  19) TodoList contains tasks with the neccessary interface
     Failure/Error: task = todo_list.first
     NoMethodError:
       undefined method `each' for #<TodoList:0xb9417274>
     # /tmp/d20131107-4393-li3qcl/spec.rb:146:in `first'
     # /tmp/d20131107-4393-li3qcl/spec.rb:146: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)>'

  20) TodoList tasks have an array of tags
     Failure/Error: todo_list.first.tags.should be_an Array
     NoMethodError:
       undefined method `each' for #<TodoList:0xb940ea48>
     # /tmp/d20131107-4393-li3qcl/spec.rb:155:in `first'
     # /tmp/d20131107-4393-li3qcl/spec.rb:155: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)>'

  21) TodoList preserves the order of tasks
     Failure/Error: todo_list.map(&:description).should eq [
     NoMethodError:
       undefined method `each' for #<TodoList:0xb93fe508>
     # /tmp/d20131107-4393-li3qcl/spec.rb:159:in `map'
     # /tmp/d20131107-4393-li3qcl/spec.rb:159: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.03722 seconds
22 examples, 21 failures

Failed examples:

rspec /tmp/d20131107-4393-li3qcl/spec.rb:18 # TodoList filters tasks by status
rspec /tmp/d20131107-4393-li3qcl/spec.rb:25 # TodoList filters tasks by priority
rspec /tmp/d20131107-4393-li3qcl/spec.rb:35 # TodoList filters tasks by tag
rspec /tmp/d20131107-4393-li3qcl/spec.rb:39 # TodoList filters tasks by multiple tags
rspec /tmp/d20131107-4393-li3qcl/spec.rb:46 # TodoList filtering by multiple tags matches only tasks with all the tags
rspec /tmp/d20131107-4393-li3qcl/spec.rb:50 # TodoList supports a conjuction of filters
rspec /tmp/d20131107-4393-li3qcl/spec.rb:55 # TodoList supports a disjunction of filters
rspec /tmp/d20131107-4393-li3qcl/spec.rb:65 # TodoList supports a negation of filters
rspec /tmp/d20131107-4393-li3qcl/spec.rb:75 # TodoList supports simple filters combination
rspec /tmp/d20131107-4393-li3qcl/spec.rb:80 # TodoList supports complex filters combination
rspec /tmp/d20131107-4393-li3qcl/spec.rb:96 # TodoList can be adjoined with another to-do list
rspec /tmp/d20131107-4393-li3qcl/spec.rb:109 # TodoList constructs an object for each task
rspec /tmp/d20131107-4393-li3qcl/spec.rb:118 # TodoList returns the number of the tasks todo
rspec /tmp/d20131107-4393-li3qcl/spec.rb:122 # TodoList returns the number of the tasks in progress
rspec /tmp/d20131107-4393-li3qcl/spec.rb:126 # TodoList returns the number of the completed tasks
rspec /tmp/d20131107-4393-li3qcl/spec.rb:130 # TodoList checks if all tasks are completed
rspec /tmp/d20131107-4393-li3qcl/spec.rb:135 # TodoList doesn't modify the to-do list when filtering
rspec /tmp/d20131107-4393-li3qcl/spec.rb:140 # TodoList implements Enumerable
rspec /tmp/d20131107-4393-li3qcl/spec.rb:145 # TodoList contains tasks with the neccessary interface
rspec /tmp/d20131107-4393-li3qcl/spec.rb:154 # TodoList tasks have an array of tags
rspec /tmp/d20131107-4393-li3qcl/spec.rb:158 # TodoList preserves the order of tasks

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

Никола обнови решението на 06.11.2013 15:21 (преди над 10 години)

+class TodoList
+ include Enumerable
+ attr_reader :tasks
+
+ def self.parse text
+ self.new(Parser.to_array(text))
+ end
+
+ def filter criteria
+ TodoList.new(Filter.filter(criteria,tasks))
+ end
+
+ def initialize tasks
+ @tasks = tasks
+ end
+
+ def adjoin todoList
+ TodoList.new(self.tasks | todoList.tasks)
+ end
+
+ def tasks_todo
+ tasks.map {|task| task.status == :todo }.count
+ end
+
+ def tasks_in_progress
+ tasks.map {|task| task.status == :current }.count
+ end
+
+ def tasks_completed
+ tasks.map {|task| task.status == :done }.count
+ end
+
+ def completed?
+ self.tasks_completed == tasks.count
+ end
+end
+
+class Filter
+ def self.filter criteria, tasks
+ criteria.criteria.call(tasks)
+ end
+ def self.display_all list
+ list.map {|t| 'Task:\n' + p_status(t) + p_desc(t) + p_prior(t) + p_tags(t)}
+ end
+ def self.p_status task
+ 'status: ' + task.status.to_s
+ end
+ def self.p_desc task
+ 'description: ' + task.description
+ end
+ def self.p_prior task
+ 'priority: ' + task.priority.to_s
+ end
+ def self.p_tags task
+ 'tags: ' + task.tags.join(',')
+ end
+end
+
+class Task
+ attr_reader :status, :description, :priority, :tags
+
+ def initialize(status,description,priority,tags)
+ @status = status
+ @description = description
+ @priority = priority
+ @tags = tags
+ end
+end
+
+class Parser
+ def self.to_array text
+ procedure = Proc.new {|item| item.strip! }
+ text.each_line.map {|line| parse_task line.split('|').map &procedure}
+ end
+
+ private
+
+ def self.parse_status text
+ text.downcase.to_sym
+ end
+ def self.parse_priority text
+ text.downcase.to_sym
+ end
+ def self.parse_tags text
+ text.split(',').map {|item| item.strip!}
+ end
+ def self.parse_task text
+ status = parse_status text[0]
+ priority = parse_priority text[2]
+ tags = parse_tags text[3]
+ Task.new(status,text[1],priority,tags)
+ end
+end
+
+class Criteria
+ attr_reader :criteria
+
+ def initialize criteria
+ @criteria = criteria
+ end
+
+ def self.status status
+ procedure = Proc.new {|task| task.status == status}
+ self.new Proc.new { |tasks| tasks.select &procedure}
+ end
+
+ def self.priority priority
+ procedure = Proc.new {|task| task.priority == priority}
+ self.new Proc.new { |tasks| tasks.select &procedure}
+ end
+
+ def self.tags tags
+ procedure = Proc.new {|task| task.tags.each_cons(tags.size).include? tags}
+ self.new Proc.new { |tasks| tasks.select &procedure}
+ end
+
+ def &(other)
+ Criteria.new Proc.new { |tasks| criteria.(tasks) & other.criteria.(tasks)}
+ end
+
+ def |(other)
+ Criteria.new Proc.new { |tasks| criteria.(tasks) | other.criteria.(tasks)}
+ end
+
+ def !
+ Criteria.new Proc.new { |tasks| tasks - criteria.(tasks)}
+ end
+end

Никола обнови решението на 06.11.2013 16:47 (преди над 10 години)

class TodoList
include Enumerable
attr_reader :tasks
def self.parse text
self.new(Parser.to_array(text))
end
def filter criteria
TodoList.new(Filter.filter(criteria,tasks))
end
def initialize tasks
@tasks = tasks
end
def adjoin todoList
TodoList.new(self.tasks | todoList.tasks)
end
def tasks_todo
tasks.map {|task| task.status == :todo }.count
end
def tasks_in_progress
tasks.map {|task| task.status == :current }.count
end
def tasks_completed
tasks.map {|task| task.status == :done }.count
end
def completed?
self.tasks_completed == tasks.count
end
end
class Filter
def self.filter criteria, tasks
criteria.criteria.call(tasks)
end
def self.display_all list
list.map {|t| 'Task:\n' + p_status(t) + p_desc(t) + p_prior(t) + p_tags(t)}
end
def self.p_status task
'status: ' + task.status.to_s
end
def self.p_desc task
'description: ' + task.description
end
def self.p_prior task
'priority: ' + task.priority.to_s
end
def self.p_tags task
'tags: ' + task.tags.join(',')
end
end
class Task
attr_reader :status, :description, :priority, :tags
def initialize(status,description,priority,tags)
@status = status
@description = description
@priority = priority
@tags = tags
end
end
class Parser
def self.to_array text
procedure = Proc.new {|item| item.strip! }
text.each_line.map {|line| parse_task line.split('|').map &procedure}
end
private
def self.parse_status text
text.downcase.to_sym
end
def self.parse_priority text
text.downcase.to_sym
end
def self.parse_tags text
- text.split(',').map {|item| item.strip!}
+ text.split(',').map {|item| item.strip}
end
def self.parse_task text
status = parse_status text[0]
priority = parse_priority text[2]
tags = parse_tags text[3]
Task.new(status,text[1],priority,tags)
end
end
class Criteria
attr_reader :criteria
def initialize criteria
@criteria = criteria
end
def self.status status
procedure = Proc.new {|task| task.status == status}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def self.priority priority
procedure = Proc.new {|task| task.priority == priority}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def self.tags tags
procedure = Proc.new {|task| task.tags.each_cons(tags.size).include? tags}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def &(other)
Criteria.new Proc.new { |tasks| criteria.(tasks) & other.criteria.(tasks)}
end
def |(other)
Criteria.new Proc.new { |tasks| criteria.(tasks) | other.criteria.(tasks)}
end
def !
Criteria.new Proc.new { |tasks| tasks - criteria.(tasks)}
end
end

Никола обнови решението на 06.11.2013 17:05 (преди над 10 години)

class TodoList
include Enumerable
attr_reader :tasks
def self.parse text
self.new(Parser.to_array(text))
end
def filter criteria
+ #You can use Filter.display_all to print by passing TodoList
TodoList.new(Filter.filter(criteria,tasks))
end
def initialize tasks
@tasks = tasks
end
def adjoin todoList
TodoList.new(self.tasks | todoList.tasks)
end
def tasks_todo
tasks.map {|task| task.status == :todo }.count
end
def tasks_in_progress
tasks.map {|task| task.status == :current }.count
end
def tasks_completed
tasks.map {|task| task.status == :done }.count
end
def completed?
self.tasks_completed == tasks.count
end
end
class Filter
def self.filter criteria, tasks
criteria.criteria.call(tasks)
end
- def self.display_all list
- list.map {|t| 'Task:\n' + p_status(t) + p_desc(t) + p_prior(t) + p_tags(t)}
+ def self.display_all todoList
+ tasks = todoList.tasks
+ tasks.each_with_index.map {|t,i| display_task t,i}
end
+ def self.display_task t,num
+ print "Task " + num.to_s + p_status(t) + p_desc(t) + p_prior(t) + p_tags(t)
+ end
def self.p_status task
- 'status: ' + task.status.to_s
+ "\n" + 'status: ' + task.status.to_s + "\n"
end
def self.p_desc task
- 'description: ' + task.description
+ 'description: ' + task.description + "\n"
end
def self.p_prior task
- 'priority: ' + task.priority.to_s
+ 'priority: ' + task.priority.to_s + "\n"
end
def self.p_tags task
- 'tags: ' + task.tags.join(',')
+ 'hashtags: ' + task.tags.join(',') + "\n"
end
end
class Task
attr_reader :status, :description, :priority, :tags
def initialize(status,description,priority,tags)
@status = status
@description = description
@priority = priority
@tags = tags
end
end
class Parser
def self.to_array text
procedure = Proc.new {|item| item.strip! }
text.each_line.map {|line| parse_task line.split('|').map &procedure}
end
private
def self.parse_status text
text.downcase.to_sym
end
def self.parse_priority text
text.downcase.to_sym
end
def self.parse_tags text
text.split(',').map {|item| item.strip}
end
def self.parse_task text
status = parse_status text[0]
priority = parse_priority text[2]
tags = parse_tags text[3]
Task.new(status,text[1],priority,tags)
end
end
class Criteria
attr_reader :criteria
def initialize criteria
@criteria = criteria
end
def self.status status
procedure = Proc.new {|task| task.status == status}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def self.priority priority
procedure = Proc.new {|task| task.priority == priority}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def self.tags tags
procedure = Proc.new {|task| task.tags.each_cons(tags.size).include? tags}
self.new Proc.new { |tasks| tasks.select &procedure}
end
def &(other)
Criteria.new Proc.new { |tasks| criteria.(tasks) & other.criteria.(tasks)}
end
def |(other)
Criteria.new Proc.new { |tasks| criteria.(tasks) | other.criteria.(tasks)}
end
def !
Criteria.new Proc.new { |tasks| tasks - criteria.(tasks)}
end
end