Решение на Седма задача от Йоан Динков

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

Към профила на Йоан Динков

Резултати

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

Код

class LazyMode
class Date
attr_reader :year
attr_reader :month
attr_reader :day
attr_reader :interval
def initialize(input, repeater_input = nil)
@year, @month, @day = input.split('-').map(&:to_i)
@interval = get_interval_as_days(repeater_input)
end
def to_s
justified_year = @year.to_s.rjust(4, '0')
justified_month = @month.to_s.rjust(2, '0')
justified_day = @day.to_s.rjust(2, '0')
"#{justified_year}-#{justified_month}-#{justified_day}"
end
def to_days
@day + (30 * @month) + (360 * year)
end
def next_date
new_day = @day + 1
new_month = @month
new_year = @year
new_month += 1 if new_day > 30
new_year += 1 if new_month > 12
Date.new("#{new_year}-#{new_month % 12}-#{new_day % 30}")
end
def next_occurrence
current_date = Date.new("#{@year}-#{@month}-#{@day}")
@interval.times do
current_date = current_date.next_date
end
update_date(current_date)
end
private
def get_interval_as_days(repeater_input)
return nil if repeater_input.nil?
time = repeater_input.scan(/\d+/).first.to_i
multiplier = get_multiplier(repeater_input[-1, 1])
time * multiplier
end
def get_multiplier(symbol)
case symbol
when 'd' then return 1
when 'w' then return 7
when 'm' then return 30
end
end
def update_date(date)
@day = date.day
@month = date.month
@year = date.year
end
end
class Note
attr_reader :header
attr_reader :tags
attr_reader :file_name
attr_reader :date
def initialize(header, *tags, file_name, notes)
@header = header
@tags = tags
@status = :topostpone
@file_name = file_name
@notes = notes || []
end
def scheduled(input)
@date, repeater = input.split(' ')
@date = Date.new(input, repeater)
end
def body(input = nil)
return @body unless input
@body = input
end
def status(input = nil)
return @status unless input
@status = input
end
def note(header, *tags, &block)
note = Note.new(header, *tags, @name, @notes)
note.instance_eval(&block)
@notes.push(note)
end
def match(input_date)
return @date.to_days == input_date.to_days if @date.interval.nil?
@date.next_occurrence while @date.to_days < input_date.to_days
@date.to_days == input_date.to_days
end
alias_method :file_name=, :file_name
alias_method :body=, :body
alias_method :status=, :status
private
def match_days(days, input_days, interval)
while input_days >= days
result = input_days == days
input_days -= interval
end
result
end
end
class File
attr_reader :name
attr_reader :notes
def initialize(name, &block)
@name = name
@notes = []
instance_eval(&block)
end
def daily_agenda(date)
AgendaNotes.new(notes_for_date(date))
end
def weekly_agenda(date)
filtered = notes_for_date(date)
6.times do
date = date.next_date
filtered += notes_for_date(date)
end
AgendaNotes.new(filtered)
end
def note(header, *tags, &block)
note = Note.new(header, *tags, @name, @notes)
note.instance_eval(&block)
@notes.push(note)
end
private
def notes_for_date(date)
@notes.select { |note| note.match(date) }
end
end
class AgendaNotes
attr_reader :notes
def initialize(notes)
@notes = notes
end
def where(tag: nil, text: nil, status: nil)
filtered = @notes
filtered = filter_by_tag(filtered, tag) unless tag.nil?
filtered = filter_by_text(filtered, text) unless text.nil?
filtered = filter_by_status(filtered, status) unless status.nil?
AgendaNotes.new(filtered)
end
private
def filter_by_tag(notes, tag)
notes.select { |note| note.tags.include? tag }
end
def filter_by_text(notes, expression)
notes.select do |note|
expression.match(note.header) || expression.match(note.body)
end
end
def filter_by_status(notes, status)
notes.select { |note| note.status == status }
end
end
def self.create_file(title, &block)
File.new(title, &block)
end
end

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

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

