Project: Business Card Management System

This is the capstone project for Phase 2. All the knowledge from previous lessons — lists, dictionaries, comprehensions, string methods — will be used to build a real, usable command-line business card management system. Completing this project means you've truly mastered Python's container core concepts.


Project Requirements

We will build a "Business Card Manager" that runs in the terminal and supports the following features:

TEXT
1. Add a card — enter name, phone, email
2. Display all cards — list them in table format
3. Search cards — search by name (supports fuzzy search)
4. Modify a card — update information by name
5. Delete a card — delete by name
6. Statistics — show total count, email domain statistics
7. Exit the program

Data is stored using list + dictionary: all cards in a list, each card as a dictionary.


1. Data Structure Design

Example: Business Card Data Structure

PYTHON
# Each card is a dictionary
# All cards are stored in a list
[
    {"name": "Zhang San", "phone": "13800138000", "email": "zhangsan@example.com"},
    {"name": "Li Si", "phone": "13900139000", "email": "lisi@test.com"},
]
▶ Try it Yourself

2. Complete Code

Save this file as card_manager.py and run it directly:

Example: Business Card Management System

PYTHON
# ====== Business Card Management System ======

# Data storage
cards = []

def show_menu():
    """Display the main menu"""
    print("\n" + "=" * 35)
    print("Business Card Management System")
    print("=" * 35)
    print("1. Add Card")
    print("2. List All Cards")
    print("3. Search Cards")
    print("4. Modify Card")
    print("5. Delete Card")
    print("6. Statistics")
    print("7. Exit")
    print("=" * 35)


def add_card():
    """Add a business card"""
    print("\n--- Add Card ---")
    name = input("Name: ").strip()
    if not name:
        print("Name cannot be empty!")
        return

    phone = input("Phone: ").strip()
    email = input("Email: ").strip()

    # Check for duplicate name
    for card in cards:
        if card["name"] == name:
            print(f"A card named {name} already exists. Cannot add duplicate.")
            return

    cards.append({"name": name, "phone": phone, "email": email})
    print(f"Card for {name} added.")


def list_cards():
    """Display all cards"""
    if not cards:
        print("\nNo cards yet.")
        return

    print("\n--- All Cards ---")
    print(f"{'#':<4}{'Name':<10}{'Phone':<15}{'Email':<25}")
    print("-" * 54)

    for i, card in enumerate(cards, 1):
        print(f"{i:<4}{card['name']:<10}{card['phone']:<15}{card['email']:<25}")

    print(f"\nTotal: {len(cards)} cards")


def search_card():
    """Search cards (supports fuzzy search)"""
    if not cards:
        print("\nNo cards yet.")
        return

    keyword = input("\nEnter name to search (partial match supported): ").strip()
    if not keyword:
        print("Please enter a keyword!")
        return

    # List comprehension + in for fuzzy search
    results = [card for card in cards if keyword in card["name"]]

    if not results:
        print(f"No cards found matching '{keyword}'.")
        return

    print(f"\n--- Found {len(results)} cards ---")
    for card in results:
        print(f"Name: {card['name']}")
        print(f"Phone: {card['phone']}")
        print(f"Email: {card['email']}")
        print("-" * 20)


def modify_card():
    """Modify a card"""
    if not cards:
        print("\nNo cards yet.")
        return

    name = input("\nEnter the name to modify: ").strip()
    for card in cards:
        if card["name"] == name:
            print(f"Found card for {name}. Enter new info (press Enter to keep current):")

            new_name = input(f"Name ({card['name']}): ").strip()
            new_phone = input(f"Phone ({card['phone']}): ").strip()
            new_email = input(f"Email ({card['email']}): ").strip()

            if new_name:
                card["name"] = new_name
            if new_phone:
                card["phone"] = new_phone
            if new_email:
                card["email"] = new_email

            print(f"Card for {name} has been updated.")
            return

    print(f"No card found for {name}.")


def delete_card():
    """Delete a card"""
    if not cards:
        print("\nNo cards yet.")
        return

    name = input("\nEnter the name to delete: ").strip()
    for i, card in enumerate(cards):
        if card["name"] == name:
            confirm = input(f"Are you sure you want to delete {name}'s card? (y/n): ")
            if confirm.lower() == "y":
                cards.pop(i)
                print(f"Card for {name} has been deleted.")
            else:
                print("Deletion cancelled.")
            return

    print(f"No card found for {name}.")


