Free Python Course for Beginners with No Code Experience

๐Ÿ Python for Beginners โ€” Complete Course

A rigorous, comprehensive curriculum designed to take you from zero to confident Python programmer.

Advertisement

Course Overview ๐Ÿ“‹

DetailInfo
Target AudienceAbsolute beginners with no prior programming experience
Total Modules12 Core Modules + 1 Capstone Project Module
Estimated Duration10โ€“14 weeks (5โ€“8 hours/week)
PrerequisitesBasic computer literacy, willingness to practice daily
Final OutcomeBuild real-world Python projects independently

๏ธ Learning Path ๐Ÿ—บ

graph TD
    A["Module 1: Foundations & Setup"] --> B["Module 2: Variables & Data Types"]
    B --> C["Module 3: Control Flow"]
    C --> D["Module 4: Functions"]
    D --> E["Module 5: Data Structures"]
    E --> F["Module 6: Strings & Text"]
    F --> G["Module 7: File Handling & I/O"]
    G --> H["Module 8: Error Handling"]
    H --> I["Module 9: Modules & Packages"]
    I --> J["Module 10: OOP Fundamentals"]
    J --> K["Module 11: Working with Data"]
    K --> L["Module 12: APIs & Web Basics"]
    L --> M["Module 13: Capstone Projects"]

    style A fill:#6C5CE7,color:#fff
    style B fill:#0984E3,color:#fff
    style C fill:#00B894,color:#fff
    style D fill:#FDCB6E,color:#000
    style E fill:#E17055,color:#fff
    style F fill:#A29BFE,color:#fff
    style G fill:#55EFC4,color:#000
    style H fill:#FF7675,color:#fff
    style I fill:#74B9FF,color:#000
    style J fill:#FD79A8,color:#fff
    style K fill:#00CEC9,color:#fff
    style L fill:#E84393,color:#fff
    style M fill:#2D3436,color:#fff

Assessment Strategy ๐ŸŽฏ

Each module includes:

ComponentDescription
๐Ÿง  Concept ChecksQuick-fire questions after each lesson to test understanding
๐Ÿ’ป Coding ExercisesHands-on practice problems (Easy โ†’ Medium โ†’ Hard)
๐Ÿงฉ Mini-ProjectA small project at the end of each module integrating learned skills
๐Ÿ“ Module Quiz15โ€“20 questions covering all module topics
๐Ÿ† Challenge ProblemAn optional brain-teaser for advanced learners

Module Directory ๐Ÿ“š

#ModuleKey TopicsEst. Time
1Foundations & SetupInstallation, IDE, first program, how computers run code4โ€“5 hrs
2Variables & Data TypesVariables, int, float, str, bool, type conversion, input/output5โ€“6 hrs
3Control Flowif/elif/else, comparison & logical operators, nested conditions6โ€“7 hrs
4FunctionsDefining functions, parameters, return values, scope, recursion intro7โ€“8 hrs
5Data StructuresLists, tuples, dictionaries, sets, comprehensions8โ€“10 hrs
6Strings & Text ProcessingString methods, formatting, regex basics, encoding5โ€“6 hrs
7File Handling & I/OReading/writing files, CSV, JSON, context managers5โ€“6 hrs
8Error HandlingExceptions, try/except, custom exceptions, debugging5โ€“6 hrs
9Modules & PackagesImporting, standard library, pip, virtual environments4โ€“5 hrs
10OOP FundamentalsClasses, objects, inheritance, encapsulation, polymorphism8โ€“10 hrs
11Working with DataCollections, itertools, datetime, basic data analysis6โ€“7 hrs
12APIs & Web BasicsHTTP, requests library, JSON APIs, web scraping intro6โ€“7 hrs
13Capstone Projects5 complete projects applying all skills15โ€“20 hrs

[!TIP]
How to use this course: Work through modules sequentially. Each module builds on the previous. Complete ALL exercises before moving to the next module. The mini-projects are NOT optional โ€” they are where real learning happens.

[!IMPORTANT]
The detailed content for each module is in the companion document: Python Course โ€” Full Modules

Module 1: Foundations & Environment Setup

โฑ๏ธ Estimated Time: 4โ€“5 hours | ๐ŸŽฏ Difficulty: Beginner


Learning Objectives ๐ŸŽฏ

By the end of this module, you will:

  • Understand what programming is and why Python is an excellent first language
  • Install Python and configure a development environment
  • Write, save, and run your first Python program
  • Understand how the Python interpreter executes code
  • Use the interactive Python shell (REPL) for quick experiments

Lesson 1.1 โ€” What is Programming?

Programming is the art of giving precise instructions to a computer. Think of it like writing a recipe โ€” each step must be clear, unambiguous, and in the correct order.

Why Python?

FeatureBenefit
Readable syntaxReads almost like English โ€” low barrier to entry
VersatileWeb, data science, AI, automation, games, IoT
Massive communityMillions of developers, endless free resources
Rich ecosystem400,000+ packages on PyPI
Industry demandTop 3 most in-demand programming languages globally

How Computers Execute Code

graph LR
    A["Source Code (.py)"] --> B["Python Interpreter"]
    B --> C["Bytecode (.pyc)"]
    C --> D["Python Virtual Machine (PVM)"]
    D --> E["Machine Output"]

    style A fill:#6C5CE7,color:#fff
    style B fill:#0984E3,color:#fff
    style E fill:#00B894,color:#fff

[!NOTE]
Python is an interpreted language โ€” your code is translated line by line at runtime, unlike compiled languages (C, Java) that convert everything upfront. This makes development faster but execution slightly slower.


Lesson 1.2 โ€” Installing Python

Step-by-Step Installation

Windows:

  1. Go to python.org/downloads
  2. Download the latest Python 3.x installer
  3. โš ๏ธ CHECK “Add Python to PATH” during installation
  4. Click “Install Now”
  5. Verify: Open Command Prompt โ†’ type python --version

macOS:

  1. Open Terminal
  2. Install Homebrew: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  3. Run: brew install python
  4. Verify: python3 --version

Linux (Ubuntu/Debian):

sudo apt update
sudo apt install python3 python3-pip python3-venv
python3 --version

Choosing an IDE/Editor

EditorBest ForCost
VS Code โญAll-around best for beginnersFree
PyCharm CommunityPython-specific featuresFree
ThonnyAbsolute beginner simplicityFree
Jupyter NotebookData exploration & learningFree

[!TIP]
Recommended setup: VS Code + Python extension + Code Runner extension. This gives you IntelliSense, debugging, and one-click code execution.


Lesson 1.3 โ€” Your First Python Program

The Interactive Shell (REPL)

Open your terminal and type python (or python3):

>>> print("Hello, World!")
Hello, World!

>>> 2 + 3
5

>>> "Python" * 3
'PythonPythonPython'

The REPL (Read-Evaluate-Print Loop) is perfect for quick experiments.

Writing a Script File

Create a file called hello.py:

# My first Python program
# This program greets the user

print("=" * 40)
print("  Welcome to Python Programming!")
print("=" * 40)

name = input("What is your name? ")
print(f"Hello, {name}! Let's learn Python together! ๐Ÿ")

Run it:

python hello.py

Anatomy of a Python Program

# 1. Comments start with '#' โ€” they're notes for humans, ignored by Python
# 2. print() is a built-in FUNCTION that displays output
# 3. input() is a built-in FUNCTION that reads user input
# 4. Variables (like 'name') store data for later use
# 5. f-strings (f"...{variable}...") embed variables inside text

Lesson 1.4 โ€” Python Syntax Fundamentals

Indentation Matters!

Python uses indentation (whitespace) to define code blocks โ€” not curly braces like other languages.

# โœ… Correct
if True:
    print("This is indented correctly")
    print("Same block")

# โŒ Wrong โ€” will cause IndentationError
if True:
print("This will crash!")

Comments

# This is a single-line comment

"""
This is a multi-line comment (docstring).
Use it to document functions, classes, or modules.
"""

Python is Case-Sensitive

Name = "Alice"
name = "Bob"
NAME = "Charlie"
# These are THREE different variables!

Exercises ๐Ÿ’ป

Exercise 1.1 โ€” Hello Customizer

Write a program that asks for the user’s name and favorite color, then prints a personalized greeting.

Expected Output:
What is your name? Alice
What is your favorite color? Blue
Hello, Alice! Blue is a wonderful color! ๐ŸŽจ

Exercise 1.2 โ€” ASCII Art Generator

Create a program that prints a simple ASCII art pattern:

Expected Output:
    *
   ***
  *****
 *******
*********
   |||

Exercise 1.3 โ€” Personal Info Card

Write a program that collects a user’s name, age, and city, then displays a formatted info card:

Advertisement
Expected Output:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     PERSONAL INFO       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Name:  Alice            โ”‚
โ”‚ Age:   25               โ”‚
โ”‚ City:  New York         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Mini-Project: Interactive Calculator ๐Ÿงฉ

Build a simple calculator that:

  1. Asks the user for two numbers
  2. Asks which operation (+, -, *, /)
  3. Displays the result with formatting
# Starter template:
print("๐Ÿงฎ Simple Calculator")
print("-" * 20)

num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))
operation = input("Choose operation (+, -, *, /): ")

# YOUR CODE HERE: perform the calculation and print the result

Module 1 Quiz (Sample Questions) ๐Ÿ“

  1. What does REPL stand for?
  2. Why is indentation important in Python?
  3. What is the difference between print() and input()?
  4. What happens if you forget to add Python to PATH during installation?
  5. Is Python compiled or interpreted? Explain the difference.
  6. What will print("Hello" * 3) output?
  7. Write a one-line program that prints your name.
  8. What character starts a single-line comment in Python?

Challenge Problem ๐Ÿ†

Write a program that asks the user for their birth year and calculates:

  • Their current age
  • The year they will turn 100
  • How many days (approximately) they have been alive

Use print() with f-strings for clean output formatting.

Module 2: Variables & Data Types

โฑ๏ธ Estimated Time: 5โ€“6 hours | ๐ŸŽฏ Difficulty: Beginner


Learning Objectives ๐ŸŽฏ

  • Create and name variables following Python conventions
  • Understand and use all primitive data types: int, float, str, bool, None
  • Perform type conversions between data types
  • Use arithmetic, assignment, and comparison operators
  • Accept and process user input

Lesson 2.1 โ€” Variables: Storing Data

A variable is a named container that holds a value in memory.

# Creating variables โ€” no type declaration needed!
age = 25                  # integer
price = 19.99             # float
name = "Alice"            # string
is_student = True         # boolean
nothing = None            # NoneType

# Python figures out the type automatically (dynamic typing)
print(type(age))          # <class 'int'>
print(type(price))        # <class 'float'>

Naming Rules & Conventions

# โœ… Valid names
user_name = "Alice"        # snake_case (Python convention)
_private = "hidden"        # leading underscore = "private by convention"
MAX_SIZE = 100             # ALL_CAPS = constant by convention
player1_score = 95

# โŒ Invalid names
# 1st_place = "Gold"      # Cannot start with a digit
# my-variable = 10        # Hyphens not allowed
# class = "Math"          # Reserved keyword

Variable Reassignment & Dynamic Typing

x = 10          # x is an integer
print(type(x))  # <class 'int'>

x = "hello"     # x is now a string โ€” Python allows this!
print(type(x))  # <class 'str'>

# Multiple assignment
a, b, c = 1, 2, 3
x = y = z = 0   # All set to 0

Lesson 2.2 โ€” Data Types Deep Dive

Integers (int)

count = 42
negative = -17
big_number = 1_000_000     # Underscores for readability
binary = 0b1010            # Binary literal = 10
hex_val = 0xFF             # Hexadecimal literal = 255
octal = 0o77               # Octal literal = 63

# Python integers have unlimited precision!
huge = 10 ** 100           # No overflow โ€” Python handles it

Floats (float)

pi = 3.14159
scientific = 2.5e6         # 2,500,000.0
tiny = 1.23e-4             # 0.000123

[!WARNING]
Floating-point precision:

print(0.1 + 0.2)  # 0.30000000000000004 (NOT 0.3!)

This is a universal computer science issue, not a Python bug. For exact decimal math, use from decimal import Decimal.

Strings (str)

single = 'Hello'
double = "World"
multi = """This is a
multi-line string"""

# Escape characters
newline = "Line1\nLine2"
tab = "Col1\tCol2"
quote = "She said \"hello\""
backslash = "C:\\Users\\folder"

# Raw strings (ignore escapes)
path = r"C:\Users\folder"  # Treated literally

Booleans (bool)

is_active = True
is_deleted = False

# Truthy and Falsy values
bool(0)          # False
bool("")         # False
bool(None)       # False
bool([])         # False (empty list)
bool(42)         # True (any non-zero number)
bool("hello")    # True (any non-empty string)

NoneType

result = None    # Represents "no value" or "nothing"

# Check for None with 'is', not '=='
if result is None:
    print("No result yet")

Lesson 2.3 โ€” Operators

Arithmetic Operators

a, b = 17, 5

print(a + b)     # 22   Addition
print(a - b)     # 12   Subtraction
print(a * b)     # 85   Multiplication
print(a / b)     # 3.4  Division (always returns float)
print(a // b)    # 3    Floor division (rounds down)
print(a % b)     # 2    Modulo (remainder)
print(a ** b)    # 1419857  Exponentiation

Assignment Operators

x = 10
x += 5    # x = x + 5  โ†’ 15
x -= 3    # x = x - 3  โ†’ 12
x *= 2    # x = x * 2  โ†’ 24
x /= 4    # x = x / 4  โ†’ 6.0
x //= 2   # x = x // 2 โ†’ 3.0
x **= 3   # x = x ** 3 โ†’ 27.0

Operator Precedence (PEMDAS)

result = 2 + 3 * 4      # 14 (not 20 โ€” multiplication first)
result = (2 + 3) * 4    # 20 (parentheses override)
result = 2 ** 3 ** 2    # 512 (right-to-left: 3**2=9, 2**9=512)

Lesson 2.4 โ€” Type Conversion

# Explicit conversion
int("42")          # 42
float("3.14")      # 3.14
str(100)           # "100"
bool(1)            # True

# Common pattern: converting user input
age = int(input("Enter your age: "))     # input() always returns str
price = float(input("Enter price: "))

# Checking types
isinstance(age, int)       # True
type(age) == int           # True (less preferred)

[!CAUTION]

int("hello")    # โŒ ValueError: invalid literal
int("3.14")     # โŒ ValueError: can't convert float string directly
int(float("3.14"))  # โœ… Two-step: string โ†’ float โ†’ int = 3

Exercises ๐Ÿ’ป

Exercise 2.1 โ€” Variable Swap

Swap the values of two variables WITHOUT using a third variable.

a = 10
b = 20
# After swap: a = 20, b = 10

Exercise 2.2 โ€” BMI Calculator

Input: weight (kg), height (m)
Formula: BMI = weight / heightยฒ
Output: "Your BMI is 24.5" (rounded to 1 decimal)

Exercise 2.3 โ€” Time Converter

Convert a given number of seconds into hours, minutes, and seconds.

Input: 3661 seconds
Output: 1 hour(s), 1 minute(s), 1 second(s)

Exercise 2.4 โ€” Temperature Converter

Convert between Celsius and Fahrenheit. Formula: F = C ร— 9/5 + 32


Mini-Project: Smart Unit Converter ๐Ÿงฉ

Build a program that converts between:

  • Celsius โ†” Fahrenheit
  • Kilometers โ†” Miles
  • Kilograms โ†” Pounds

The user selects the conversion type, enters a value, and gets the result.


Module 2 Quiz (Sample) ๐Ÿ“

  1. What is dynamic typing?
  2. What does type() return for 3.14?
  3. Why does 0.1 + 0.2 != 0.3?
  4. What are the falsy values in Python?
  5. What is the difference between / and //?
  6. Convert "42" to an integer in one line.
  7. What happens when you multiply a string by an integer?
  8. Explain the difference between is and ==.

Challenge ๐Ÿ†

Write a program that takes a number of days and converts it to years, months, weeks, and remaining days (assume 365 days/year, 30 days/month).

Module 3: Control Flow โ€” Decisions & Loops

โฑ๏ธ Estimated Time: 6โ€“7 hours | ๐ŸŽฏ Difficulty: Beginnerโ€“Intermediate


Learning Objectives ๐ŸŽฏ

  • Write conditional statements with if, elif, else
  • Use comparison and logical operators
  • Build while and for loops
  • Control loop execution with break, continue, pass
  • Implement nested conditions and loops
  • Understand the match-case statement (Python 3.10+)

Lesson 3.1 โ€” Conditional Statements

Basic if Statement

age = 18

if age >= 18:
    print("You are an adult")

if-else

temperature = 35

if temperature > 30:
    print("It's hot! ๐Ÿ”ฅ")
else:
    print("It's comfortable ๐Ÿ˜Š")

if-elif-else Chain

score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"Your grade: {grade}")

Comparison Operators

x, y = 10, 20

x == y    # Equal to             โ†’ False
x != y    # Not equal to         โ†’ True
x > y     # Greater than         โ†’ False
x < y     # Less than            โ†’ True
x >= y    # Greater or equal     โ†’ False
x <= y    # Less or equal        โ†’ True

Logical Operators

age = 25
income = 50000

# AND โ€” both must be True
if age >= 18 and income >= 30000:
    print("Loan approved")

# OR โ€” at least one must be True
if age < 18 or income < 20000:
    print("Loan denied")

# NOT โ€” inverts the boolean
is_blocked = False
if not is_blocked:
    print("Access granted")

Nested Conditions

has_ticket = True
age = 15

if has_ticket:
    if age >= 18:
        print("Welcome to the R-rated movie")
    else:
        print("Sorry, you must be 18+ for this movie")
else:
    print("Please buy a ticket first")

Ternary Expression (One-line if-else)

age = 20
status = "adult" if age >= 18 else "minor"

Match-Case (Python 3.10+)

command = input("Enter command: ")

match command:
    case "start":
        print("Starting...")
    case "stop":
        print("Stopping...")
    case "pause":
        print("Pausing...")
    case _:
        print("Unknown command")

Lesson 3.2 โ€” Loops

while Loop

count = 1
while count <= 5:
    print(f"Count: {count}")
    count += 1

[!CAUTION]
Infinite loops โ€” Always ensure the loop condition eventually becomes False:

# โŒ INFINITE LOOP โ€” never ends!
while True:
    print("Stuck forever...")

for Loop

# Iterating over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# Iterating over a string
for char in "Python":
    print(char)

# Using range()
for i in range(5):          # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 10, 2):   # 2, 4, 6, 8 (start, stop, step)
    print(i)

for i in range(10, 0, -1):  # 10, 9, 8, ..., 1 (countdown)
    print(i)

Loop Control: break, continue, pass

# break โ€” exit the loop entirely
for num in range(1, 100):
    if num == 5:
        break
    print(num)       # Prints 1, 2, 3, 4

# continue โ€” skip current iteration
for num in range(1, 6):
    if num == 3:
        continue
    print(num)       # Prints 1, 2, 4, 5

# pass โ€” do nothing (placeholder)
for num in range(5):
    pass             # TODO: implement later

for-else and while-else

# The else block runs ONLY if the loop completes without break
for num in range(2, 10):
    for i in range(2, num):
        if num % i == 0:
            break
    else:
        print(f"{num} is prime")

