Skip to content

Instantly share code, notes, and snippets.

@samullen
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samullen/213df109bbffb2240d2e to your computer and use it in GitHub Desktop.
Save samullen/213df109bbffb2240d2e to your computer and use it in GitHub Desktop.
Very basic todo script for use in an "Intro to Ruby" project I'm developing.
#!/usr/bin/env ruby
require "date"
class Todo
attr_accessor :complete
attr_reader :name, :due_on
def initialize(name, due_on=nil, complete=false)
@name = name
@due_on = due_on
@complete = complete
end
def self.from_string(string)
todo = string.split("::")
complete = todo[0] == "x"
name = todo[1]
due_on = todo[2] ? Date.parse(todo[2]) : nil
self.new(name, due_on, complete)
end
def complete!
self.complete = true
end
def complete?
self.complete == true
end
def to_s
complete = self.complete? ? "x" : "-"
[complete, self.name, self.due_on].join("::")
end
end
class TodoList
attr_reader :todos
TODOPATH = File.join(ENV["HOME"], "todos.txt")
def initialize
@todos = []
load_todos
end
def all
self.todos
end
def add(name, due_on)
self.todos << Todo.new(name, due_on)
save_todos
end
def complete(index)
self.todos[index].complete!
save_todos
end
def move(start_index, end_index)
todo = self.todos.delete_at(start_index)
self.todos.insert(end_index, todo)
save_todos
end
def delete(index)
self.todos.delete_at(index)
save_todos
end
private
def load_todos
File.open(TODOPATH, "a+") do |file|
file.each do |line|
self.todos << Todo.from_string(line.chomp)
end
end
end
def save_todos
File.open(TODOPATH, "w") do |file|
self.todos.each do |todo|
file.puts todo.to_s
end
end
end
end
todo_list = TodoList.new
def list_todos(todo_list)
todo_list.all.each_with_index do |todo, index|
complete = todo.complete? ? "x" : " "
line = "#{index + 1}. [#{complete}] #{todo.name}"
line += " - #{todo.due_on}" if todo.due_on
puts line
end
end
def puts_title(title)
puts title
puts "-" * title.length
end
puts
case ARGV[0]
when "list"
puts_title "Listing todos"
list_todos(todo_list)
when "add"
puts_title "Adding a todo"
todo_list.add(ARGV[1], ARGV[2])
list_todos(todo_list)
when "complete"
puts_title "Completing todo #{ARGV[1]}"
todo_list.complete(ARGV[1].to_i - 1)
list_todos(todo_list)
when "move"
puts_title "Moving todo #{ARGV[1]} to #{ARGV[2]}"
todo_list.move(ARGV[1].to_i - 1, ARGV[2].to_i - 1)
list_todos(todo_list)
when "delete"
puts_title "Deleting todo #{ARGV[1]}"
todo_list.delete(ARGV[1].to_i - 1)
list_todos(todo_list)
else
puts <<-EOL
Usage: todo.rb <option> [option argument(s)]
list # List the todo items in your list
add <name> [due date] # Add new todo to your list with optional due date
complete <position> # Mark a todo complete
move <pos> <new pos> # Move a todo to a different position
delete <position> # Remove a todo at a position
help
EOL
end
puts
@samullen
Copy link
Author

samullen commented Nov 3, 2014

Great! Thanks everyone for your input. I implemented most of the suggestions, but not all; some was left in for the purpose of illustration, even if not the "Ruby Way"(tm).

I really appreciate the help and constructive feedback.

@4ydx
Copy link

4ydx commented Nov 8, 2014

Looks great. I am a bit surprised that people feel regex is seldom used. It is a good skill to have, but definitely a subject in and of itself :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment