Of course! Since "phone" is a broad term, I'll provide a comprehensive set of Python tasks, ranging from beginner-friendly to more advanced.

Task 1: The Basic Phone (Beginner Level)
Objective: Create a simple command-line phonebook that can store, view, and search for contacts.
This task focuses on using fundamental Python data structures like dictionaries and lists.
Core Requirements:
- Store Contacts: Each contact should have a name and a phone number.
- View All Contacts: Display a list of all stored contacts.
- Add a New Contact: Prompt the user to enter a name and number to add to the phonebook.
- Search for a Contact: Allow the user to search for a contact by name and display their number.
- Delete a Contact: Allow the user to remove a contact by name.
Solution Code:
# A simple, command-line phonebook
phonebook = {}
def display_menu():
"""Displays the main menu options."""
print("\n--- Simple Phonebook ---")
print("1. View all contacts")
print("2. Add a new contact")
print("3. Search for a contact")
print("4. Delete a contact")
print("5. Exit")
print("------------------------")
def view_contacts(phonebook):
"""Displays all contacts in the phonebook."""
if not phonebook:
print("Your phonebook is empty.")
return
print("\n--- All Contacts ---")
for name, number in phonebook.items():
print(f"Name: {name}, Number: {number}")
print("---------------------")
def add_contact(phonebook):
"""Adds a new contact to the phonebook."""
name = input("Enter contact name: ").strip()
if not name:
print("Name cannot be empty.")
return
# Check if contact already exists
if name in phonebook:
print(f"Contact '{name}' already exists.")
# Option to update
update = input("Do you want to update the number? (y/n): ").lower()
if update == 'y':
number = input("Enter new phone number: ").strip()
phonebook[name] = number
print(f"Contact '{name}' updated successfully.")
return
number = input("Enter phone number: ").strip()
if not number:
print("Number cannot be empty.")
return
phonebook[name] = number
print(f"Contact '{name}' added successfully.")
def search_contact(phonebook):
"""Searches for a contact by name."""
search_term = input("Enter the name to search for: ").strip().lower()
if not search_term:
print("Search term cannot be empty.")
return
found = False
print("\n--- Search Results ---")
for name, number in phonebook.items():
if search_term in name.lower():
print(f"Name: {name}, Number: {number}")
found = True
if not found:
print(f"No contacts found matching '{search_term}'.")
print("----------------------")
def delete_contact(phonebook):
"""Deletes a contact from the phonebook."""
name_to_delete = input("Enter the name of the contact to delete: ").strip()
if name_to_delete in phonebook:
del phonebook[name_to_delete]
print(f"Contact '{name_to_delete}' deleted successfully.")
else:
print(f"Contact '{name_to_delete}' not found.")
def main():
"""Main function to run the phonebook application."""
while True:
display_menu()
choice = input("Enter your choice (1-5): ")
if choice == '1':
view_contacts(phonebook)
elif choice == '2':
add_contact(phonebook)
elif choice == '3':
search_contact(phonebook)
elif choice == '4':
delete_contact(phonebook)
elif choice == '5':
print("Exiting phonebook. Goodbye!")
break
else:
print("Invalid choice. Please enter a number between 1 and 5.")
# Run the main application
if __name__ == "__main__":
main()
Task 2: The Smart Phone (Intermediate Level)
Objective: Enhance the basic phonebook by making it persistent (saving to a file) and adding more contact details.
This task introduces file I/O and working with more complex data structures.