Nested Loops

# Multiplication table
for i in range(1, 6):
    for j in range(1, 6):
        print(f"{i*j:4}", end="")
    print()  # New line after each row

Common Loop Patterns

# Accumulator pattern
total = 0
for i in range(1, 101):
    total += i
print(f"Sum of 1-100: {total}")

# Counter pattern
text = "hello world"
vowel_count = 0
for char in text:
    if char in "aeiou":
        vowel_count += 1

# Search pattern
numbers = [4, 7, 2, 9, 1, 5]
target = 9
for i, num in enumerate(numbers):
    if num == target:
        print(f"Found {target} at index {i}")
        break

Exercises ๐Ÿ’ป

Exercise 3.1 โ€” FizzBuzz

Print numbers 1โ€“100. For multiples of 3 print “Fizz”, for 5 print “Buzz”, for both print “FizzBuzz”.

Exercise 3.2 โ€” Password Validator

Check if a password meets: min 8 chars, has uppercase, has digit, has special character.

Exercise 3.3 โ€” Triangle Pattern

Input: 5
Output:
*
**
***
****
*****
****
***
**
*

Exercise 3.4 โ€” Prime Checker

Write a program that checks if a given number is prime.

Exercise 3.5 โ€” Collatz Conjecture

Take a number. If even, divide by 2. If odd, multiply by 3 and add 1. Repeat until you reach 1. Print each step.

Advertisement

Mini-Project: Number Guessing Game ๐Ÿงฉ

Build a game where:

  1. Computer generates a random number (1โ€“100)
  2. User guesses with hints (“Too high!” / “Too low!”)
  3. Track number of attempts
  4. Show score based on attempts when they win
  5. Ask if they want to play again
import random
# Hint: random.randint(1, 100)

Module 3 Quiz (Sample) ๐Ÿ“

  1. What is the difference between while and for?
  2. What does break do inside a nested loop?
  3. Write a ternary expression that returns “even” or “odd”.
  4. What values does range(2, 10, 3) produce?
  5. Explain for-else in Python.

Challenge ๐Ÿ†

Write a program that prints all perfect numbers between 1 and 10,000. A perfect number equals the sum of its proper divisors (e.g., 6 = 1+2+3).

Module 4: Functions โ€” Building Reusable Code

โฑ๏ธ Estimated Time: 7โ€“8 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Define and call functions with various parameter types
  • Understand return values and multiple returns
  • Master variable scope (LEGB rule)
  • Write clean docstrings
  • Use *args and **kwargs
  • Understand lambda functions and higher-order functions
  • Introduction to recursion

Lesson 4.1 โ€” Defining Functions

# Basic function definition
def greet():
    """Display a greeting message."""
    print("Hello, World!")

greet()  # Call the function โ†’ Hello, World!

# Function with parameters
def greet_user(name):
    """Greet a specific user."""
    print(f"Hello, {name}! Welcome aboard! ๐Ÿš€")

greet_user("Alice")

Parameters vs Arguments

def add(a, b):       # a, b are PARAMETERS (definition)
    return a + b

result = add(3, 5)   # 3, 5 are ARGUMENTS (call)

Parameter Types

# 1. Positional parameters
def power(base, exponent):
    return base ** exponent

power(2, 10)  # 1024

# 2. Default parameters
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

greet("Alice")           # "Hello, Alice!"
greet("Alice", "Hey")    # "Hey, Alice!"

# 3. Keyword arguments
def create_profile(name, age, city):
    return f"{name}, {age}, from {city}"

create_profile(age=25, city="NYC", name="Alice")  # Order doesn't matter

# 4. *args โ€” variable positional arguments
def total(*numbers):
    """Accept any number of arguments."""
    return sum(numbers)

total(1, 2, 3)        # 6
total(10, 20, 30, 40) # 100

# 5. **kwargs โ€” variable keyword arguments
def build_dict(**kwargs):
    """Accept any keyword arguments."""
    for key, value in kwargs.items():
        print(f"{key}: {value}")

build_dict(name="Alice", age=25, role="Developer")

Lesson 4.2 โ€” Return Values

# Single return
def square(n):
    return n ** 2

# Multiple returns (via tuple)
def divide(a, b):
    quotient = a // b
    remainder = a % b
    return quotient, remainder

q, r = divide(17, 5)  # q=3, r=2

# Early return
def absolute(n):
    if n >= 0:
        return n
    return -n

# Returning None (implicit)
def say_hello(name):
    print(f"Hello, {name}")
    # No return statement โ†’ returns None implicitly

Lesson 4.3 โ€” Scope & the LEGB Rule

# L - Local: Inside the current function
# E - Enclosing: Inside enclosing functions (closures)
# G - Global: Module level
# B - Built-in: Python's built-in names

x = "global"          # Global scope

def outer():
    x = "enclosing"   # Enclosing scope

    def inner():
        x = "local"   # Local scope
        print(x)      # โ†’ "local"

    inner()
    print(x)          # โ†’ "enclosing"

outer()
print(x)              # โ†’ "global"
# Modifying global variables
counter = 0

def increment():
    global counter     # Declare intent to modify global
    counter += 1

increment()
print(counter)  # 1

[!WARNING]
Avoid global when possible โ€” it makes code harder to debug. Prefer passing values as parameters and returning results.


Lesson 4.4 โ€” Docstrings

def calculate_bmi(weight_kg, height_m):
    """
    Calculate Body Mass Index (BMI).

    Args:
        weight_kg (float): Weight in kilograms.
        height_m (float): Height in meters.

    Returns:
        float: The calculated BMI value.

    Examples:
        >>> calculate_bmi(70, 1.75)
        22.86
    """
    return round(weight_kg / height_m ** 2, 2)

# Access docstring
print(calculate_bmi.__doc__)
help(calculate_bmi)

Lesson 4.5 โ€” Lambda & Higher-Order Functions

# Lambda: anonymous one-line functions
square = lambda x: x ** 2
add = lambda a, b: a + b

# map() โ€” apply function to every item
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))  # [1, 4, 9, 16, 25]

# filter() โ€” keep items that return True
evens = list(filter(lambda x: x % 2 == 0, numbers))  # [2, 4]

# sorted() with key
students = [("Alice", 90), ("Bob", 75), ("Charlie", 85)]
by_grade = sorted(students, key=lambda s: s[1], reverse=True)

Lesson 4.6 โ€” Recursion Introduction

# Factorial: n! = n ร— (n-1) ร— ... ร— 1
def factorial(n):
    if n <= 1:        # Base case
        return 1
    return n * factorial(n - 1)  # Recursive case

print(factorial(5))  # 120

# Fibonacci sequence
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

[!NOTE]
Every recursive function needs a base case (when to stop) and a recursive case (calling itself with a simpler input). Without a base case, you get infinite recursion โ†’ RecursionError.


Exercises ๐Ÿ’ป

Exercise 4.1 โ€” Password Generator

Write a function generate_password(length=12) that returns a random password with uppercase, lowercase, digits, and symbols.

Exercise 4.2 โ€” Palindrome Checker

Write a function that checks if a string is a palindrome (reads the same forwards and backwards).

Exercise 4.3 โ€” Decorator Timer

Write a function time_it(func) that measures how long another function takes to run.

Exercise 4.4 โ€” Recursive Sum

Write a recursive function that calculates the sum of digits of a number. sum_digits(1234) โ†’ 10


Mini-Project: Text Analysis Toolkit ๐Ÿงฉ

Build a module with these functions:

  • word_count(text) โ€” returns word count
  • char_frequency(text) โ€” returns dict of character frequencies
  • find_longest_word(text) โ€” returns the longest word
  • readability_score(text) โ€” approximate reading difficulty
  • summarize(text) โ€” prints a formatted analysis report

Module 4 Quiz (Sample) ๐Ÿ“

  1. What is the difference between a parameter and an argument?
  2. What does a function return if it has no return statement?
  3. Explain the LEGB rule.
  4. When would you use *args vs **kwargs?
  5. What are the two parts every recursive function must have?

Challenge ๐Ÿ†

Write a function flatten(nested_list) that takes a deeply nested list (e.g., [1, [2, [3, [4]], 5]]) and returns a flat list [1, 2, 3, 4, 5] using recursion.

Module 5: Data Structures โ€” Lists, Tuples, Dicts & Sets

โฑ๏ธ Estimated Time: 8โ€“10 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Master lists: indexing, slicing, methods, comprehensions
  • Understand tuples and immutability
  • Work with dictionaries for key-value data
  • Use sets for unique collections and set operations
  • Choose the right data structure for any problem

Lesson 5.1 โ€” Lists

# Creating lists
fruits = ["apple", "banana", "cherry"]
mixed = [1, "hello", 3.14, True, None]
nested = [[1, 2], [3, 4], [5, 6]]
empty = []

# Indexing (0-based)
print(fruits[0])     # "apple"
print(fruits[-1])    # "cherry" (last item)

# Slicing [start:stop:step]
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nums[2:5])     # [2, 3, 4]
print(nums[:3])      # [0, 1, 2]
print(nums[::2])     # [0, 2, 4, 6, 8]
print(nums[::-1])    # [9, 8, 7, ..., 0] (reversed)

List Methods

fruits = ["apple", "banana"]

fruits.append("cherry")       # Add to end
fruits.insert(1, "blueberry") # Insert at index
fruits.extend(["date", "elderberry"])  # Add multiple

fruits.remove("banana")       # Remove by value
popped = fruits.pop()         # Remove and return last
popped = fruits.pop(0)        # Remove and return at index

fruits.sort()                 # Sort in-place
fruits.sort(reverse=True)     # Sort descending
fruits.reverse()              # Reverse in-place

