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

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

Към профила на Стефан Василев

Резултати

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

Код

class Criteria
attr_accessor :assets, :not
def initialize(assets_array, not_array)
@assets = assets_array
@not = not_array
end
def self.status(status)
Criteria.new([[] << status] , [])
end
def self.priority(priority)
Criteria.new([[] << priority] , [])
end
def self.tags(tags)
Criteria.new([] << tags, [])
end
def |(other)
Criteria.new(@assets + other.assets, other.not)
end
def &(other)
Criteria.new([] << @assets.flatten + other.assets.flatten, other.not)
end
def !
Criteria.new([], @assets.flatten)
end
end
class Task
attr_accessor :text
def initialize(line)
@text = line
end
def status
@text.split("|")[0].strip.downcase.intern
end
def description
@text.split("|")[1].strip
end
def priority
@text.split("|")[2].strip.downcase.intern
end
def tags
return [] if @text.split("|")[3] == nil
@text.split("|")[3].strip.split ", "
end
end
class TodoList
require 'set'
attr_accessor :tasks
def initialize(tasks_array)
@tasks = tasks_array.to_set
end
def self.parse(string)
tasks = []
string.split("\n").each { |item| tasks << Task.new(item) }
TodoList.new(tasks)
end
def filter(criteria)
result_array = []
@tasks.each { |item| result_array << match(item, criteria) }
TodoList.new(result_array.compact)
end
def adjoin(other_list)
result_list = @tasks + other_list.tasks
TodoList.new(result_list)
end
def tasks_todo
result = 0
@tasks.each { |element| result += element.status.to_s.chop.count "t" }
result
end
def tasks_in_progress
result = 0
@tasks.each { |element| result += element.status.to_s.count "c" }
result
end
def tasks_completed
result = 0
@tasks.each { |element| result += element.status.to_s.chop.chop.count "d" }
result
end
def completed?
@tasks.all? { |element| element.status == :done }
end
end
#Dont kill me for having functions outside the class
def match(element, criteria)
return nil if criteria.not.any? { |i| element.text.include?(i.to_s) }
return element if criteria.assets.any? { |item| pass?(item, element) }
end
def pass?(array, element)
return true if array.all? { |item| element.text.include?(convert(item)) }
end
def convert(item)
return item if item.class == String
return item.to_s.upcase if [:todo, :current, :done].include?(item)
return item.to_s.capitalize if [:low, :normal, :high].include?(item)
end

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

FFFFFFFFFFFF....FFFFF.

Failures:

  1) TodoList filters tasks by status
     Failure/Error: todo_list.filter(Criteria.status :done).map(&:description).should =~ [
     NoMethodError:
       undefined method `map' for #<TodoList:0xb97e264c>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb97e200c>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb97de830>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb97dce90>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb97d3840>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb97d189c>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb9846e6c>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb98445a4 @tasks=#<Set: {}>>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb983e514>
     # /tmp/d20131107-4393-vrrr1z/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 `map' for #<TodoList:0xb983c408>
     # /tmp/d20131107-4393-vrrr1z/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 `count' for #<TodoList:0xb979e1e0>
     # /tmp/d20131107-4393-vrrr1z/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 `first' for #<TodoList:0xb979dab0>
     # /tmp/d20131107-4393-vrrr1z/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 doesn't modify the to-do list when filtering
     Failure/Error: todo_list.should have(text_input.lines.count).items
     NoMethodError:
       undefined method `items' for #<TodoList:0xb96bd2e4>
     # /tmp/d20131107-4393-vrrr1z/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)>'

  14) TodoList implements Enumerable
     Failure/Error: todo_list.should respond_to :each
       expected #<TodoList:0xb96b1a70 @tasks=#<Set: {#<Task:0xb96b1b38 @text="      TODO    | Eat spaghetti.               | High   | food, happiness">, #<Task:0xb96b1b24 @text="      TODO    | Get 8 hours of sleep.        | Low    | health">, #<Task:0xb96b1b10 @text="      CURRENT | Party animal.                | Normal | socialization">, #<Task:0xb96b1afc @text="      CURRENT | Grok Ruby.                   | High   | development, ruby">, #<Task:0xb96b1ae8 @text="      DONE    | Have some tea.               | Normal |">, #<Task:0xb96b1ad4 @text="      TODO    | Destroy Facebook and Google. | High   | save humanity, conspiracy">, #<Task:0xb96b1ac0 @text="      DONE    | Do the 5th Ruby challenge.   | High   | ruby course, FMI, development, ruby">, #<Task:0xb96b1aac @text="      TODO    | Find missing socks.          | Low    |">, #<Task:0xb96b1a98 @text="      TODO    | Occupy Sofia University.     | High   | #ДАНСwithMe, #occupysu, #оставка">}>> to respond to :each
     # /tmp/d20131107-4393-vrrr1z/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)>'

  15) TodoList contains tasks with the neccessary interface
     Failure/Error: task = todo_list.first
     NoMethodError:
       undefined method `first' for #<TodoList:0xb96acc00>
     # /tmp/d20131107-4393-vrrr1z/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)>'

  16) TodoList tasks have an array of tags
     Failure/Error: todo_list.first.tags.should be_an Array
     NoMethodError:
       undefined method `first' for #<TodoList:0xb96a7b60>
     # /tmp/d20131107-4393-vrrr1z/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)>'

  17) TodoList preserves the order of tasks
     Failure/Error: todo_list.map(&:description).should eq [
     NoMethodError:
       undefined method `map' for #<TodoList:0xb96a642c>
     # /tmp/d20131107-4393-vrrr1z/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.03528 seconds
