Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialSean Flanagan
33,235 PointsProblem with 'complete' items
Hi. I have a problem with the complete items.
todo_list.rb
require "./todo_item"
class TodoList
attr_reader :name, :todo_items
def initialize(name)
@name = name
@todo_items = []
end
def add_item(name)
todo_items.push(TodoItem.new(name))
end
def remove_item(name)
if index = find_index(name)
todo_items.delete_at(index)
return true
else
return false
end
end
def mark_complete(name)
if index = find_index(name)
todo_items[index].mark_complete!
return true
else
return false
end
end
def find_index(name)
index = 0
found = false
todo_items.each do |todo_item|
if todo_item.name == name
found = true
end
if found
break
else
index += 1
end
end
if found
return index
else
return nil
end
end
def print_list(kind='all')
puts "#{name} List - #{kind} items"
puts "-" * 30
todo_items.each do |todo_item|
case kind
when 'all'
puts todo_item
when 'complete'
puts todo_item if todo_item.complete?
end
end
puts "\n"
end
end
todo_list = TodoList.new("Groceries")
todo_list.add_item("Milk")
todo_list.add_item("Eggs")
todo_list.add_item("Bread")
todo_list.add_item("Butter")
if todo_list.remove_item("Eggs")
puts "Eggs were removed from the list."
end
if todo_list.mark_complete("Milk")
puts "Milk was marked as complete."
end
puts "\n"
todo_list.print_list
todo_list.print_list('complete')
Output:
Eggs were removed from the list.
Milk was marked as complete.
Groceries List - all items
------------------------------
[C] Milk
[I] Bread
[I] Butter
Groceries List - complete items
------------------------------
todo_list.rb:61:in `block in print_list': undefined method `complete?' for #<TodoItem:0x0055d41a0
903c8 @name="Milk", @complete=true> (NoMethodError)
from todo_list.rb:56:in `each'
from todo_list.rb:56:in `print_list'
from todo_list.rb:84:in `<main>'
I would appreciate any help. :-)
2 Answers
John Steer-Fowler
Courses Plus Student 11,734 PointsHi Sean,
The error message from the console is telling you what is wrong:
todo_list.rb:61:in `block in print_list': undefined method `complete?' for #<TodoItem:0x0055d41a0
903c8 @name="Milk", @complete=true> (NoMethodError)
This error message is telling you that on line 61 of todo_list.rb you have an undefined method 'complete?' for the TodoItem Class instance 0x0055d41a0903c8.
This would either tell me that 'complete?' is a syntax error on the method you wanted to use, OR you have not yet defined a method called 'complete?' for use with the TodoItem class.
This line here (line 61):
puts todo_item if todo_item.complete?
Hope this helps sort the issue out
Sean Flanagan
33,235 PointsHi John.
I looked at my code again and I noticed that the method was unfinished; there was no "incomplete" line that also had a question mark. I wonder if that had anything to do with my problem.
I think I understand what you say about "find_names". In plain English, "find names" isn't a question so a question mark would be inappropriate. Would "room.find_names" without the question mark be better?
Thanks John. :-)
John Steer-Fowler
Courses Plus Student 11,734 PointsThat might have something to do with it. I am not too sure without seeing all of your code.
My find names example was a situation where a question mark would not make sense.
We usually use question marks in a method name when the method is used to find the state of something, ie. Dead or Alive, Complete or Incomplete, Exists or Doesn't Exist etc.
For example, rather than our find_names, if we were using a method to find whether a name existed in a room then we could call our method name_exists?. This would make a lot more sense than find_names? because it is as though we are asking the program a question, "Does this name exist?" rather than "Find all the names in the room" which is a statement not a question.
This might help clarify
Sean Flanagan
33,235 PointsSean Flanagan
33,235 PointsLooks like I made the same mistake twice by putting in a question mark that shouldn't have been there, although the question mark worked fine for Jason.
Thanks again John. :-)
John Steer-Fowler
Courses Plus Student 11,734 PointsJohn Steer-Fowler
Courses Plus Student 11,734 PointsHi Sean,
When you say it worked fine for Jason, did Jason define the complete method with a question mark?
When calling methods, you have to be exact with the spelling. If you define the method with a question mark you need to refer to it with a question mark also. I am guessing Jason defined the complete method with a question mark.
-- Off Topic --
Question marks can be useful in method names that seem as though they are asking a question. For example here we are using 'complete' in the context of asking the question 'is it complete?'. It feels natural to use complete? as the method name in this context when trying to determine the state something is in. Other examples are 'alive?' or 'dead?'.
Using a question mark doesn't make sense in some context. For example a method named 'find_names' to find the names of all the people in a room would not make sense to be called like this room.find_names?.
I am sure you already understand this, but it's sometimes nice to have things explained a little more.
Keep up the good work