idx = fruits.index("apple")   # Find index of value
cnt = fruits.count("apple")   # Count occurrences
length = len(fruits)           # Number of items

List Comprehensions

# Basic: [expression for item in iterable]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# With condition: [expression for item in iterable if condition]
evens = [x for x in range(20) if x % 2 == 0]

# Nested comprehension
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]

# With transformation
words = ["Hello", "World", "Python"]
lower = [w.lower() for w in words]

[!TIP]
List comprehensions are more Pythonic and often faster than equivalent for loops. Use them for simple transformations. For complex logic, stick with regular loops.


Lesson 5.2 โ€” Tuples

# Tuples are IMMUTABLE lists
point = (3, 4)
rgb = (255, 128, 0)
single = (42,)        # Note the comma for single-element tuple

# Unpacking
x, y = point
name, age, city = ("Alice", 25, "NYC")

# Tuple as function return
def min_max(numbers):
    return min(numbers), max(numbers)

lo, hi = min_max([4, 7, 2, 9, 1])

# Named tuples (more readable)
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)  # 3, 4

When to use tuples vs lists:

Use Tuples WhenUse Lists When
Data shouldn’t changeData needs to be modified
Used as dict keysOrder and mutability matter
Function returns multiple valuesBuilding collections incrementally
Representing fixed recordsHomogeneous collections

Lesson 5.3 โ€” Dictionaries

# Creating dictionaries
student = {
    "name": "Alice",
    "age": 25,
    "grades": [90, 85, 92],
    "active": True
}

# Accessing values
print(student["name"])          # "Alice"
print(student.get("email", "N/A"))  # "N/A" (safe access)

# Modifying
student["age"] = 26             # Update
student["email"] = "a@mail.com" # Add new key
del student["active"]           # Delete key
popped = student.pop("email")   # Remove and return

# Dictionary methods
student.keys()     # dict_keys(['name', 'age', 'grades'])
student.values()   # dict_values(['Alice', 26, [90, 85, 92]])
student.items()    # dict_items([('name', 'Alice'), ...])

# Iterating
for key, value in student.items():
    print(f"{key}: {value}")

Dictionary Comprehensions