Failures:

  1) LazyMode LazyMode::Note can have nested notes
     Failure/Error: expect(file.notes.first.body).to eq('')
       
       expected: ""
            got: nil
       
       (compared using ==)
     # /tmp/d20160107-5693-1e3jafu/spec.rb:114: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 LazyMode::Note #body can have no body
     Failure/Error: expect(file.notes.first.body).to eq('')
       
       expected: ""
            got: nil
       
       (compared using ==)
     # /tmp/d20160107-5693-1e3jafu/spec.rb:94: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#daily_agenda returns note scheduled with daily repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     Timeout::Error:
       execution expired
     # /tmp/d20160107-5693-1e3jafu/solution.rb:9:in `initialize'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `new'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `next_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:41:in `block in next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `times'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:114:in `match'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `block in notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `select'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:147:in `daily_agenda'
     # /tmp/d20160107-5693-1e3jafu/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)>'

  4) LazyMode#daily_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     Timeout::Error:
       execution expired
     # /tmp/d20160107-5693-1e3jafu/solution.rb:9:in `initialize'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `new'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `next_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:41:in `block in next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `times'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:114:in `match'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `block in notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `select'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:147:in `daily_agenda'
     # /tmp/d20160107-5693-1e3jafu/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)>'

  5) LazyMode#daily_agenda returns note scheduled with monthly repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2013-01-12'))
     Timeout::Error:
       execution expired
     # /tmp/d20160107-5693-1e3jafu/solution.rb:9:in `map'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:9:in `initialize'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `new'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `next_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:41:in `block in next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `times'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:114:in `match'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `block in notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `select'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:147:in `daily_agenda'
     # /tmp/d20160107-5693-1e3jafu/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)>'

  6) LazyMode#weekly_agenda returns note scheduled without repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-1e3jafu/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)>'

  7) 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: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-1e3jafu/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)>'

  8) LazyMode#weekly_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-12-10'))
     Timeout::Error:
       execution expired
     # /tmp/d20160107-5693-1e3jafu/solution.rb:9:in `initialize'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `new'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `next_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:41:in `block in next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `times'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:114:in `match'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `block in notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `select'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:151:in `weekly_agenda'
     # /tmp/d20160107-5693-1e3jafu/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'))
     Timeout::Error:
       execution expired
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `next_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:41:in `block in next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `times'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:114:in `match'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `block in notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `select'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:151:in `weekly_agenda'
     # /tmp/d20160107-5693-1e3jafu/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 returns nested notes
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-09-05'))
     Timeout::Error:
       execution expired
     # /tmp/d20160107-5693-1e3jafu/solution.rb:9:in `initialize'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `new'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:34:in `next_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:41:in `block in next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `times'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:40:in `next_occurrence'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:114:in `match'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `block in notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `select'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:173:in `notes_for_date'
     # /tmp/d20160107-5693-1e3jafu/solution.rb:151:in `weekly_agenda'
     # /tmp/d20160107-5693-1e3jafu/spec.rb:359: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 6.61 seconds
31 examples, 10 failures

Failed examples:

rspec /tmp/d20160107-5693-1e3jafu/spec.rb:98 # LazyMode LazyMode::Note can have nested notes
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:88 # LazyMode LazyMode::Note #body can have no body
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:141 # LazyMode#daily_agenda returns note scheduled with daily repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:163 # LazyMode#daily_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:186 # LazyMode#daily_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:237 # LazyMode#weekly_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:283 # LazyMode#weekly_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:315 # LazyMode#weekly_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-1e3jafu/spec.rb:348 # LazyMode#weekly_agenda returns nested notes

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

Йоан обнови решението на 19.12.2015 18:55 (преди над 8 години)

