Решение на Седма задача от Адриана Стефанова

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

Към профила на Адриана Стефанова

Резултати

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

Код

class LazyMode
def self.create_file(name, &block)
File.new(name, &block)
end
class File
attr_accessor :name, :notes
def initialize(name)
@name = name
self.instance_eval( &Proc.new ) if block_given?
end
def note(note_header, *note_tags, &block)
@notes = Array.new if @notes == nil
@notes.push(Note.new(@name, note_header, *note_tags, &block))
end
def daily_agenda(date)
agenda = Agenda.new
add_to_agenda(agenda, date)
agenda
end
def weekly_agenda(date)
agenda = Agenda.new
(0..7).each { |day|
new_date = date
new_date = new_date.add_days(day)
add_to_agenda(agenda, new_date)
}
agenda
end
def add_to_agenda(agenda, date)
@notes.each{ |note|
check(note, date, agenda)
}
end
def check(note, date, agenda)
if note.eligible?(date)
agenda.add_note(note, date)
end
check_inner_tasks(note, date, agenda)
end
def check_inner_tasks(note, date, agenda)
note.inner_tasks.each { |inner_task|
check_inner_task(inner_task, date, agenda)
}
end
def check_inner_task(inner_task, date, agenda)
if inner_task.eligible?(date)
agenda.add_note(inner_task, date)
end
end
end
module DateHelper
def subtract_days(days)
new_date = Date.new(self.to_s)
while days > 30
days = days - 30
new_date.month = new_date.month - 1
end
new_date.day = new_date.day - days
new_date
end
def subtract_weeks(weeks)
days = 7 * weeks
subtract_days(days)
end
def subtract_months(months)
new_date = Date.new(self.to_s)
while(new_date.month - months < 0)
new_date.year = new_date.year - 1
months = months - 12
end
new_date.month = new_date.month - months
new_date
end
def add_days(days)
new_date = Date.new(self.to_s)
if new_date.day + days > 30
new_date.month = new_date.month + 1
new_date.day = new_date.day + days - 30
else
new_date.day = new_date.day + days
end
new_date
end
end
class Date
include DateHelper
attr_accessor :year, :month, :day
def initialize(date)
@year, @month, @day = date.split('-').map(&:to_i)
raise "Invalid date" if @month > 12 || @day > 30
end
def to_s
year, month, day = @year.to_s, @month.to_s, @day.to_s
year = add_missing_zeroes(year, 4)
month = add_missing_zeroes(month, 2)
day = add_missing_zeroes(day, 2)
"#{year}-#{month}-#{day}"
end
def add_missing_zeroes(string, length)
while(string.length < length)
string = "0" << string
end
string
end
def ==(other)
@year == other.year && @month == other.month && @day == other.day
end
def <=>(other)
if @year < other.year
-1
elsif @year > other.year
1
else
compare_months(other)
end
end
def compare_months(other)
if @month < other.month
-1
elsif @month > other.month
1
else
compare_days(other)
end
end
def compare_days(other)
if @day < other.day
-1
elsif @day > other.day
1
else
0
end
end
end
module NoteHelper
def calculate_days(date)
new_date = date
new_date = new_date.subtract_days(@repetition)
new_date == @scheduled
end
def calculate_weeks(date)
new_date = date
new_date = new_date.subtract_weeks(@repetition)
new_date == @scheduled
end
def calculate_months(date)
new_date = date
new_date = new_date.subtract_months(@repetition)
new_date == @scheduled
end
def eligible_for_months_and_weeks?(date)
if @interval == 'w'
return calculate_weeks(date)
else
return eligible_for_months?(date)
end
end
def eligible_for_months?(date)
if @interval == 'm'
return calculate_months(date)
end
end
end
class Note
include NoteHelper
STATUSES = [:topostpone, :postponed]
attr_accessor :header, :file_name, :body, :status, :tags, :scheduled,
:repetition, :inner_tasks, :date
def initialize(file_name, header, *tags, &block)
@file_name = file_name
@header = header
#defaults
@tags = Array.new.push(*tags)
@status = :topostpone
@body = ""
self.instance_eval( &Proc.new ) if block_given?
end
def scheduled(*date)
if date.size == 0
@scheduled
else
assign_scheduled(date.first)
end
end
def assign_scheduled(date)
date, repetition = date.split(' ')
@scheduled = Date.new(date)
if repetition != nil
@interval = repetition.split('').last
repetition[0], repetition[-1] = '', ''
@repetition = repetition.to_i
end
end
def status(*note_status)
if note_status.size == 0
@status
elsif(STATUSES.include? note_status.first)
@status = note_status.first
end
end
def body(*note_body)
if note_body.size == 0
@body
else
@body = note_body.first
end
end
def note(note_header, *note_tags, &block)
@inner_tasks = Array.new if @inner_tasks == nil
@inner_tasks.push(Note.new(@file_name, note_header, *note_tags, &block))
end
def eligible?(date)
return true if @scheduled == date
if @interval == 'd'
return calculate_days(date)
else
return eligible_for_months_and_weeks?(date)
end
false
end
end
module AgendaHelper
def check_tag_if_present(note, tag)
if tag != ""
check_tag(note, tag)
end
end
def check_tag(note, tag)
unless note.tags.include? tag
@notes.delete(note)
end
end
def check_text_if_present(note, text)
if text != ""
check_text(note, text)
end
end
def check_text(note, text)
if (note.header =~ text) == nil && (note.body =~ text) == nil
@notes.delete(note)
end
end
def check_status_if_present(note, status)
if status != ""
check_status(note, status)
end
end
def check_status(note, status)
unless note.status == status
@notes.delete(note)
end
end
end
class Agenda
include AgendaHelper
attr_accessor :notes, :date
def initialize
@notes = Array.new
end
def add_note(note, date)
note.date = date
@notes.push(note)
end
def where(tag: "", text: "", status: "")
where_tag(tag)
where_text(text)
where_status(status)
self
end
def where_tag(tag)
@notes.each{ |note|
check_tag_if_present(note, tag)
}
end
def where_text(text)
@notes.each { |note|
check_text_if_present(note, text)
}
end
def where_status(status)
@notes.each {|note|
check_status_if_present(note, status)
}
end
end
end

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