# {key_expr: value_expr for item in iterable}
squares = {x: x**2 for x in range(6)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Filtering
high_scores = {name: score for name, score in 
               [("Alice", 90), ("Bob", 65), ("Charlie", 85)]
               if score >= 80}

Nested Dictionaries

school = {
    "class_a": {
        "teacher": "Ms. Smith",
        "students": ["Alice", "Bob"]
    },
    "class_b": {
        "teacher": "Mr. Jones",
        "students": ["Charlie", "Diana"]
    }
}

print(school["class_a"]["teacher"])  # "Ms. Smith"

Lesson 5.4 โ€” Sets

# Sets: unordered, unique elements
colors = {"red", "green", "blue"}
nums = set([1, 2, 2, 3, 3, 3])  # {1, 2, 3} โ€” duplicates removed

# Set operations
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

a | b   # Union:        {1, 2, 3, 4, 5, 6}
a & b   # Intersection: {3, 4}
a - b   # Difference:   {1, 2}
a ^ b   # Symmetric difference: {1, 2, 5, 6}

# Methods
colors.add("yellow")
colors.discard("red")    # Remove (no error if missing)
colors.remove("green")   # Remove (KeyError if missing)

# Use case: removing duplicates
names = ["Alice", "Bob", "Alice", "Charlie", "Bob"]
unique = list(set(names))  # ["Alice", "Bob", "Charlie"]

Exercises ๐Ÿ’ป

Exercise 5.1 โ€” List Flattener

Flatten [[1, 2], [3, 4], [5, 6]] โ†’ [1, 2, 3, 4, 5, 6] using a comprehension.

Exercise 5.2 โ€” Word Frequency Counter

Given a string, return a dictionary with each word’s frequency.

Exercise 5.3 โ€” Matrix Operations

Write functions to add and transpose two matrices (represented as lists of lists).

Exercise 5.4 โ€” Unique Characters

Find characters that appear in string A but not in string B using sets.


Mini-Project: Contact Book ๐Ÿงฉ

Build a command-line contact manager:

  • Add contacts (name, phone, email)
  • Search by name
  • Update contact information
  • Delete contacts
  • Display all contacts in a formatted table
  • Store data in a dictionary

Module 5 Quiz (Sample) ๐Ÿ“

  1. What is the difference between append() and extend()?
  2. Can a tuple be used as a dictionary key? Why?
  3. How do you safely access a dictionary key that might not exist?
  4. What is a set comprehension?
  5. What does slicing a[1:5:2] return for a = [0,1,2,3,4,5]?

Challenge ๐Ÿ†

Write a function that finds the two numbers in a list that add up to a given target. Return their indices. Use a dictionary for O(n) time complexity.

Advertisement

Module 6: Strings & Text Processing

โฑ๏ธ Estimated Time: 5โ€“6 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Master all essential string methods
  • Use f-strings, .format(), and % formatting
  • Process and transform text data
  • Introduction to regular expressions
  • Understand Unicode and encoding

Lesson 6.1 โ€” String Methods

text = "  Hello, Python World!  "

# Case methods
text.upper()         # "  HELLO, PYTHON WORLD!  "
text.lower()         # "  hello, python world!  "
text.title()         # "  Hello, Python World!  "
text.capitalize()    # "  hello, python world!  "
text.swapcase()      # "  hELLO, pYTHON wORLD!  "

# Whitespace
text.strip()         # "Hello, Python World!"
text.lstrip()        # "Hello, Python World!  "
text.rstrip()        # "  Hello, Python World!"

# Search
text.find("Python")     # 9 (index of first occurrence)
text.rfind("o")         # 20 (last occurrence)
text.count("l")         # 2
text.startswith("  He") # True
text.endswith("!  ")    # True

# Replace & Split
text.replace("Python", "Java")  # "  Hello, Java World!  "
"a,b,c".split(",")             # ["a", "b", "c"]
"hello".split("")              # Error! Use list("hello")
",".join(["a", "b", "c"])      # "a,b,c"

# Testing
"hello123".isalnum()    # True
"hello".isalpha()       # True
"12345".isdigit()       # True
"  ".isspace()          # True

Lesson 6.2 โ€” String Formatting

name, age, gpa = "Alice", 25, 3.856

# Method 1: f-strings (Python 3.6+) โญ RECOMMENDED
print(f"Name: {name}, Age: {age}, GPA: {gpa:.2f}")
# "Name: Alice, Age: 25, GPA: 3.86"

# Expressions inside f-strings
print(f"In 5 years: {age + 5}")
print(f"{'HEADER':=^30}")   # "===========HEADER==========="
print(f"{1000000:,.2f}")      # "1,000,000.00"

# Method 2: .format()
print("Name: {}, Age: {}".format(name, age))
print("Name: {0}, Again: {0}".format(name))
print("{name} is {age}".format(name="Bob", age=30))

# Method 3: % operator (legacy)
print("Name: %s, Age: %d, GPA: %.2f" % (name, age, gpa))

Format Specification Mini-Language

# Alignment
f"{'left':<20}"      # "left                "
f"{'center':^20}"    # "       center       "
f"{'right':>20}"     # "               right"

# Numbers
f"{42:05d}"           # "00042" (zero-padded)
f"{3.14159:.2f}"      # "3.14" (2 decimal places)
f"{1000000:,}"        # "1,000,000" (thousands separator)
f"{0.85:.1%}"         # "85.0%" (percentage)
f"{255:08b}"          # "11111111" (binary)
f"{255:04x}"          # "00ff" (hexadecimal)

Lesson 6.3 โ€” Regular Expressions (Regex)

import re

text = "Contact us at support@email.com or sales@company.org"

# re.findall() โ€” find all matches
emails = re.findall(r'[\w.+-]+@[\w-]+\.[\w.]+', text)
# ['support@email.com', 'sales@company.org']

# re.search() โ€” find first match
match = re.search(r'\d{3}-\d{4}', "Call 555-1234")
if match:
    print(match.group())  # "555-1234"

# re.sub() โ€” replace matches
cleaned = re.sub(r'\s+', ' ', "too   many    spaces")
# "too many spaces"

# Common patterns
r'\d'      # Any digit [0-9]
r'\w'      # Any word char [a-zA-Z0-9_]
r'\s'      # Any whitespace
r'.'       # Any character (except newline)
r'^...$'   # Start and end of string
r'+'       # One or more
r'*'       # Zero or more
r'?'       # Zero or one
r'{n,m}'   # Between n and m occurrences

[!TIP]
Use regex101.com to test and visualize your regex patterns interactively.


Lesson 6.4 โ€” Unicode & Encoding

# Python 3 strings are Unicode by default
emoji = "Hello ๐Ÿ๐ŸŽ‰"
print(len(emoji))       # 9 (including emojis)
print(ord("A"))          # 65 (Unicode code point)
print(chr(65))           # "A"

# Encoding/decoding
text = "Hรฉllo Wรถrld"
encoded = text.encode("utf-8")     # b'H\xc3\xa9llo W\xc3\xb6rld'
decoded = encoded.decode("utf-8")  # "Hรฉllo Wรถrld"

Exercises ๐Ÿ’ป

Exercise 6.1 โ€” Email Validator

Write a function that validates email addresses using regex.

Exercise 6.2 โ€” Title Case Converter

Convert “hello world from python” to “Hello World From Python” โ€” but skip words like “from”, “the”, “a”, “an”.

Exercise 6.3 โ€” String Compression

Compress “aaabbbccccdd” โ†’ “a3b3c4d2”

Exercise 6.4 โ€” CSV Parser

Parse a multi-line CSV string into a list of dictionaries using string methods.


Mini-Project: Caesar Cipher ๐Ÿงฉ

Build an encryption/decryption tool:

  • Encrypt text by shifting each letter by N positions
  • Decrypt by shifting back
  • Handle uppercase, lowercase, and non-alpha characters
  • Bonus: Brute-force attack mode (try all 26 shifts)

Module 6 Quiz (Sample) ๐Ÿ“

  1. What is the difference between find() and index()?
  2. Why are f-strings preferred over .format()?
  3. What does r'\d+' match in regex?
  4. How do you center a string in a 30-character field?
  5. What is the difference between split() and partition()?

Challenge ๐Ÿ†

Write a function that detects the language of a text based on Unicode character ranges (e.g., Latin, Cyrillic, Arabic, CJK).

Module 7: File Handling & I/O

โฑ๏ธ Estimated Time: 5โ€“6 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Read and write text files safely
  • Use context managers (with statement)
  • Work with CSV and JSON files
  • Navigate file paths with pathlib
  • Handle binary files and directories

Lesson 7.1 โ€” Reading & Writing Text Files

# Writing to a file
with open("output.txt", "w") as f:
    f.write("Hello, File!\n")
    f.write("Second line\n")

# Reading entire file
with open("output.txt", "r") as f:
    content = f.read()
    print(content)

# Reading line by line (memory efficient)
with open("output.txt", "r") as f:
    for line in f:
        print(line.strip())

# Reading into a list
with open("output.txt", "r") as f:
    lines = f.readlines()  # ["Hello, File!\n", "Second line\n"]

# Appending
with open("output.txt", "a") as f:
    f.write("Appended line\n")

File Modes

ModeDescription
"r"Read (default) โ€” file must exist
"w"Write โ€” creates or overwrites
"a"Append โ€” creates or adds to end
"x"Exclusive create โ€” fails if file exists
"r+"Read and write
"b"Binary mode (add to above, e.g., "rb")

[!IMPORTANT]
Always use with (context manager) to open files. It automatically closes the file even if an error occurs:

# โœ… Good โ€” auto-closes
with open("file.txt") as f:
    data = f.read()

# โŒ Bad โ€” may leak resources
f = open("file.txt")
data = f.read()
f.close()  # What if an error happens before this?

Lesson 7.2 โ€” CSV Files

import csv

# Writing CSV
with open("students.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["Name", "Age", "Grade"])
    writer.writerow(["Alice", 25, "A"])
    writer.writerow(["Bob", 22, "B"])

# Reading CSV
with open("students.csv", "r") as f:
    reader = csv.reader(f)
    header = next(reader)  # Skip header
    for row in reader:
        print(f"{row[0]} is {row[1]} years old")

# DictReader/DictWriter (column names as keys)
with open("students.csv", "r") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['Name']}: {row['Grade']}")

Lesson 7.3 โ€” JSON Files

import json

# Python dict โ†’ JSON file
data = {
    "name": "Alice",
    "age": 25,
    "hobbies": ["reading", "coding"],
    "address": {"city": "NYC", "zip": "10001"}
}

# Write JSON
with open("data.json", "w") as f:
    json.dump(data, f, indent=4)

# Read JSON
with open("data.json", "r") as f:
    loaded = json.load(f)
    print(loaded["name"])  # "Alice"

# String conversion
json_string = json.dumps(data, indent=2)
parsed = json.loads(json_string)

Lesson 7.4 โ€” File Paths with pathlib

from pathlib import Path

# Creating paths
p = Path("data") / "files" / "output.txt"
home = Path.home()
cwd = Path.cwd()

# Path operations
p.name           # "output.txt"
p.stem           # "output"
p.suffix         # ".txt"
p.parent         # Path("data/files")
p.exists()       # True/False
p.is_file()      # True/False
p.is_dir()       # True/False

# Directory operations
Path("new_folder").mkdir(exist_ok=True)
for file in Path(".").glob("*.py"):
    print(file)

# Recursive glob
for file in Path(".").rglob("*.txt"):
    print(file)

Exercises ๐Ÿ’ป

Exercise 7.1 โ€” File Word Counter

Count the total words, lines, and characters in a text file.

Exercise 7.2 โ€” CSV Merger

Merge two CSV files with the same headers into one output file.

Exercise 7.3 โ€” Config File Manager

Build a program that reads/writes application settings from a JSON config file.


Mini-Project: Log File Analyzer ๐Ÿงฉ

Given a server log file, build a tool that:

  • Counts total requests
  • Finds the most common HTTP status codes
  • Lists the top 10 most visited URLs
  • Identifies peak traffic hours
  • Exports the analysis as a formatted report

Module 7 Quiz (Sample) ๐Ÿ“

  1. What is the difference between "w" and "a" file modes?
  2. Why should you use with when opening files?
  3. What does json.dumps() do vs json.dump()?
  4. How do you read a CSV file as dictionaries?
  5. What is pathlib.Path and why prefer it over os.path?

Challenge ๐Ÿ†

Build a file deduplicator โ€” scan a directory for duplicate files (by content hash, not name) and report them.

Module 8: Error Handling & Debugging

โฑ๏ธ Estimated Time: 5โ€“6 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Understand Python’s exception hierarchy
  • Write robust try/except/else/finally blocks
  • Raise and create custom exceptions
  • Debug code effectively using tools and techniques
  • Use assertions for defensive programming

Lesson 8.1 โ€” Understanding Exceptions

# Common exceptions
print(10 / 0)          # ZeroDivisionError
int("hello")           # ValueError
my_list = [1, 2, 3]
my_list[10]            # IndexError
my_dict = {}
my_dict["key"]         # KeyError
undefined_var          # NameError
"hello" + 5            # TypeError

Exception Hierarchy (Simplified)

BaseException
โ”œโ”€โ”€ KeyboardInterrupt
โ”œโ”€โ”€ SystemExit
โ””โ”€โ”€ Exception
    โ”œโ”€โ”€ ValueError
    โ”œโ”€โ”€ TypeError
    โ”œโ”€โ”€ KeyError
    โ”œโ”€โ”€ IndexError
    โ”œโ”€โ”€ FileNotFoundError
    โ”œโ”€โ”€ ZeroDivisionError
    โ”œโ”€โ”€ AttributeError
    โ”œโ”€โ”€ ImportError
    โ””โ”€โ”€ RuntimeError

Lesson 8.2 โ€” Try/Except/Else/Finally

# Basic try/except
try:
    number = int(input("Enter a number: "))
    result = 100 / number
except ValueError:
    print("That's not a valid number!")
except ZeroDivisionError:
    print("Cannot divide by zero!")

# Full structure
try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File not found!")
except PermissionError:
    print("No permission to read file!")
else:
    # Runs ONLY if no exception occurred
    print(f"File has {len(content)} characters")
finally:
    # ALWAYS runs โ€” cleanup code goes here
    print("Operation complete")

Catching Multiple Exceptions

# Catch multiple in one block
try:
    risky_operation()
except (ValueError, TypeError, KeyError) as e:
    print(f"Error occurred: {e}")

# Catch ALL exceptions (use sparingly)
try:
    risky_operation()
except Exception as e:
    print(f"Unexpected error: {type(e).__name__}: {e}")

[!WARNING]
Never use bare except: โ€” it catches everything including KeyboardInterrupt and SystemExit, making your program impossible to terminate.


Lesson 8.3 โ€” Raising Exceptions

# Raise built-in exceptions
def set_age(age):
    if not isinstance(age, int):
        raise TypeError("Age must be an integer")
    if age < 0 or age > 150:
        raise ValueError(f"Age must be 0-150, got {age}")
    return age

# Re-raising exceptions
try:
    process_data()
except ValueError:
    print("Logging the error...")
    raise  # Re-raise the same exception

Custom Exceptions

class InsufficientFundsError(Exception):
    """Raised when a withdrawal exceeds the balance."""
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        super().__init__(
            f"Cannot withdraw ${amount:.2f}. "
            f"Balance: ${balance:.2f}"
        )

class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def withdraw(self, amount):
        if amount > self.balance:
            raise InsufficientFundsError(self.balance, amount)
        self.balance -= amount

# Usage
account = BankAccount(100)
try:
    account.withdraw(150)
except InsufficientFundsError as e:
    print(e)  # Cannot withdraw $150.00. Balance: $100.00

Lesson 8.4 โ€” Debugging Techniques

1. Print Debugging

def buggy_function(data):
    print(f"DEBUG: data = {data}")          # Checkpoint 1
    result = process(data)
    print(f"DEBUG: result = {result}")      # Checkpoint 2
    return result

2. Using pdb (Python Debugger)

import pdb

def complex_function(x):
    result = x * 2
    pdb.set_trace()      # Execution pauses here
    result += 10          # Step through with 'n'
    return result

# pdb commands: n(ext), s(tep), c(ontinue), p(rint), q(uit)

3. Using breakpoint() (Python 3.7+)

def calculate(x, y):
    result = x + y
    breakpoint()          # Built-in, replaces pdb.set_trace()
    return result * 2

4. Assertions

def calculate_average(numbers):
    assert len(numbers) > 0, "Cannot average an empty list"
    assert all(isinstance(n, (int, float)) for n in numbers), \
        "All elements must be numbers"
    return sum(numbers) / len(numbers)

Lesson 8.5 โ€” Common Errors & Fixes

ErrorCauseFix
IndentationErrorInconsistent whitespaceUse 4 spaces consistently
TypeError: unsupported operandWrong types in operationCheck types, convert if needed
AttributeErrorMethod doesn’t exist on objectCheck spelling, verify type
ModuleNotFoundErrorPackage not installedpip install package_name
RecursionErrorMissing base caseAdd/fix base case in recursion

Exercises ๐Ÿ’ป

Exercise 8.1 โ€” Safe Division

Write a function that performs division with full error handling for all possible edge cases.

Exercise 8.2 โ€” Input Validator

Create a function that keeps asking the user for valid input (integer in a specific range) until they provide it.

Exercise 8.3 โ€” Custom Exception Hierarchy

Create a hierarchy: AppError โ†’ ValidationError, DatabaseError, NetworkError.

Advertisement

Mini-Project: Robust Data Processor ๐Ÿงฉ

Build a program that reads a CSV file, validates each row, handles malformed data gracefully, logs all errors to a separate file, and produces a clean output file with only valid records.


Module 8 Quiz (Sample) ๐Ÿ“

  1. What is the difference between else and finally in try blocks?
  2. When should you create custom exceptions?
  3. What does raise without arguments do?
  4. Why is bare except: dangerous?
  5. Name three debugging tools available in Python.

Challenge ๐Ÿ†

Write a decorator @retry(max_attempts=3, delay=1) that automatically retries a function if it raises an exception, with a configurable delay between attempts.

Module 9: Modules & Packages

โฑ๏ธ Estimated Time: 4โ€“5 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Import and use modules effectively
  • Create your own reusable modules
  • Navigate the Python Standard Library
  • Install packages with pip
  • Set up virtual environments

Lesson 9.1 โ€” Importing Modules

# Full import
import math
print(math.sqrt(16))    # 4.0
print(math.pi)          # 3.14159...

# Import specific items
from math import sqrt, pi
print(sqrt(16))         # 4.0

# Import with alias
import numpy as np
from datetime import datetime as dt

# Import everything (avoid in production!)
from math import *

How Python Finds Modules

import sys
print(sys.path)  # List of directories Python searches
# 1. Current directory
# 2. PYTHONPATH environment variable
# 3. Standard library
# 4. site-packages (pip installs)

Lesson 9.2 โ€” Creating Your Own Modules

# File: myutils.py
"""My utility functions module."""

def greet(name):
    """Return a greeting string."""
    return f"Hello, {name}!"

def factorial(n):
    """Calculate factorial recursively."""
    if n <= 1:
        return 1
    return n * factorial(n - 1)

PI = 3.14159

# This block runs ONLY when the file is executed directly
if __name__ == "__main__":
    print(greet("World"))
    print(factorial(5))
# File: main.py โ€” using the module
import myutils

print(myutils.greet("Alice"))
print(myutils.factorial(5))
print(myutils.PI)

Packages (Multi-file Modules)

my_package/
โ”œโ”€โ”€ __init__.py       # Makes it a package
โ”œโ”€โ”€ math_tools.py
โ”œโ”€โ”€ string_tools.py
โ””โ”€โ”€ io_tools.py
# __init__.py
from .math_tools import add, multiply
from .string_tools import capitalize_words

# Usage
from my_package import add, capitalize_words

Lesson 9.3 โ€” Standard Library Essentials

# os โ€” Operating system interface
import os
os.getcwd()                    # Current directory
os.listdir(".")                # List files
os.path.exists("file.txt")    # Check existence

# sys โ€” System-specific parameters
import sys
sys.argv        # Command-line arguments
sys.version     # Python version

# math โ€” Mathematical functions
import math
math.ceil(4.3)    # 5
math.floor(4.7)   # 4
math.gcd(12, 8)   # 4

# random โ€” Random number generation
import random
random.randint(1, 100)          # Random int 1-100
random.choice(["a", "b", "c"]) # Random choice
random.shuffle(my_list)         # Shuffle in-place
random.sample(range(100), 5)   # 5 unique random numbers

# datetime โ€” Dates and times
from datetime import datetime, timedelta
now = datetime.now()
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
future = now + timedelta(days=30)

# collections โ€” Specialized containers
from collections import Counter, defaultdict, deque
word_counts = Counter("abracadabra")
# Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

# itertools โ€” Iterator building blocks
from itertools import chain, combinations, permutations
list(combinations([1, 2, 3], 2))
# [(1, 2), (1, 3), (2, 3)]

Lesson 9.4 โ€” pip & Virtual Environments

# Installing packages
pip install requests
pip install pandas numpy matplotlib
pip install requests==2.28.0  # Specific version

# Listing & managing
pip list
pip show requests
pip freeze > requirements.txt
pip install -r requirements.txt
pip uninstall requests

# Virtual environments
python -m venv myenv           # Create
myenv\Scripts\activate         # Activate (Windows)
source myenv/bin/activate      # Activate (macOS/Linux)
deactivate                     # Deactivate

[!IMPORTANT]
Always use virtual environments for projects. They isolate dependencies so different projects don’t conflict. Never install packages globally for project work.


Exercises ๐Ÿ’ป

Exercise 9.1 โ€” Module Explorer

Write a script that lists all functions in the math module using dir() and help().

Exercise 9.2 โ€” Date Calculator

Build a program using datetime that calculates the number of days between two dates, and what day of the week a specific date falls on.

Exercise 9.3 โ€” Password Generator Module

Create a reusable password_utils module with functions for generating, validating, and hashing passwords.


Mini-Project: Personal Utility Library ๐Ÿงฉ

Build your own utility package pytools/ with:

  • pytools/math_utils.py โ€” statistical functions (mean, median, mode, std deviation)
  • pytools/string_utils.py โ€” text processing helpers
  • pytools/file_utils.py โ€” file operation helpers
  • pytools/__init__.py โ€” clean public API
  • Write a setup.py or pyproject.toml to make it installable

Module 9 Quiz (Sample) ๐Ÿ“

  1. What does if __name__ == "__main__": do?
  2. What is a virtual environment and why use one?
  3. How does pip freeze differ from pip list?
  4. Name five useful standard library modules.
  5. What is an __init__.py file?

Challenge ๐Ÿ†

Create a CLI tool using argparse that accepts command-line arguments to perform different math operations (e.g., python calc.py add 3 5 โ†’ 8).

Module 10: Object-Oriented Programming (OOP)

โฑ๏ธ Estimated Time: 8โ€“10 hours | ๐ŸŽฏ Difficulty: Intermediateโ€“Advanced


Learning Objectives ๐ŸŽฏ

  • Understand the OOP paradigm and its benefits
  • Create classes with attributes and methods
  • Implement inheritance and polymorphism
  • Use encapsulation and properties
  • Master magic/dunder methods
  • Understand composition vs inheritance

Lesson 10.1 โ€” Classes & Objects

class Dog:
    """A simple Dog class."""

    # Class attribute (shared by all instances)
    species = "Canis familiaris"

    def __init__(self, name, age, breed):
        """Initialize a Dog instance."""
        # Instance attributes (unique to each instance)
        self.name = name
        self.age = age
        self.breed = breed

    def bark(self):
        """Make the dog bark."""
        return f"{self.name} says: Woof! ๐Ÿ•"

    def describe(self):
        """Return a description of the dog."""
        return f"{self.name} is a {self.age}-year-old {self.breed}"

# Creating objects (instances)
dog1 = Dog("Buddy", 3, "Golden Retriever")
dog2 = Dog("Luna", 5, "German Shepherd")

print(dog1.bark())       # "Buddy says: Woof! ๐Ÿ•"
print(dog2.describe())   # "Luna is a 5-year-old German Shepherd"
print(Dog.species)       # "Canis familiaris"

Lesson 10.2 โ€” Methods Types

class MathHelper:
    pi = 3.14159

    def __init__(self, value):
        self.value = value

    # Instance method โ€” operates on instance data
    def square(self):
        return self.value ** 2

    # Class method โ€” operates on class data
    @classmethod
    def circle_area(cls, radius):
        return cls.pi * radius ** 2

    # Static method โ€” utility, no access to instance or class
    @staticmethod
    def add(a, b):
        return a + b

m = MathHelper(5)
m.square()                    # 25
MathHelper.circle_area(3)     # 28.27
MathHelper.add(3, 4)          # 7

Lesson 10.3 โ€” Inheritance

class Animal:
    def __init__(self, name, sound):
        self.name = name
        self.sound = sound

    def speak(self):
        return f"{self.name} says {self.sound}!"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "Woof")  # Call parent __init__
        self.breed = breed

    def fetch(self, item):
        return f"{self.name} fetches the {item}! ๐ŸŽพ"

