Every lesson in the Python Fundamentals slide course, in full text: 32 decks, 3171 slides.
Session 1 - Getting Started: Code, Output & SyntaxSession 1 of the universal Python Fundamentals series, covered in depth. It explains what a program is and how Python runs it from top to bottom, then covers print() in full: printing several values, the sep and end options, and blank lines. It goes on to strings with single and double quotes, quotes inside quotes, and the escape codes \n and \t, then joining with + and repeating with *, and comments. It ends with the two errors every beginner hits: missing quotes, which raises a NameError, and missing parentheses, which raises a SyntaxError. Every snippet and error message was copied verbatim from CPython 3.12.
Session 2 - Variables & TypesSession 2 of the Python Fundamentals series, covered in depth. It starts with variables and assignment, where Python evaluates the right-hand side and then binds the name, and covers the naming rules and case sensitivity, reassignment, augmented assignment with += and -=, and swapping. It then works through the arithmetic operators, including //, %, and **, operator precedence, and the fact that / always yields a float. From there it covers the four core types - int, float, str, and bool - the type() function, comparisons that produce booleans, and the trap that putting quotes around a number turns it into text. Every snippet and error message was copied verbatim from CPython 3.12.
Session 3 - Input & OutputSession 3 of the Python Fundamentals series, covered in depth. It makes the program listen with input() and talk back with print(). The central rule is that input() ALWAYS returns a string, so doing math on it requires int() or float() first. The session covers the prompt, the string trap, conversion with int() and float() and the ValueError it can raise, and building output with str() and f-strings, including {value:.2f} formatting, then works several read-compute-print programs. The snippets were verified under CPython 3.12, with input shown as the value the user types.
Session 4 - Conditionals (if / elif / else)Session 4 of the Python Fundamentals series, covered in depth. It makes the program choose using if, elif, and else, starting with the colon and the indentation that mark a block. It covers the comparison operators, else and elif chains checked in order so that the first true branch wins, the difference between == and =, comparing strings and converted input, nested ifs, and boundary conditions. It ends with the classic traps: separate ifs that all fire, using = where == was meant, and indentation errors. Every snippet and error message was copied verbatim from CPython 3.12.
Session 5 - Comparisons & Logic (and / or / not)Session 5 of the Python Fundamentals series, covered in depth. It builds precise conditions from the comparison operators and combines them with and, or, and not. It covers truth tables, the precedence order that runs from comparisons to not to and to or, range checks, and chained comparisons such as 0 < x < 10, then finishes with the famous x == 1 or 2 trap. Every snippet was copied verbatim from CPython 3.12.
Session 6 - while LoopsSession 6 of the Python Fundamentals series, covered in depth. It repeats a block with while, covering the condition that is checked on each pass and the loop variable that must change. It then works through counters and countdowns, the infinite-loop trap, accumulators for running totals and counts, sentinel-controlled loops that stop on a chosen value, flags, and break and continue, and ends with a full guess-the-number game. Every snippet was copied verbatim from CPython 3.12, with interactive input shown as the sequence the user types.
Session 7 - for Loops & ListsSession 7 of the Python Fundamentals series, covered in depth. It introduces lists, which hold many values in order, covering how to create them, zero-based indexing, len(), negative indexing, and testing membership with in. It then covers the for loop, which makes one pass per item, range() in all three of its forms, looping by index, building a list with append(), and computing totals, averages, maxima, minima, and counts over a list. The traps are index out of range, the zero-based off-by-one, and range() stopping before its end value. Every snippet was copied verbatim from CPython 3.12.
Session 8 - DictionariesSession 8 of the Python Fundamentals series, covered in depth. A dictionary maps a key to a value, and the session covers creating one, looking up with d[key] and with the safer d.get(key, default), adding and updating entries, checking for a key with in, len(), and looping over the keys and over .items(). It then replaces a long if/elif chain with a single lookup, tallies counts, and uses numeric keys. The traps are a KeyError on a missing key, indexing a dictionary as though it were a list, and duplicate keys overwriting one another. Every snippet and error message was copied verbatim from CPython 3.12.
Session 9 - FunctionsSession 9 of the Python Fundamentals series, covered in depth. It packages code into a named, reusable tool, covering def, parameters as inputs, return as output, and calling with parentheses. It draws the difference between return and print, shows that a function with no return gives None, and covers default arguments, functions that call other functions, and refactoring a repeated block into a single function. The traps are printing when you needed to return, calling without parentheses, and calling before the def. Every snippet and error message was copied verbatim from CPython 3.12.
Session 10 - Functions, Deeper (Scope & Design)Session 10 of the Python Fundamentals series, covered in depth. It designs programs out of small functions, covering local variables and scope, parameters as local names, reading outer variables, and keeping one job per function. It then covers composition, returning several values as a tuple and unpacking them, and builds a menu program in which each option is its own function. The traps are using a local variable outside its function, which raises a NameError, and expecting a reassigned parameter to change the caller's variable. Every snippet and error message was copied verbatim from CPython 3.12.
Session 11 - Strings ToolkitSession 11 of the Python Fundamentals series, covered in depth. It cleans and shapes text so that messy user input behaves, covering .lower() and .upper(), .strip(), the in keyword for substrings, .startswith() and .endswith(), length, indexing and slicing, .split() and .replace(), and f-strings with formatting. It builds the robust clean-then-compare pattern and a word-count text analyzer, and covers the key traps: strings are immutable, string methods return a new string, .strip() trims only the ends, and comparisons are case-sensitive. Every snippet and error message was copied verbatim from CPython 3.12.
Session 12 - Errors & DebuggingSession 12 of the Python Fundamentals series, covered in depth. Its aim is to stop you fearing the red text. It shows how to read a traceback from the bottom up and how to recognize the common errors - NameError, TypeError, ValueError, IndexError, KeyError, ZeroDivisionError, SyntaxError, and IndentationError - along with their exact messages. It then guards risky code with try and except, catches specific error types, captures the message with "as e", and validates input in a loop, before covering how to debug by printing values, reproducing the problem, and narrowing it down. The traps are a bare except that hides bugs, and catching the wrong error type. Every snippet, message, and traceback was copied verbatim from CPython 3.12.
Session 13 - Capstone: Adventure Game (Part 1)Session 13 of the Python Fundamentals series, and the first part of the capstone. You plan and start a multi-room text adventure using every Phase 1 skill: sketch the map of rooms and choices, then model each room as a function that prints the scene, reads a cleaned choice, and returns the name of the next room. A while-loop state machine drives the whole thing, and you connect rooms, loop back from dead ends, and handle invalid input by re-prompting. The traps are a room with no handler, forgetting to return the next room, and a loop that never ends. Every snippet was verified under CPython 3.12, with interactive input shown as the sequence the player types.
Session 14 - Capstone: Adventure Game (Part 2)Session 14 of the Python Fundamentals series, and the second part of the capstone. You finish the adventure game by giving it state that travels through the play-through: a dictionary holding items and a score, rooms that read and update it, a locked door that checks for a key, and real winning and losing endings chosen from the final state. You then polish it with an ask helper and invalid-choice handling. The traps are forgetting to pass the state, so that changes are lost, and reassigning the state dictionary instead of updating it. Every snippet was verified under CPython 3.12, with interactive input shown as the sequence the player types.
Session 15 - Tuples & UnpackingSession 15 of the Python Fundamentals series, covered in depth. Tuples are immutable, ordered sequences, and the session covers creating them with (a, b), the trailing-comma rule for a single element, packing and unpacking, multiple assignment, swapping in one line, unpacking tuples in for loops, returning several values from a function, and star unpacking with *rest. It explains why immutability matters, since it gives safe fixed records and lets a tuple serve as a dictionary key, and when to reach for a tuple rather than a list. The traps are that (x) is not a tuple, that reassigning t[0] raises a TypeError, and that unpacking the wrong number of values raises a ValueError. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 16 - Sets & Set OperationsSession 16 of the Python Fundamentals series, covered in depth. Sets are unordered collections of unique items, and the session covers building them with {1, 2, 3} and with set(), why the empty set is set() and never {}, adding with .add, removing safely with .discard rather than .remove, fast membership testing with in, deduplicating a list with set(), and the four combining operators: union |, intersection &, difference -, and symmetric difference ^. The traps are that {} is an empty dictionary and not a set, that sets silently drop duplicates and order, that sets cannot be indexed, so set[0] raises a TypeError, that only hashable items may be stored, and that .remove on a missing item raises a KeyError while .discard is safe. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 17 - ComprehensionsSession 17 of the Python Fundamentals series, covered in depth. It builds a whole list on one line with a comprehension, covering the [expr for x in it] form, adding a filter with if, and rewriting an accumulate-in-a-loop pattern as a comprehension. It then covers dictionary comprehensions, set comprehensions that drop duplicates, and nested iteration with two for clauses. The traps are that the comprehension variable does NOT leak the way a for-loop variable does, that running a comprehension only for its side effects wastes a list of None, and that an over-nested one-liner is less clear than the loop it replaced. Each idea is shown side by side with the equivalent explicit loop in a trace table. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 18 - Mutability & AliasingSession 18 of the Python Fundamentals series, covered in depth, and the session about hidden bugs. A name is a label bound to an object, so `b = a` gives you two names for ONE list, and mutating through either one shows through the other. You prove that two names refer to the same object with `id()` and `is`, sort the mutable types (list, dict, set) from the immutable ones (int, str, tuple), and copy safely with `list.copy()`, `[:]`, and `dict.copy()` - then see why a shallow copy still shares nested objects, which `copy.deepcopy` fixes. It ends on the two classic traps: passing a list into a function mutates the caller's list, and a mutable default argument such as `def f(x, acc=[])` quietly accumulates across calls. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 19 - Files & Text I/OSession 19 of the Python Fundamentals series, covered in depth. It reads and writes real text files, covering open(path, mode), the with statement, whose context manager always closes the file, and the reading options: .read(), .readline(), iterating with for line in f, and .readlines(). It then covers writing with 'w', which truncates, against appending with 'a', stripping the trailing newline, and encoding='utf-8'. The traps are that 'w' silently erases the file, that a file used after it is closed will fail, that reading the same file object twice returns an empty string the second time, forgetting to strip the newline, writing a non-string, and the FileNotFoundError you get for a missing path in 'r'. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 20 - CSV & JSONSession 20 of the Python Fundamentals series, covered in depth. It saves and loads structured data with two standard-library modules. From json it covers dumps and loads for strings, dump and load for files, and the Python-to-JSON type map in which True becomes true and None becomes null. From csv it covers reader and writer, DictReader and DictWriter, and the newline='' rule that applies when you open the file. It also covers when to reach for CSV, which suits flat tabular rows, and when for JSON, which suits nested data. The traps are that json.loads rejects single quotes with a JSONDecodeError, that every value a CSV reader hands back is a string that needs int() before any math, and that forgetting newline='' leaves blank rows between your data on Windows. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 21 - Modules, Packages & pipSession 21 of the Python Fundamentals series, covered in depth. It reuses code beyond a single file, covering imports from the standard library in all their forms - import math, from math import sqrt, import x as np, and from x import * - then writing and importing your own module, the if __name__ == '__main__' guard, and packages as folders of modules. It goes on to installing third-party code with pip and requirements.txt, isolating projects with virtual environments, and the import search path. The traps are ModuleNotFoundError, shadowing a standard-library name by calling your file random.py, and running work at import time. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 22 - Standard Library TourSession 22 of the Python Fundamentals series: the "batteries included" tour. It is a guided, runnable walk through the modules you reach for daily - math, with sqrt, floor, ceil, and pi; random, with randint, choice, shuffle, and seed for reproducibility; datetime, with date, timedelta, and strftime; pathlib.Path, with the / operator, name, suffix, and stem, and exists; and collections, with Counter and defaultdict - plus a look at os and sys. The traps are calling a function before you import its module, reinventing something the library already ships, and using random without a seed, so that results can never be reproduced. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 23 - Classes & ObjectsSession 23 of the Python Fundamentals series, covered in depth. It moves from a dictionary that only holds data to a class that bundles data and behavior together, covering the class keyword, __init__, self, instance attributes, creating instances, and the fact that each instance carries its own state. It also covers the two roles the dot plays - obj.attr to reach a value, and obj.method() to run a method - and what self really is: the instance, handed in automatically. The traps are dropping self from a method signature, which raises a TypeError about positional arguments, reading an attribute that was never set, which raises an AttributeError, and naming a method without parentheses, which gives you a bound method object rather than a call. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 24 - Methods & EncapsulationSession 24 of the Python Fundamentals series, covered in depth. It distinguishes methods that read state from methods that change it, and shows one method calling another through self. It then covers encapsulation - keeping internals private by convention with a leading underscore and exposing behavior through methods - and protecting an invariant, such as a balance that must never go negative, by raising a ValueError. It ends with the difference between class attributes, which every instance shares, and instance attributes, of which each object has its own. The traps are forgetting self, bypassing a method and breaking an invariant, and the classic shared-mutable-class-attribute surprise, where one object's append shows up on all of them. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 25 - Dunder MethodsSession 25 of the Python Fundamentals series, covered in depth. It covers the special double-underscore methods that hook Python's own syntax onto your classes: __init__, which you already know; __str__ against __repr__, which serve print and the shell against containers; __eq__ for value equality; __len__ for len(); __lt__ for sorting; and __add__ for +. The traps are defining __str__ but expecting a list of your objects to use it, when containers print each item with __repr__, and comparing objects with == when there is no __eq__, since Python falls back to identity and two objects with equal values come out False. Every snippet, output line, and error message was executed and copied verbatim from CPython 3.12.
Session 26 - Inheritance & CompositionSession 26 of the Python Fundamentals series, covered in depth. It covers two ways to reuse classes: inheritance, where a Dog IS-A Animal, through subclassing, overriding methods, and super() to reuse the parent; and composition, where a Car HAS-A Engine, building objects out of other objects. It also covers isinstance and the is-a test, why you should prefer composition to inheritance, and how method resolution walks the class chain. The traps are forgetting super().__init__, so that the parent's attributes are never set and you hit an AttributeError, deep inheritance chains, and overriding a method without calling super(), which silently loses the parent's behavior. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 27 - classmethod, staticmethod & propertySession 27 of the Python Fundamentals series, covered in depth. It covers three decorators that reshape how a class exposes behavior: @staticmethod, for a namespaced helper that takes no self; @classmethod, for cls-based alternate constructors such as from_string; and @property, which exposes a computed value that reads like a plain attribute, together with a matching setter that validates every assignment. The traps are assigning to a property that has no setter, which raises AttributeError: property '...' has no setter; forgetting @staticmethod and getting a positional-argument TypeError; and putting validation in a raw attribute, where nothing guards it. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 28 - DataclassesSession 28 of the Python Fundamentals series, covered in depth. The @dataclass decorator writes the boilerplate that a plain class needs by hand: __init__, a readable __repr__, and a value-based __eq__. The session covers type-annotated fields, default values, default_factory for mutable defaults such as lists, frozen=True for read-only records, and field(), along with when a dataclass is the right tool - plain data records - and when it is not. The traps are that a bare mutable default raises ValueError: mutable default ... is not allowed, that a field with a default placed before a required one raises a TypeError, and that assigning to a frozen instance raises a FrozenInstanceError. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 29 - Lambdas & Functional ToolsSession 29 of the Python Fundamentals series, covered in depth. Functions are values you can store and pass around, and lambda writes a tiny anonymous function inline. The session covers sorted(data, key=...), which sorts by anything you compute, and map and filter, which return lazy iterators that you wrap in list(). The traps are reaching for a lambda when the logic really wants a def, forgetting that map and filter are one-shot lazy iterators, so that printing one shows <map object at ...>, and the old cmp= habit that key= replaced. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 30 - Iterators & GeneratorsSession 30 of the Python Fundamentals series, covered in depth. It explains what actually happens when you write a for loop: iter() builds an iterator, next() pulls one value at a time, and a StopIteration signal ends the loop. It then covers generators - functions with yield that produce values lazily, pausing and resuming - along with the compact (x*x for x in it) generator expression, the memory win on large or infinite sequences, and the big trap that a generator is used up after a single pass. The traps covered are that a second loop over a spent generator yields nothing, that calling next past the end raises StopIteration, and that return and yield are easily confused. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 31 - DecoratorsSession 31 of the Python Fundamentals series, covered in depth. A decorator is a function that wraps another function to add behavior around it, and the session builds up to that from the ground: functions are ordinary objects you can pass around, a function can return another function to form a closure, and the @decorator line is just sugar for f = deco(f). You write a logging and timing wrapper that forwards *args and **kwargs, use functools.wraps to keep the original __name__ and docstring, and stack two decorators. The traps are forgetting to return the wrapper, which makes the decorated function None, losing __name__ by omitting functools.wraps, and a wrapper that does not forward its arguments. Every snippet and error message was executed and copied verbatim from CPython 3.12.
Session 32 - Context Managers & Type HintsTwo professional finishers. The first part covers context managers: the with statement, __enter__ and __exit__, cleanup that is guaranteed even when an error is raised, writing a class-based context manager, and the shorter form built from contextlib.contextmanager and yield. The second part covers type hints: annotating parameters and returns, as in def f(x: int) -> str, variable annotations, list[int] and dict[str, int], Optional and None with the X | None shorthand, and the key surprise that hints are NOT enforced at runtime, so a mis-typed call still runs. The traps are assuming that type hints validate types at runtime, and cleanup being skipped when you manage a resource by hand and an error strikes part-way through. Every snippet and every traceback was executed and copied verbatim from CPython 3.12.
Want this taught 1-on-1? Alexander tutors Python Fundamentals — $55/session, free consultation.