............FFFFF.FFFFF.FFFFF..

Failures:

  1) LazyMode#daily_agenda returns note scheduled without repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:130: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)>'

  2) LazyMode#daily_agenda returns note scheduled with daily repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:152: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)>'

  3) LazyMode#daily_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:174: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)>'

  4) LazyMode#daily_agenda returns note scheduled with monthly repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2013-01-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:197: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 does not return note whose start date is in the future
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-10-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:215: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#weekly_agenda returns note scheduled without repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-12-06'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:34:in `block in weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:248: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 multiple notes with different dates when scheduled with daily repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-12-06'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:34:in `block in weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:270: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 note scheduled with weekly repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-12-10'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:34:in `block in weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:294: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 monthly repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2013-01-10'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:34:in `block in weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:326: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 does not return note whose start date is in the future
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-10-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:34:in `block in weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:31:in `weekly_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:344: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 tag
     Failure/Error: @agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:387: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 body text
     Failure/Error: @agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:387: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 header text
     Failure/Error: @agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:387: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 status
     Failure/Error: @agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:387: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#where filters by multiple filters
     Failure/Error: @agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `each' for nil:NilClass
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:53:in `check_inner_tasks'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:49:in `check'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:41:in `block in add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `each'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:40:in `add_to_agenda'
     # /tmp/d20160107-5693-1m5zmxg/solution.rb:23:in `daily_agenda'
     # /tmp/d20160107-5693-1m5zmxg/spec.rb:387: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.01815 seconds
31 examples, 15 failures

Failed examples:

rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:119 # LazyMode#daily_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:141 # LazyMode#daily_agenda returns note scheduled with daily repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:163 # LazyMode#daily_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:186 # LazyMode#daily_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:208 # LazyMode#daily_agenda does not return note whose start date is in the future
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:237 # LazyMode#weekly_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:283 # LazyMode#weekly_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:315 # LazyMode#weekly_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:337 # LazyMode#weekly_agenda does not return note whose start date is in the future
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:390 # LazyMode#where filters by tag
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:408 # LazyMode#where filters by body text
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:420 # LazyMode#where filters by header text
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:432 # LazyMode#where filters by status
rspec /tmp/d20160107-5693-1m5zmxg/spec.rb:443 # LazyMode#where filters by multiple filters

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