+class LazyMode
+ class Time
+ end
+
+ class Date
+ attr_reader :year
+ attr_reader :month
+ attr_reader :day
+ attr_reader :interval
+
+ def initialize(input, repeater_input = nil)
+ @year, @month, @day = input.split('-').map(&:to_i)
+
+ @interval = get_interval_as_days(repeater_input)
+ end
+
+ def to_s
+ justified_year = @year.to_s.rjust(4, '0')
+ justified_month = @month.to_s.rjust(2, '0')
+ justified_day = @day.to_s.rjust(2, '0')
+
+ "#{justified_year}-#{justified_month}-#{justified_day}"
+ end
+
+ def to_days
+ @day + (30 * @month) + (360 * year)
+ end
+
+ def next_date
+ new_day = @day + 1
+ new_month = @month
+ new_year = @year
+
+ new_month += 1 if new_day > 30
+ new_year += 1 if new_month > 12
+
+ Date.new("#{new_year}-#{new_month % 12}-#{new_day % 30}")
+ end
+
+ def next_occurrence
+ current_date = Date.new("#{@year}-#{@month}-#{@day}")
+
+ @interval.times do
+ current_date = current_date.next_date
+ end
+
+ update_date(current_date)
+ end
+
+ private
+
+ def get_interval_as_days(repeater_input)
+ return nil if repeater_input.nil?
+
+ time = repeater_input.scan(/\d+/).first.to_i
+
+ multiplier = get_multiplier(repeater_input[-1, 1])
+
+ time * multiplier
+ end
+
+ def get_multiplier(symbol)
+ case symbol
+ when 'd' then return 1
+ when 'w' then return 7
+ when 'm' then return 30
+ end
+ end
+
+ def update_date(date)
+ @day = date.day
+ @month = date.month
+ @year = date.year
+ end
+ end
+
+ class Note
+ attr_reader :header
+ attr_reader :tags
+ attr_reader :file_name
+ attr_reader :date
+
+ def initialize(header, *tags, file_name, notes)
+ @header = header
+ @tags = tags
+ @status = :topostpone
+ @file_name = file_name
+ @notes = notes || []
+ end
+
+ def scheduled(input)
+ @date, repeater = input.split(' ')
+ @date = Date.new(input, repeater)
+ end
+
+ def body(input = nil)
+ return @body unless input
+ @body = input
+ end
+
+ def status(input = nil)
+ return @status unless input
+ @status = input
+ end
+
+ def note(header, *tags, &block)
+ note = Note.new(header, *tags, @name, @notes)
+
+ note.instance_eval(&block)
+
+ @notes.push(note)
+ end
+
+ def match(input_date)
+ return @date.to_days == input_date.to_days if @date.interval.nil?
+
+ while @date.to_days <= input_date.to_days
+ result = @date.to_days == input_date.to_days
+
+ @date.next_occurrence
+ end
+
+ result
+ end
+
+ alias_method :file_name=, :file_name
+ alias_method :body=, :body
+ alias_method :status=, :status
+
+ private
+
+ def match_days(days, input_days, interval)
+ while input_days >= days
+ result = input_days == days
+
+ input_days -= interval
+ end
+
+ result
+ end
+ end
+
+ class File
+ attr_reader :name
+ attr_reader :notes
+
+ def initialize(name, &block)
+ @name = name
+ @notes = []
+ instance_eval(&block)
+ end
+
+ def daily_agenda(date)
+ AgendaNotes.new(notes_for_date(date))
+ end
+
+ def weekly_agenda(date)
+ filtered = notes_for_date(date)
+
+ current_date = date
+
+ 6.times do
+ current_date = current_date.next_date
+
+ filtered += notes_for_date(current_date)
+ end
+
+ AgendaNotes.new(filtered)
+ end
+
+ def note(header, *tags, &block)
+ note = Note.new(header, *tags, @name, @notes)
+
+ note.instance_eval(&block)
+
+ @notes.push(note)
+ end
+
+ private
+
+ def notes_for_date(date)
+ @notes.select { |note| note.match(date) }
+ end
+ end
+
+ class AgendaNotes
+ attr_reader :notes
+
+ def initialize(notes)
+ @notes = notes
+ end
+
+ def where
+ puts 'a'
+ end
+ end
+
+ def self.create_file(title, &block)
+ File.new(title, &block)
+ end
+end

Йоан обнови решението на 19.12.2015 19:10 (преди над 8 години)

