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

Isaac Byrne
Isaac Byrne
17,720 Points

Can any one help me with Grocery List Loop?

Hello everyone, I am currently trying to do the extra credit for the Ruby Grocery list application I made. The goal is to get the program to ask for a list item until i enter "done". Then I want it to break out of the loop and create the list like it was doing before. So far here is my code. I am trying to make the add_list_item function a loop but I can not get it work.

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
 loop do
  print "What is the item called? "
  item_name = gets.chomp

    if item_name == "done"
      break 
    else
      print "How Much? "
      quantity = gets.chomp.to_i

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

  end
  return hash 
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 list.inspect

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

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


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

So far this is what I am able to get it to print out(this includes me running through the app).

What is the list name?Groceries                                                                               
{"name"=>"Groceries", "items"=>[]}                                                                            
Great! Add some items to your list.                                                                           
What is the item called? Milk                                                                                 
How Much? 1                                                                                                   
What is the item called? Eggs                                                                                 
How Much? 1                                                                                                   
What is the item called? done                                                                                 
Here's your list:                                                                                             
List: Groceries                                                                                               
--------------------------------------------------------------------------------                              
shopping_list.rb:36:in `[]': no implicit conversion of String into Integer (TypeError)                        
        from shopping_list.rb:36:in `block in print_list'                                                     
        from shopping_list.rb:35:in `each'                                                                    
        from shopping_list.rb:35:in `print_list'                                                              
        from shopping_list.rb:51:in `<main>'  

Thanks in advance!

2 Answers

You also have a potential bug. If you say "done" without creating a hash, you don't have anything to push on your list.

Josip Dorvak
Josip Dorvak
18,126 Points

It's not necessarily a 'bug'. You're allowed to call push with no parameters. It will not crash or add anything to the array. But it probably is better to only call push when you do wish to add something.

Josip Dorvak
Josip Dorvak
18,126 Points

The best place to add the loop is after all the function (where you are pushing your items, after you create the list).

list = create_list
while true #this is just a way to write an infinite loop

then maybe prompt the user if they wish to add another one

while true
  print_options
  selection = gets.chomp.to_i

  case selection
    when 1
      list['items'].push(add_list_item)
    when 2
      print_list(list)
    when 3
      puts 'Thank You! Come Again'
      break
    else
      puts 'Invalid Selection'

  end

The way you have it now, only 1 item will be added no matter how many times you loop.

My answer uses a case statement. I call a function called print_option which just prints a list of available options the user has (1 - add item, 2 - print the list, 3 - quit). I use those values for my case statement.