Every lesson in the Python slide course, in full text: 71 decks, 4771 slides.
Capstone: Maze Rover + Reading TracebacksLesson 8 of 8 in the Pre-COSMOS series, 39 slides, and the capstone. It snaps the whole series together into a dry run of camp's signature task: a Rover class from Lesson 2, driven by a control loop from Lesson 3 whose state is steered by an FSM next_state dictionary, also from Lesson 3, fed by a NumPy camera grid from Lesson 4 and a red color mask from Lesson 5, and paced by time.sleep, all to follow colored markers through a maze. The second half is explicit traceback practice: the LAST line names the error type and message, the line just above it points at the offending code, and the five errors you met across the series - a TypeError saying the object is not callable, a KeyError, an IndexError, an AttributeError, and a NameError - each map to one specific mistake. Three debugging traps show real tracebacks copied from CPython - a KeyError from a typo in a state name, a TypeError from an int that is not callable, and an out-of-bounds IndexError - and you find the culprit line and the fix. There are five checks and a scaffolded your-turn Maze Rover Simulator build that ends on "you're ready for camp." Every snippet was run on CPython 3.12 with numpy 2.3, and the printed output and traceback text were copied verbatim.
1a What a Program Is, and How to Run OneThis lesson defines a program as a sequence of instructions, names the five kinds of instruction every language provides, and gets a first program running at the Python prompt.
1b Arithmetic, Values, Types, and Your First ErrorsThis lesson turns the prompt into a calculator, meets the int, float and str types through the type function, and explains the two surprises Python plants on purpose: why division gives 42.0 and why the caret does not mean exponentiation.
2a Assignment, Names, Expressions and StatementsThis lesson introduces the assignment statement and the state diagram, gives the rules for legal variable names, separates expressions from statements, and explains why the same three lines print something at the prompt and nothing in a script.
2b Order of Operations, String Operations, and CommentsThis lesson gives the precedence rules that decide what an expression means, shows what the plus and star operators do to strings, explains what makes a comment worth writing, and names the three kinds of error that the rest of the course depends on telling apart.
3a Calling Functions, Importing Modules, and CompositionThis lesson gives the vocabulary of a function call, meets the int, float and str conversion functions and the way int chops rather than rounds, introduces modules and dot notation through the math module, and shows how expressions compose.
3b Defining Your Own FunctionsThis lesson introduces the def statement with its header and indented body, separates defining a function from calling one, traces the detour a call makes through the flow of execution, and distinguishes a parameter from an argument.
3c Local Variables, Stack Diagrams, and Why FunctionsThis lesson shows that variables and parameters inside a function are local and vanish when it returns, introduces the stack diagram and the traceback that mirrors it, separates fruitful functions from void ones, and gives the four reasons to divide a program into functions.
4a The Turtle Module, Repetition, and EncapsulationThis lesson introduces the turtle module and the idea of a method, gives the for statement in its simplest form as a way of repeating instructions, and performs the first process move of the case study: wrapping working code in a function.
4b Generalization, Interface Design, Refactoring, and DocstringsThis lesson adds parameters to make functions general, argues about what belongs in an interface and what does not, factors shared code out into polyline, states the development plan as five steps, and documents a function's contract with a docstring and its pre- and postconditions.
5a Floor Division, Modulus, and Boolean ExpressionsThis lesson introduces floor division and the modulus operator with the uses that make them worth knowing, then the relational and logical operators and the bool type, assembling everything an if statement needs for a condition.
5b Conditional Execution: if, else, elif, and NestingThis lesson introduces the if statement in all four of its forms, explains why only the first true branch of a chain runs, and shows the two ways to flatten a nested conditional: logical operators and Python's chained comparison.
5c Recursion, Infinite Recursion, and Keyboard InputThis lesson introduces recursion through the countdown function, uses a stack diagram to show why each recursive call has its own variables, explains infinite recursion and the base case that prevents it, and adds keyboard input with the conversion its result usually needs.
6a Return Values and Incremental DevelopmentThis lesson introduces the return statement and the rules that come with it, then teaches incremental development: building a function a line at a time, testing against a known answer, and removing the scaffolding at the end.
6b Boolean Functions, More Recursion, and the Leap of FaithThis lesson writes functions that return True or False and names them like questions, translates a recursive mathematical definition into a recursive function that returns a value, and introduces the leap of faith as a way of reading recursion without tracing it.
6c Checking Types and Debugging Fruitful FunctionsThis lesson meets fibonacci, whose double recursion cannot be traced by hand, then diagnoses an infinite recursion caused by a non-integer argument and fixes it with the guardian pattern, and closes with the three possibilities to consider when a function is not working.
7a Reassignment, Updating Variables, and the while StatementThis lesson separates assignment from equality once and for all, introduces updating a variable and the initialization it requires, gives the formal flow of execution for a while statement, and asks what it takes to prove that a loop terminates.
7b break, Square Roots, and What an Algorithm IsThis lesson introduces the break statement and the while True idiom, builds Newton's method as a loop that improves an estimate until it stops changing, explains why floats must not be tested for equality, and defines what an algorithm is.
8a A String Is a Sequence: Indexing, len, and TraversalThis lesson reclassifies the string as a sequence of characters, introduces the bracket operator and zero-based indexing, meets the IndexError at the end of a string, and gives the two ways to traverse a string one character at a time.
8b Slices, Immutability, Searching, and CountingThis lesson introduces the slice operator and the between-the-characters picture that explains it, discovers that strings cannot be changed at all, and names the two computational patterns most string processing is built from: the search and the counter.
8c String Methods, the in Operator, and String ComparisonThis lesson introduces string methods and the dot notation that invokes them, meets optional arguments through the built-in find, adds the in operator, explains why uppercase letters sort before lowercase ones, and works a live diagnosis of an index traversal with two bugs in it.
9a Reading Word Lists and Writing Search FunctionsThis lesson opens a real word list with 113,809 entries, reads it line by line, and then writes four search functions that are the same pattern with one thing changed each time — ending with the development plan of reducing a problem to one already solved.
9b Looping with Indices, and Debugging by TestingThis lesson meets the puzzles a plain for loop cannot solve — comparing adjacent letters, and comparing a word with itself from both ends — gives three different solutions to the same problem, and closes with what testing can and cannot establish.
10a A List Is a Sequence, and Lists Are MutableThis lesson introduces the list as a sequence whose elements can be of any type, shows that everything learned about string indexing and slicing carries over unchanged, and then introduces the one difference that changes everything: a list can be modified in place.
10b List Methods, Map, Filter, Reduce, and Deleting ElementsThis lesson introduces the list methods and the fact that most of them return None, names the three patterns that most list processing is built from, gives four ways to delete an element, and converts between lists and strings with list, split and join.
10c Objects, Values, Aliasing, and List ArgumentsThis lesson separates objects from values, introduces the is operator, explains aliasing and why it is dangerous only for mutable objects, shows that a function can modify its caller's list, and gives the rules for avoiding the resulting bugs.
11a A Dictionary Is a Mapping, and a Collection of CountersThis lesson introduces the dictionary as a mapping from keys to values, covers creation, lookup, KeyError, len and the in operator, explains why in is fast for dictionaries and slow for lists, and builds the histogram function two ways.
11b Looping, Reverse Lookup, and Dictionaries of ListsThis lesson loops over dictionaries, writes a reverse lookup that has to search, introduces the raise statement and LookupError, inverts a dictionary using lists as values, and explains why keys must be hashable.
11c Memos, Global Variables, and Debugging Large DataThis lesson explains why the recursive Fibonacci is so slow, fixes it with a memo stored in a dictionary, introduces global variables and the global statement, distinguishes modifying a global from reassigning one, and gives three techniques for debugging large datasets.
12a Tuples Are Immutable, and Tuple AssignmentThis lesson introduces the tuple as an immutable sequence, covers its syntax and the singleton comma, shows which list operations carry over and which do not, explains how sequences are compared, and uses tuple assignment to swap variables and return several values at once.
12b Variable-Length Argument Tuples, Lists and TuplesThis lesson introduces the gather and scatter operators for functions that take any number of arguments, then covers zip, iterators, tuple assignment in a for loop, and enumerate — the idioms for traversing two sequences at once or a sequence with its indices.
12c Dictionaries and Tuples, and Sequences of SequencesThis lesson converts between dictionaries and lists of tuples, uses tuples as dictionary keys, gives the criteria for choosing between strings, lists and tuples, and introduces shape errors in compound data structures.
13a Word Frequency Analysis and Random NumbersThis lesson opens the case study by setting out the word-frequency problem and the string tools for cleaning text, then introduces determinism, pseudorandom numbers, and the random module's three core functions.
13b Histograms, Most Common Words, and Optional ParametersThis lesson gives the book's solution to the word-frequency exercises: reading a file into a histogram, counting it two ways, finding the commonest words by sorting tuples, writing functions with optional parameters, and subtracting one dictionary from another.
13c Random Words, Markov Analysis, and Choosing a Data StructureThis lesson generates random words weighted by frequency, builds a Markov model mapping prefixes to suffixes, works through the data structure choices that model forces, and closes with the five strategies for debugging a hard problem.
14b Filenames, Paths, and Catching ExceptionsThis lesson covers the current directory, relative and absolute paths, the os.path functions for inspecting files, a recursive directory walk, and the try statement for handling the many things that go wrong when a program touches the file system.
14c Databases, Pickling, Pipes, and Writing ModulesThis lesson covers dbm databases that behave like dictionaries on disk, the pickle module for storing arbitrary objects, pipes for running other programs, writing importable modules with the __name__ idiom, and repr for debugging invisible whitespace.
15a Programmer-Defined Types, Attributes, and RectanglesThis lesson defines a new type with the class statement, creates instances, assigns and reads attributes with dot notation, and works through the design decision of which attributes a class should have.
15b Instances as Return Values, Mutability, and CopyingThis lesson returns objects from functions, modifies objects through their attributes, copies instances with the copy module, explains why a shallow copy of a nested object is error-prone, and covers the tools for debugging attribute problems.
16a The Time Class and Pure FunctionsThis lesson defines a Time class, introduces pure functions and the prototype-and-patch development plan, and works through the carrying problem that a naive time addition runs into.
16b Modifiers, and Prototyping versus PlanningThis lesson writes a modifier and weighs it against a pure function, then replaces the whole approach with the insight that a Time is a base-60 number, and closes with invariants and the assert statement.
17a Methods: Object-Oriented Features and Printing ObjectsThis lesson turns functions into methods, covers the two ways to invoke one, explains the self convention and the subject metaphor, and decodes the argument-count error that method syntax produces.
17b The init Method and the __str__ MethodThis lesson introduces the two special methods Python calls for you: __init__, which assigns an object's attributes at the moment it is created, and __str__, which supplies a printable representation.
17c Operator Overloading, Type-Based Dispatch, and PolymorphismThis lesson makes operators work on programmer-defined types with special methods, handles operands of different types with dispatch and the right-side add, and closes with polymorphism — functions that work on types they were never written for.
18b Decks: Building, Printing, Adding, Removing, ShufflingThis lesson builds a Deck class that holds a list of cards, generates all fifty-two with a nested loop, prints them by joining a list of strings, and wraps list operations in methods appropriate for decks.
18c Inheritance, Class Diagrams, and Data EncapsulationThis lesson defines a class as a modified version of another, overrides an inherited method, reads class diagrams showing IS-A and HAS-A relationships, and discovers a class interface by encapsulating global state.
19a Conditional Expressions, Comprehensions, and GeneratorsThis lesson covers the syntax the book deliberately postponed: conditional expressions, list comprehensions for map and filter, generator expressions that compute on demand, and the any and all functions.
19b Sets, Counters, and defaultdictThis lesson introduces three containers from the standard library: sets for collections of unique keys, Counters for counting occurrences, and defaultdict for generating a value when a key is missing.
19c Named Tuples and Gathering Keyword ArgumentsThis lesson replaces a simple class with a named tuple, weighs what that gives up, and completes the gather-and-scatter pair with the double star for keyword arguments.
Aa Syntax Errors and Runtime ErrorsThis lesson distinguishes the three kinds of error, covers the specific causes of syntax errors and why their locations mislead, and works through runtime errors by symptom — nothing happening, hanging, and exceptions.
Ab Semantic Errors: Making the Program Say What You MeanThis lesson covers the error kind that produces no message: forming a hypothesis about what a program is doing, breaking complex expressions into temporary variables, correcting a faulty mental model, and knowing when and how to ask for help.
Ba Order of Growth and the Cost of Python OperationsThis lesson introduces order of growth as a way of comparing algorithms, works through why the leading term dominates, and catalogues the run time of the Python operations the course has been using.
Bb Search Algorithms and HashtablesThis lesson analyses linear and bisection search, then builds a hashtable from a list of tuples in three steps to explain why dictionary operations are constant time.
Color & Seeing: Detecting a Color is a MaskLesson 5 of 8 in the Pre-COSMOS series, 41 slides, on how a computer "sees" a color. A pixel is three numbers, [R, G, B], each from 0 to 255, and a color image is a grid of pixels with shape (H, W, 3). Asking whether a pixel is red means checking ranges - R high, G low, B low - to get a True or False. You then do it for every pixel at once with a MASK: red = (pixels[:,:,0] > 150) & (pixels[:,:,1] < 80) & (pixels[:,:,2] < 80), after which red.sum() counts the red cells and np.argwhere(red) finds where they are. It is built in NumPy so that it RUNS; OpenCV (cv2) and HSV are NAMED as the camp's real post-it-maze tools, previewed but not taught today. The two traps are the classic NumPy color bugs: using Python's and and or instead of the array operators & and |, which raises ValueError: ambiguous truth value, and comparing a whole pixel to a single number instead of picking a channel with [:,:,0]. There are five checks and a scaffolded your-turn Maze Rover Simulator build that counts and locates red cells with no camera. Every snippet was run on CPython 3.12, and the printed output was copied verbatim.
Data Types & ConversionPre-COSMOS Day 2, for Cluster 10: Robot Inventors, covered in depth. It covers the core types int, float, and str, plus bool, and checking a value with type(). It then explains that floats are approximate, covers // and %, points out that input() always returns text, and converts with int(), float(), and str() and with f-strings. From there it separates round() from the truncation that int() performs, covers the truthiness of bool(), and builds two calculators. The three high-confidence misconceptions each appear as a trap slide. Every snippet is runnable, and the outputs and error messages were copied verbatim from CPython 3.12.
Dictionaries: Mapping Colors to ActionsPre-COSMOS Day 12, for Cluster 10: Robot Inventors - an advanced session of 50 slides. Dictionaries are the natural way to map a color to an action, or a state to what comes next, which is exactly how the camp's finite-state robot logic works, and the diagnostic rated this fragile. The session covers key-to-value lookup, dictionaries against lists, and the KeyError trap, since keys are not numeric positions - it is actions["red"], not actions[0]. It then covers safe lookups with .get(key, default) and the in operator, adding and updating keys, len, and looping with keys(), values(), and items(), before two advanced patterns: the counter or tally, and the dictionary as a finite state machine. It builds to a fully scaffolded your-turn Cheat-Code Console - a codes dictionary, input, a .get default, and a while-quit loop - with a usage-tally stretch. There are five checks, three traps, two photos, and SVG diagrams of the lookup table and the FSM. Every snippet was run in real Python, covering the KeyErrors, .get, the tally, and the FSM transitions, with the output copied verbatim into the trace tables.
for Loops as Robot Scanning LoopsPre-COSMOS Day 8, for Cluster 10: Robot Inventors, a 60-minute robotics upgrade. It teaches for loops as the known-repeat scanning loops a robot uses: processing each sensor reading, repeating exactly N times with range(), scanning every other position with range(start, stop, step), counting obstacles, and using nested loops to scan a 3x5 camera image row by row. The watch-outs around range() excluding its end value appear both as trap slides and as checks. Every snippet was executed under CPython 3.12.4.
Functions: Arguments, Scope & Small ProgramsPre-COSMOS Day 11 - Functions, part 2 of 2, an advanced session of 50 slides. It picks up where Day 10 left off and goes deep on how small functions cooperate to make a real program. It covers positional against keyword arguments and why defaults must come last, then scope: locals do not leak, parameters are local copies, and assigning to a global raises an UnboundLocalError - with the clean alternative of passing values in and returning them out. From there it covers the accumulator pattern, calling functions inside loops, decomposing a problem into helpers with a main loop, and the random module, using seed for reproducible demos. It culminates in a fully scaffolded your-turn build of Robo-Battle: two robots, a decide(hp) function, and a turn loop that runs until one robot's hp reaches 0, with a randomized-damage stretch. There are five checks, three traps, two real photos, and diagrams of scope and decomposition. Every snippet, including the seeded random calls and the full battle, was run in real Python with the output copied verbatim into the trace tables.
Functions as Robot Decision HelpersPre-COSMOS Day 10 - Functions, part 1 of 2, an advanced session of 40 slides. It teaches def, parameters, and return in depth, as the way to build the reusable decision helpers that a robot's control loop calls. It covers multiple parameters and the order of arguments, return against print - the hardest topic in the diagnostic - and the None trap, then using a returned value, the fact that code after return is dead, functions calling other functions, boolean helpers, default parameters, returning several values, and local scope. It includes real photos of the robot car and its sensors, hand-built diagrams of the function machine, the data flow, and composition, three checks, three traps, and a fully scaffolded your-turn build of is_obstacle, choose_action, and update_battery. Every snippet was run in real Python with the output copied into the trace tables.
Hardware as Objects: a gpiozero PreviewLesson 7 of 8 in the Pre-COSMOS series, 37 slides, showing that real robot code has the SHAPE you already know. Motors and sensors are OBJECTS - Robot, Motor, DistanceSensor - that you make and then call methods on, exactly like the Rover from Lessons 1 to 3. Using a small fake gpiozero-style API, supplied so that everything runs without a Raspberry Pi, you see that motor.forward() and motor.stop() are methods you CALL, while sensor.distance is an ATTRIBUTE you READ - the world coming in. You then build a driver loop that reads the distance and stops when it drops below a threshold, and otherwise rolls forward. The two traps are writing sensor.distance() with parentheses, which raises TypeError: 'float' object is not callable, and treating real gpiozero as something to memorize rather than recognizing the object shape - and note that distance is measured in meters. There are five checks and a scaffolded your-turn Maze Rover driver. The goal is familiarity rather than mastery, since the camp teaches this best on the real robot. Every snippet was run on CPython 3.12, with the outputs copied verbatim.
Decisions: if / elif / else & Finite-State ThinkingPre-COSMOS Day 6, for Cluster 10: Robot Inventors, running two hours or more in depth. It covers comparisons and booleans, then if, elif, and else, where the first true branch wins and so the order matters, and and, or, and not, including the classic "or green" bug and the == against = trap. It goes on to more advanced techniques - the in operator, chained comparisons, truthiness, operator precedence, and De Morgan's law - then builds the Maze Robot Brain v1. It ends with finite state machines done two ways: as nested if/elif, and table-driven, using dictionary dispatch together with a transition table mapping (state, input) to (action, next_state). Every snippet is runnable, and the outputs and error messages came verbatim from CPython 3.12.
The Library Mindset: import, Docs & Small ModulesLesson 6 of 8 in the Pre-COSMOS series, 38 slides, on the meta-skill: nobody memorizes a library, you read an example or a doc and adapt it. A module is a toolbox you import, and you reach its tools with the SAME dot you have used all camp, as module.function. You learn to read a function's signature to find out what it takes, then copy the example and adapt it. You practice on three real modules: random, with randint(a, b), which includes BOTH ends, choice(seq), and seed(n) for reproducible runs; math, with sqrt, floor, and ceil; and time, with sleep and time. The two traps are the classic beginner errors: calling sqrt(144) bare after import math, which raises a NameError, and assuming that randint(1, 6) excludes 6 the way range does, when in fact it includes both ends. There are five checks and a scaffolded your-turn Maze Rover Loot Run that you build from documentation you have never been taught. Every snippet was run on CPython 3.12 with random.seed(7), and the output was copied verbatim.
List Methods: append, sort, lenPre-COSMOS Day 4, for Cluster 10: Robot Inventors, covered in depth. It grows a list with append(), orders it with sort() and sort(reverse=True), and counts with len(), building to the big idea that in-place methods return None - so nums = nums.sort() wipes your data. It then builds the High-Score Board project, with a top-three stretch. Every snippet is runnable, and the outputs and error messages came verbatim from CPython 3.12.
Lists: Operations & SlicingAn in-depth session of 41 slides. It covers indexing from 0, negative indexes, and slicing with the end excluded, along with the slice shortcuts, joining with + and repeating with *, changing items, and append. The three misses the diagnostic found each appear as a trap slide, and there are five checks, followed by a scaffolded build-it-yourself Dream Team Roster project. It was built for the Pre-COSMOS Day 3 hour.
NumPy as Grids: an Image is a Table of NumbersLesson 4 of 8 in the Pre-COSMOS series, 37 slides, on the one NumPy idea that powers camp vision: a 2D array is a grid, and a grayscale image is a grid of brightness numbers running from 0 for dark to 255 for bright. Using numpy as np, you build a grid with np.zeros((rows, cols), dtype=int), read its shape as (rows, cols), index it ROW-FIRST as img[row, col], and "draw" by setting a cell bright, as in img[1,2] = 9. You then find the brightest cell with img.max() and np.unravel_index(img.argmax(), img.shape). The two traps are the classic grid mistakes: reading [x, y] or img[col, row] instead of img[row, col], and the off-by-one IndexError from img[0,5] in a five-column grid, where the columns are numbered 0 to 4. There are five checks and a scaffolded your-turn Maze Rover Simulator build in which students draw a shape into a grid and report the brightest cell. NumPy is a library you install once with pip install numpy, not a piece of hardware. Every snippet was run on CPython 3.12 with numpy 2.3, and the outputs were copied verbatim.
Objects, Part 1: What the Dot MeansLesson 1 of 8 in the Pre-COSMOS series, 41 slides, teaching objects through USE rather than through writing classes. The dot you have been typing all along - robot.look(), "hi".upper(), nums.append() - reaches inside an object, and an object bundles data, its attributes, which you read without parentheses, together with actions, its methods, which you call with parentheses. You work entirely with a Rover that is provided for you: reading .energy, .name, and .facing, calling .move() and .charge(amount), watching methods change the object's own state, and seeing that two rovers, Rex and Nova, keep their data separate. The three traps are the classic beginner errors: rover.move against rover.move(), rover.energy(), which gives 'int' object is not callable, and thinking that energy is shared between rovers. There are five checks and a scaffolded your-turn Drive the Rover build. Every snippet was run on CPython 3.12, with the outputs copied verbatim.
Objects, Part 2: Write Your Own ClassLesson 2 of 8 in the Pre-COSMOS series, 41 slides, and the leap from USING a provided Rover to WRITING the class yourself - the heaviest new lift of the eight lessons. It is built concrete and tiny across five ideas. First, class Rover defines a new TYPE, a blueprint, while an instance is one rover built from it. Second, __init__(self, name) is the setup method that runs automatically when you make one, storing the starting attributes with self.name = ... and self.energy = 100. Third, self means this particular object. Fourth, methods are written as def move(self): and def charge(self, amount):, and they change self.energy. Fifth, rex = Rover("Rex") and nova = Rover("Nova") each build fresh, independent state. The three traps are the classic class-writing errors: forgetting self in a method header, which gives TypeError: takes 0 positional arguments but 1 was given; dropping the self. prefix in __init__, which surfaces later as AttributeError: object has no attribute 'energy'; and forgetting the argument, which gives TypeError: __init__() missing 1 required positional argument: 'name'. There are five checks and a scaffolded your-turn build in which students write the Rover class from scratch to reproduce an energy of 70 and then 95. Every snippet was run on CPython 3.12, with the outputs and error text copied verbatim.
The Robot Control Loop (sense, decide, act, wait)Lesson 3 of 8 in the Pre-COSMOS series, 40 slides, on the shape of every robot program. A robot runs the same heartbeat forever - sense, decide, act, wait - and this lesson names that pattern and builds it. time.sleep(seconds) supplies the wait. The decide step is a finite-state-machine dictionary, next_state = {"sense":"decide", "decide":"act", "act":"wait", "wait":"sense"}, advanced with state = next_state[state]. You then put it together from a provided Rover, the loop, and the dictionary, using a BOUNDED loop - range(8), or while rover.energy > 0 - so that the demo terminates. The lesson points out that this quietly reuses loops, a function, a dictionary lookup, and the class from Lessons 1 and 2, all at once. The three traps are the classic FSM bugs: while True with no exit, which loops forever; forgetting state = next_state[state], which sticks you in one state; and a typo in a state name that is not in the dictionary, which raises a KeyError. There are five checks and a scaffolded your-turn Maze Rover Simulator control loop. Every snippet was run on CPython 3.12, with the outputs copied verbatim.
while Loops as Robot Control LoopsPre-COSMOS Day 7, for Cluster 10: Robot Inventors, a 60-minute maze block covered in depth. It teaches while loops as a robot control loop - sense, decide, act, update, stop - built around the core question of what makes this robot stop. Students BUILD the maze controller themselves across four "your turn" levels, each giving a skeleton and the target behavior but no answer; the teacher demo shows only the target behavior; the debug challenges hide the body; and the complete solution is revealed on a single slide at the very end. Every reference trace was run through a real Python grid-maze simulator.
Want this taught 1-on-1? Alexander tutors Python — $55/session, free consultation.