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

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

Към профила на Марк Андонов

Резултати

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

Код

class LazyMode
def self.create_file(file_name, &block)
file = File.new(file_name)
file.instance_eval &block if block_given?
file
end
class Date
attr_accessor :period
def initialize(date)
@year = date.split("-")[0].rjust(4, "0")
@month = date.split("-")[1].rjust(2, "0")
@day = date.split("-")[2].rjust(2, "0")
end
def day
@day.to_i
end
def year
@year.to_i
end
def month
@month.to_i
end
def to_s
[@year, @month, @day].join("-")
end
def add_day
@day == "30" ? @day = "01" : @day = (day + 1).to_s.rjust(2,"0")
add_month if @day == "01"
end
def add_month
@month == "12" ? @month = "01" : @month = (month + 1).to_s.rjust(2,"0")
@year = (year + 1).to_s.rjust(4,"0") if @month == "01"
end
end
class Note
attr_accessor :file_name, :body, :status, :date
attr_reader :header, :tags
def initialize(header, *tags, file_name)
@header = header
@tags = tags.flatten
@file_name = file_name
@body = ""
@status = :topostpone
end
def clone_with_different_date(date)
note = self.clone
note.date = date
note
end
end
class Agenda
def initialize(date)
@date = date
end
def days_between_dates(note)
difference_year = @date.year - note.date.year
difference_month = @date.month - note.date.month
difference_day = @date.day - note.date.day
difference_year * 360 + difference_month * 30 + difference_day
end
end
class DailyAgenda < Agenda
def initialize(date, notes)
@date = date
@notes = notes
daily_notes
end
def daily_notes
@daily_notes = []
@notes.each { |note| add_daily_note?(note) }
end
def notes
@daily_notes
end
def add_daily_note?(note)
if note.date.to_s == @date.to_s
@daily_notes.push(note)
elsif(note.date.period && days_between_dates(note) % note.date.period == 0)
@daily_notes.push(note.clone_with_different_date(@date))
end
end
end
class WeeklyAgenda
def initialize(date, notes)
@date = date
@notes = notes
weekly_notes
end
def weekly_notes
@weekly_notes = []
date = @date
(0...7).each do
@weekly_notes.concat(DailyAgenda.new(date, @notes).notes)
date.add_day
end
@filtered_notes = @weekly_notes
end
def notes
@weekly_notes
end
def where(filter_hash, filter_1 = {}, filter_2 = {})
filter_hash.merge!(filter_1).merge!(filter_2)
@filtered_notes.delete_if do |note|
check_tag(filter_hash.fetch(:tag, nil), note) ||
check_text(filter_hash.fetch(:text, //), note) ||
check_status(filter_hash.fetch(:status, nil))
end
FilteredAgenda.new(@filtered_notes)
end
def check_tag(tag, note)
tag == nil ? false : !note.tags.include?(tag)
end
def check_status(status)
status == nil ? false : !(status == :topostpone || status == :postponed)
end
def check_text(text, note)
!((note.header + note.body) =~ text)
end
end
class EvaluateNote
def initialize(header, *tags, file_name)
@file_name = file_name
@note = Note.new(header, tags, file_name)
@notes = []
end
def body(body)
@note.body = body
end
def status(status)
@note.status = status
end
def scheduled(date)
@note.date = Date.new(date.split("+")[0])
calculate_period(date.split("+")[1]) if date.split("+")[1]
end
def calculate_period(period_string)
period = period_string.slice!(-1)
@note.date.period = period_string.to_i if period == "d"
@note.date.period = period_string.to_i * 7 if period == "w"
@note.date.period = period_string.to_i * 30 if period == "m"
end
def note(header, *tags, &block)
@notes.push(@note)
@note = Note.new(header, tags, @file_name)
self.instance_eval &block
end
def notes
@notes.push(@note)
end
end
class FilteredAgenda
def initialize(notes)
@notes = notes
end
def notes
@notes
end
end
class File
attr_accessor :name
def initialize(name)
@name = name
@notes = []
end
def notes
@notes
end
def note(header, *tags, &block)
object = EvaluateNote.new(header, tags, @name)
object.instance_eval &block if block_given?
@notes.concat(object.notes)
end
def daily_agenda(date)
DailyAgenda.new(date,@notes)
end
def weekly_agenda(date)
WeeklyAgenda.new(date,@notes)
end
end
end

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

................F..FFFF.FFFFF..

Failures:

  1) LazyMode#daily_agenda does not return note whose start date is in the future
     Failure/Error: expect(agenda.notes.size).to eq(0)
       
       expected: 0
            got: 1
       
       (compared using ==)
     # /tmp/d20160107-5693-dpcysa/spec.rb:216: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#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: 7
       
       (compared using ==)
     # /tmp/d20160107-5693-dpcysa/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)>'

  3) LazyMode#weekly_agenda returns note scheduled with weekly repeater
     Failure/Error: expect(first_note.date.day).to eq(12)
       
       expected: 12
            got: 17
       
       (compared using ==)
     # /tmp/d20160107-5693-dpcysa/spec.rb:303: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#weekly_agenda returns note scheduled with monthly repeater
     Failure/Error: expect(note.date.day).to eq(12)
       
       expected: 12
            got: 17
       
       (compared using ==)
     # /tmp/d20160107-5693-dpcysa/spec.rb:334: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#weekly_agenda does not return note whose start date is in the future
     Failure/Error: expect(agenda.notes.size).to eq(0)
       
       expected: 0
            got: 1
       
       (compared using ==)
     # /tmp/d20160107-5693-dpcysa/spec.rb:345: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#where filters by tag
     Failure/Error: notes = @agenda.where(tag: :important).notes
     NoMethodError:
       undefined method `where' for #<LazyMode::DailyAgenda:0x007fd6428861c8>
     # /tmp/d20160107-5693-dpcysa/spec.rb:391: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#where filters by body text
     Failure/Error: notes = @agenda.where(text: /Very/).notes
     NoMethodError:
       undefined method `where' for #<LazyMode::DailyAgenda:0x007fd64287daa0>
     # /tmp/d20160107-5693-dpcysa/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)>'

  8) LazyMode#where filters by header text
     Failure/Error: notes = @agenda.where(text: /not important/).notes
     NoMethodError:
       undefined method `where' for #<LazyMode::DailyAgenda:0x007fd6428785f0>
     # /tmp/d20160107-5693-dpcysa/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)>'

  9) LazyMode#where filters by status
     Failure/Error: notes = @agenda.where(status: :postponed).notes
     NoMethodError:
       undefined method `where' for #<LazyMode::DailyAgenda:0x007fd64286fb80>
     # /tmp/d20160107-5693-dpcysa/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)>'

  10) LazyMode#where filters by multiple filters
     Failure/Error: notes = @agenda.where(text: /important/, status: :postponed).notes
     NoMethodError:
       undefined method `where' for #<LazyMode::DailyAgenda:0x007fd64286b648>
     # /tmp/d20160107-5693-dpcysa/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.01853 seconds
31 examples, 10 failures

Failed examples:

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

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

Марк обнови решението на 21.12.2015 14:56 (преди над 8 години)

+class LazyMode
+ def self.create_file(file_name, &block)
+ file = File.new(file_name)
+ file.instance_eval &block if block_given?
+ file
+ end
+
+ class Date
+ attr_accessor :period
+
+ def initialize(date)
+ @year = date.split("-")[0].rjust(4, "0")
+ @month = date.split("-")[1].rjust(2, "0")
+ @day = date.split("-")[2].rjust(2, "0")
+ end
+
+ def day
+ @day.to_i
+ end
+
+ def year
+ @year.to_i
+ end
+
+ def month
+ @month.to_i
+ end
+
+ def to_s
+ [@year, @month, @day].join("-")
+ end
+
+ def add_day
+ @day == "30" ? @day = "01" : @day = (day + 1).to_s.rjust(2,"0")
+ add_month if @day == "01"
+ end
+
+ def add_month
+ @month == "12" ? @month = "01" : @month = (month + 1).to_s.rjust(2,"0")
+ @year = (year + 1).to_s.rjust(4,"0") if @month == "01"
+ end
+ end
+
+ class Note
+ attr_accessor :file_name, :body, :status, :date
+ attr_reader :header, :tags
+
+ def initialize(header, *tags, file_name)
+ @header = header
+ @tags = tags.flatten
+ @file_name = file_name
+ @body = ""
+ @status = :topostpone
+ end
+
+ def clone_with_different_date(date)
+ note = self.clone
+ note.date = date
+ note
+ end
+ end
+
+ class Agenda
+
+ def initialize(date)
+ @date = date
+ end
+
+ def days_between_dates(note)
+ difference_year = @date.year - note.date.year
+ difference_month = @date.month - note.date.month
+ difference_day = @date.day - note.date.day
+ difference_year * 360 + difference_month * 30 + difference_day
+ end
+ end
+
+ class DailyAgenda < Agenda
+
+ def initialize(date, notes)
+ @date = date
+ @notes = notes
+ daily_notes
+ end
+
+ def daily_notes
+ @daily_notes = []
+ @notes.each { |note| add_daily_note?(note) }
+ end
+
+ def notes
+ @daily_notes
+ end
+
+ def add_daily_note?(note)
+ if note.date.to_s == @date.to_s
+ @daily_notes.push(note)
+ elsif(note.date.period && days_between_dates(note) % note.date.period == 0)
+ @daily_notes.push(note.clone_with_different_date(@date))
+ end
+ end
+ end
+
+ class WeeklyAgenda
+
+ def initialize(date, notes)
+ @date = date
+ @notes = notes
+ weekly_notes
+ end
+
+ def weekly_notes
+ @weekly_notes = []
+ date = @date
+ (0...7).each do
+ @weekly_notes.concat(DailyAgenda.new(date, @notes).notes)
+ date.add_day
+ end
+ @filtered_notes = @weekly_notes
+ end
+
+ def notes
+ @weekly_notes
+ end
+
+ def where(filter_hash, filter_1 = {}, filter_2 = {})
+ filter_hash.merge!(filter_1).merge!(filter_2)
+ @filtered_notes.delete_if do |note|
+ check_tag(filter_hash.fetch(:tag, nil), note) ||
+ check_text(filter_hash.fetch(:text, //), note) ||
+ check_status(filter_hash.fetch(:status, nil))
+ end
+ FilteredAgenda.new(@filtered_notes)
+ end
+
+ def check_tag(tag, note)
+ tag == nil ? false : !note.tags.include?(tag)
+ end
+
+ def check_status(status)
+ status == nil ? false : !(status == :topostpone || status == :postponed)
+ end
+
+ def check_text(text, note)
+ !((note.header + note.body) =~ text)
+ end
+ end
+
+
+ class EvaluateNote
+
+ def initialize(header, *tags, file_name)
+ @file_name = file_name
+ @note = Note.new(header, tags, file_name)
+ @notes = []
+ end
+
+ def body(body)
+ @note.body = body
+ end
+
+ def status(status)
+ @note.status = status
+ end
+
+ def scheduled(date)
+ @note.date = Date.new(date.split("+")[0])
+ calculate_period(date.split("+")[1]) if date.split("+")[1]
+ end
+
+ def calculate_period(period_string)
+ period = period_string.slice!(-1)
+ @note.date.period = period_string.to_i if period == "d"
+ @note.date.period = period_string.to_i * 7 if period == "w"
+ @note.date.period = period_string.to_i * 30 if period == "m"
+ end
+
+ def note(header, *tags, &block)
+ @notes.push(@note)
+ @note = Note.new(header, tags, @file_name)
+ self.instance_eval &block
+ end
+
+ def notes
+ @notes.push(@note)
+ end
+ end
+
+ class FilteredAgenda
+ def initialize(notes)
+ @notes = notes
+ end
+
+ def notes
+ @notes
+ end
+ end
+
+ class File
+ attr_accessor :name
+ def initialize(name)
+ @name = name
+ @notes = []
+ end
+
+ def notes
+ @notes
+ end
+
+ def note(header, *tags, &block)
+ object = EvaluateNote.new(header, tags, @name)
+ object.instance_eval &block if block_given?
+ @notes.concat(object.notes)
+ end
+
+ def daily_agenda(date)
+ DailyAgenda.new(date,@notes)
+ end
+
+ def weekly_agenda(date)
+ WeeklyAgenda.new(date,@notes)
+ end
+ end
+end