Решение на Седма задача от Димитър Терзиев

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

Към профила на Димитър Терзиев

Резултати

  • 2 точки от тестове
  • 0 бонус точки
  • 2 точки общо
  • 12 успешни тест(а)
  • 19 неуспешни тест(а)

Код

class LazyMode
class Date
YEAR_DAYS = 30 * 12
MONTH_DAYS = 30
WEEK_DAYS = 7
def initialize(start_date)
@year, @month, @day = start_date.split("-")
end
def year
@year
end
def month
@month
end
def day
@day
end
def to_s
"#{@year}-#{@month}-#{@day}"
end
def match_date(other_date, period, match_type)
difference = days_difference(other_date)
difference %= period_frequency(period) if period
case match_type
when :weekly then difference.between?(0, WEEK_DAYS)
when :daily then difference == 0
end
end
def days_difference(other_date)
days_difference = (other_date.year.to_i - year.to_i) * YEAR_DAYS
days_difference += (other_date.month.to_i - month.to_i) * MONTH_DAYS
days_difference += other_date.day.to_i - day.to_i
end
def period_frequency(period)
n = period[1 .. -2].to_i
n * case period[-1]
when "m" then MONTH_DAYS
when "w" then WEEK_DAYS
when "d" then 1
end
end
end
class Note
def initialize(header, file, *tags)
@header = header
@file = file
@tags = tags.flatten
@status = :topostpone
end
def header
@header
end
def file_name
@file.name
end
def body(new_body = nil)
@body = new_body ? new_body : @body
end
def status(new_status = nil)
@status = new_status ? new_status : @status
end
def tags
@tags
end
def scheduled(new_date = nil)
@date = new_date ? new_date : @date
end
def note(header, *tags, &initialization_block)
@file.note header, *tags, &initialization_block
end
end
def self.create_file(file_name, &initialization_block)
file = File.new file_name
file.instance_eval &initialization_block
file
end
class File
def initialize(file_name)
@file_name = file_name
@notes = []
end
def name
@file_name
end
def notes
@notes
end
def note(header, *tags, &initialization_block)
@notes << Note.new(header, self, tags)
@notes.last.instance_eval &initialization_block
end
def daily_agenda(date)
create_agenda date, :daily
end
def weekly_agenda(date)
create_agenda date, :weekly
end
def create_agenda(date, type)
Agenda.new (@notes.select do |note|
note_date = note.scheduled
other_date = Date.new note_date[/\d{4}-\d{2}-\d{2}/]
period = note_date[/\+\d[mdw]/]
date.match_date other_date, period, type
end), date, type
end
end
class Agenda
def initialize(notes, date, type)
@notes = notes
@type = type
@date = date
@notes.each{ |note| define_date_to_note note }
end
def define_date_to_note(note)
date = determine_date note
note.instance_eval do
@agenda_date = date
def date
@agenda_date
end
end
end
def determine_date(note)
date = note.scheduled
if date.length > 10
return periodic_date(date)
else
return date
end
end
def periodic_date(date_string)
return @date unless @type == "weekly"
date = Date.new date_string[/\d{4}-\d{2}-\d{2}/]
period = date_string[/\+\d[mdw]/]
weekly_periodic_date date, period
end
def weekly_periodic_date(date, period)
difference = @date.days_difference(date) % @date.period_frequency(period)
day = date.day.to_i + difference
month = date.month.to_i + (day / 30)
year = date.year.to_i + (month / 12)
new_date = [year, month % 12, day % 30]
new_date.map{ |time| time.to_s.rjust(2, '0')}.join("-")
end
def notes
@notes
end
def where(tag: nil, text: /.*/, status: nil)
notes = @notes.select do |note|
note.header =~ text &&
(note.tags.include? tag || ! tag) &&
(note.status == status || ! status)
end
Agenda.new notes, @date, @type
end
end
end

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

FFF..F.....FFFFFF.FFFFF..FFFF..