Core Requirements:
- Persistent Storage: Load contacts from a file (e.g.,
contacts.jsonorcontacts.csv) when the program starts. Save contacts to this file whenever they are added, updated, or deleted. - Rich Contact Details: Store more information for each contact, such as:
- Name
- Phone Number
- Email Address
- Address
- Data Serialization: Use JSON or CSV to handle the structured data.
- Error Handling: Gracefully handle file read/write errors.
Solution Code (using JSON):
import json
import os
# Define the filename for our data store
CONTACTS_FILE = "contacts.json"
def load_contacts():
"""Loads contacts from a JSON file."""
if os.path.exists(CONTACTS_FILE):
try:
with open(CONTACTS_FILE, 'r') as f:
return json.load(f)
except (json.JSONDecodeError, IOError) as e:
print(f"Error loading contacts file: {e}. Starting with an empty phonebook.")
return {}
return {}
def save_contacts(phonebook):
"""Saves the contacts dictionary to a JSON file."""
try:
with open(CONTACTS_FILE, 'w') as f:
json.dump(phonebook, f, indent=4)
print("Contacts saved successfully.")
except IOError as e:
print(f"Error saving contacts to file: {e}")
# --- The rest of the functions from Task 1 are adapted here ---
def display_menu():
print("\n--- Smart Phonebook ---")
print("1. View all contacts")
print("2. Add a new contact")
print("3. Search for a contact")
print("4. Delete a contact")
print("5. Exit")
print("------------------------")
def view_contacts(phonebook):
if not phonebook:
print("Your phonebook is empty.")
return
print("\n--- All Contacts ---")
for name, details in phonebook.items():
print(f"Name: {name}")
print(f" - Phone: {details.get('phone', 'N/A')}")
print(f" - Email: {details.get('email', 'N/A')}")
print(f" - Address: {details.get('address', 'N/A')}")
print("-" * 20)
def add_contact(phonebook):
name = input("Enter contact name: ").strip()
if not name or name in phonebook:
if name in phonebook:
print(f"Contact '{name}' already exists. Use 'Update' functionality if available.")
return
phone = input("Enter phone number: ").strip()
email = input("Enter email address: ").strip()
address = input("Enter address: ").strip()
phonebook[name] = {
"phone": phone,
"email": email,
"address": address
}
print(f"Contact '{name}' added successfully.")
def search_contact(phonebook):
search_term = input("Enter the name to search for: ").strip().lower()
if not search_term:
return
found = False
print("\n--- Search Results ---")
for name, details in phonebook.items():
if search_term in name.lower():
print(f"Name: {name}")
print(f" - Phone: {details.get('phone', 'N/A')}")
print(f" - Email: {details.get('email', 'N/A')}")
print(f" - Address: {details.get('address', 'N/A')}")
print("-" * 20)
found = True
if not found:
print(f"No contacts found matching '{search_term}'.")
print("----------------------")
def delete_contact(phonebook):
name_to_delete = input("Enter the name of the contact to delete: ").strip()
if name_to_delete in phonebook:
del phonebook[name_to_delete]
print(f"Contact '{name_to_delete}' deleted successfully.")
else:
print(f"Contact '{name_to_delete}' not found.")
def main():
# Load contacts at the start
phonebook = load_contacts()
while True:
display_menu()
choice = input("Enter your choice (1-5): ")
if choice == '1':
view_contacts(phonebook)
elif choice == '2':
add_contact(phonebook)
save_contacts(phonebook) # Save after adding
elif choice == '3':
search_contact(phonebook)
elif choice == '4':
delete_contact(phonebook)
save_contacts(phonebook) # Save after deleting
elif choice == '5':
save_contacts(phonebook) # Save one last time before exiting
print("Exiting phonebook. Goodbye!")
break
else:
print("Invalid choice. Please enter a number between 1 and 5.")
if __name__ == "__main__":
main()
Task 3: The Smartphone App (Advanced Level)
Objective: Create a more robust, object-oriented phone application with a class-based structure and potentially a graphical user interface (GUI).
This task focuses on Object-Oriented Programming (OOP) and introduces a GUI library like Tkinter.
Core Requirements:
- Object-Oriented Design:
- Create a
Contactclass to represent a single contact. - Create a
Phonebookclass to manage a collection ofContactobjects. This class will handle adding, deleting, searching, and saving/loading.
- Create a
- Graphical User Interface (GUI):
- Use a library like Tkinter (built-in) or PyQt/PySide for a more professional look.
- Create windows for:
- Main contact list.
- A form to add/edit a new contact.
- A search bar or window.
- Separation of Concerns: Keep the logic for data management separate from the GUI code.
Solution Code (OOP Structure with Tkinter - Conceptual)
This is a more complex project. Here’s the structure and key code snippets.
contact.py (The Model)

# contact.py
class Contact:
def __init__(self, name, phone, email="", address=""):
self.name = name
self.phone = phone
self.email = email
self.address = address
def to_dict(self):
"""Converts the contact object to a dictionary for JSON serialization."""
return {
"name": self.name,
"phone": self.phone,
"email": self.email,
"address": self.address
}
@staticmethod
def from_dict(data):
"""Creates a Contact object from a dictionary."""
return Contact(
name=data.get("name", ""),
phone=data.get("phone", ""),
email=data.get("email", ""),
address=data.get("address", "")
)
def __str__(self):
return f"{self.name} - {self.phone}"
phonebook.py (The Controller/Manager)
# phonebook.py
import json
import os
from contact import Contact
class Phonebook:
def __init__(self, filename="contacts.json"):
self.filename = filename
self.contacts = {}
self.load()
def load(self):
if os.path.exists(self.filename):
try:
with open(self.filename, 'r') as f:
data = json.load(f)
self.contacts = {name: Contact.from_dict(details) for name, details in data.items()}
except (json.JSONDecodeError, IOError):
print(f"Error loading {self.filename}. Starting with an empty phonebook.")
self.contacts = {}
def save(self):
try:
data = {name: contact.to_dict() for name, contact in self.contacts.items()}
with open(self.filename, 'w') as f:
json.dump(data, f, indent=4)
except IOError as e:
print(f"Error saving contacts: {e}")
def add_contact(self, contact):
if contact.name in self.contacts:
return False # Or raise an error
self.contacts[contact.name] = contact
self.save()
return True
def delete_contact(self, name):
if name in self.contacts:
del self.contacts[name]
self.save()
return True
return False
def search(self, query):
query = query.lower()
return [c for c in self.contacts.values() if query in c.name.lower()]
app.py (The View - Tkinter GUI)
# app.py
import tkinter as tk
from tkinter import messagebox, simpledialog
from phonebook import Phonebook
from contact import Contact
class PhonebookApp:
def __init__(self, root):
self.root = root
self.root.title("Python Phonebook App")
self.phonebook = Phonebook()
self.create_widgets()
self.update_contact_list()
def create_widgets(self):
# --- Listbox ---
self.contact_listbox = tk.Listbox(self.root, height=15, width=50)
self.contact_listbox.grid(row=0, column=0, columnspan=2, padx=10, pady=10)
# --- Buttons ---
btn_add = tk.Button(self.root, text="Add Contact", command=self.add_contact_dialog)
btn_add.grid(row=1, column=0, padx=5, pady=5)
btn_delete = tk.Button(self.root, text="Delete Contact", command=self.delete_contact)
btn_delete.grid(row=1, column=1, padx=5, pady=5)
btn_search = tk.Button(self.root, text="Search", command=self.search_dialog)
btn_search.grid(row=1, column=2, padx=5, pady=5)
def update_contact_list(self):
self.contact_listbox.delete(0, tk.END)
for contact in self.phonebook.contacts.values():
self.contact_listbox.insert(tk.END, str(contact))
def add_contact_dialog(self):
dialog = tk.Toplevel(self.root)
dialog.title("Add New Contact")
tk.Label(dialog, text="Name:").grid(row=0, column=0)
tk.Label(dialog, text="Phone:").grid(row=1, column=0)
tk.Label(dialog, text="Email:").grid(row=2, column=0)
tk.Label(dialog, text="Address:").grid(row=3, column=0)
e_name = tk.Entry(dialog)
e_phone = tk.Entry(dialog)
e_email = tk.Entry(dialog)
e_address = tk.Entry(dialog)
e_name.grid(row=0, column=1)
e_phone.grid(row=1, column=1)
e_email.grid(row=2, column=1)
e_address.grid(row=3, column=1)
def save():
name = e_name.get().strip()
phone = e_phone.get().strip()
if name and phone:
contact = Contact(name, phone, e_email.get().strip(), e_address.get().strip())
self.phonebook.add_contact(contact)
self.update_contact_list()
dialog.destroy()
else:
messagebox.showerror("Error", "Name and Phone are required.")
tk.Button(dialog, text="Save", command=save).grid(row=4, column=0, columnspan=2)
def delete_contact(self):
selection = self.contact_listbox.curselection()
if selection:
index = selection[0]
contact_str = self.contact_listbox.get(index)
name = contact_str.split(" - ")[0]
if messagebox.askyesno("Confirm Delete", f"Delete {name}?"):
self.phonebook.delete_contact(name)
self.update_contact_list()
else:
messagebox.showinfo("Info", "Please select a contact to delete.")
def search_dialog(self):
query = simpledialog.askstring("Search", "Enter name to search:")
if query:
self.contact_listbox.delete(0, tk.END)
results = self.phonebook.search(query)
if results:
for contact in results:
self.contact_listbox.insert(tk.END, str(contact))
else:
self.contact_listbox.insert(tk.END, "No contacts found.")
if __name__ == "__main__":
root = tk.Tk()
app = PhonebookApp(root)
root.mainloop()
How to Choose a Task
- If you are a beginner: Start with Task 1. It will teach you loops, conditionals, functions, and dictionaries.
- If you are comfortable with the basics: Move to Task 2. It will introduce you to file handling and JSON, which are essential skills for any real-world application.
- If you are comfortable with intermediate concepts and want a challenge: Tackle Task 3. It will teach you Object-Oriented Programming and give you a tangible GUI application to build, which is a fantastic portfolio piece.