Адриана обнови решението на 20.12.2015 15:57 (преди около 9 години)

+class LazyMode
+
+ def self.create_file(name, &block)
+ File.new(name, &block)
+ end
+
+ class File
+ attr_accessor :name, :notes
+
+ def initialize(name)
+ @name = name
+ self.instance_eval( &Proc.new ) if block_given?
+ end
+
+ def note(note_header, *note_tags, &block)
+ @notes = Array.new if @notes == nil
+ @notes.push(Note.new(@name, note_header, *note_tags, &block))
+ end
+
+ def daily_agenda(date)
+ agenda = Agenda.new
+
+ add_to_agenda(agenda, date)
+
+ agenda
+ end
+
+ def weekly_agenda(date)
+ agenda = Agenda.new
+
+ (0..7).each { |day|
+ new_date = date
+ new_date = new_date.add_days(day)
+ add_to_agenda(agenda, new_date)
+ }
+ agenda
+ end
+
+ def add_to_agenda(agenda, date)
+ @notes.each{ |note|
+ check(note, date, agenda)
+ }
+ end
+
+ def check(note, date, agenda)
+ if note.eligible?(date)
+ agenda.add_note(note, date)
+ end
+ check_inner_tasks(note, date, agenda)
+ end
+
+ def check_inner_tasks(note, date, agenda)
+ note.inner_tasks.each { |inner_task|
+ check_inner_task(inner_task, date, agenda)
+ }
+ end
+
+ def check_inner_task(inner_task, date, agenda)
+ if inner_task.eligible?(date)
+ agenda.add_note(inner_task, date)
+ end
+ end
+
+ end
+
+ module DateHelper
+ def subtract_days(days)
+ new_date = Date.new(self.to_s)
+
+ while days > 30
+ days = days - 30
+ new_date.month = new_date.month - 1
+ end
+
+ new_date.day = new_date.day - days
+
+ new_date
+ end
+
+ def subtract_weeks(weeks)
+ days = 7 * weeks
+ subtract_days(days)
+ end
+
+ def subtract_months(months)
+ new_date = Date.new(self.to_s)
+
+ while(new_date.month - months < 0)
+ new_date.year = new_date.year - 1
+ months = months - 12
+ end
+
+ new_date.month = new_date.month - months
+
+ new_date
+ end
+
+ def add_days(days)
+ new_date = Date.new(self.to_s)
+ if new_date.day + days > 30
+ new_date.month = new_date.month + 1
+ new_date.day = new_date.day + days - 30
+ else
+ new_date.day = new_date.day + days
+ end
+ new_date
+ end
+
+ end
+
+ class Date
+ include DateHelper
+ attr_accessor :year, :month, :day
+
+ def initialize(date)
+ @year, @month, @day = date.split('-').map(&:to_i)
+ raise "Invalid date" if @month > 12 || @day > 30
+ end
+
+ def to_s
+ year, month, day = @year.to_s, @month.to_s, @day.to_s
+
+ year = add_missing_zeroes(year, 4)
+ month = add_missing_zeroes(month, 2)
+ day = add_missing_zeroes(day, 2)
+
+ "#{year}-#{month}-#{day}"
+ end
+
+ def add_missing_zeroes(string, length)
+
+ while(string.length < length)
+ string = "0" << string
+ end
+
+ string
+ end
+
+ def ==(other)
+ @year == other.year && @month == other.month && @day == other.day
+ end
+
+ def <=>(other)
+ if @year < other.year
+ -1
+ elsif @year > other.year
+ 1
+ else
+ compare_months(other)
+ end
+ end
+
+ def compare_months(other)
+ if @month < other.month
+ -1
+ elsif @month > other.month
+ 1
+ else
+ compare_days(other)
+ end
+ end
+
+ def compare_days(other)
+ if @day < other.day
+ -1
+ elsif @day > other.day
+ 1
+ else
+ 0
+ end
+ end
+
+ end
+
+ module NoteHelper
+ def calculate_days(date)
+ new_date = date
+ new_date = new_date.subtract_days(@repetition)
+ new_date == @scheduled
+ end
+
+ def calculate_weeks(date)
+ new_date = date
+ new_date = new_date.subtract_weeks(@repetition)
+ new_date == @scheduled
+ end
+
+ def calculate_months(date)
+ new_date = date
+ new_date = new_date.subtract_months(@repetition)
+ new_date == @scheduled
+ end
+
+ def eligible_for_months_and_weeks?(date)
+ if @interval == 'w'
+ return calculate_weeks(date)
+ else
+ return eligible_for_months?(date)
+ end
+ end
+
+ def eligible_for_months?(date)
+ if @interval == 'm'
+ return calculate_months(date)
+ end
+ end
+
+ end
+
+ class Note
+ include NoteHelper
+
+ STATUSES = [:topostpone, :postponed]
+
+ attr_accessor :header, :file_name, :body, :status, :tags, :scheduled,
+ :repetition, :inner_tasks, :date
+
+ def initialize(file_name, header, *tags, &block)
+ @file_name = file_name
+ @header = header
+
+ #defaults
+ @tags = Array.new.push(*tags)
+ @status = :topostpone
+ @body = ""
+
+ self.instance_eval( &Proc.new ) if block_given?
+ end
+
+ def scheduled(*date)
+ if date.size == 0
+ @scheduled
+ else
+ assign_scheduled(date.first)
+ end
+ end
+
+ def assign_scheduled(date)
+ date, repetition = date.split(' ')
+ @scheduled = Date.new(date)
+
+ if repetition != nil
+ @interval = repetition.split('').last
+ repetition[0], repetition[-1] = '', ''
+ @repetition = repetition.to_i
+ end
+ end
+
+ def status(*note_status)
+ if note_status.size == 0
+ @status
+ elsif(STATUSES.include? note_status.first)
+ @status = note_status.first
+ end
+ end
+
+ def body(*note_body)
+ if note_body.size == 0
+ @body
+ else
+ @body = note_body.first
+ end
+ end
+
+ def note(note_header, *note_tags, &block)
+ @inner_tasks = Array.new if @inner_tasks == nil
+ @inner_tasks.push(Note.new(@file_name, note_header, *note_tags, &block))
+ end
+
+ def eligible?(date)
+
+ return true if @scheduled == date
+
+ if @interval == 'd'
+ return calculate_days(date)
+ else
+ return eligible_for_months_and_weeks?(date)
+ end
+ false
+ end
+ end
+
+ module AgendaHelper
+
+ def check_tag_if_present(note, tag)
+ if tag != ""
+ check_tag(note, tag)
+ end
+ end
+
+ def check_tag(note, tag)
+ unless note.tags.include? tag
+ @notes.delete(note)
+ end
+ end
+
+ def check_text_if_present(note, text)
+ if text != ""
+ check_text(note, text)
+ end
+ end
+
+ def check_text(note, text)
+ if (note.header =~ text) == nil && (note.body =~ text) == nil
+ @notes.delete(note)
+ end
+ end
+
+ def check_status_if_present(note, status)
+ if status != ""
+ check_status(note, status)
+ end
+ end
+
+ def check_status(note, status)
+ unless note.status == status
+ @notes.delete(note)
+ end
+ end
+
+ end
+
+ class Agenda
+ include AgendaHelper
+ attr_accessor :notes, :date
+
+ def initialize
+ @notes = Array.new
+ end
+
+ def add_note(note, date)
+ note.date = date
+ @notes.push(note)
+ end
+
+ def where(tag: "", text: "", status: "")
+
+ where_tag(tag)
+ where_text(text)
+ where_status(status)
+
+ self
+ end
+
+ def where_tag(tag)
+ @notes.each{ |note|
+ check_tag_if_present(note, tag)
+ }
+ end
+
+ def where_text(text)
+ @notes.each { |note|
+ check_text_if_present(note, text)
+ }
+ end
+
+ def where_status(status)
+ @notes.each {|note|
+ check_status_if_present(note, status)
+ }
+ end
+
+ end
+
+end