Failures:

  1) LazyMode LazyMode::Date can parse year
     Failure/Error: expect(date.year).to eq(2012)
       
       expected: 2012
            got: "2012"
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:5: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::Date can parse month
     Failure/Error: expect(date.month).to eq(10)
       
       expected: 10
            got: "10"
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:10: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 LazyMode::Date can parse day
     Failure/Error: expect(date.day).to eq(3)
       
       expected: 3
            got: "03"
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:15: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 LazyMode::Note can have nested notes
     Failure/Error: expect(file.notes.first.body).to eq('')
       
       expected: ""
            got: nil
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/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)>'

  5) 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-656k8o/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)>'

  6) LazyMode#daily_agenda returns note scheduled without repeater
     Failure/Error: expect(note.date.year).to eq(2012)
     NoMethodError:
       undefined method `year' for "2012-12-12":String
     # /tmp/d20160107-5693-656k8o/spec.rb:136: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#daily_agenda returns note scheduled with daily repeater
     Failure/Error: expect(note.date.year).to eq(2012)
       
       expected: 2012
            got: "2012"
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:158: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#daily_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     NoMethodError:
       undefined method `split' for nil:NilClass
     # /tmp/d20160107-5693-656k8o/solution.rb:8:in `initialize'
     # /tmp/d20160107-5693-656k8o/solution.rb:125:in `new'
     # /tmp/d20160107-5693-656k8o/solution.rb:125:in `block in create_agenda'
     # /tmp/d20160107-5693-656k8o/solution.rb:123:in `select'
     # /tmp/d20160107-5693-656k8o/solution.rb:123:in `create_agenda'
     # /tmp/d20160107-5693-656k8o/solution.rb:115:in `daily_agenda'
     # /tmp/d20160107-5693-656k8o/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)>'

  9) LazyMode#daily_agenda returns note scheduled with monthly repeater
     Failure/Error: expect(note.date.year).to eq(2013)
       
       expected: 2013
            got: "2013"
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:203: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#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-656k8o/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)>'

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

  12) 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-656k8o/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)>'

  13) LazyMode#weekly_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-12-10'))
     NoMethodError:
       undefined method `split' for nil:NilClass
     # /tmp/d20160107-5693-656k8o/solution.rb:8:in `initialize'
     # /tmp/d20160107-5693-656k8o/solution.rb:125:in `new'
     # /tmp/d20160107-5693-656k8o/solution.rb:125:in `block in create_agenda'
     # /tmp/d20160107-5693-656k8o/solution.rb:123:in `select'
     # /tmp/d20160107-5693-656k8o/solution.rb:123:in `create_agenda'
     # /tmp/d20160107-5693-656k8o/solution.rb:119:in `weekly_agenda'
     # /tmp/d20160107-5693-656k8o/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)>'

  14) LazyMode#weekly_agenda returns note scheduled with monthly repeater
     Failure/Error: expect(note.date.year).to eq(2013)
       
       expected: 2013
            got: "2013"
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:332: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#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-656k8o/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)>'

  16) LazyMode#where filters by body text
     Failure/Error: expect(notes.size).to eq(1)
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:411: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)>'

  17) LazyMode#where filters by header text
     Failure/Error: expect(notes.size).to eq(1)
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:423: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)>'

  18) LazyMode#where filters by status
     Failure/Error: expect(notes.size).to eq(1)
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:434: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)>'

  19) LazyMode#where filters by multiple filters
     Failure/Error: expect(notes.size).to eq(1)
       
       expected: 1
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-656k8o/spec.rb:445: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.01557 seconds
31 examples, 19 failures

Failed examples:

rspec /tmp/d20160107-5693-656k8o/spec.rb:3 # LazyMode LazyMode::Date can parse year
rspec /tmp/d20160107-5693-656k8o/spec.rb:8 # LazyMode LazyMode::Date can parse month
rspec /tmp/d20160107-5693-656k8o/spec.rb:13 # LazyMode LazyMode::Date can parse day
rspec /tmp/d20160107-5693-656k8o/spec.rb:98 # LazyMode LazyMode::Note can have nested notes
rspec /tmp/d20160107-5693-656k8o/spec.rb:88 # LazyMode LazyMode::Note #body can have no body
rspec /tmp/d20160107-5693-656k8o/spec.rb:119 # LazyMode#daily_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:141 # LazyMode#daily_agenda returns note scheduled with daily repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:163 # LazyMode#daily_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:186 # LazyMode#daily_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:208 # LazyMode#daily_agenda does not return note whose start date is in the future
rspec /tmp/d20160107-5693-656k8o/spec.rb:237 # LazyMode#weekly_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:283 # LazyMode#weekly_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:315 # LazyMode#weekly_agenda returns note scheduled with monthly repeater
rspec /tmp/d20160107-5693-656k8o/spec.rb:337 # LazyMode#weekly_agenda does not return note whose start date is in the future
rspec /tmp/d20160107-5693-656k8o/spec.rb:408 # LazyMode#where filters by body text
rspec /tmp/d20160107-5693-656k8o/spec.rb:420 # LazyMode#where filters by header text
rspec /tmp/d20160107-5693-656k8o/spec.rb:432 # LazyMode#where filters by status
rspec /tmp/d20160107-5693-656k8o/spec.rb:443 # LazyMode#where filters by multiple filters

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