class Cat(Animal):
    def __init__(self, name, indoor=True):
        super().__init__(name, "Meow")
        self.indoor = indoor

    def purr(self):
        return f"{self.name} is purring... ๐Ÿ˜บ"

dog = Dog("Buddy", "Labrador")
cat = Cat("Whiskers")

print(dog.speak())    # "Buddy says Woof!"
print(dog.fetch("ball"))
print(cat.speak())    # "Whiskers says Meow!"

Lesson 10.4 โ€” Encapsulation & Properties

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner           # Public
        self._account_id = "12345"   # Protected (convention)
        self.__balance = balance     # Private (name mangling)

    @property
    def balance(self):
        """Get the current balance."""
        return self.__balance

    @balance.setter
    def balance(self, amount):
        """Set balance with validation."""
        if amount < 0:
            raise ValueError("Balance cannot be negative")
        self.__balance = amount

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Deposit must be positive")
        self.__balance += amount
        return self.__balance

    def withdraw(self, amount):
        if amount > self.__balance:
            raise ValueError("Insufficient funds")
        self.__balance -= amount
        return self.__balance

account = BankAccount("Alice", 1000)
print(account.balance)        # 1000 (property getter)
account.deposit(500)
# account.__balance             # AttributeError (private!)

Lesson 10.5 โ€” Polymorphism

class Shape:
    def area(self):
        raise NotImplementedError("Subclasses must implement area()")

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    def area(self):
        return 3.14159 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def area(self):
        return self.width * self.height

# Polymorphism in action โ€” same method, different behavior
shapes = [Circle(5), Rectangle(4, 6), Circle(3)]
for shape in shapes:
    print(f"{type(shape).__name__}: area = {shape.area():.2f}")

