Lesson 2
Applying Python Dictionaries to Address Book Management
Introduction

Welcome! Today, we will explore creating a simple address book application using Python dictionaries. This task will help you understand manipulating dictionaries in Python, focusing on adding, retrieving, and deleting entries. By the end of this lesson, you'll have a solid grasp of these fundamental operations.

Introducing Methods to Implement

In this task, we will implement three methods to manage our address book:

  • add_contact(self, name: str, phone_number: str) -> bool: Adds a new contact. Returns False if the contact already exists, otherwise adds the contact and returns True. In this task, let's assume phone numbers do not change, so it's not allowed to overwrite the existing contact's number.
  • get_contact(self, name: str) -> str | None: Retrieves the phone number for a given name. Returns None if the contact does not exist.
  • delete_contact(self, name: str) -> bool: Deletes a contact with the given name. Returns True if the contact exists and is deleted, False otherwise.

Let's break down each method in detail in the next sections.

Step 1: Implementing 'add_contact'

This method adds a new contact to the address book with the given name and phone_number. If the contact already exists, it returns False. Otherwise, it adds the contact and returns True.

Question: Why do you think we need to check if the contact already exists?

Answer: To avoid duplicating existing entries. If a contact with the same name already exists, we shouldn't allow overwriting its phone number in this method, as it's only for creation.

Here is the method implementation:

Python
1class AddressBook: 2 def __init__(self): 3 self.contacts = {} 4 5 def add_contact(self, name: str, phone_number: str) -> bool: 6 if name in self.contacts: 7 return False 8 self.contacts[name] = phone_number 9 return True 10 11# Example usage: 12address_book = AddressBook() 13print(address_book.add_contact("Alice", "123-456-7890")) # True 14print(address_book.add_contact("Alice", "098-765-4321")) # False 15print(address_book.contacts) # {'Alice': '123-456-7890'}

In this method:

  • We verify if the contact already exists using if name in self.contacts.
  • If it exists, we return False.
  • If it doesn't exist, we add it to our dictionary and return True.
Step 2: Implementing 'get_contact'

This method retrieves the phone number associated with a given name. If the contact does not exist, it returns None.

Question: What do we gain by returning None when a contact doesn't exist?

Answer: It provides a clear indicator that the contact is not in the address book, allowing us to handle such cases gracefully.

Here is the method implementation:

Python
1class AddressBook: 2 def __init__(self): 3 self.contacts = {} 4 5 def add_contact(self, name: str, phone_number: str) -> bool: 6 if name in self.contacts: 7 return False 8 self.contacts[name] = phone_number 9 return True 10 11 def get_contact(self, name: str) -> str | None: 12 return self.contacts.get(name) 13 14# Example usage: 15address_book = AddressBook() 16address_book.add_contact("Alice", "123-456-7890") 17print(address_book.get_contact("Alice")) # '123-456-7890' 18print(address_book.get_contact("Bob")) # None

In this method:

  • We use the get method of the dictionary to retrieve the phone number.
  • If the name doesn't exist in the dictionary, get will return None.
Step 3: Implementing 'delete_contact'

This method deletes a contact with the given name. If the contact exists and is deleted, it returns True. If the contact does not exist, it returns False.

Question: What could be a real-world consequence of not checking if the contact exists before deletion?

Answer: Attempting to delete a non-existent contact could result in errors or unintended behavior.

Here is the method implementation:

Python
1class AddressBook: 2 def __init__(self): 3 self.contacts = {} 4 5 def add_contact(self, name: str, phone_number: str) -> bool: 6 if name in self.contacts: 7 return False 8 self.contacts[name] = phone_number 9 return True 10 11 def get_contact(self, name: str) -> str | None: 12 return self.contacts.get(name) 13 14 def delete_contact(self, name: str) -> bool: 15 if name in self.contacts: 16 del self.contacts[name] 17 return True 18 return False 19 20# Example usage: 21address_book = AddressBook() 22address_book.add_contact("Alice", "123-456-7890") 23print(address_book.delete_contact("Alice")) # True 24print(address_book.delete_contact("Bob")) # False 25print(address_book.contacts) # {}

In this method:

  • We verify if the contact exists using if name in self.contacts.
  • If it exists, we delete it using del self.contacts[name] and return True.
  • If the contact doesn't exist, we return False.

That's it! We now have the AddressBook class fully implemented, and all three methods are working and well functional!

Why Dictionaries are Efficient for These Tasks

Dictionaries are particularly efficient for managing an address book due to several reasons:

  • Efficient Lookups: Dictionaries provide average O(1)O(1) time complexity for lookups. This means retrieving a contact's phone number by name is very fast, even with a large number of contacts.
  • Uniqueness: Dictionaries inherently ensure that keys (in this case, contact names) are unique. This prevents duplicate entries and simplifies data integrity management.
  • Readability: The syntax for accessing dictionary entries is straightforward and highly readable. This makes the code easier to understand and maintain.
  • Flexibility: Dictionaries in Python are versatile and can hold a variety of data types as values. This flexibility allows for easily extending the address book to store additional information, such as email addresses or physical addresses if needed in the future.

These characteristics make Python dictionaries an ideal choice for implementing an address book.

Lesson Summary

In this lesson, we created a simple address book application using Python dictionaries. We implemented methods to add, retrieve, and delete contacts. Each step was built upon the previous one, enhancing our understanding of manipulating dictionaries in Python. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.