DEV Community

Mate Technologies
Mate Technologies

Posted on

Build a Simple Contact Book CLI in Python

In this tutorial, we'll create a Contact Book CLI that allows you to add, update, delete, search, and bulk edit contacts using Python. We'll go step by step with explanations to make it beginner-friendly.

Step 1: Import Required Modules

We'll start by importing the Python modules we need:

import os
import json
import re
Enter fullscreen mode Exit fullscreen mode

Explanation:

os – Used to check if our contacts file exists.

json – Used to store and read contacts from a JSON file.

re – Provides regular expressions for search and replace functionality.

Step 2: Define Global Variables

We'll set up global variables to keep track of our contacts:

contacts_file = "contacts.json"
contacts = {}
Enter fullscreen mode Exit fullscreen mode

Explanation:

contacts_file – Name of the file where contacts will be stored.

contacts – A dictionary that holds all contacts in memory.

Step 3: Load and Save Contacts

We need functions to load contacts from a file and save changes back to it.

def load_contacts():
    global contacts
    if os.path.exists(contacts_file):
        with open(contacts_file, "r", encoding="utf-8") as f:
            contacts = json.load(f)
    else:
        contacts = {}

def save_contacts():
    with open(contacts_file, "w", encoding="utf-8") as f:
        json.dump(contacts, f, indent=4)
Enter fullscreen mode Exit fullscreen mode

Explanation:

load_contacts() – Reads contacts from contacts.json if it exists.

save_contacts() – Saves the current contacts dictionary to the file in JSON format.

Step 4: Display Contacts

We want to see all contacts or search for specific ones.

def display_contacts(filter_term=None):
    if not contacts:
        print("\nNo contacts available.\n")
        return

    print("\nContacts List:")
    print("-" * 40)
    for name, info in contacts.items():
        if filter_term and filter_term.lower() not in name.lower():
            continue
        print(f"Name: {name}")
        print(f"  Phone: {info.get('phone', 'N/A')}")
        print(f"  Email: {info.get('email', 'N/A')}")
        print("-" * 40)
    print()
Enter fullscreen mode Exit fullscreen mode

Explanation:

Loops through all contacts and prints them nicely.

Optional filter_term allows searching for contacts by name.

Step 5: Add a New Contact

We need a way to add new contacts:

def add_contact():
    name = input("Enter name: ").strip()
    if not name:
        print("Name cannot be empty!")
        return
    phone = input("Enter phone: ").strip()
    email = input("Enter email: ").strip()

    contacts[name] = {"phone": phone, "email": email}
    save_contacts()
    print(f"Contact '{name}' added successfully.\n")
Enter fullscreen mode Exit fullscreen mode

Explanation:

Prompts user for name, phone, and email.

Saves the new contact to the contacts dictionary and updates the file.

Step 6: Update a Contact

def update_contact():
    name = input("Enter the name of the contact to update: ").strip()
    if name not in contacts:
        print(f"No contact found with name '{name}'\n")
        return

    print("Leave blank to keep current value.")
    phone = input(f"Enter new phone [{contacts[name].get('phone','')}]: ").strip()
    email = input(f"Enter new email [{contacts[name].get('email','')}]: ").strip()

    if phone:
        contacts[name]['phone'] = phone
    if email:
        contacts[name]['email'] = email

    save_contacts()
    print(f"Contact '{name}' updated successfully.\n")
Enter fullscreen mode Exit fullscreen mode

Explanation:

Lets users update phone or email of an existing contact.

Blank input keeps the current value.

Step 7: Delete a Contact

def delete_contact():
    name = input("Enter the name of the contact to delete: ").strip()
    if name not in contacts:
        print(f"No contact found with name '{name}'\n")
        return
    confirm = input(f"Are you sure you want to delete '{name}'? (y/n): ").strip().lower()
    if confirm == 'y':
        contacts.pop(name)
        save_contacts()
        print(f"Contact '{name}' deleted.\n")
    else:
        print("Deletion canceled.\n")
Enter fullscreen mode Exit fullscreen mode

Explanation:

Prompts the user to confirm deletion before removing a contact.

Step 8: Search Contacts

def search_contacts():
    term = input("Enter search term: ").strip()
    if not term:
        print("Search term cannot be empty!\n")
        return
    display_contacts(filter_term=term)
Enter fullscreen mode Exit fullscreen mode

Explanation:

Uses the display_contacts() function with a filter to search for names.

Step 9: Bulk Search & Replace

def bulk_search_replace():
    global contacts
    if not contacts:
        print("\nNo contacts available for bulk search & replace.\n")
        return

    print("\n--- Bulk Search & Replace ---")
    field = input("Choose field to update (name/phone/email): ").strip().lower()
    if field not in ['name', 'phone', 'email']:
        print("Invalid field. Choose 'name', 'phone', or 'email'.")
        return

    search_text = input("Enter text to search: ").strip()
    replace_text = input("Enter replacement text: ").strip()

    if not search_text:
        print("Search text cannot be empty!")
        return

    changes = []
    updated_contacts = {}

    for name, info in contacts.items():
        if field == "name":
            if re.search(re.escape(search_text), name, re.IGNORECASE):
                new_name = re.sub(re.escape(search_text), replace_text, name, flags=re.IGNORECASE)
                updated_contacts[new_name] = info
                changes.append(f"{name} -> {new_name}")
            else:
                updated_contacts[name] = info
        else:
            value = info.get(field, "")
            if re.search(re.escape(search_text), value, re.IGNORECASE):
                new_value = re.sub(re.escape(search_text), replace_text, value, flags=re.IGNORECASE)
                info[field] = new_value
                changes.append(f"{name}: {field} -> {new_value}")
            updated_contacts[name] = info

    if not changes:
        print("No matches found for the given search text.\n")
        return

    print("\nPreview of changes:")
    print("-" * 40)
    for change in changes:
        print(change)
    print("-" * 40)

    confirm = input("Apply these changes? (y/n): ").strip().lower()
    if confirm == 'y':
        contacts = updated_contacts
        save_contacts()
        print(f"{len(changes)} changes applied successfully.\n")
    else:
        print("Bulk replacement canceled.\n")
Enter fullscreen mode Exit fullscreen mode

Explanation:

Allows updating multiple contacts at once.

Works on name, phone, or email.

Shows a preview before applying changes.

Step 10: Main Menu

def main_menu():
    load_contacts()
    while True:
        print("\n=== Contact Book CLI ===")
        print("1. Display all contacts")
        print("2. Add contact")
        print("3. Update contact")
        print("4. Delete contact")
        print("5. Search contacts")
        print("6. Bulk Search & Replace")
        print("7. Exit")
        choice = input("Choose an option [1-7]: ").strip()

        if choice == '1':
            display_contacts()
        elif choice == '2':
            add_contact()
        elif choice == '3':
            update_contact()
        elif choice == '4':
            delete_contact()
        elif choice == '5':
            search_contacts()
        elif choice == '6':
            bulk_search_replace()
        elif choice == '7':
            print("Exiting Contact Book. Goodbye!")
            break
        else:
            print("Invalid choice. Please enter a number between 1 and 7.\n")
Enter fullscreen mode Exit fullscreen mode

Explanation:

Provides a simple CLI menu for interacting with your contact book.

Loops until the user chooses to exit.

Step 11: Run the Program

Finally, we add this at the bottom to run the program:

if __name__ == "__main__":
    main_menu()
Enter fullscreen mode Exit fullscreen mode

✅ And that’s it! You now have a fully functional Contact Book CLI with the ability to add, update, delete, search, and bulk edit contacts.

Top comments (0)