Lesson 10.6 โ€” Magic/Dunder Methods

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __len__(self):
        return int((self.x**2 + self.y**2) ** 0.5)

    def __getitem__(self, index):
        if index == 0: return self.x
        if index == 1: return self.y
        raise IndexError

v1 = Vector(3, 4)
v2 = Vector(1, 2)

print(v1 + v2)         # (4, 6)
print(v1 == Vector(3, 4))  # True
print(len(v1))          # 5
print(v1[0])            # 3

Common Dunder Methods

MethodPurposeTrigger
__init__Constructorobj = Class()
__str__User-friendly stringprint(obj)
__repr__Developer stringrepr(obj)
__len__Lengthlen(obj)
__eq__Equalityobj1 == obj2
__lt__Less thanobj1 < obj2
__add__Additionobj1 + obj2
__contains__Membershipitem in obj
__iter__Iterationfor x in obj

Exercises ๐Ÿ’ป

Exercise 10.1 โ€” Student Grade Book

Create a Student class with methods to add grades, calculate GPA, and determine honor roll status.

Exercise 10.2 โ€” Shape Hierarchy

Build a shape hierarchy: Shape โ†’ Circle, Rectangle, Triangle with area and perimeter methods.

Exercise 10.3 โ€” Playlist Manager

Create Song and Playlist classes where Playlist supports adding, removing, shuffling, and iterating.


Mini-Project: Library Management System ๐Ÿงฉ

Build a complete system with:

  • Book class (title, author, ISBN, available status)
  • Member class (name, ID, borrowed books)
  • Library class (catalog, members, checkout/return logic)
  • Search books by title/author
  • Track borrowing history
  • Late fee calculation

Module 10 Quiz (Sample) ๐Ÿ“

  1. What is the difference between a class and an object?
  2. Explain self in Python methods.
  3. What is the difference between __str__ and __repr__?
  4. When should you use composition over inheritance?
  5. What does super() do?

Challenge ๐Ÿ†

Implement a LinkedList class with append, prepend, delete, find, __len__, __iter__, and __repr__ methods.

Module 11: Working with Data

โฑ๏ธ Estimated Time: 6โ€“7 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Use collections module for specialized containers
  • Master itertools for efficient iteration
  • Work with dates and times confidently
  • Understand generators and yield
  • Perform basic data analysis with pure Python

Lesson 11.1 โ€” Collections Module

from collections import Counter, defaultdict, deque, namedtuple

# Counter โ€” count element frequencies
words = "the cat sat on the mat the cat".split()
counts = Counter(words)
print(counts.most_common(2))  # [('the', 3), ('cat', 2)]

# defaultdict โ€” dict with default values for missing keys
word_groups = defaultdict(list)
for word in ["apple", "banana", "avocado", "blueberry", "cherry"]:
    word_groups[word[0]].append(word)
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}

# deque โ€” double-ended queue (fast append/pop from both ends)
d = deque([1, 2, 3])
d.appendleft(0)    # deque([0, 1, 2, 3])
d.rotate(1)        # deque([3, 0, 1, 2])

Lesson 11.2 โ€” Itertools

from itertools import chain, product, combinations, permutations, groupby, accumulate

# chain โ€” combine multiple iterables
list(chain([1, 2], [3, 4], [5, 6]))  # [1, 2, 3, 4, 5, 6]

# product โ€” cartesian product
list(product("AB", "12"))  # [('A','1'), ('A','2'), ('B','1'), ('B','2')]

# combinations & permutations
list(combinations([1, 2, 3], 2))  # [(1,2), (1,3), (2,3)]
list(permutations([1, 2, 3], 2))  # [(1,2), (1,3), (2,1), (2,3), (3,1), (3,2)]

# accumulate โ€” running totals
list(accumulate([1, 2, 3, 4, 5]))  # [1, 3, 6, 10, 15]

# groupby โ€” group consecutive elements
data = sorted(["Alice", "Bob", "Anna", "Brian", "Charlie"], key=lambda x: x[0])
for key, group in groupby(data, key=lambda x: x[0]):
    print(f"{key}: {list(group)}")

Lesson 11.3 โ€” Datetime Deep Dive

from datetime import datetime, date, timedelta

# Current date/time
now = datetime.now()
today = date.today()

# Creating specific dates
birthday = date(1995, 6, 15)
meeting = datetime(2025, 12, 25, 14, 30, 0)

# Formatting (strftime)
now.strftime("%Y-%m-%d %H:%M:%S")   # "2025-04-05 19:00:00"
now.strftime("%B %d, %Y")            # "April 05, 2025"
now.strftime("%A")                    # "Saturday"

# Parsing (strptime)
parsed = datetime.strptime("2025-04-05", "%Y-%m-%d")

# Arithmetic
future = now + timedelta(days=30, hours=5)
age_days = (date.today() - birthday).days

Lesson 11.4 โ€” Generators

# Generator function โ€” uses yield instead of return
def countdown(n):
    while n > 0:
        yield n
        n -= 1

for num in countdown(5):
    print(num)  # 5, 4, 3, 2, 1

# Generator expression (like list comprehension but lazy)
squares = (x**2 for x in range(1000000))  # No memory usage!
first_ten = [next(squares) for _ in range(10)]

# Infinite generator
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()
first_20 = [next(fib) for _ in range(20)]

[!TIP]
Generators are memory-efficient because they produce values one at a time instead of storing everything in memory. Use them when working with large datasets.


Lesson 11.5 โ€” Useful Patterns

# enumerate โ€” get index + value
fruits = ["apple", "banana", "cherry"]
for i, fruit in enumerate(fruits, start=1):
    print(f"{i}. {fruit}")

# zip โ€” pair up iterables
names = ["Alice", "Bob", "Charlie"]
scores = [90, 85, 92]
for name, score in zip(names, scores):
    print(f"{name}: {score}")

# Sorting with key
students = [("Alice", 90), ("Bob", 75), ("Charlie", 85)]
by_grade = sorted(students, key=lambda s: s[1], reverse=True)

# any() and all()
numbers = [2, 4, 6, 8]
all(n % 2 == 0 for n in numbers)  # True โ€” all even
any(n > 7 for n in numbers)       # True โ€” at least one > 7

Exercises ๐Ÿ’ป

Exercise 11.1 โ€” Anagram Detector

Using Counter, write a function to check if two words are anagrams.

Exercise 11.2 โ€” Date Range Generator

Write a generator that yields all dates between a start and end date.

Exercise 11.3 โ€” Moving Average

Write a generator that computes a rolling average over a stream of numbers.

Advertisement

Mini-Project: Sales Data Analyzer ๐Ÿงฉ

Given a list of sales records (date, product, quantity, price):

  • Calculate total revenue per product
  • Find best/worst selling products
  • Compute monthly trends
  • Generate a text-based sales report
  • Use only standard library (no pandas)

Module 11 Quiz (Sample) ๐Ÿ“

  1. What is the advantage of defaultdict over a regular dict?
  2. How does a generator differ from a regular function?
  3. What does zip() do with unequal-length iterables?
  4. Name three itertools functions and their use cases.
  5. How do you parse a date string in Python?

Challenge ๐Ÿ†

Write a generator-based pipeline that reads a large log file line by line, filters lines containing “ERROR”, extracts timestamps, and groups errors by hour โ€” all without loading the entire file into memory.

Module 12: APIs & Web Basics

โฑ๏ธ Estimated Time: 6โ€“7 hours | ๐ŸŽฏ Difficulty: Intermediate


Learning Objectives ๐ŸŽฏ

  • Understand HTTP fundamentals (methods, status codes)
  • Make API requests with the requests library
  • Parse and use JSON API responses
  • Handle authentication and rate limiting
  • Introduction to web scraping with BeautifulSoup

Lesson 12.1 โ€” HTTP Fundamentals

HTTP Methods

MethodPurposeExample
GETRetrieve dataGet user profile
POSTCreate new dataRegister new user
PUTUpdate existing dataUpdate profile
DELETERemove dataDelete account

Status Codes

CodeMeaningCategory
200OK โ€” Successโœ… Success
201Createdโœ… Success
400Bad RequestโŒ Client Error
401UnauthorizedโŒ Client Error
404Not FoundโŒ Client Error
429Too Many RequestsโŒ Rate Limited
500Internal Server ErrorโŒ Server Error

Lesson 12.2 โ€” Using the requests Library

pip install requests
import requests

# GET request
response = requests.get("https://api.github.com/users/python")
print(response.status_code)   # 200
print(response.json())        # Parsed JSON as dict

# POST request
data = {"title": "Hello", "body": "World", "userId": 1}
response = requests.post(
    "https://jsonplaceholder.typicode.com/posts",
    json=data
)
print(response.status_code)  # 201

# Query parameters
params = {"q": "python", "sort": "stars", "order": "desc"}
response = requests.get(
    "https://api.github.com/search/repositories",
    params=params
)

# Headers
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}
response = requests.get(url, headers=headers)

# Timeout
response = requests.get(url, timeout=10)  # 10 second timeout

Lesson 12.3 โ€” Working with JSON APIs

import requests

def get_weather(city):
    """Fetch weather data for a city."""
    API_KEY = "your_api_key"
    url = "https://api.openweathermap.org/data/2.5/weather"
    params = {
        "q": city,
        "appid": API_KEY,
        "units": "metric"
    }

    try:
        response = requests.get(url, params=params, timeout=10)
        response.raise_for_status()  # Raise exception for 4xx/5xx

        data = response.json()
        return {
            "city": data["name"],
            "temp": data["main"]["temp"],
            "description": data["weather"][0]["description"],
            "humidity": data["main"]["humidity"]
        }
    except requests.exceptions.HTTPError as e:
        print(f"HTTP Error: {e}")
    except requests.exceptions.ConnectionError:
        print("Connection failed")
    except requests.exceptions.Timeout:
        print("Request timed out")
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")
    return None