Димитър обнови решението на 18.12.2015 00:59 (преди около 9 години)

+class LazyMode
+ class Date
+ YEAR_DAYS = 30 * 12
+ MONTH_DAYS = 30
+ WEEK_DAYS = 7
+
+ def initialize(start_date)
+ @year, @month, @day = start_date.split("-")
+ end
+
+ def year
+ @year
+ end
+
+ def month
+ @month
+ end
+
+ def day
+ @day
+ end
+
+ def to_s
+ "#{@year}-#{@month}-#{@day}"
+ end
+
+ def match_date(other_date, period, match_type)
+ difference = days_difference(other_date)
+ difference %= period_frequency(period) if period
+ case match_type
+ when :weekly then difference.between?(0, WEEK_DAYS)
+ when :daily then difference == 0
+ end
+ end
+
+ def days_difference(other_date)
+ days_difference = (other_date.year.to_i - year.to_i) * YEAR_DAYS
+ days_difference += (other_date.month.to_i - month.to_i) * MONTH_DAYS
+ days_difference += other_date.day.to_i - day.to_i
+ end
+
+ def period_frequency(period)
+ n = period[1 .. -2].to_i
+ n * case period[-1]
+ when "m" then MONTH_DAYS
+ when "w" then WEEK_DAYS
+ when "d" then 1
+ end
+ end
+ end
+
+ class Note
+ def initialize(header, file, *tags)
+ @header = header
+ @file = file
+ @tags = tags.flatten
+ @status = :topostpone
+ end
+
+ def header
+ @header
+ end
+
+ def file_name
+ @file.name
+ end
+
+ def body(new_body = nil)
+ @body = new_body ? new_body : @body
+ end
+
+ def status(new_status = nil)
+ @status = new_status ? new_status : @status
+ end
+
+ def tags
+ @tags
+ end
+
+ def scheduled(new_date = nil)
+ @date = new_date ? new_date : @date
+ end
+
+ def note(header, *tags, &initialization_block)
+ @file.note header, *tags, &initialization_block
+ end
+ end
+
+ def self.create_file(file_name, &initialization_block)
+ file = File.new file_name
+ file.instance_eval &initialization_block
+ file
+ end
+
+ class File
+ def initialize(file_name)
+ @file_name = file_name
+ @notes = []
+ end
+
+ def name
+ @file_name
+ end
+
+ def notes
+ @notes
+ end
+
+ def note(header, *tags, &initialization_block)
+ @notes << Note.new(header, self, tags)
+ @notes.last.instance_eval &initialization_block
+ end
+
+ def daily_agenda(date)
+ create_agenda date, :daily
+ end
+
+ def weekly_agenda(date)
+ create_agenda date, :weekly
+ end
+
+ def create_agenda(date, type)
+ Agenda.new (@notes.select do |note|
+ note_date = note.scheduled
+ other_date = Date.new note_date[/\d{4}-\d{2}-\d{2}/]
+ period = note_date[/\+\d[mdw]/]
+ date.match_date other_date, period, type
+ end), date
+ end
+ end
+
+ class Agenda
+ def initialize(notes, date)
+ @notes = notes
+ @date = date
+ @notes.each do |note|
+ define_date_to_note note, date
+ end
+ end
+
+ def define_date_to_note(note, date)
+ note.instance_eval do
+ @agenda_date = date
+ def date
+ @agenda_date
+ end
+ end
+ end
+
+ def notes
+ @notes
+ end
+
+ def where(tag: nil, text: /.*/, status: nil)
+ notes = @notes.select do |note|
+ note.header =~ text &&
+ (note.tags.include? tag || ! tag) &&
+ (note.status == status || ! status)
+ end
+ Agenda.new notes, @date
+ end
+ end
+end

