Now that we have the basic structure of our contact book application – adding contacts – it's time to make it more robust by adding the essential features of editing, deleting, and persisting our data. This will make our application much more practical and user-friendly.
We'll start by tackling the deletion feature. Deleting a contact involves finding a specific contact and removing it from our list. To do this, we'll need a way for the user to specify which contact to delete. A common approach is to ask for the contact's name. We'll then iterate through our contacts, find the matching one, and remove it. It's important to handle cases where the contact might not exist to avoid errors.
def delete_contact(contacts, name):
for i, contact in enumerate(contacts):
if contact['name'].lower() == name.lower():
del contacts[i]
print(f"'{name}' has been deleted.")
return
print(f"Contact '{name}' not found.")Next, let's add the editing functionality. Editing a contact is similar to deleting, in that we first need to find the contact. Once found, we'll allow the user to update the details (like phone number or email) for that specific contact. This often involves asking for the new information after confirming the contact to be edited.
def edit_contact(contacts, name):
for contact in contacts:
if contact['name'].lower() == name.lower():
print(f"Editing contact: {contact['name']}")
new_phone = input("Enter new phone number (leave blank to keep current): ")
if new_phone:
contact['phone'] = new_phone
new_email = input("Enter new email (leave blank to keep current): ")
if new_email:
contact['email'] = new_email
print("Contact updated successfully.")
return
print(f"Contact '{name}' not found.")Now, for the crucial part: saving and loading our contacts. Without this, all our hard work would be lost every time the program closes. We'll use Python's built-in json module for this. JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. We can save our list of dictionaries directly to a JSON file and load it back when the application starts.
import json
def save_contacts(contacts, filename='contacts.json'):
try:
with open(filename, 'w') as f:
json.dump(contacts, f, indent=4)
print(f"Contacts saved to {filename}.")
except IOError as e:
print(f"Error saving contacts: {e}")
def load_contacts(filename='contacts.json'):
try:
with open(filename, 'r') as f:
return json.load(f)
except FileNotFoundError:
print(f"{filename} not found. Starting with an empty contact book.")
return []
except json.JSONDecodeError:
print(f"Error decoding JSON from {filename}. Starting with an empty contact book.")
return []
except IOError as e:
print(f"Error loading contacts: {e}")
return []To integrate these features into our main application loop, we'll need to modify the user interface to present these new options. The main loop will now offer choices like 'Add', 'View', 'Edit', 'Delete', 'Save', and 'Exit'. When the program starts, it will attempt to load existing contacts. Before exiting, it will prompt the user to save changes.
graph TD;
A[Start Application] --> B{Load Contacts?};
B -- Yes --> C[Load from File];
B -- No --> D[Initialize Empty List];
C --> E[Main Menu];
D --> E;
E --> F{User Choice?};
F -- Add --> G[Add Contact Function];
F -- View --> H[View Contacts Function];
F -- Edit --> I[Edit Contact Function];
F -- Delete --> J[Delete Contact Function];
F -- Save --> K[Save Contacts Function];
F -- Exit --> L{Save Changes?};
L -- Yes --> M[Save Contacts];
M --> N[End Application];
L -- No --> N;
G --> E;
H --> E;
I --> E;
J --> E;
K --> E;
By implementing these features, our contact book application transforms from a simple data entry tool into a functional and persistent data management system. Remember to test each feature thoroughly to ensure it works as expected.