def show_stats():
    """Show data statistics"""
    if not cards:
        print("\nNo cards yet.")
        return

    print("\n--- Statistics ---")
    print(f"Total cards: {len(cards)}")

    # Count email domains
    domains = {}
    for card in cards:
        email = card["email"]
        if "@" in email:
            domain = email.split("@")[1]
            domains[domain] = domains.get(domain, 0) + 1

    if domains:
        print("\nEmail domain distribution:")
        for domain, count in sorted(domains.items(), key=lambda x: x[1], reverse=True):
            print(f"  {domain}: {count}")

    # Count how many have phone and email
    has_phone = sum(1 for card in cards if card["phone"])
    has_email = sum(1 for card in cards if card["email"])
    print(f"\nWith phone: {has_phone}")
    print(f"With email: {has_email}")


# ====== Main Program ======
print("Welcome to the Business Card Management System!")
print("Enter the corresponding number to select a function.")

while True:
    show_menu()
    choice = input("Select option (1-7): ").strip()

    if choice == "1":
        add_card()
    elif choice == "2":
        list_cards()
    elif choice == "3":
        search_card()
    elif choice == "4":
        modify_card()
    elif choice == "5":
        delete_card()
    elif choice == "6":
        show_stats()
    elif choice == "7":
        print("Thank you for using! Goodbye!")
        break
    else:
        print("Invalid choice. Please enter a number between 1 and 7.")
▶ Try it Yourself

Code design approach: Each feature is implemented as an independent function. The main program uses a while loop + if-elif for dispatching. This makes the code structure clear — adding a new feature requires only a new function and an elif branch.


3. Sample Run

TEXT
Welcome to the Business Card Management System!
Enter the corresponding number to select a function.

===================================
Business Card Management System
===================================
1. Add Card
2. List All Cards
3. Search Cards
4. Modify Card
5. Delete Card
6. Statistics
7. Exit
===================================
Select option (1-7): 1

--- Add Card ---
Name: Zhang San
Phone: 13800138000
Email: zhangsan@example.com
Card for Zhang San added.

Select option (1-7): 2

--- All Cards ---
#    Name       Phone           Email
──────────────────────────────────────────────────────
1    Zhang San  13800138000     zhangsan@example.com

Total: 1 card

4. Extension Suggestions

After completing the project, try adding these features:

Feature Implementation Idea
Data persistence Use json.dump() to save to a file, and json.load() to load on startup (file operations will be covered later)
Group management Add a group field to cards (colleagues/friends/family), organize with a dictionary by group
Data import/export Use join() to output CSV files that can be opened in Excel
Sorted display Sort by name: sorted(cards, key=lambda c: c["name"])
Batch delete Accept multiple names separated by commas, loop through deletions

FAQ

Q Why use list + dictionary instead of direct file operations?
A This project focuses on container operations — the list stores all cards, dictionaries store individual cards. This lets you practice list CRUD and dictionary key-value operations. File I/O (persistence) will be covered in Phase 3. Master containers first, then file operations — a step-by-step approach.
Q Data is lost when the program closes. What should I do?
A This is normal — our data is stored in memory, which is released when the program ends. To persist data, after learning file operations and the JSON module, use json.dump(cards, open("data.json", "w")) to save to disk.
Q The fuzzy search uses the in keyword. Is it case-sensitive?
A Yes. "Zhang" in "Zhang San" is True, but "zhang" in "Zhang" is False (case-sensitive). If you need case-insensitive search, convert to lowercase before comparing: keyword.lower() in card["name"].lower().

Summary


Exercises

  1. Beginner (Difficulty: Star): Add a new feature to the card system — display cards sorted by name (using sorted() with the key parameter).

  2. Intermediate (Difficulty: Star-Star): Add a "group management" feature to the card system. Add a group field to each card ("colleagues," "friends," "family"), then implement a menu option to view cards by group.

  3. Advanced (Difficulty: Star-Star-Star): Write a "book management system" from scratch without referring to the code above. Features include: add book (title, author, year), display all, search by author, sort by year, count books by author. Use list + dictionary for storage, all running in the command line.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