Решение на Седма задача от Георги Киряков

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

Към профила на Георги Киряков

Резултати

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

Код

class LazyMode
class Date
private
def set_date(year, month, day)
@year = year.to_i
@month = month.to_i
@day = day.to_i
end
public
attr :year, :month, :day, :step
def Date.new_date(year, month, day)
Date.new("#{year}-#{month}-#{day}")
end
def initialize(date)
date_match = date.match(/(\d+-\d+-\d+)(\s\+(\d+)([mdw]))?/)
set_date(*date_match[1].split('-'))
@step = date_match[3].to_i if date_match[2]
case date_match[4]
when 'w' then @step *= 7
when 'm' then @step *= 30
end
end
def next_day
year, month, day = @year, @month, @day + 1
month += 1 if day > 30
day %= 30
year += 1 if month > 12
month %= 12
Date.new_date(year, month, day)
end
def to_s
year = @year.to_s.rjust(4, '0')
month = @month.to_s.rjust(2, '0')
day = @day.to_s.rjust(2, '0')
"#{year}-#{month}-#{day}"
end
def fix(date)
if @step != nil && date =~ self
@day = date.day
@month = date.month
@year = date.year
end
end
def to_i
year * 360 + month * 30 + day
end
def =~(other)
return false if to_s < other.to_s
return true if to_s == other.to_s
return (to_i - other.to_i) % other.step == 0 if other.step
false
end
end
class Note
attr_accessor :header, :file_name, :body, :status, :tags, :date
def initialize(file_name, header, tags = [])
@file_name = file_name
@header = header
@tags = tags
@status = :topostpone
@body = ""
end
end
class NoteDSL
attr :note, :file
def initialize(note, file, &block)
@note = note
@file = file
end
def body(value)
@note.body = value
end
def status(value)
@note.status = value
end
def scheduled(date_string)
@note.date = Date.new(date_string)
end
def note(*args, &block)
@file.send(:note, *args, &block)
end
end
class Agenda
attr :notes
def initialize(notes, date = nil)
@notes = notes
select(date) if date
end
def where(tag: nil, text: nil, status: nil)
notes = @notes.select { |note| tag.nil? || note.tags.include?(tag) }
notes.select! do |note|
text.nil? || note.body.match(text) || note.header.match(text)
end
notes.select! { |note| status.nil? || note.status == status }
Agenda.new(notes)
end
private
def select(date)
@notes = @notes.select { |note| date =~ note.date }
@notes = @notes.map do |note|
agenda_note = note.clone
agenda_note.date.fix(date)
agenda_note
end
end
end
class File
attr :name, :notes
def initialize(name)
@name = name
@notes = []
end
def daily_agenda(date)
Agenda.new(@notes, date)
end
def weekly_agenda(date)
notes = []
(0...7).each do
agenda = daily_agenda(date)
notes += agenda.notes
date = date.next_day
end
Agenda.new(notes)
end
private
def note(header, *tags, &block)
new_note = Note.new(@name, header, tags)
@notes.push new_note
note = NoteDSL.new(new_note, self)
note.instance_eval(&block)
new_note
end
end
def self.create_file(name, &block)
file = File.new name
file.instance_eval &block
file
end
end

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

..................FFF..........

Failures:

  1) 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-r0gq2c/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)>'

  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: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-r0gq2c/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(agenda.notes.size).to eq(2)
       
       expected: 2
            got: 0
       
       (compared using ==)
     # /tmp/d20160107-5693-r0gq2c/spec.rb:295: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.02078 seconds
31 examples, 3 failures

Failed examples:

rspec /tmp/d20160107-5693-r0gq2c/spec.rb:237 # LazyMode#weekly_agenda returns note scheduled without repeater
rspec /tmp/d20160107-5693-r0gq2c/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-r0gq2c/spec.rb:283 # LazyMode#weekly_agenda returns note scheduled with weekly repeater

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

Георги обнови решението на 21.12.2015 15:47 (преди над 8 години)

