Before heading into the final stretch, it helps to take stock of the foundation the course has been building on. The programming concepts covered in Parts 1–4 — values and types, control flow, data structures, functions, modules, I/O, exceptions, classes — are the vocabulary used by every larger topic that follows. A short review makes sure they are fluent, not just familiar.
The mental model is layered. At the bottom are values (ints, strings, lists, dicts) and the operations you perform on them. Above that sit expressions and statements — assignment, conditionals, loops, function calls. Functions compose statements into named reusable units. Modules compose functions into files. Packages compose modules into libraries. Each layer hides complexity from the next.
Alongside structure there is flow. Data flows through your program as function arguments and return values. Errors flow via exceptions, caught at the right scope. Control flows through if/for/while/try. Effects (I/O, network, database) happen at the edges — the pure functions in the middle are what you test.
Finally, the Python-specific habits: iterate by default, use comprehensions for transforms, prefer composition over inheritance, let the standard library do the heavy lifting, type your public API. These habits are what turn the building blocks into Pythonic code. The rest of this course assumes all of them.
Values, containers, control flow
Immutable values: int, float, str, tuple, frozenset. Mutable: list, dict, set. Containers have methods; strings have the richest set. Loops iterate; comprehensions iterate and build at once.
if / elif / else, for / while, try / except / finally, with, return, break, continue, yield. That small list is almost every statement-level construct you will use.
Functions, classes, modules
Functions take arguments and return values. Keyword-only arguments make options explicit. Closures capture enclosing scope. Decorators wrap functions to add behavior.
Classes bundle state and behavior. Inheritance is optional; composition and Protocol often fit better. Modules are files; packages are folders; both expose a public surface and hide internals.
Concepts to be fluent with.
| Tool | Purpose |
|---|---|
Data structurestopic | Lists, dicts, sets, tuples. |
Control flowtopic | if/for/while/try, functions. |
Modules + packagestopic | Imports and structure. |
Classestopic | OOP basics. |
Exceptionstopic | Error flow. |
Input/outputtopic | Files and formatting. |
Typingtopic | Static contracts. |
Zen of Pythonphilosophy | The taste that makes code Pythonic. |
Reviewing Core Programming Concepts code example
The script compresses the main language features into one small program: types, collections, control flow, functions, classes, exceptions, I/O, and context managers.
# Lesson: Reviewing Core Programming Concepts
from dataclasses import dataclass
from pathlib import Path
from tempfile import TemporaryDirectory
# 1) Values and collections
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
unique = sorted(set(numbers))
counts = {n: numbers.count(n) for n in unique}
print("unique:", unique)
print("counts:", counts)
# 2) Control flow
total = 0
for n in numbers:
if n % 2 == 0:
total += n
else:
continue
print("even sum:", total)
# 3) Functions
def even_squares(seq):
return [x * x for x in seq if x % 2 == 0]
print("even squares:", even_squares(numbers))
# 4) Classes (dataclass for brevity)
@dataclass
class Point:
x: float
y: float
def norm(self) -> float:
return (self.x ** 2 + self.y ** 2) ** 0.5
print("point norm:", Point(3, 4).norm())
# 5) Exceptions
def safe_div(a, b):
try:
return a / b
except ZeroDivisionError:
return float("inf")
print("safe div:", safe_div(10, 0))
# 6) I/O + context manager
with TemporaryDirectory() as tmp:
p = Path(tmp) / "greet.txt"
p.write_text("hello", encoding="utf-8")
content = p.read_text(encoding="utf-8")
print("file says:", content)
# 7) Generator
def running_sum(values):
total = 0
for v in values:
total += v
yield total
print("running:", list(running_sum([1, 2, 3, 4])))
Each block exercises one concept:
1) Collections + comprehension = concise transform.
2) Control flow (if/continue) maps closely to intent.
3) Functions bundle a named expression; dataclass bundles a named record.
4) Try/except contains the error category you know how to handle.
Combine several core features in one task.
from collections import Counter
def word_stats(text: str) -> dict:
words = [w.lower() for w in text.split()]
return {
"count": len(words),
"unique": len(set(words)),
"top": Counter(words).most_common(2),
}
print(word_stats("python is fun and python is fast"))
Core features come together.
assert [x*x for x in range(5) if x % 2] == [1, 9]
assert sorted({3, 1, 2}) == [1, 2, 3]
assert {"a": 1, "b": 2}["a"] == 1
try:
1/0
except ZeroDivisionError:
pass
Running prints:
unique: [1, 2, 3, 4, 5, 6, 9]
counts: {1: 2, 2: 1, 3: 2, 4: 1, 5: 2, 6: 1, 9: 1}
even sum: 12
even squares: [16, 4, 36]
point norm: 5.0
safe div: inf
file says: hello
running: [1, 3, 6, 10]