Ruby Build an Address Book in Ruby Input and Output Saving The Address Book

Andrew Phythian
Andrew Phythian
19,595 Points

Extra credit solution - slightly different approach

I took a slightly different approach to the solution for extra credit.

I added the option to the menu (abbreviated code below)

puts "r: Remove a contact"
case input
   when 'a'
      add_contact
   when 'r'
      remove_contact

Then, in the print_contact_list method I added a number to each contact

def print_contact_list
        puts "Contact List"
        i = 1
        contacts.each do |contact|
            print "#{i}. "
            print "#{contact.to_s('first_last')}"
            i = i + 1
        end
    end

So when the contact list is printed it now produces the following output

1.  Contact 1
2.  Contact 2
3.  Contact 3

This means that when I ask the user for a contact, they can give a number so they can target a specific contact rather than a name which could result in multiple returns if more than one contact shares an identical name.

In my remove_contact method, I added a check in there to make sure they'd picked the person they wanted as well as a way of backing out if they changed their mind...

def remove_contact
        # Check that there are contacts to delete
        if contacts.length > 0
            # Present contact list to choose from
            print_contact_list
            # Loop to verify that a valid contact is chosen
            loop do
                print "Select a contact (number): "
                id = gets.chomp
                # Checks for a valid contact number
                if id.to_i <= contacts.length
                    puts "You have selected contact #{id} - #{contacts[id.to_i - 1].first_name}"
                    print "Please confirm you wish to delete this contact (y/n): "
                    confirm = gets.chomp
                    case confirm
                    when 'y'
                        puts "Removing contact"
                        contact = id.to_i - 1
                        contacts.delete_at(contact)
                        puts "Here is the updated contacts list"
                        # Display updated contact list
                        print_contact_list
                        break
                    when 'n'
                        # Allows user to change their mind
                        puts "No problem, the contact will not be deleted."
                        break
                    end
                else
                    puts "Please try again!"
                end
            end
        else
            puts "There are no contacts to remove."
        end
    end

It also gives the user an updated contact list after they have deleted so they get immediate feedback on their action.

2 Answers

Dillon Wyatt
Dillon Wyatt
5,990 Points
def print_contact_list
        puts "Contact List"
        i = 1
        contacts.each do |contact|
            print "#{i}. "
            print "#{contact.to_s('first_last')}"
            i = i + 1
        end
    end

Might I add a suggestion to help clean up this bit?

Ruby offers a method "each_with_index". You can use it on an array, pull out both the content of the slot and its position in one shot. This way you don't need to create an counter that must be incremented.

Thus

contacts.each_with_index do |contact, index|
    print "#{index + 1}"  # Indexes start at 0
    print "#{contact}"
Andrew Phythian
Andrew Phythian
19,595 Points

Thanks for the suggestion, works perfectly.

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 23,580 Points

Nice work! Easy to read and does way more than the basic requirement. You're practicing a good paradigm making deletion of a contact require an explicit confirmation.