Димитър обнови решението на 18.12.2015 09:46 (преди около 9 години)

class LazyMode
class Date
YEAR_DAYS = 30 * 12
MONTH_DAYS = 30
WEEK_DAYS = 7
def initialize(start_date)
@year, @month, @day = start_date.split("-")
end
def year
@year
end
def month
@month
end
def day
@day
end
def to_s
"#{@year}-#{@month}-#{@day}"
end
def match_date(other_date, period, match_type)
difference = days_difference(other_date)
difference %= period_frequency(period) if period
case match_type
when :weekly then difference.between?(0, WEEK_DAYS)
when :daily then difference == 0
end
end
def days_difference(other_date)
days_difference = (other_date.year.to_i - year.to_i) * YEAR_DAYS
days_difference += (other_date.month.to_i - month.to_i) * MONTH_DAYS
days_difference += other_date.day.to_i - day.to_i
end
def period_frequency(period)
n = period[1 .. -2].to_i
n * case period[-1]
when "m" then MONTH_DAYS
when "w" then WEEK_DAYS
when "d" then 1
end
end
end
class Note
def initialize(header, file, *tags)
@header = header
@file = file
@tags = tags.flatten
@status = :topostpone
end
def header
@header
end
def file_name
@file.name
end
def body(new_body = nil)
@body = new_body ? new_body : @body
end
def status(new_status = nil)
@status = new_status ? new_status : @status
end
def tags
@tags
end
def scheduled(new_date = nil)
@date = new_date ? new_date : @date
end
def note(header, *tags, &initialization_block)
@file.note header, *tags, &initialization_block
end
end
def self.create_file(file_name, &initialization_block)
file = File.new file_name
file.instance_eval &initialization_block
file
end
class File
def initialize(file_name)
@file_name = file_name
@notes = []
end
def name
@file_name
end
def notes
@notes
end
def note(header, *tags, &initialization_block)
@notes << Note.new(header, self, tags)
@notes.last.instance_eval &initialization_block
end
def daily_agenda(date)
create_agenda date, :daily
end
def weekly_agenda(date)
create_agenda date, :weekly
end
def create_agenda(date, type)
Agenda.new (@notes.select do |note|
note_date = note.scheduled
other_date = Date.new note_date[/\d{4}-\d{2}-\d{2}/]
period = note_date[/\+\d[mdw]/]
date.match_date other_date, period, type
- end), date
+ end), date, type
end
end
class Agenda
- def initialize(notes, date)
+ def initialize(notes, date, type)
@notes = notes
+ @type = type
@date = date
- @notes.each do |note|
- define_date_to_note note, date
- end
+ @notes.each{ |note| define_date_to_note note }
end
- def define_date_to_note(note, date)
+ def define_date_to_note(note)
+ date = determine_date note
note.instance_eval do
- @agenda_date = date
+ @agenda_date = date
def date
@agenda_date
end
end
end
+ def determine_date(note)
+ date = note.scheduled
+ if date.length > 10
+ return periodic_date(date)
+ else
+ return date
+ end
+ end
+
+ def periodic_date(date_string)
+ return @date unless @type == "weekly"
+ date = Date.new date_string[/\d{4}-\d{2}-\d{2}/]
+ period = date_string[/\+\d[mdw]/]
+ weekly_periodic_date date, period
+ end
+
+ def weekly_periodic_date(date, period)
+ difference = @date.days_difference(date) % @date.period_frequency(period)
+ day = date.day.to_i + difference
+ month = date.month.to_i + (day / 30)
+ year = date.year.to_i + (month / 12)
+ new_date = [year, month % 12, day % 30]
+ new_date.map{ |time| time.to_s.rjust(2, '0')}.join("-")
+ end
+
def notes
@notes
end
def where(tag: nil, text: /.*/, status: nil)
notes = @notes.select do |note|
note.header =~ text &&
(note.tags.include? tag || ! tag) &&
(note.status == status || ! status)
end
- Agenda.new notes, @date
+ Agenda.new notes, @date, @type
end
end
end