Skip to main content

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:


🔰 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 with statements
  • 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 FileNotFoundError not just Exception. 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.

← Back to Exercises