Lesson 12.4 โ€” Robust API Usage

import requests
import time

# Retry with exponential backoff
def api_call_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.get(url, timeout=10)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            wait = 2 ** attempt  # 1s, 2s, 4s
            print(f"Attempt {attempt+1} failed: {e}. Retrying in {wait}s...")
            time.sleep(wait)
    raise Exception(f"Failed after {max_retries} attempts")

# Pagination
def get_all_pages(base_url):
    all_data = []
    page = 1
    while True:
        response = requests.get(base_url, params={"page": page, "per_page": 100})
        data = response.json()
        if not data:
            break
        all_data.extend(data)
        page += 1
    return all_data

Lesson 12.5 โ€” Web Scraping Basics

pip install beautifulsoup4
import requests
from bs4 import BeautifulSoup

# Fetch and parse a webpage
url = "https://news.ycombinator.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")

# Find elements
titles = soup.find_all("span", class_="titleline")
for title in titles[:10]:
    link = title.find("a")
    print(f"๐Ÿ“ฐ {link.text}")
    print(f"   {link.get('href', 'No URL')}\n")

[!CAUTION]
Web scraping ethics:

  • Always check robots.txt before scraping
  • Respect rate limits โ€” add delays between requests
  • Check the website’s Terms of Service
  • Prefer official APIs when available

Exercises ๐Ÿ’ป

Exercise 12.1 โ€” GitHub User Explorer

Use the GitHub API to display info about any GitHub user (repos, followers, bio).

Exercise 12.2 โ€” Quote of the Day

Fetch a random quote from a public quotes API and display it beautifully in the terminal.

Exercise 12.3 โ€” Link Checker

Write a program that checks if a list of URLs are accessible (return 200).


Mini-Project: Weather Dashboard ๐Ÿงฉ

Build a CLI weather app that:

  • Accepts city names as input
  • Displays current temperature, conditions, humidity, wind
  • Shows a 5-day forecast
  • Saves favorite cities to a JSON file
  • Handles API errors gracefully
  • Formats output with colors (using colorama)

Module 12 Quiz (Sample) ๐Ÿ“

  1. What is the difference between GET and POST?
  2. What does response.raise_for_status() do?
  3. When should you use query parameters vs request body?
  4. What is robots.txt?
  5. How do you handle API rate limiting?

Challenge ๐Ÿ†

Build a currency converter that fetches real-time exchange rates from an API, caches results for 1 hour, and supports conversion between any two currencies.

Module 13: Capstone Projects

โฑ๏ธ Estimated Time: 15โ€“20 hours | ๐ŸŽฏ Difficulty: Intermediateโ€“Advanced


Purpose ๐ŸŽฏ

Apply everything you’ve learned across Modules 1โ€“12 in real-world projects. Each project integrates multiple modules and pushes you to solve problems independently.

[!IMPORTANT]
How to approach these projects:

  1. Read the full requirements before coding
  2. Plan your classes and functions on paper first
  3. Build incrementally โ€” get a basic version working, then add features
  4. Write clean code with docstrings and comments
  5. Handle ALL errors gracefully

๏ธ Project 1: Personal Finance Tracker ๐Ÿ—

Overview

A CLI application to track income and expenses, categorize transactions, and generate financial reports.

Skills Used

Variables Data Structures Functions OOP File I/O Error Handling Datetime

Requirements

  • Add income/expense transactions (amount, category, date, description)
  • View transactions filtered by date range or category
  • Calculate totals, averages, and category breakdowns
  • Save/load data from JSON file
  • Generate monthly summary reports
  • Budget alerts (warn when spending exceeds category limits)

Architecture Hints

class Transaction:
    """amount, category, date, description, type (income/expense)"""

class Budget:
    """category limits, tracking, alerts"""

class FinanceTracker:
    """Manages transactions, budgets, reporting"""
    def add_transaction(self, ...): ...
    def get_summary(self, month, year): ...
    def export_report(self, filename): ...

Suggested Enhancements

  • Chart visualization using matplotlib
  • Recurring transactions
  • CSV import/export
  • Multi-currency support

๏ธ Project 2: Quiz Game Engine ๐Ÿ—

Overview

A dynamic quiz game that loads questions from JSON files, supports multiple categories and difficulty levels, tracks scores, and maintains a leaderboard.

Skills Used

Control Flow Functions Data Structures File I/O OOP Random Error Handling

Requirements

  • Load questions from JSON files (category, question, options, answer, difficulty)
  • Multiple game modes: timed, untimed, practice
  • Score tracking with multipliers for difficulty
  • Leaderboard saved to file
  • Hint system (reduces points)
  • Progress tracking across sessions

Sample Question Format

{
  "category": "Science",
  "difficulty": "medium",
  "question": "What is the chemical symbol for gold?",
  "options": ["Go", "Gd", "Au", "Ag"],
  "answer": "Au",
  "hint": "It comes from the Latin word 'aurum'"
}

Suggested Enhancements

  • Fetch questions from an API (Open Trivia DB)
  • Multiplayer mode
  • Custom quiz creation tool
  • Statistics dashboard

๏ธ Project 3: Web Scraper & Data Pipeline ๐Ÿ—

Overview

Build a web scraper that collects structured data from websites, processes it, and exports clean datasets.

Skills Used

Requests BeautifulSoup Regex File I/O CSV/JSON Error Handling OOP

Requirements

  • Scrape data from a public website (e.g., book listings, job postings, news)
  • Parse HTML to extract structured data
  • Clean and validate scraped data
  • Handle pagination automatically
  • Rate limiting and polite scraping (delays between requests)
  • Export to CSV and JSON
  • Logging of scraping progress and errors

Architecture Hints

class Scraper:
    """Handles HTTP requests with retry logic"""

class Parser:
    """Extracts structured data from HTML"""

class DataCleaner:
    """Validates and cleans raw data"""

class Exporter:
    """Writes data to CSV/JSON files"""

class Pipeline:
    """Orchestrates the full scrape โ†’ clean โ†’ export flow"""

Suggested Enhancements

  • Database storage (SQLite)
  • Scheduled scraping with timestamps
  • Data comparison (detect changes between scrapes)
  • Email notifications for new data

๏ธ Project 4: Task Management System ๐Ÿ—

Overview

A full-featured CLI task manager with priorities, due dates, categories, and persistent storage.

Skills Used

OOP File I/O Datetime Collections Error Handling Modules

Requirements

  • Create, update, delete, and complete tasks
  • Priority levels (High, Medium, Low) with color coding
  • Due dates with overdue detection
  • Categories/tags for organization
  • Search and filter (by status, priority, category, keyword)
  • Persistent storage (JSON)
  • Undo last action
  • Export task report

Sample Interface

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                  ๐Ÿ“‹ TASK MANAGER                     โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘  1. Add Task       5. Search Tasks                   โ•‘
โ•‘  2. View Tasks     6. Statistics                     โ•‘
โ•‘  3. Update Task    7. Export Report                   โ•‘
โ•‘  4. Delete Task    8. Exit                            โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Suggested Enhancements

  • Subtask support (nested tasks)
  • Recurring tasks
  • Time tracking per task
  • Integration with a REST API

๏ธ Project 5: Static Website Generator ๐Ÿ—

Overview

Build a Python program that converts Markdown files into a complete HTML website with navigation, styling, and templating.

Skills Used

File I/O Strings Regex OOP Modules Pathlib Error Handling

Requirements

  • Read Markdown files from a content/ directory
  • Convert Markdown syntax to HTML (headers, bold, italic, links, code, lists)
  • Apply an HTML template with header, footer, navigation
  • Generate a site index/table of contents
  • Copy static assets (CSS, images) to output directory
  • Watch mode: auto-rebuild when files change

Architecture Hints

class MarkdownParser:
    """Converts markdown text to HTML"""

class Template:
    """HTML template with placeholder substitution"""

class SiteGenerator:
    """Orchestrates parsing, templating, file output"""
    def build(self): ...
    def watch(self): ...

Suggested Enhancements

  • Blog support with date-sorted posts
  • Syntax highlighting for code blocks
  • RSS feed generation
  • Deploy to GitHub Pages

Course Completion Checklist ๐ŸŽ“

  • [ ] Module 1: Foundations & Setup โœ…
  • [ ] Module 2: Variables & Data Types โœ…
  • [ ] Module 3: Control Flow โœ…
  • [ ] Module 4: Functions โœ…
  • [ ] Module 5: Data Structures โœ…
  • [ ] Module 6: Strings & Text Processing โœ…
  • [ ] Module 7: File Handling & I/O โœ…
  • [ ] Module 8: Error Handling & Debugging โœ…
  • [ ] Module 9: Modules & Packages โœ…
  • [ ] Module 10: Object-Oriented Programming โœ…
  • [ ] Module 11: Working with Data โœ…
  • [ ] Module 12: APIs & Web Basics โœ…
  • [ ] Module 13: At least 2 Capstone Projects โœ…

What’s Next? ๐Ÿš€

After completing this course, explore these specializations:

PathKey LibrariesUse Case
Data Sciencepandas, numpy, matplotlib, seabornData analysis & visualization
Machine Learningscikit-learn, TensorFlow, PyTorchAI & predictive models
Web DevelopmentDjango, Flask, FastAPIBuilding web applications
Automationselenium, pyautogui, scheduleAutomating tasks
Game Developmentpygame, arcadeBuilding games
DevOpsfabric, ansible, docker SDKInfrastructure automation

Congratulations on completing the Python for Beginners course! ๐ŸŽ‰๐Ÿ
You now have the foundation to build anything with Python.

Advertisement

Leave a Comment