class LazyMode
- class Time
- end
-
class Date
attr_reader :year
attr_reader :month
attr_reader :day
attr_reader :interval
def initialize(input, repeater_input = nil)
@year, @month, @day = input.split('-').map(&:to_i)
@interval = get_interval_as_days(repeater_input)
end
def to_s
justified_year = @year.to_s.rjust(4, '0')
justified_month = @month.to_s.rjust(2, '0')
justified_day = @day.to_s.rjust(2, '0')
"#{justified_year}-#{justified_month}-#{justified_day}"
end
def to_days
@day + (30 * @month) + (360 * year)
end
def next_date
new_day = @day + 1
new_month = @month
new_year = @year
new_month += 1 if new_day > 30
new_year += 1 if new_month > 12
Date.new("#{new_year}-#{new_month % 12}-#{new_day % 30}")
end
def next_occurrence
current_date = Date.new("#{@year}-#{@month}-#{@day}")
@interval.times do
current_date = current_date.next_date
end
update_date(current_date)
end
private
def get_interval_as_days(repeater_input)
return nil if repeater_input.nil?
time = repeater_input.scan(/\d+/).first.to_i
multiplier = get_multiplier(repeater_input[-1, 1])
time * multiplier
end
def get_multiplier(symbol)
case symbol
when 'd' then return 1
when 'w' then return 7
when 'm' then return 30
end
end
def update_date(date)
@day = date.day
@month = date.month
@year = date.year
end
end
class Note
attr_reader :header
attr_reader :tags
attr_reader :file_name
attr_reader :date
def initialize(header, *tags, file_name, notes)
@header = header
@tags = tags
@status = :topostpone
@file_name = file_name
@notes = notes || []
end
def scheduled(input)
@date, repeater = input.split(' ')
@date = Date.new(input, repeater)
end
def body(input = nil)
return @body unless input
@body = input
end
def status(input = nil)
return @status unless input
@status = input
end
def note(header, *tags, &block)
note = Note.new(header, *tags, @name, @notes)
note.instance_eval(&block)
@notes.push(note)
end
def match(input_date)
return @date.to_days == input_date.to_days if @date.interval.nil?
- while @date.to_days <= input_date.to_days
- result = @date.to_days == input_date.to_days
+ @date.next_occurrence while @date.to_days < input_date.to_days
- @date.next_occurrence
- end
-
- result
+ @date.to_days == input_date.to_days
end
alias_method :file_name=, :file_name
alias_method :body=, :body
alias_method :status=, :status
private
def match_days(days, input_days, interval)
while input_days >= days
result = input_days == days
input_days -= interval
end
result
end
end
class File
attr_reader :name
attr_reader :notes
def initialize(name, &block)
@name = name
@notes = []
instance_eval(&block)
end
def daily_agenda(date)
AgendaNotes.new(notes_for_date(date))
end
def weekly_agenda(date)
filtered = notes_for_date(date)
current_date = date
6.times do
current_date = current_date.next_date
filtered += notes_for_date(current_date)
end
AgendaNotes.new(filtered)
end
def note(header, *tags, &block)
note = Note.new(header, *tags, @name, @notes)
note.instance_eval(&block)
@notes.push(note)
end
private
def notes_for_date(date)
@notes.select { |note| note.match(date) }
end
end
class AgendaNotes
attr_reader :notes
def initialize(notes)
@notes = notes
end
- def where
- puts 'a'
+ def where(tag: nil, text: nil, status: nil)
+ filtered = @notes
+
+ filtered = filter_by_tag(filtered, tag) unless tag.nil?
+ filtered = filter_by_text(filtered, text) unless text.nil?
+ filtered = filter_by_status(filtered, status) unless status.nil?
+
+ AgendaNotes.new(filtered)
+ end
+
+ private
+
+ def filter_by_tag(notes, tag)
+ notes.select { |note| note.tags.include? tag }
+ end
+
+ def filter_by_text(notes, expression)
+ notes.select do |note|
+ expression.match(note.header) || expression.match(note.body)
+ end
+ end
+
+ def filter_by_status(notes, status)
+ notes.select { |note| note.status == status }
end
end
def self.create_file(title, &block)
File.new(title, &block)
end
end

