Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Ruby Ruby Collections Build a Grocery List Program Build a Grocery List Program: Part 4

Grocery List Extra Credit

I did the extra credit (making the grocery list loop so you could keep adding items). I also coded a (rather crude) way to make it exit the loop when you're finished adding items.

If anyone has a more elegant way to do this, please post it up!

The original code (from the tutorial):

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 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())

puts "Here's your list:\n"

print_list(list)

My modified code:

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

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

def add_list_item

    print "\nWhat is the item called? (press [ENTER] for none): "
    item_name = gets.chomp

    print "How much? (press [ENTER] for none): "
    quantity = gets.chomp.to_i

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

    return hash

end

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

def print_list(list)
    puts "\nList: #{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 "\nGreat! Add some items to your list."


loop do

var = add_list_item()

break if var == {"name"=>"", "quantity"=>0}

list['items'].push(var)

end


puts "\nHere's your list:\n"

print_list(list)

Nice work Andrew Stelmach! Think that's a fine way to exit the list personally.

7 Answers

Sandra Grassl
Sandra Grassl
6,933 Points

Just another way of doing the loop with the yes/no question:

loop do
  list['items'].push(add_list_item())
  puts "Add another item (yes/no)?"
  answer = gets.chomp.downcase
  break if answer!="yes"
end
Shaun Dixon
Shaun Dixon
10,944 Points

This is my solution using a while loop.

def create_list
  print "What is the list called? "
  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 many? "
  quantity = gets.chomp.to_i

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

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

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

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

  end
  print_seperator()
end

list = create_list()

puts "Great, lets add some items to your list!"

x = "yes"

while x == "yes" do
  list["items"].push(add_list_item)
  puts "Do you want to add another item to the list? (type 'yes' or 'no')"
  x = gets.chomp.downcase
end

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

Here is an alternative solution. I have modified both the add_list_item method and the exit from loop.

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 }
  puts "Any more items? (Yes/No) "
  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
    print_separator()
  end
end

list = create_list()

puts "Great! Go ahead and add your first item."

loop do
  list['items'].push(add_list_item())
  user_input = gets.chomp.downcase
  break if user_input != "yes"
end


puts "Here's your list:\n"

print_list(list)
Arman Jon Villalobos
Arman Jon Villalobos
2,451 Points

Nice solution!!! this is better than mine, and a lot shorter!

Arman Jon Villalobos
Arman Jon Villalobos
2,451 Points

I choose the while loop here. Will improve it more! Thanks!

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 many? "
  quantity = gets.chomp.to_i

  hash = { "name" => item_name, "quantity" => quantity }
  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()

done = false
while done == false do
  item = add_list_item
  list['items'].push(item)
  print "Do you want to add more?(yes,no): "
  choice = gets.chomp
  if choice == "no"
    done = true
    print_list(list)
  else
    done = false
  end
end
Joe Ainsworth
Joe Ainsworth
13,588 Points

I managed to refactor to 4 lines of code via the following conditional

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 print_seperator(character="-")
  puts character * 80
end

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

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

  print_seperator()
end

list = create_list()

puts "Great, lets add some items to your list!\n"

begin
  list['items'].push(add_list_item)
  puts "Would you like to add another item? (y/n): "
end while gets.chomp.downcase == "y"

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

Not quite what the extra credit was asking for but I've done it in a way that asks the user first how many items they would like to add with the method 'how_many_entries?'

### start methods

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

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

def add_list_item
  print "\nWhat 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 print_list(list)
  puts "\nHere's your list:\n"

  puts "\nList: #{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

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

def how_many_entries?(list)

  print "\nHow many items would you like to add: "
  number_of_entries = gets.chomp.to_i

  while number_of_entries > 0 do
    list['items'].push(add_list_item())
    number_of_entries -= 1
  end

  return list
end

### end methods

list = create_list()

how_many_entries?(list)

print_list(list)
David Borrero
David Borrero
3,089 Points

I also wanted to find out from the user the number of items. I created one more method called list_size and replaced the integer which would've gone before the .times method with the return value of list_size.

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

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

def list_size
  print "Great! How many items are in your list?"
  times_to_ask = gets.chomp.to_i
end

def add_list_item
  print "What's the name of the item? "
  item_name = gets.chomp

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

  hash = { "name" => item_name, "quantity" => quantity }
  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()

list_size.times do |question|
   list['items'].push(add_list_item())
  end

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