Build a contact book. Contacts live in a dictionary mapping each name to an inner dictionary with a "phone" and an "email" key.
Define four functions.
add_contact(book, name, phone, email) — stores the contact. If name is already in the book, raise ValueError with the message contact already exists.update_phone(book, name, phone) — replaces an existing contact's phone number. If name is not in the book, raise ValueError with the message no such contact.remove_contact(book, name) — deletes the contact. If name is not in the book, raise ValueError with the message no such contact.export_lines(book) — returns a list of strings, one per contact, sorted by name, each in the form:<name>: <phone> <email>
book = {}
add_contact(book, "Grace", "555-0202", "grace@example.com")
add_contact(book, "Ada", "555-0101", "ada@example.com")
print(export_lines(book))
Output:
['Ada: 555-0101 ada@example.com', 'Grace: 555-0202 grace@example.com']
Run your code to see the output, then press Submit.
add_contact: {"phone": phone, "email": email}.update_phone changes one key of the inner dictionary; it must not touch the email.export_lines, loop over sorted(book) to get the names in order.import unittest
class TestContactBook(unittest.TestCase):
def make_book(self):
book = {}
add_contact(book, "Grace", "555-0202", "grace@example.com")
add_contact(book, "Ada", "555-0101", "ada@example.com")
return book
def test_add_stores_phone_and_email(self):
book = self.make_book()
self.assertEqual(book["Ada"], {"phone": "555-0101", "email": "ada@example.com"})
def test_adding_a_duplicate_raises(self):
book = self.make_book()
with self.assertRaises(ValueError) as context:
add_contact(book, "Ada", "1", "a@b.c")
self.assertEqual(str(context.exception), "contact already exists")
def test_update_phone_keeps_the_email(self):
book = self.make_book()
update_phone(book, "Ada", "555-0303")
self.assertEqual(book["Ada"], {"phone": "555-0303", "email": "ada@example.com"})
def test_update_phone_of_missing_contact_raises(self):
with self.assertRaises(ValueError) as context:
update_phone({}, "Ada", "1")
self.assertEqual(str(context.exception), "no such contact")
def test_remove_deletes_the_contact(self):
book = self.make_book()
remove_contact(book, "Grace")
self.assertNotIn("Grace", book)
def test_remove_missing_contact_raises(self):
with self.assertRaises(ValueError) as context:
remove_contact({}, "Grace")
self.assertEqual(str(context.exception), "no such contact")
def test_export_is_sorted_and_formatted(self):
book = self.make_book()
self.assertEqual(
export_lines(book),
[
"Ada: 555-0101 ada@example.com",
"Grace: 555-0202 grace@example.com",
],
)
def test_export_of_empty_book_is_empty(self):
self.assertEqual(export_lines({}), [])
def add_contact(book, name, phone, email):
if name in book:
raise ValueError("contact already exists")
book[name] = {"phone": phone, "email": email}
def update_phone(book, name, phone):
if name not in book:
raise ValueError("no such contact")
book[name]["phone"] = phone
def remove_contact(book, name):
if name not in book:
raise ValueError("no such contact")
del book[name]
def export_lines(book):
lines = []
for name in sorted(book):
contact = book[name]
lines.append(f"{name}: {contact['phone']} {contact['email']}")
return lines
book = {}
add_contact(book, "Grace", "555-0202", "grace@example.com")
add_contact(book, "Ada", "555-0101", "ada@example.com")
update_phone(book, "Ada", "555-0303")
for line in export_lines(book):
print(line)
Sign in to join the discussion.
No comments yet. Be the first to ask a question.
Press Run to execute your code, or Submit to test and complete this problem.