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

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

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

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 16 успешни тест(а)
  • 15 неуспешни тест(а)

Код

module LazyMode
require 'date'
@notes = {}
class Date
attr :date
attr_reader :year, :month, :day
def initialize(date)
date = date.split('-')
@year, @month, @day = date[0].to_i, date[1].to_i, date[2].to_i
@date = "%04d" % @year << "-" << "%02d" % @month << "-" << "%02d" % @day
end
def to_s
@date
end
end
class Note
attr_reader :header, :file_name, :body, :status, :tags, :repeat
def initialize(header, tags = [], file_name, block)
@header, @tags, @status, @body = header, tags, :topostpone, ''
@file_name = file_name
@repeat_toggle = false
instance_eval &block
end
def scheduled(date = nil)
if date.nil? then return @scheduled end
date = date.split(' ')
@scheduled = Date.new(date[0]).to_s
@repeat = date[1] if date.size > 1
end
def status(value = nil)
if value.nil? then @status else @status = value end
end
def body(value = nil)
if value.nil? then @body else @body = value end
end
def note(header, *tags, &block)
new_note = LazyMode::Note.new(header, tags, @file_name, block)
LazyMode::notes[@file_name] << new_note
end
def date
if not @repeat.nil?
Date.new(repeat_date)
else
Date.new(scheduled)
end
end
def repeat_date
return if @repeat.nil?
first = @repeat[1, @repeat.length]
period = first.slice!(first.length - 1)
days = LazyMode.period_days(period)
new_date = ::DateTime.strptime(scheduled, '%Y-%m-%d')
(new_date + (first.to_i * days)).strftime('%Y-%m-%d')
end
def use_repeat(value)
@repeat_toggle = value
end
end
class File
def initialize(name)
@name = name
end
def name
@name
end
def notes
LazyMode::notes[@name]
end
def daily_agenda(date)
agenda = Filter.new
agenda.notes = notes.select do |note|
repeat_check(date, note)
date.to_s == note.scheduled or date.to_s == note.repeat_date
end
agenda
end
def weekly_agenda(date)
agenda = Filter.new
agenda.notes = notes.select do |note|
repeat_check(date, note)
week_date_check(date, note)
end
agenda
end
def repeat_check(date, note)
if date == note.repeat_date
note.use_repeat(true)
else
note.use_repeat(false)
end
end
def week_date_check(date, note)
new_date, dates = ::DateTime.strptime(date.to_s, '%Y-%m-%d'), []
(0..6).each { |i| dates << (new_date + i).strftime('%Y-%m-%d') }
dates.include?(note.scheduled) or dates.include?(note.repeat_date)
end
end
class Filter
attr_accessor :notes
def initialize
@notes = []
end
def where(tag: nil, text: nil, status: nil)
a = filter_tag(tag) if not tag.nil?
a.filter_text(text) if not text.nil?
a.filter_status(status) if not status.nil?
a
end
def filter_tag(tag)
@notes.select! { |note| note.tags.include?(tag) }
self
end
def filter_text(pattern)
@notes.select! do |note|
pattern.match(note.header) or pattern.match(note.body)
end
self
end
def filter_status(status)
@notes.select! { |note| note.status == status }
self
end
end
class << self
attr_accessor :notes
def create_file(name, &block)
@current_file = name
@notes[name] = [] if not @notes.has_key?(name)
class_eval &block
@current_file = nil
LazyMode::File.new(name)
end
def note(header, *tags, &block)
new_note = LazyMode::Note.new(header, tags, @current_file, block)
@notes[@current_file] << new_note
end
def scheduled(date)
end
def period_days(period)
case period
when 'd' then 1
when 'w' then 7
when 'm' then 30
end
end
end
end

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

......F.F.F..FFF..FFFF...FFFF.F

