Решение на Седма задача от Виктор Радивчев

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

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

Резултати

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

Код

module LazyMode
attr_accessor :name, :notes
class Date
attr_accessor :year, :month, :day
def initialize(date = '')
date_as_array = date.split('-')
@year = date_as_array[0].to_i
@month = date_as_array[1].to_i
@day = date_as_array[2].to_i
end
def to_s
[year.to_s.rjust(4, '0'), month.to_s.rjust(2, '0'),
day.to_s.rjust(2, '0')].join('-')
end
def to_days
year * 360 + (month - 1) * 30 + day - 1
end
def +(integer)
result = Date.new
days = to_days + integer
result.year = days / 360
result.month = (days % 360) / 30 + 1
result.day = (days % 30) + 1
result
end
end
class Note
attr_reader :header, :tags, :file_name, :repetition
def initialize(header, file_name, *tags)
@header = header
@tags = tags
@body = ''
@status = :topostpone
@file_name = file_name
end
def body(information = nil)
@body = information unless information.nil?
@body
end
def status(new_status = nil)
@status = new_status unless new_status.nil?
@status
end
def string_to_days(string)
period = string.to_i
preriod += 1 if period == 0
type = string.chars.last
type_to_days = { 'd' => 1, 'w' => 7, 'm' => 30 }
type_to_days[type] * period
end
def scheduled(date)
array_for_repetition = date.split(' +')
@scheduled = Date.new(array_for_repetition.first)
if array_for_repetition.size > 1
@repetition = string_to_days(array_for_repetition.last)
else @repetition = 0
end
end
def note(header, *tags, &block)
LazyMode::note(header, *tags, &block)
end
def date
@scheduled
end
def date=(new_date)
@scheduled = new_date
end
end
class File
attr_accessor :name, :notes
def initialize(name)
@name = name
@notes = []
end
def check_for_date(note, date)
differ, repeat = note.date.to_days - date.to_days, note.repetition
return note if differ == 0
new_note = note.dup
new_note.date = date
return new_note if differ < 0 and repeat > 0 and differ % repeat == 0
nil
end
def daily_agenda(date)
result = AgendaFile.new
notes.each do |note|
result.notes << check_for_date(note, date)
end
result.notes.select! { |note| note != nil }
result
end
def up_to_date(note, date)
new_note = note.dup
differ = note.date.to_days - date.to_days
while differ < 0
differ += note.repetition
new_note.date = new_note.date + note.repetition
end
new_note
end
def check_for_week(note, date)
differ, repeat = note.date.to_days - date.to_days, note.repetition
return note if differ >= 0 and differ < 7 and repeat == 0
return nil if repeat == 0
new_note = up_to_date(note, date)
return new_note if new_note.date.to_days - date.to_days < 7
nil
end
def weekly_agenda(date)
result = AgendaFile.new
notes.each do |note|
result.notes << check_for_week(note, date)
end
result.notes.select! { |note| note != nil }
result
end
end
class AgendaFile
attr_accessor :notes
def initialize
@notes = []
end
def appropriate_tag(note, tag)
return true if tag.nil?
note.tags.include? tag
end
def appropriate_text(note, text)
return true if text.nil?
text.match note.header or text.match note.body
end
def appropriate_status(note, status)
return true if status.nil?
note.status == tag
end
def where(hash)
result = self.dup
result.notes.select! { |note| appropriate_tag(note, hash[:tag]) }
result.notes.select! { |note| appropriate_text(note, hash[:text]) }
result.notes.select! { |note| appropriate_status(note, hash[:status]) }
result
end
end
def self.create_file(name, &block)
@name = name
@notes = []
file = File.new(name)
self.instance_exec(&block)
file.notes = @notes
file
end
def self.note(header, *tags, &block)
result = Note.new(header, @name, *tags)
result.instance_exec(&block)
@notes << result
end
end

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

...................F.......FF..

Failures:

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

  2) LazyMode#where filters by status
     Failure/Error: notes = @agenda.where(status: :postponed).notes
     NameError:
       undefined local variable or method `tag' for #<LazyMode::AgendaFile:0x007fa1776bf768>
     # /tmp/d20160107-5693-h9mn5e/solution.rb:158:in `appropriate_status'
     # /tmp/d20160107-5693-h9mn5e/solution.rb:165:in `block in where'
     # /tmp/d20160107-5693-h9mn5e/solution.rb:165:in `select!'
     # /tmp/d20160107-5693-h9mn5e/solution.rb:165:in `where'
     # /tmp/d20160107-5693-h9mn5e/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)>'

  3) LazyMode#where filters by multiple filters
     Failure/Error: notes = @agenda.where(text: /important/, status: :postponed).notes
     NameError:
       undefined local variable or method `tag' for #<LazyMode::AgendaFile:0x007fa1776bc090>
     # /tmp/d20160107-5693-h9mn5e/solution.rb:158:in `appropriate_status'
     # /tmp/d20160107-5693-h9mn5e/solution.rb:165:in `block in where'
     # /tmp/d20160107-5693-h9mn5e/solution.rb:165:in `select!'
     # /tmp/d20160107-5693-h9mn5e/solution.rb:165:in `where'
     # /tmp/d20160107-5693-h9mn5e/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)>'

