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 trialErik Nuber
20,629 PointsExtra Credit: Delete a contact from the address book
Finished the extra credit. Will explain each area...
just added the Delete Contact Option in the menu area.
def run
loop do
puts "Address Book"
puts "a: Add Contact"
puts "d: Delete Contact"
puts "p: Print Adddress Book"
puts "s: search"
puts "e: Exit"
print "Enter your choice: "
input = gets.chomp.downcase
case input
when 'e'
save()
break
when 'p'
print_contact_list
when 's'
print "Search term: "
search = gets.chomp
find_by_name(search)
find_by_phone_number(search)
find_by_address(search)
when 'a'
add_contact
when 'd'
delete_contact
end
end
end
first we have the delete_contact method. It assigns an index to 0 which I use to keep track of the length of the array. It is used in another method and will get passed to it.
• first i check to see if the contacts are empty and if so, I let the user know and it will exit out of the menu
• next I check to see if the user would like to remove a contact based on first or last name and set that to a variable nameType
• then I find out what the name is to be removed and set it to the variable nameRemove
• a case statement based on the nameType variable is performed and, within the case statement there is an each loop that will either check by first or last name. To use DRY coding, I moved the code to be performed on each contact into another method. When the method check_name is finished I then increase the index which is also passed to the check_name method.
def delete_contact
index = 0
if contacts.empty?
puts "There are no contacts in your address book. \n"
else
print "Would you like to remove a contact based on first or last name? (first/last) "
nameType = gets.chomp.downcase
print "What is the name you would like to remove? "
nameRemove = gets.chomp.downcase
case nameType
when "first"
contacts.each do |contact|
if contact.first_name.downcase.include?(nameRemove)
check_name(contact, index)
index += 1
end
end
when "last"
contacts.each do |contact|
if contact.last_name.downcase.include?(nameRemove)
check_name(contact)
index += 1
end
end
else
puts "You did not enter first or last as a choice."
end
end
end
The check_name method is designed to find out if the given contact is the correct contact to remove. As there can be several people with the same first or last name on the list, this will allow the correct contact to be removed rather than just the first one on the list.
So it starts by putting the contact name down, and then asks if it is the correct person to remove. the loop forces the user into a Y or N answer and, finally when that condition is met, it calls yet another method that will actually deal with deleting the name. It sends three arguments, the answer of Y or N, the contact in question and the index position within the array
def check_name(contact, index)
puts contact.to_s('last_first')
loop do
print "Is this the person you would like to remove? (Y/N) "
answer = gets.chomp.downcase
if (answer == "y" || answer == "n")
remove_name(answer, contact, index)
break
end
end
end
Finally the method that will actually remove the contact. If the answer is Y it simply deletes the contact. If the contact is N it puts some flavor text. However, that flavor text will only run if there are still names to be checked else, it just exits out to the main menu.
def remove_name(answer, contact, index)
case answer
when "y"
contacts.delete(contact)
when "n"
if (index < contacts.size - 1)
puts "Okay, how about this one? "
end
end
end
Yes, I likely made this more complicated than necessary. It could have been shorted to two methods but, I expanded on the code for my own learning purposes. I want to reinforce the materials, send arguments all over etc. I also wanted to cover various cases such as no contacts to delete and, if there was more than one person sharing the same name.
This was not necessarily easy to accomplish. I used a lot of testing to see what was actually happening especially when what I thought what was supposed to happen didn't happen.
6 Answers
Nelly Nelly
7,134 PointsThank you very miuch I didn't find how to do, you did a GREAT job: Something went wrong for me with this code "wrong number of arguments"
def delete_contact
index = 0
if contacts.empty?
puts "There are no contacts in your address book. \n"
else
print "Would you like to remove a contact based on first or last name? (first/last) "
nameType = gets.chomp.downcase
print "What is the name you would like to remove? "
nameRemove = gets.chomp.downcase
case nameType
when "first"
contacts.each do |contact|
if contact.first_name.downcase.include?(nameRemove)
check_name(contact, index)
index += 1
end
end
when "last"
contacts.each do |contact|
if contact.last_name.downcase.include?(nameRemove)
check_name(contact) #mistake was here
index += 1
end
end
else
puts "You did not enter first or last as a choice."
end
end
end
I have added the "index" argument in this part :
when "last"
contacts.each do |contact|
if contact.last_name.downcase.include?(nameRemove)
check_name(contact, index) #added it there :)
index += 1
end
end
else
puts "You did not enter first or last as a choice."
end
Cheers :)
Melissa Ramirez
6,503 PointsFor solving this extra credit challenger I created only this two methods:
def remove
print "Write the name or last name to remove: "
remove_title = gets.chomp
delete_contact(remove_title)
end
def delete_contact(remove_title)
contacts.each do |contact|
if contact.full_name.downcase.include?(remove_title)
contacts.delete(contact)
end
end
save
end
roberthopman
16,502 PointsSmall improvement:
def delete_contact
index = 0
if contacts.empty?
puts "There are no contacts in your address book. \n"
else
print "Would you like to remove a contact based on first or last name? (first/last) "
nameType = gets.chomp.downcase
if (nameType == 'first' || nameType == 'last')
print "What is the name you would like to remove? "
nameRemove = gets.chomp.downcase
case nameType
when "first"
contacts.each do |contact|
if contact.first_name.downcase.include?(nameRemove)
check_name(contact, index)
index += 1
end
end
when "last"
contacts.each do |contact|
if contact.last_name.downcase.include?(nameRemove)
check_name(contact, index)
index += 1
end
end
end
else
puts "You did not enter first or last as a choice."
end
end
end
Todd MacIntyre
12,248 PointsNice, very clean!
Daniel Grieve
6,432 PointsI added one method which should account for contacts with the same name, or contacts with similar names.
when 'r'
results = []
puts "Enter a search term for the contact you wish to remove"
search = gets.chomp.downcase
contacts.each do |contact|
if contact.first_name.downcase.include?(search) || contact.last_name.downcase.include?(search)
results.push(contact)
end
end
results.each do |contact|
puts "Is this the contact you wish to delete: "
puts contact.full_name
contact.print_phone_numbers
puts "Delete contact? y/n"
if gets.chomp == 'y'
contacts.delete(contact)
end
end
Andela Restacking
2,608 PointsHere is how I went about implementing mine, this allows a user to see all the contacts listed with serials even if the user does not pass a query for contact to be deleted. Where a first name or last name argument is provided and there are multiple contacts that match the search, the results are printed out and the user can select by serial number.
def delete_contact
if contacts.empty?
puts "There are no contacts in your address book"
end
loop do
break if contacts.empty?
puts "e: Exit"
input = prompt("Enter contact first name or last name").downcase
case input
when 'e'
break
end
results = contacts.select { |contact| contact.full_name.downcase.include?(input) }
results.each_with_index {|contact, index| puts "#{index + 1}. #{contact.to_s('last_first')}"}
input = prompt("Select contact index to delete (1 to delete first contact e.t.c)")
if (1..results.length).include?(input.to_i)
loop do
puts "Enter any key to go back: "
contact = results[input.to_i - 1]
input = prompt("Delete #{contact.to_s('last_first')}! Are you sure? (y)").downcase
case input
when 'y'
@contacts.delete(contact)
puts "#{contact.to_s('last_first')} deleted!"
break
else
puts "Operation aborted!"
break
end
end
end
end
end
Another caveat is what happens when you delete the last contact in the address book which is why I decided to break the loop after every run if the contacts list is empty