Йоан обнови решението на 21.12.2015 01:06 (преди над 8 години)

class LazyMode
class Date
attr_reader :year
attr_reader :month
attr_reader :day
attr_reader :interval
def initialize(input, repeater_input = nil)
@year, @month, @day = input.split('-').map(&:to_i)
@interval = get_interval_as_days(repeater_input)
end
def to_s
justified_year = @year.to_s.rjust(4, '0')
justified_month = @month.to_s.rjust(2, '0')
justified_day = @day.to_s.rjust(2, '0')
"#{justified_year}-#{justified_month}-#{justified_day}"
end
def to_days
@day + (30 * @month) + (360 * year)
end
def next_date
new_day = @day + 1
new_month = @month
new_year = @year
new_month += 1 if new_day > 30
new_year += 1 if new_month > 12
Date.new("#{new_year}-#{new_month % 12}-#{new_day % 30}")
end
def next_occurrence
current_date = Date.new("#{@year}-#{@month}-#{@day}")
@interval.times do
current_date = current_date.next_date
end
update_date(current_date)
end
private
def get_interval_as_days(repeater_input)
return nil if repeater_input.nil?
time = repeater_input.scan(/\d+/).first.to_i
multiplier = get_multiplier(repeater_input[-1, 1])
time * multiplier
end
def get_multiplier(symbol)
case symbol
when 'd' then return 1
when 'w' then return 7
when 'm' then return 30
end
end
def update_date(date)
@day = date.day
@month = date.month
@year = date.year
end
end
class Note
attr_reader :header
attr_reader :tags
attr_reader :file_name
attr_reader :date
def initialize(header, *tags, file_name, notes)
@header = header
@tags = tags
@status = :topostpone
@file_name = file_name
@notes = notes || []
end
def scheduled(input)
@date, repeater = input.split(' ')
@date = Date.new(input, repeater)
end
def body(input = nil)
return @body unless input
@body = input
end
def status(input = nil)
return @status unless input
@status = input
end
def note(header, *tags, &block)
note = Note.new(header, *tags, @name, @notes)
note.instance_eval(&block)
@notes.push(note)
end
def match(input_date)
return @date.to_days == input_date.to_days if @date.interval.nil?
@date.next_occurrence while @date.to_days < input_date.to_days
@date.to_days == input_date.to_days
end
alias_method :file_name=, :file_name
alias_method :body=, :body
alias_method :status=, :status
private
def match_days(days, input_days, interval)
while input_days >= days
result = input_days == days
input_days -= interval
end
result
end
end
class File
attr_reader :name
attr_reader :notes
def initialize(name, &block)
@name = name
@notes = []
instance_eval(&block)
end
def daily_agenda(date)
AgendaNotes.new(notes_for_date(date))
end
def weekly_agenda(date)
filtered = notes_for_date(date)
- current_date = date
-
6.times do
- current_date = current_date.next_date
+ date = date.next_date
- filtered += notes_for_date(current_date)
+ filtered += notes_for_date(date)
end
AgendaNotes.new(filtered)
end
def note(header, *tags, &block)
note = Note.new(header, *tags, @name, @notes)
note.instance_eval(&block)
@notes.push(note)
end
private
def notes_for_date(date)
@notes.select { |note| note.match(date) }
end
end
class AgendaNotes
attr_reader :notes
def initialize(notes)
@notes = notes
end
def where(tag: nil, text: nil, status: nil)
filtered = @notes
filtered = filter_by_tag(filtered, tag) unless tag.nil?
filtered = filter_by_text(filtered, text) unless text.nil?
filtered = filter_by_status(filtered, status) unless status.nil?
AgendaNotes.new(filtered)
end
private
def filter_by_tag(notes, tag)
notes.select { |note| note.tags.include? tag }
end
def filter_by_text(notes, expression)
notes.select do |note|
expression.match(note.header) || expression.match(note.body)
end
end
def filter_by_status(notes, status)
notes.select { |note| note.status == status }
end
end
def self.create_file(title, &block)
File.new(title, &block)
end
end