Skip to content

Instantly share code, notes, and snippets.

@todlazarov
Created February 11, 2016 20:47
Show Gist options
  • Save todlazarov/eac40afa64ad31131689 to your computer and use it in GitHub Desktop.
Save todlazarov/eac40afa64ad31131689 to your computer and use it in GitHub Desktop.
# This class represents a todo item and its associated
# data: name and description. There's also a "done"
# flag to show whether this todo item is done.
class Todo
DONE_MARKER = 'X'
UNDONE_MARKER = ' '
attr_accessor :title, :description, :done
def initialize(title, description='')
@title = title
@description = description
@done = false
end
def done!
self.done = true
end
def done?
done
end
def undone!
self.done = false
end
def to_s
"[#{done? ? DONE_MARKER : UNDONE_MARKER}] #{title}"
end
end
# This class represents a collection of Todo objects.
# You can perform typical collection-oriented actions
# on a TodoList object, including iteration and selection.
class TodoList
attr_accessor :title
def initialize(title)
@title = title
@todos = []
end
def add(todo)
if todo.instance_of? Todo
@todos << todo
return @todos
else
raise TypeError, 'can only add Todo objects'
end
end
alias_method :<<, :add
def size
@todos.size
end
def first
@todos.first
end
def last
@todos.last
end
def shift
@todos.shift
end
def pop
@todos.pop
end
def item_at(key)
@todos.fetch(key)
end
def mark_done_at(key)
item_at(key).done!
end
def mark_undone_at(key)
item_at(key).undone!
end
def done!
@todos.each_index do |idx|
mark_done_at(idx)
end
end
def done?
@todos.all? {|todo| todo.done?}
end
def remove_at(key)
@todos.delete(item_at(key))
end
def to_s
text = "#{title} \n"
text << @todos.map(&:to_s).join("\n")
text
end
def to_a
@todos
end
def each
@todos.each do |todo|
yield(todo)
end
self
end
def select
list = Todolist.new(title)
each do |todo|
list.add(todo) if yield(todo)
end
list
end
def find_by_title(str)
select {|todo| todo.title == str}.first
end
def all_done
select{|todo| todo.done?}
end
def all_not_done
select{|todo| !todo.done?}
end
def mark_done(str)
find_by_title(str) && find_by_title(str).done!
end
def mark_all_done
each {|todo| todo.done!}
end
def mark_all_undone
each {|todo| todo.undone!}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment