Phase 7 ⚡ — Advanced
Topics: File I/O, exception handling, algorithms (search/sort), database basics
Write robust programs that handle errors gracefully, work with files, implement fundamental algorithms, and interact with databases.
🔄 Exercise Flow
📚 Prerequisites
Before starting these exercises, make sure you've read:
- File Handling — Reading and writing files
- Exception Handling — Try-except blocks and error handling
- Stack & Queue — Fundamental data structures
- Decorators & Generators — Advanced Python features
- Database Integration — SQLite with Python
🔰 Starter: File Log Reader with Error Handling
Time: 12 minutes
Build a robust log file reader that handles missing files, malformed data, and empty files gracefully.
Learning Objectives
- Open and read files using
withstatements - Handle
FileNotFoundError,PermissionError, and generic exceptions - Parse structured text data line by line
- Write cleaned data back to a new file
Starter Code
# Starter: File Log Reader with Error Handling
import os
# Create a sample log file for testing
sample_log = """2025-01-15 10:30:00 INFO User logged in
2025-01-15 10:31:22 WARN High memory usage
2025-01-15 10:32:45 ERROR Database connection failed
INVALID LINE
2025-01-15 10:35:12 INFO User logged out"""
with open("sample.log", "w") as f:
f.write(sample_log)
# TODO 1: Read "sample.log" with proper error handling
# TODO 2: Use try-except to handle FileNotFoundError and other exceptions
# TODO 3: Parse each line into (timestamp, level, message) — skip malformed lines
# TODO 4: Count how many lines of each level (INFO, WARN, ERROR) were found
# TODO 5: Write a cleaned version to "cleaned.log"
# TODO 6: Print a summary
# Your code here 👇
Expected Output
=== LOG ANALYSIS ===
File: sample.log
Total lines: 5
Valid lines: 4
Skipped: 1 (malformed)
Breakdown:
INFO: 2
WARN: 1
ERROR: 1
Cleaned log written to: cleaned.log
⭐ Medium: Algorithm Challenge — Search & Sort
Time: 22 minutes
Implement classic search and sort algorithms from scratch, then benchmark them against Python's built-in implementations.
Learning Objectives
- Implement linear search and binary search
- Implement bubble sort, selection sort, and merge sort
- Compare algorithmic performance with
timeit - Use recursion for divide-and-conquer algorithms
- Handle edge cases (empty list, single element, duplicates)
Starter Code
# Medium: Algorithm Challenge — Search & Sort
import time
import random
# --- Search Algorithms ---
def linear_search(arr, target):
"""Return index of target or -1 if not found."""
# TODO: Implement linear search
pass
def binary_search(arr, target):
"""Return index of target or -1 if not found. Assumes arr is sorted."""
# TODO: Implement binary search (recursive or iterative)
pass
# --- Sort Algorithms ---
def bubble_sort(arr):
"""Sort the list using bubble sort. Return new list."""
# TODO: Implement bubble sort
pass
def selection_sort(arr):
"""Sort the list using selection sort. Return new list."""
# TODO: Implement selection sort
pass
def merge_sort(arr):
"""Sort the list using merge sort. Return new list."""
# TODO: Implement merge sort (recursive)
pass
# --- Benchmarking ---
# TODO: Generate a random list of 1000 integers
# TODO: Time each algorithm and print results
# TODO: Verify correctness by comparing with sorted()
# Your code here 👇
Expected Output
=== ALGORITHM BENCHMARK ===
List size: 1000 integers (random 0–999)
Search:
Linear Search (target=500): 0.0023 ms (found at index 482)
Binary Search (target=500): 0.0001 ms (found at index 501)
Sort:
Bubble Sort: 0.0852 sec ✓ Correct
Selection Sort: 0.0421 sec ✓ Correct
Merge Sort: 0.0038 sec ✓ Correct
Python sort(): 0.0001 sec ✓ Correct
Performance Winner: Python's built-in sort() 🏆
🏆 Hard: Student Database Management System
Time: 40 minutes
Build a complete student database management system using SQLite, file I/O for CSV import/export, exception handling, and algorithmic operations on the data.
Learning Objectives
- Connect to SQLite and execute CRUD operations
- Import data from CSV files into a database
- Export query results back to CSV
- Implement algorithmic operations (search, sort, filter) on database records
- Handle all edge cases with try-except blocks
- Build a complete CLI application
Starter Code
# Hard: Student Database Management System
import sqlite3
import csv
import os
# --- Database Setup ---
def init_db(db_name="students.db"):
"""Create the database and students table if it doesn't exist."""
# TODO: Connect to SQLite database
# TODO: Create table: students(id INTEGER PK, name TEXT, age INT, grade TEXT, marks REAL, city TEXT)
# TODO: Return the connection
pass
# TODO 1: Implement insert_student(conn, name, age, grade, marks, city)
# TODO 2: Implement import_from_csv(conn, csv_path) — read CSV and insert rows
# TODO 3: Implement search_students(conn, name=None, city=None, min_marks=None)
# — allow searching by any combination of criteria
# TODO 4: Implement get_top_students(conn, n=5) — return top n by marks
# TODO 5: Implement get_average_by_city(conn) — average marks per city
# TODO 6: Implement export_to_csv(conn, csv_path) — export all records to CSV
# TODO 7: Implement delete_student(conn, student_id) — with confirmation
# TODO 8: Build a CLI menu that ties everything together
# TODO 9: Wrap ALL database operations in try-except blocks
# Your code here 👇
Expected Output
═══════════════════════════════════════
STUDENT DATABASE MANAGEMENT SYSTEM
═══════════════════════════════════════
1. Add Student
2. Import from CSV
3. Search Students
4. Top Students
5. Average by City
6. Export to CSV
7. Delete Student
8. Exit
───────────────────────────────────────
Choice: 3
Search Criteria (leave blank to skip):
Name: Alice
City:
Min Marks: 80
Results (2 found):
ID Name Age Grade Marks City
──────────────────────────────────────
101 Alice 17 A+ 95.5 Mumbai
105 Alice M. 16 A 88.0 Delhi
───────────────────────────────────────
Choice: 4
Top 5 Students:
1. Bob Johnson — 98.5 ⭐
2. Alice Smith — 95.5
3. Charlie Lee — 92.0
4. Diana Patel — 90.5
5. Eva Torres — 89.0
Choice: 5
Average Marks by City:
Mumbai: 85.3%
Delhi: 82.1%
Chennai: 78.9%
Bengaluru: 80.5%
───────────────────────────────────────
💡 Tips for Success
- Always use
with open(...)for file operations — it automatically closes the file even if an error occurs. - Be specific with exceptions — catch
FileNotFoundErrornot justException. Catching everything hides bugs. - Use parameterised queries with SQLite — never use f-strings to build SQL. It prevents SQL injection attacks.
- Close database connections — use
conn.close()or a context manager to avoid locked databases. - Remember: Python's built-in
sort()uses Timsort — O(n log n) with real-world optimisations. Your hand-crafted sorts are for learning, not production.