🐍
Syllabus / Python Programming / Phase 6: Mini Projects, Coding Challenges, Interview Preparation (Days 26–30)
Intermediate

Mini Project: Building a Console-Based Application

📂 Phase 6: Mini Projects, Coding Challenges, Interview Preparation (Days 26–30) · Python Programming

This lesson ties together everything from Phases 1 through 4 — functions, OOP, file handling, and exception handling — into a single, complete, working project: a console-based Contact Book. Building one full project from scratch is far more valuable for interview readiness than studying any individual topic in isolation.

Project Overview

The Contact Book will let a user add, view, search, update, and delete contacts, with all data persisted to a JSON file so the contacts survive between program runs.

Step 1: The Contact Class

class Contact:
    def __init__(self, name, phone, email):
        self.name = name
        self.phone = phone
        self.email = email

    def to_dict(self):
        return {"name": self.name, "phone": self.phone, "email": self.email}

    def __str__(self):
        return f"{self.name} | {self.phone} | {self.email}"

Step 2: The ContactBook Class — Managing Storage

import json
import os

class ContactBook:
    def __init__(self, filename="contacts.json"):
        self.filename = filename
        self.contacts = self.load_contacts()

    def load_contacts(self):
        if os.path.exists(self.filename):
            with open(self.filename, "r") as file:
                return json.load(file)
        return []

    def save_contacts(self):
        with open(self.filename, "w") as file:
            json.dump(self.contacts, file, indent=2)

    def add_contact(self, contact):
        self.contacts.append(contact.to_dict())
        self.save_contacts()
        print(f"Added {contact.name} successfully!")

Step 3: Search, Update, and Delete Logic

    def search_contact(self, name):
        results = [c for c in self.contacts if name.lower() in c["name"].lower()]
        return results

    def delete_contact(self, name):
        original_count = len(self.contacts)
        self.contacts = [c for c in self.contacts if c["name"].lower() != name.lower()]
        if len(self.contacts) < original_count:
            self.save_contacts()
            print(f"Deleted {name}")
        else:
            print(f"No contact found named {name}")

Step 4: Adding Error Handling

    def add_contact_safe(self, name, phone, email):
        try:
            if not name or not phone:
                raise ValueError("Name and phone are required fields")
            contact = Contact(name, phone, email)
            self.add_contact(contact)
        except ValueError as e:
            print(f"Could not add contact: {e}")

Step 5: The Command-Line Menu Loop

def main():
    book = ContactBook()

    while True:
        print("
1. Add Contact  2. Search  3. Delete  4. View All  5. Exit")
        choice = input("Choose an option: ")

        if choice == "1":
            name = input("Name: ")
            phone = input("Phone: ")
            email = input("Email: ")
            book.add_contact_safe(name, phone, email)
        elif choice == "2":
            name = input("Search for: ")
            for contact in book.search_contact(name):
                print(contact)
        elif choice == "3":
            name = input("Name to delete: ")
            book.delete_contact(name)
        elif choice == "4":
            for contact in book.contacts:
                print(contact)
        elif choice == "5":
            print("Goodbye!")
            break
        else:
            print("Invalid option, try again")

if __name__ == "__main__":
    main()

What This Project Demonstrates

ConceptWhere It Is Used
OOP (classes, encapsulation)Contact and ContactBook classes
File handlingPersisting contacts to contacts.json
Exception handlingadd_contact_safe validating input
List comprehensionssearch_contact and delete_contact filtering logic
Functions and control flowThe main() menu loop

The if __name__ == "__main__": Pattern

This line ensures main() only runs when the file is executed directly — not when it is imported as a module into another file. It is one of the most universal conventions in Python scripts and projects.

Interview tip: When asked to "build a small project," interviewers are usually evaluating structure and decision-making far more than raw cleverness — separating data (the Contact class) from logic (ContactBook) from the user interface (main()) shows a level of organization that a single giant function never demonstrates.