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 trial

Ruby

Ryan Sutherland
PLUS
Ryan Sutherland
Courses Plus Student 5,051 Points

Ruby Collections Extra Credit

I'm trying to do the Extra Credit for Ruby Collections before I go on to learn about loops. If you haven't taken the course, the EC is to create a loop that prompts the user continuously for new items, rather than a static 3 items. Here is my code so far:

def create_list print "What is the list name? " name = gets.chomp

hash = {"name"=>name,"items"=>Array.new} return hash end

def add_list_item print "What is the item called? " item_name = gets.chomp

print "How much? " quantity = gets.chomp.to_i

hash = {"name"=>item_name,"quantity" => quantity} return hash end

def more_items() puts "Do you have more items? " items_answer = gets.chomp.downcase

while items_answer == "y" do add_list_item() list['items'].push(add_list_item()) end end

def print_separator(character="-") puts character * 80 end

def print_list(list) puts "List: #{list['name']}" print_separator()

list["items"].each do |item| puts "\tItem: " + item['name'] + "\t\t\t" + "Quantity: " + item['quantity'].to_s end print_separator() end

list = create_list()

puts "Great! Add some items to your list."

list['items'].push(add_list_item()) more_items()

puts "Here's your list:\n" print_list(list)

Whenever I run it, as long as I say no, it works fine. But if I say yes and want to add the second item, it lets me add the name and quantity but then I get the following error:

shopping_list.rb:26:in more_items': undefined local variable or methodlist' for main:Object (NameErro r)
from shopping_list.rb:50:in `<main>'

If I'm reading the error right it's saying that it can't find the variable "list". But I don't know how to fix that. Please help.

Ryan Sutherland
Ryan Sutherland
Courses Plus Student 5,051 Points

So I manged to create a loop, but now I'm running into a different problem. Here is my code now (thanks for the format tip, btw Kourosh):

#Creates the grocery list array
def create_list
  print "What is the list name? "
  name = gets.chomp

  hash = {"name"=>name,"items"=>Array.new}
  return hash
end

#Adds the first item to the list
def add_list_item
  print "What is the item called? "
  item_name = gets.chomp

  print "How much? "
  quantity = gets.chomp.to_i

  hash = {"name"=>item_name,"quantity" => quantity}
  return hash
end

#Loop for adding more items
#I'm sure there's a more elegant way of writing this but I couldn't figure it out
#If you have thoughts I'm all ears
def add_more_items(list)
  print "Do you have more items? "
  more_items = gets.chomp.downcase

  until more_items != "y" || "yes" do
    list['items'].push(add_list_item())
    print "Do you have more items? "
    more_items = gets.chomp.downcase
  end
end

#Creates a separator between title of list and list items
def print_separator(character="-")
  puts character * 80
end

#Prints the list to the page upon completion
def print_list(list)
  puts "List: #{list['name']}"
  print_separator()

  list["items"].each do |item|
    puts "\tItem: " + item['name'] + "\t\t\t" +
         "Quantity: " + item['quantity'].to_s
    end
  print_separator()
end

list = create_list()

puts "Great! Add some items to your list."

list['items'].push(add_list_item())
add_more_items(list)

puts "Here's your list:\n"
print_list(list)

When I run it, the loop works. However as soon as the program runs I get this message:

"shopping_list.rb:28: warning: string literal in condition"

I've never seen this before and have no idea what it means. In addition, now the only way my loop works is if I put "y". If I put "Y" or "Yes" or "yes" it just prints my shopping list out. I don't understand why this is, as I downcased my answer.

3 Answers

Kourosh Raeen
Kourosh Raeen
23,733 Points

To get rid of the warning change

until more_items != "y" || "yes" do

to

until more_items != "y" || more_items != "yes" do

The reason is that ruby interprets that as (more_items != "y") || "yes" and since "yes" is always true the whole expression will always be true no matter what the truth value of more_items is.

Also, the loop wouldn't work as expected if you use or. You should use and instead:

until more_items != "y" and more_items != "yes" do
Kourosh Raeen
Kourosh Raeen
23,733 Points

Inside the more_items() method you have this line:

list['items'].push(add_list_item())

But you haven't defined list in that method nor have you pass it in as an argument.

Also, try formatting the code you posted by adding three backticks, ```, followed by ruby on a line by itself right before the first line of code. Then add another line of three backticks right after the last line of code.