Created
February 11, 2016 20:47
-
-
Save todlazarov/eac40afa64ad31131689 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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