Failures:

  1) LazyMode LazyMode::Note #tags has tags
     Failure/Error: expect(file.notes.first.tags).to eq([:important, :wip, :blocker])
       
       expected: [:important, :wip, :blocker]
            got: []
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[:important, :wip, :blocker]
       +[]
     # /tmp/d20160107-5693-kfc4l/spec.rb:45:in `block (4 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) LazyMode LazyMode::Note #status has status
     Failure/Error: expect(file.notes.first.status).to eq(:postponed)
       
       expected: :postponed
            got: :topostpone
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -:postponed
       +:topostpone
     # /tmp/d20160107-5693-kfc4l/spec.rb:65:in `block (4 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) LazyMode LazyMode::Note #body has body
     Failure/Error: expect(file.notes.first.body).to eq('Do not forget to...')
       
       expected: "Do not forget to..."
            got: ""
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:85:in `block (4 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) LazyMode#daily_agenda returns note scheduled with daily repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 2
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:153:in `block (3 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) LazyMode#daily_agenda returns note scheduled with weekly repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 3
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:175:in `block (3 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) LazyMode#daily_agenda returns note scheduled with monthly repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:198:in `block (3 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) LazyMode#weekly_agenda returns note scheduled without repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 5
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:249:in `block (3 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) LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
     Failure/Error: expect(agenda.notes.size).to eq(2)
       
       expected: 2
            got: 6
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:271:in `block (3 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) LazyMode#weekly_agenda returns note scheduled with weekly repeater
     Failure/Error: expect(agenda.notes.size).to eq(2)
       
       expected: 2
            got: 14
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:295:in `block (3 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) LazyMode#weekly_agenda returns note scheduled with monthly repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 2
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:327:in `block (3 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) LazyMode#where filters by body text
     Failure/Error: notes = @agenda.where(text: /Very/).notes
     NoMethodError:
       undefined method `filter_text' for nil:NilClass
     # /tmp/d20160107-5693-kfc4l/solution.rb:129:in `where'
     # /tmp/d20160107-5693-kfc4l/spec.rb:409:in `block (3 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) LazyMode#where filters by header text
     Failure/Error: notes = @agenda.where(text: /not important/).notes
     NoMethodError:
       undefined method `filter_text' for nil:NilClass
     # /tmp/d20160107-5693-kfc4l/solution.rb:129:in `where'
     # /tmp/d20160107-5693-kfc4l/spec.rb:421:in `block (3 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) LazyMode#where filters by status
     Failure/Error: notes = @agenda.where(status: :postponed).notes
     NoMethodError:
       undefined method `filter_status' for nil:NilClass
     # /tmp/d20160107-5693-kfc4l/solution.rb:130:in `where'
     # /tmp/d20160107-5693-kfc4l/spec.rb:433:in `block (3 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) LazyMode#where filters by multiple filters
     Failure/Error: notes = @agenda.where(text: /important/, status: :postponed).notes
     NoMethodError:
       undefined method `filter_text' for nil:NilClass
     # /tmp/d20160107-5693-kfc4l/solution.rb:129:in `where'
     # /tmp/d20160107-5693-kfc4l/spec.rb:444:in `block (3 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) LazyMode.create_file can build notes in the block
     Failure/Error: expect(file.notes.size).to eq(3)
       
       expected: 3
            got: 14
       
       (compared using ==)
     # /tmp/d20160107-5693-kfc4l/spec.rb:477:in `block (3 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.02784 seconds
31 examples, 15 failures

Failed examples:

rspec /tmp/d20160107-5693-kfc4l/spec.rb:39 # LazyMode LazyMode::Note #tags has tags
rspec /tmp/d20160107-5693-kfc4l/spec.rb:59 # LazyMode LazyMode::Note #status has status
rspec /tmp/d20160107-5693-kfc4l/spec.rb:79 # LazyMode LazyMode::Note #body has body
rspec /tmp/d20160107-5693-kfc4l/spec.rb:141 # LazyMode#daily_agenda returns note scheduled with daily repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:163 # LazyMode#daily_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:186 # LazyMode#daily_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:237 # LazyMode#weekly_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:283 # LazyMode#weekly_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:315 # LazyMode#weekly_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-kfc4l/spec.rb:408 # LazyMode#where filters by body text
rspec /tmp/d20160107-5693-kfc4l/spec.rb:420 # LazyMode#where filters by header text
rspec /tmp/d20160107-5693-kfc4l/spec.rb:432 # LazyMode#where filters by status
rspec /tmp/d20160107-5693-kfc4l/spec.rb:443 # LazyMode#where filters by multiple filters
rspec /tmp/d20160107-5693-kfc4l/spec.rb:463 # LazyMode.create_file can build notes in the block

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

Веселин обнови решението на 15.12.2015 21:30 (преди около 9 години)

+module LazyMode
+ require 'date'
+
+ @notes = {}
+
+ class Date
+ attr :date
+ attr_reader :year, :month, :day
+
+ def initialize(date)
+ date = date.split('-')
+ @year, @month, @day = date[0].to_i, date[1].to_i, date[2].to_i
+
+ @date = "%04d" % @year << "-" << "%02d" % @month << "-" << "%02d" % @day
+ end
+
+ def to_s
+ @date
+ end
+ end
+
+ class Note
+ attr_reader :header, :file_name, :body, :status, :tags, :repeat
+
+ def initialize(header, tags = [], file_name, block)
+ @header, @tags, @status, @body = header, tags, :topostpone, ''
+ @file_name = file_name
+ @repeat_toggle = false
+ instance_eval &block
+ end
+
+ def scheduled(date = nil)
+ if date.nil? then return @scheduled end
+ date = date.split(' ')
+ @scheduled = Date.new(date[0]).to_s
+ @repeat = date[1] if date.size > 1
+ end
+
+ def status(value = nil)
+ if value.nil? then @status else @status = value end
+ end
+
+ def body(value = nil)
+ if value.nil? then @body else @body = value end
+ end
+
+ def note(header, *tags, &block)
+ new_note = LazyMode::Note.new(header, tags, @file_name, block)
+ LazyMode::notes[@file_name] << new_note
+ end
+
+ def date
+ if not @repeat.nil?
+ Date.new(repeat_date)
+ else
+ Date.new(scheduled)
+ end
+ end
+
+ def repeat_date
+ return if @repeat.nil?
+ first = @repeat[1, @repeat.length]
+ period = first.slice!(first.length - 1)
+ days = LazyMode.period_days(period)
+ new_date = ::DateTime.strptime(scheduled, '%Y-%m-%d')
+ (new_date + (first.to_i * days)).strftime('%Y-%m-%d')
+ end
+
+ def use_repeat(value)
+ @repeat_toggle = value
+ end
+ end
+
+ class File
+ def initialize(name)
+ @name = name
+ end
+
+ def name
+ @name
+ end
+
+ def notes
+ LazyMode::notes[@name]
+ end
+
+ def daily_agenda(date)
+ agenda = Filter.new
+ agenda.notes = notes.select do |note|
+ repeat_check(date, note)
+ date.to_s == note.scheduled or date.to_s == note.repeat_date
+ end
+ agenda
+ end
+
+ def weekly_agenda(date)
+ agenda = Filter.new
+ agenda.notes = notes.select do |note|
+ repeat_check(date, note)
+ week_date_check(date, note)
+ end
+ agenda
+ end
+
+ def repeat_check(date, note)
+ if date == note.repeat_date
+ note.use_repeat(true)
+ else
+ note.use_repeat(false)
+ end
+ end
+
+ def week_date_check(date, note)
+ new_date, dates = ::DateTime.strptime(date.to_s, '%Y-%m-%d'), []
+ (0..6).each { |i| dates << (new_date + i).strftime('%Y-%m-%d') }
+ dates.include?(note.scheduled) or dates.include?(note.repeat_date)
+ end
+ end
+
+ class Filter
+ attr_accessor :notes
+
+ def initialize
+ @notes = []
+ end
+
+ def where(tag: nil, text: nil, status: nil)
+ a = filter_tag(tag) if not tag.nil?
+ a.filter_text(text) if not text.nil?
+ a.filter_status(status) if not status.nil?
+ a
+ end
+
+ def filter_tag(tag)
+ @notes.select! { |note| note.tags.include?(tag) }
+ self
+ end
+
+ def filter_text(pattern)
+ @notes.select! do |note|
+ pattern.match(note.header) or pattern.match(note.body)
+ end
+ self
+ end
+
+ def filter_status(status)
+ @notes.select! { |note| note.status == status }
+ self
+ end
+ end
+
+ class << self
+ attr_accessor :notes
+
+ def create_file(name, &block)
+ @current_file = name
+ @notes[name] = [] if not @notes.has_key?(name)
+ class_eval &block
+ @current_file = nil
+
+ LazyMode::File.new(name)
+ end
+
+ def note(header, *tags, &block)
+ new_note = LazyMode::Note.new(header, tags, @current_file, block)
+ @notes[@current_file] << new_note
+ end
+
+ def scheduled(date)
+
+ end
+
+ def period_days(period)
+ case period
+ when 'd' then 1
+ when 'w' then 7
+ when 'm' then 30
+ end
+ end
+ end
+end