22 examples, 17 failures

Failed examples:

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

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

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

+class Criteria
+ attr_accessor :assets, :not
+ def initialize(assets_array, not_array)
+ @assets = assets_array
+ @not = not_array
+ end
+ def self.status(status)
+ Criteria.new([[] << status] , [])
+ end
+ def self.priority(priority)
+ Criteria.new([[] << priority] , [])
+ end
+ def self.tags(tags)
+ Criteria.new([] << tags, [])
+ end
+ def |(other)
+ Criteria.new(@assets + other.assets, other.not)
+ end
+ def &(other)
+ Criteria.new([] << @assets.flatten + other.assets.flatten, other.not)
+ end
+ def !
+ Criteria.new([], @assets.flatten)
+ end
+end
+
+class Task
+ attr_accessor :text
+ def initialize(line)
+ @text = line
+ end
+ def status
+ @text.split("|")[0].strip.downcase.intern
+ end
+ def description
+ @text.split("|")[1].strip
+ end
+ def priority
+ @text.split("|")[2].strip.downcase.intern
+ end
+ def tags
+ return [] if @text.split("|")[3] == nil
+ @text.split("|")[3].strip.split ", "
+ end
+end
+
+class TodoList
+ require 'set'
+ attr_accessor :tasks
+ def initialize(tasks_array)
+ @tasks = tasks_array.to_set
+ end
+ def self.parse(string)
+ tasks = []
+ string.split("\n").each { |item| tasks << Task.new(item) }
+ TodoList.new(tasks)
+ end
+ def filter(criteria)
+ result_array = []
+ @tasks.each { |item| result_array << match(item, criteria) }
+ TodoList.new(result_array.compact)
+ end
+ def adjoin(other_list)
+ result_list = @tasks + other_list.tasks
+ TodoList.new(result_list)
+ end
+ def tasks_todo
+ result = 0
+ @tasks.each { |element| result += element.status.to_s.chop.count "t" }
+ result
+ end
+ def tasks_in_progress
+ result = 0
+ @tasks.each { |element| result += element.status.to_s.count "c" }
+ result
+ end
+ def tasks_completed
+ result = 0
+ @tasks.each { |element| result += element.status.to_s.chop.chop.count "d" }
+ result
+ end
+ def completed?
+ @tasks.all? { |element| element.status == :done }
+ end
+end
+
+#Dont kill me for having functions outside the class
+def match(element, criteria)
+ return nil if criteria.not.any? { |i| element.text.include?(i.to_s) }
+ return element if criteria.assets.any? { |item| pass?(item, element) }
+end
+
+def pass?(array, element)
+ return true if array.all? { |item| element.text.include?(convert(item)) }
+end
+
+def convert(item)
+ return item if item.class == String
+ return item.to_s.upcase if [:todo, :current, :done].include?(item)
+ return item.to_s.capitalize if [:low, :normal, :high].include?(item)
+end

Говорих с Димитър, надявам се той да чете този коментар и да си спомни че ми каза все пак да си пробвам късмета да пусна следния код, който трябва да се добави в клас TodoList

def map @tasks.map { |element| yield element } end

Ще съм много благодарен ако се добави, защото без него тестовете се провалят въпреки че цялата логика на програмата е вярна.