+class LazyMode
+ class Date
+ private
+ def set_date(year, month, day)
+ @year = year.to_i
+ @month = month.to_i
+ @day = day.to_i
+ end
+
+ def Date.new_date(year, month, day)
+ Date.new("#{year}-#{month}-#{day}")
+ end
+
+ public
+ attr :year, :month, :day, :step
+
+ def initialize(date)
+ date_match = date.match(/(\d+-\d+-\d+)(\s\+(\d+)([mdw]))?/)
+
+ set_date(*date_match[1].split('-'))
+ #@year,@month,@day = *date_match[1].split('-').map{|string| string.to_i}
+ @step = date_match[3].to_i if date_match[2]
+
+ case date_match[4]
+ when 'w' then @step *= 7
+ when 'm' then @step *= 30
+ end
+ end
+
+ def next_day
+ year, month, day = @year, @month, @day + 1
+
+ month += 1 if day > 30
+ day %= 30
+
+ year += 1 if month > 12
+ month %= 12
+
+ Date.new_date(year, month, day)
+ end
+
+ def to_s
+ year = @year.to_s.rjust(4, '0')
+ month = @month.to_s.rjust(2, '0')
+ day = @day.to_s.rjust(2, '0')
+ "#{year}-#{month}-#{day}"
+ end
+
+ def fix(date)
+ if @step != nil && date =~ self
+ @day = date.day
+ @month = date.month
+ @year = date.year
+ end
+ end
+
+ def to_i
+ year * 360 + month * 30 + day
+ end
+
+ def =~(other)
+ return false if to_s < other.to_s
+ return true if to_s == other.to_s
+
+ return (to_i - other.to_i) % other.step == 0 if other.step
+
+ false
+ end
+ end
+
+ class Note
+ attr_accessor :header, :file_name, :body, :status, :tags, :date
+
+ def initialize(file_name, header, tags = [])
+ @file_name = file_name
+ @header = header
+ @tags = tags
+ @status = :topostpone
+ @body = ""
+ end
+ end
+
+ class NoteDSL
+ attr :note, :file
+
+ def initialize(note, file, &block)
+ @note = note
+ @file = file
+ end
+
+ def body(value)
+ @note.body = value
+ end
+
+ def status(value)
+ @note.status = value
+ end
+
+ def scheduled(date_string)
+ @note.date = Date.new(date_string)
+ end
+
+ def note(*args, &block)
+ @file.send(:note, *args, &block)
+ end
+ end
+
+ class Agenda
+ attr :notes
+
+ def initialize(notes, date = nil)
+ @notes = notes
+ select(date) if date
+ end
+
+ def where(tag: nil, text: nil, status: nil)
+ notes = @notes.select { |note| tag.nil? || note.tags.include?(tag) }
+
+ notes.select! do |note|
+ text.nil? || note.body.match(text) || note.header.match(text)
+ end
+
+ notes.select! { |note| status.nil? || note.status == status }
+
+ Agenda.new(notes)
+ end
+
+ private
+ def select(date)
+ @notes = @notes.select { |note| date =~ note.date }
+
+ @notes = @notes.map do |note|
+ agenda_note = note.clone
+ agenda_note.date.fix(date)
+ agenda_note
+ end
+ end
+ end
+
+ class File
+ attr :name, :notes
+
+ def initialize(name)
+ @name = name
+ @notes = []
+ end
+
+ def daily_agenda(date)
+ Agenda.new(@notes, date)
+ end
+
+ def weekly_agenda(date)
+ notes = []
+ (0...7).each do
+ agenda = Agenda.new(@notes, date)
+ notes += agenda.notes
+ date = date.next_day
+ end
+ Agenda.new(notes)
+ end
+
+ private
+ def note(header, *tags, &block)
+ new_note = Note.new(@name, header, tags)
+ @notes.push new_note
+
+ note = NoteDSL.new(new_note, self)
+ note.instance_eval(&block)
+ new_note
+ end
+ end
+
+ def self.create_file(name, &block)
+ file = File.new name
+ file.instance_eval &block
+ file
+ end
+end

Георги обнови решението на 21.12.2015 17:17 (преди над 8 години)

class LazyMode
class Date
private
def set_date(year, month, day)
@year = year.to_i
@month = month.to_i
@day = day.to_i
end
+ public
+ attr :year, :month, :day, :step
+
def Date.new_date(year, month, day)
Date.new("#{year}-#{month}-#{day}")
end
- public
- attr :year, :month, :day, :step
-
def initialize(date)
date_match = date.match(/(\d+-\d+-\d+)(\s\+(\d+)([mdw]))?/)
set_date(*date_match[1].split('-'))
- #@year,@month,@day = *date_match[1].split('-').map{|string| string.to_i}
+
@step = date_match[3].to_i if date_match[2]
case date_match[4]
when 'w' then @step *= 7
when 'm' then @step *= 30
end
end
def next_day
year, month, day = @year, @month, @day + 1
month += 1 if day > 30
day %= 30
year += 1 if month > 12
month %= 12
Date.new_date(year, month, day)
end
def to_s
year = @year.to_s.rjust(4, '0')
month = @month.to_s.rjust(2, '0')
day = @day.to_s.rjust(2, '0')
"#{year}-#{month}-#{day}"
end
def fix(date)
if @step != nil && date =~ self
@day = date.day
@month = date.month
@year = date.year
end
end
def to_i
year * 360 + month * 30 + day
end
def =~(other)
return false if to_s < other.to_s
return true if to_s == other.to_s
return (to_i - other.to_i) % other.step == 0 if other.step
false
end
end
class Note
attr_accessor :header, :file_name, :body, :status, :tags, :date
def initialize(file_name, header, tags = [])
@file_name = file_name
@header = header
@tags = tags
@status = :topostpone
@body = ""
end
end
class NoteDSL
attr :note, :file
def initialize(note, file, &block)
@note = note
@file = file
end
def body(value)
@note.body = value
end
def status(value)
@note.status = value
end
def scheduled(date_string)
@note.date = Date.new(date_string)
end
def note(*args, &block)
@file.send(:note, *args, &block)
end
end
class Agenda
attr :notes
def initialize(notes, date = nil)
@notes = notes
select(date) if date
end
def where(tag: nil, text: nil, status: nil)
notes = @notes.select { |note| tag.nil? || note.tags.include?(tag) }
notes.select! do |note|
text.nil? || note.body.match(text) || note.header.match(text)
end
notes.select! { |note| status.nil? || note.status == status }
Agenda.new(notes)
end
private
def select(date)
@notes = @notes.select { |note| date =~ note.date }
@notes = @notes.map do |note|
agenda_note = note.clone
agenda_note.date.fix(date)
agenda_note
end
end
end
class File
attr :name, :notes
def initialize(name)
@name = name
@notes = []
end
def daily_agenda(date)
Agenda.new(@notes, date)
end
def weekly_agenda(date)
notes = []
(0...7).each do
- agenda = Agenda.new(@notes, date)
+ agenda = daily_agenda(date)
notes += agenda.notes
date = date.next_day
end
Agenda.new(notes)
end
private
def note(header, *tags, &block)
new_note = Note.new(@name, header, tags)
@notes.push new_note
note = NoteDSL.new(new_note, self)
note.instance_eval(&block)
new_note
end
end
def self.create_file(name, &block)
file = File.new name
file.instance_eval &block
file
end
end