Finished in 0.01721 seconds
31 examples, 3 failures

Failed examples:

rspec /tmp/d20160107-5693-h9mn5e/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-h9mn5e/spec.rb:432 # LazyMode#where filters by status
rspec /tmp/d20160107-5693-h9mn5e/spec.rb:443 # LazyMode#where filters by multiple filters

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

Виктор обнови решението на 21.12.2015 11:57 (преди над 8 години)

+module LazyMode
+ attr_accessor :name, :notes
+
+ class Date
+ attr_accessor :year, :month, :day
+
+ def initialize(date = '')
+ date_as_array = date.split('-')
+ @year = date_as_array[0].to_i
+ @month = date_as_array[1].to_i
+ @day = date_as_array[2].to_i
+ end
+
+ def to_s
+ [year.to_s.rjust(4, '0'), month.to_s.rjust(2, '0'),
+ day.to_s.rjust(2, '0')].join('-')
+ end
+
+ def to_days
+ year * 360 + (month - 1) * 30 + day - 1
+ end
+
+ def +(integer)
+ result = Date.new
+ days = to_days + integer
+ result.year = days / 360
+ result.month = (days % 360) / 30 + 1
+ result.day = (days % 30) + 1
+ result
+ end
+ end
+
+ class Note
+ attr_reader :header, :tags, :file_name, :repetition
+
+ def initialize(header, file_name, *tags)
+ @header = header
+ @tags = tags
+ @body = ''
+ @status = :topostpone
+ @file_name = file_name
+ end
+
+ def body(information = nil)
+ @body = information unless information.nil?
+ @body
+ end
+
+ def status(new_status = nil)
+ @status = new_status unless new_status.nil?
+ @status
+ end
+
+ def string_to_days(string)
+ period = string.to_i
+ preriod += 1 if period == 0
+ type = string.chars.last
+ type_to_days = { 'd' => 1, 'w' => 7, 'm' => 30 }
+ type_to_days[type] * period
+ end
+
+ def scheduled(date)
+ array_for_repetition = date.split(' +')
+ @scheduled = Date.new(array_for_repetition.first)
+ if array_for_repetition.size > 1
+ @repetition = string_to_days(array_for_repetition.last)
+ else @repetition = 0
+ end
+ end
+
+ def note(header, *tags, &block)
+ LazyMode::note(header, *tags, &block)
+ end
+
+ def date
+ @scheduled
+ end
+
+ def date=(new_date)
+ @scheduled = new_date
+ end
+ end
+
+ class File
+ attr_accessor :name, :notes
+
+ def initialize(name)
+ @name = name
+ @notes = []
+ end
+
+ def check_for_date(note, date)
+ differ, repeat = note.date.to_days - date.to_days, note.repetition
+ return note if differ == 0
+ new_note = note.dup
+ new_note.date = date
+ return new_note if differ < 0 and repeat > 0 and differ % repeat == 0
+ nil
+ end
+
+ def daily_agenda(date)
+ result = AgendaFile.new
+ notes.each do |note|
+ result.notes << check_for_date(note, date)
+ end
+ result.notes.select! { |note| note != nil }
+ result
+ end
+
+ def up_to_date(note, date)
+ new_note = note.dup
+ differ = note.date.to_days - date.to_days
+ while differ < 0
+ differ += note.repetition
+ new_note.date = new_note.date + note.repetition
+ end
+ new_note
+ end
+
+ def check_for_week(note, date)
+ differ, repeat = note.date.to_days - date.to_days, note.repetition
+ return note if differ >= 0 and differ < 7 and repeat == 0
+ return nil if repeat == 0
+ new_note = up_to_date(note, date)
+ return new_note if new_note.date.to_days - date.to_days < 7
+ nil
+ end
+
+ def weekly_agenda(date)
+ result = AgendaFile.new
+ notes.each do |note|
+ result.notes << check_for_week(note, date)
+ end
+ result.notes.select! { |note| note != nil }
+ result
+ end
+ end
+
+ class AgendaFile
+ attr_accessor :notes
+
+ def initialize
+ @notes = []
+ end
+
+ def appropriate_tag(note, tag)
+ return true if tag.nil?
+ note.tags.include? tag
+ end
+
+ def appropriate_text(note, text)
+ return true if text.nil?
+ text.match note.header or text.match note.body
+ end
+
+ def appropriate_status(note, status)
+ return true if status.nil?
+ note.status == tag
+ end
+
+ def where(hash)
+ result = self.dup
+ result.notes.select! { |note| appropriate_tag(note, hash[:tag]) }
+ result.notes.select! { |note| appropriate_text(note, hash[:text]) }
+ result.notes.select! { |note| appropriate_status(note, hash[:status]) }
+ result
+ end
+ end
+
+ def self.create_file(name, &block)
+ @name = name
+ @notes = []
+ file = File.new(name)
+ self.instance_exec(&block)
+ file.notes = @notes
+ file
+ end
+
+ def self.note(header, *tags, &block)
+ result = Note.new(header, @name, *tags)
+ result.instance_exec(&block)
+ @notes << result
+ end
+end