Unit 4 – Teachers Guide
Unit 4 · Functions, Clean Code & the SDLC
Your day-to-day companion for delivering Unit 4 — pacing, standards, lesson plans, misconceptions, differentiation, and a Python error appendix. Unit 4 is the unit where students stop writing code that "works" and start writing code that's clean, modular, and professional. Functions are the single biggest tool jump of the year. Get this unit right and the rest of the course writes itself.
👋 Welcome — How to Use This Guide
This Teacher's Guide is your day-to-day companion for delivering Unit 4 of the Code Quest curriculum. Unit 4 is the conceptual midpoint of the year — the unit where students transition from "write code that works" to "write code that's clean, modular, and professional." It assumes students have completed Units 1–3 and are fluent with variables, conditionals, both kinds of loops, lists, .append(), sorted(), and the algorithm-first planning habit. It's designed for new and experienced CS teachers alike — no programming background required to use it effectively.
What this guide contains
- A pacing guide showing how Unit 4 maps to roughly 8–10 class periods, with extended lessons (50 min) for L2, L3, and L4 due to the conceptual density of functions, return values, scope, and systematic debugging.
- A standards & exam crosswalk showing exactly which Florida CTE standards and Coding Fundamentals exam objectives each lesson addresses. Unit 4 is the home of standards 06.03 (iterative SDLC) and 07.07 (debug), and finally fully covers Exam Objectives 4 & 7.
- A unit vocabulary glossary with all 22 key terms students will encounter — heaviest vocabulary load of any unit so far.
- Five detailed lesson plans (one per lesson), each using the same 7-section format you saw in earlier units.
- An appendix with the most common Python errors students hit in Unit 4 — including the new ones that come with functions:
NameErrorfrom scope,TypeErrorfrom missing arguments, and the dreaded "function returns None when you expected a value."
How each lesson plan is structured
Every lesson plan in this guide uses the same 7-section format so you can find what you need quickly:
- At-a-Glance — objective, time, materials, vocabulary, and a quick-reference standards box
- Lesson Flow — a suggested 45–50 minute breakdown: warm-up, instruction, guided practice, lab, exit ticket
- Watch For — the 3–5 most common student misconceptions, with how to address each in real time
- Differentiation — what to do for early finishers and what to do for struggling students
- Discussion Prompts — questions to spark whole-class conversation
- Real-World Connections — how to answer the inevitable "why does this matter?" question
- Lesson-Specific Vocabulary — terms introduced or reinforced in that lesson
How to read this in conjunction with the student lessons
Each Code Quest lesson is a self-contained HTML page that students work through at their own pace. This guide doesn't replace those lessons — it equips you to teach alongside them. The expected workflow:
- Before class: read this lesson plan (5–10 min) and skim the student HTML lesson, paying special attention to interactive widgets (the function visualizer, the scope explorer, the bug-hunt challenge, the SDLC stage-by-stage capstone)
- During class: follow the lesson flow; the student HTML is the textbook + lab
- After class: grade Knowledge Checks and labs; the capstone uses a 100-point rubric matching the student lesson
🗺️ Unit 4 Overview
The big picture
Unit 4 introduces the most important professional habit in software development: break big problems into named, reusable pieces. Students learn to write clean code (Lesson 1), define and call functions (Lesson 2), use parameters and return values with proper scope (Lesson 3), debug systematically using a 4-step strategy (Lesson 4), and finally apply the full SDLC — Plan, Code, Test, Fix, Maintain — to rebuild Mad Libs as a fully modular program (Lesson 5). Unit 4 is the inflection point of the year: students cross from "I can write code" to "I can write code professionals would respect."
What students learn
- Apply PEP 8 conventions:
snake_case, 4-space indentation, spaces around operators, blank lines between functions - Write good comments — explaining the "why," not the "what" — and avoid noisy/redundant comments
- Define functions using
def, name them with action verbs, write a docstring, and return values cleanly - Distinguish parameters (in the definition) from arguments (in the call)
- Use positional and keyword arguments and default parameter values
- Understand the difference between
print()andreturn— and why returning is almost always preferable - Chain function calls: pass one function's return value as another function's argument
- Identify local vs global scope and explain why scope is a feature, not a bug
- Read a Python traceback top to bottom and identify the file, line, and error type
- Distinguish the three kinds of bug: syntax errors (Python rejects), runtime errors (crashes mid-run), and logic errors (no error, wrong output)
- Apply the 4-step debugging strategy — Reproduce → Read → Isolate → Test — to track down any bug
- Use print-debugging as their primary in-the-moment debugging tool
- Define and use the SDLC (Plan, Code, Test, Fix, Maintain) and explain why skipping any stage causes problems
- Decompose a problem into 3+ functions, each doing ONE clear job (the heart of the capstone)
Prerequisites
Units 1–3. Students must be fluent with: variables, data types, operators, if/elif/else, input(), f-strings, for and while loops, lists with .append(), sorted(), and the algorithm-first plan-then-code mindset. Functions formalize the abstract idea students touched in Unit 3 (algorithm = named procedure) into real Python syntax. If a student is shaky on Unit 3's plan-first habit, address it before starting Unit 4 Lesson 5 — the capstone explicitly requires SDLC Stage 1 (Plan) on paper.
What comes next
Unit 5 introduces data structures — lists with full mutability, dictionaries, sets, and tuples — and shows students how functions and data structures combine. The modular thinking from Unit 4 becomes the design discipline that makes Unit 5's more complex programs manageable. Students who emerge fluent from Unit 4 will recognize the pattern instantly: define a function, accept the data structure, return a transformed version. Without Unit 4, Unit 5 looks like spaghetti.
Materials you'll need
- Computers with web browser access (one per student, or pairs)
- Knowledge Pillars CodeSkills Lab access
- Projector or large screen — Unit 4's interactive widgets (Function Visualizer in L2, Scope Explorer in L3, Bug Hunt Challenge in L4, SDLC stage-walker in L5) are designed for whole-class projection
- Whiteboard with multiple colors — used heavily in Lesson 3 to draw scope boxes (local-inside-global)
- Optional: printed PEP 8 cheat sheet (one per desk) — students will reference it for the entire unit
- Optional: a "buggy code" handout — Lesson 4 benefits from a printed program with intentional bugs students fix on paper before opening CodeSkills Lab
⏱️ Pacing Guide
Unit 4 is designed to fit in 8–10 class periods of approximately 45–50 minutes each. Lessons 2, 3, and 4 are intentionally 50 minutes rather than 45 because of conceptual density — functions, scope, and systematic debugging each need extra explanation time. The capstone is a 2-day project. This is the longest and densest unit of the year so far. Don't compress it without good reason.
Recommended pacing — 9-day plan
| Day | Lesson | Focus | Homework |
|---|---|---|---|
| Day 1 | L1: Clean Code | What "clean" means. snake_case. Comments (good vs noisy). PEP 8 intro. Lab 4.1A. | Finish Lab 4.1B (rewrite messy code) |
| Day 2 | L2: Functions (pt 1) | The problem functions solve. def, calling. Parameters vs arguments. Lab 4.2A. | Read L2 Sections 4–5 (parameters) |
| Day 3 | L2: Functions (pt 2) | Multiple parameters. Default values. Why functions are a superpower. Lab 4.2B. KC. | Plan a function for tomorrow's warm-up |
| Day 4 | L3: Return & Scope (pt 1) | print vs return. How return works. Chaining functions. Lab 4.3A. | Read L3 Sections 4–5 (scope) |
| Day 5 | L3: Return & Scope (pt 2) | Local vs global scope. Why scope is a feature. Lab 4.3B. KC. | Read L4 Sections 1–2 (kinds of bugs) |
| Day 6 | L4: Debugging (pt 1) | Three kinds of bugs. Reading tracebacks. The 4-step strategy. Lab 4.4A (paper bug hunt). | Read L4 Sections 4–5 (print debugging) |
| Day 7 | L4: Debugging (pt 2) | Print-debugging. Isolating bugs in functions. Bug Hunt Challenge. Lab 4.4B. KC. | Plan Mad Libs 4.0 functions on paper |
| Day 8 | L5: SDLC + Capstone (pt 1) | The five SDLC stages. Stage 1 (Plan) + Stage 2 (Code) of Mad Libs 4.0. Build 3 functions. | Continue building at home |
| Day 9 | L5: SDLC + Capstone (pt 2) | Stage 3 (Test) + Stage 4 (Fix) + Stage 5 (Maintain). Polish, peer test, showcase, submit. | — |
Compressed 8-day pacing
If you must compress: combine Days 6 & 7 — cover all of Lesson 4 in one 50-min block. Skip the paper bug hunt and go straight to the Bug Hunt Challenge in CodeSkills Lab. This works for stronger groups. NOT recommended if students struggled in Lesson 3 — debugging is heavily dependent on understanding scope.
Extended 10-day pacing
If you have a shorter class period (30 min) or your students hit Unit 3's algorithm-first mindset hard: split Lesson 5's capstone into THREE days instead of two. Day 8 = Plan (paper, no code). Day 9 = Code + Test. Day 10 = Fix + Maintain + Showcase. The slow-and-steady SDLC walk is the most generous pacing and often produces the most polished student work. Recommended for first-time CS classes.
Suggested grading weights for Unit 4
| Component | Weight | Notes |
|---|---|---|
| Lesson Knowledge Checks (×4) | 15% | 3 questions each, completed in-platform |
| Lab Exercises (×8) | 30% | Mix of paper-based bug hunt and CodeSkills Lab functions |
| Mad Libs 4.0 Final Project | 45% | Capstone — see 100-pt rubric in Lesson 5 plan |
| Class participation | 10% | Discussion, peer debugging, peer testing in capstone |
Note: Mad Libs 4.0 is weighted highest of any unit project (45%) because it formally integrates EVERY skill from the year so far — clean code, functions, parameters, return values, scope, debugging, and all 5 SDLC stages. It's the most professional artifact students produce in the course.
🎓 Standards & Exam Crosswalk
This crosswalk shows exactly which Florida CTE standards and Coding Fundamentals exam objectives each lesson addresses. Use this for admin reviews, IEP documentation, or to prove alignment when adopting the curriculum. Unit 4 is the home of standards 06.03 (iterative SDLC) and 07.07 (debug), and finally fully covers Exam Objectives 4 (Write and debug) and 7 (Debugging techniques) — both have been previewed since Unit 1 but only now treated formally.
Florida CTE Standards — Course #9009200
Standards from the Florida Department of Education Coding Fundamentals curriculum framework that Unit 4 addresses:
| Standard | Description | Lessons |
|---|---|---|
| 01.01 | Use specialized computer coding software to solve problems. | All (CodeSkills Lab) |
| 01.02 | Demonstrate proficiency using specialized computer software (e.g., Python). | All |
| 02.02 | Explain the components of programming languages. | L1, L2, L3, L4, L5 |
| 05.06 | Recognize that more than one algorithm can solve a given problem. | L4 (refactoring), L5 |
| 05.07 | Create a program that implements an algorithm to achieve a given goal. | L5 (Mad Libs 4.0) |
| 06.03 | Identify the iterative steps in the Software Development Life Cycle (Plan, Design, Code, Test, Deploy, Maintain). | L5 — primary unit standard |
| 07.01 | Describe the structure of a simple program; explain why sequencing is important. | L1, L2, L5 |
| 07.04 | Describe selection programming structures (if/then, else); explain logic for if statements. | L5 (capstone applies) |
| 07.05 | Explain the types and use of variables in programming. | L3 (local vs global scope) — primary deeper-dive |
| 07.07 | Troubleshoot and debug errors in code. | L4 (4-step strategy), L5 (capstone) — primary unit standard |
Coding Fundamentals Exam Objectives
Exam objectives that Unit 4 prepares students for. Objectives 4 (Write and debug) and 7 (Debugging techniques) are finally given formal, focused treatment after being previewed across Units 1–3.
| Obj | Title | Coverage in Unit 4 | Lessons |
|---|---|---|---|
| 1 | Core programming concepts | Reinforced through capstone | L2, L3, L5 |
| 2 | Analyze and predict code behavior | Tracebacks & isolating bugs | L4 |
| 3 | Algorithm understanding & design | Decomposition into functions = algorithm structure | L2, L5 |
| 4 | Write and debug simple programs | Full coverage — primary objective for L4 and L5 | L1, L2, L3, L4, L5 |
| 7 | Debugging techniques | Full coverage — explicit 4-step strategy + traceback reading | L4, L5 |
Lesson-by-lesson alignment
| Lesson | Florida Standards | Exam Objectives |
|---|---|---|
| L1: Clean Code | 01.01, 01.02, 02.02, 07.01 | 1, 4 |
| L2: Functions | 01.01, 01.02, 02.02, 07.01, 07.05 | 1, 3, 4 |
| L3: Return & Scope | 01.01, 01.02, 02.02, 07.05 | 1, 4 |
| L4: Debugging Like a Pro | 01.01, 01.02, 02.02, 07.07 | 2, 4 (primary), 7 (primary) |
| L5: SDLC + Mad Libs 4.0 | 01.01, 01.02, 05.06, 05.07, 06.03, 07.01, 07.04, 07.05, 07.07 | 1, 3, 4 (primary), 7 |
📖 Unit 4 Vocabulary Glossary
All key terms students will encounter in Unit 4 — the heaviest vocabulary load of any unit so far (22 terms). Most are concrete Python concepts students will type and run, not abstract ideas. The "Intro" column shows the lesson where the term first appears. Each lesson plan also includes its own focused vocabulary list.
| Term | Definition | Example | Intro |
|---|---|---|---|
| Clean Code | Code that's easy for another human to read, understand, and modify. The goal is communication, not just correctness. | Clear names, consistent indentation, useful comments | L1 |
| PEP 8 | Python's official style guide. The "manners" Python coders agree to follow so all Python code looks similar. | 4-space indent, snake_case | L1 |
| snake_case | Naming convention: all lowercase, words separated by underscores. Used for variables and function names in Python. | player_score, collect_words | L1 |
| Comment | A line starting with # that Python ignores. Used to explain WHY the code does something. | # Skip negative scores | L1 |
| Function | A named, reusable block of code that does ONE job. Defined once, called many times. | def greet(name): | L2 |
def | The Python keyword for defining a function. Always followed by the function name, parentheses, and a colon. | def add(a, b): | L2 |
| Function Call | Running a function by writing its name with parentheses. The code inside runs once per call. | add(3, 5) | L2 |
| Parameter | A variable name listed in the function DEFINITION. The placeholder for the value the caller will provide. | def greet(name): — name is the parameter | L2 |
| Argument | The actual value passed to a function when it's CALLED. Fills the parameter slot. | greet("Alex") — "Alex" is the argument | L2 |
| Default Value | A value a parameter takes if no argument is given. Defined with = in the parameter list. | def greet(name="friend"): | L2 |
return | Keyword that sends a value out of a function back to whoever called it. Stops the function immediately. | return total | L3 |
| Return Value | The value a function sends back when it ends. Can be assigned to a variable, printed, or passed to another function. | result = add(3, 5) — result is 8 | L3 |
None | Python's special "no value" object. What a function returns if it has no return statement. | A function that just print()s returns None | L3 |
| Scope | The region of code where a variable is "visible" (usable). Variables created inside a function aren't visible outside it. | local vs global | L3 |
| Local Variable | A variable created inside a function. Disappears when the function ends. Can't be used outside. | The name parameter inside greet() | L3 |
| Global Variable | A variable created at the top level of the file. Visible everywhere in the file. Use sparingly. | PI = 3.14 at top of file | L3 |
| Docstring | A triple-quoted string on the first line of a function. Documents what the function does. Best practice for every function. | """Return n squared.""" | L3 |
| Bug | Any defect in code: a syntax error, a crash, or a wrong result. Three flavors: syntax, runtime, logic. | The reason your program doesn't work | L4 |
| Traceback | The error report Python prints when something crashes. Names the file, line, error type, and message. | Traceback (most recent call last): | L4 |
| 4-Step Debugging | Strategy: Reproduce → Read → Hypothesize → Fix & Verify. Expansion of Unit 2's 3-step strategy. Change ONE thing at a time. | 1.Reproduce 2.Read 3.Hypothesize 4.Fix&Verify | L4 |
| Print-Debugging | Adding print() statements to inspect variable values during execution. The most-used debugging tool in the world. | print(f"DEBUG: x={x}") | L4 |
| SDLC | Software Development Lifecycle. The five iterative stages every project cycles through: Plan → Code → Test → Fix → Maintain. | The framework behind every shipped piece of software | L5 |
print vs return distinction is the single highest-leverage idea — students who internalize it write professional Python; students who don't keep printing instead of returning all year.
🧼 Lesson 1 · Clean Code — Code Other People Can Read
Lesson 1 · Clean Code
Lesson PlanAt-a-Glance
Lesson Flow (45 minutes)
🔥 Warm-Up (5 min)
- Project two versions of the same code side-by-side: one with names like
x,y,q1, no comments, inconsistent indentation; one with snake_case names, 4-space indent, and 2 helpful comments. Both do the same thing. - Ask: "Which would you rather inherit from a teammate?" Universal answer: the second. Reveal — that's the lesson. Code is read more often than written. Today we learn the rules that make code readable.
🎤 Direct Instruction (12 min)
- Open Lesson 4.1 on the projector. Walk through Section 1 ("What Makes Code Clean?"). Three pillars: clear names, consistent style, helpful comments.
- Walk through Section 2 ("Naming Conventions"). Drill snake_case: lowercase, words separated by underscores.
player_score✓.playerScore✗ (that's camelCase — used in JavaScript, not Python).PlayerScore✗ (that's PascalCase — used for classes only). - Show the variable-name "before/after" gallery in the lesson — students watch
xbecomefinal_score,nbecomenum_students. - Walk through Section 3 ("Comments — When and How"). The rule: comments explain WHY, not WHAT.
# Add 1 to countis bad (Python already says that).# Players asked us to track wins per sessionis good (explains intent). - Walk through Section 4 ("Indentation & Spacing") — quick callback to Unit 2's indentation rules + new rules: blank line between functions, single space around operators (
x = 5, notx=5). - Walk through Section 5 ("PEP 8 — Python's Style Guide"). Briefly: PEP 8 is the official Python style guide. Project the URL (pep8.org). Don't drill all 100+ rules — just hit the 4 students will be graded on (snake_case, 4-space indent, blank lines between functions, ≤ 79 chars per line as a guideline).
🤝 Guided Practice (10 min)
- Project a "messy" version of a 15-line program (a Unit 2 calculator or grade-checker). On the whiteboard list 5 things wrong with it as a class.
- Live-refactor it together — rename variables, add 4-space indent, add 2 useful comments. Save the projected file and compare before/after. The class should genuinely react ("oh, that IS easier to read").
💻 Independent Lab (13 min)
- Lab 4.1A — "Refactor for Cleanliness": students take a 20-line messy program (provided) and clean it up. Required: rename all variables to snake_case, fix indentation, add 3 useful comments, remove any redundant ones.
- Bonus: write a one-line docstring at the top describing what the program does.
- Circulate. Watch for: students renaming things to STILL-bad names (
x→val). Push for descriptive names. Watch for: students adding comments that just restate the code (# Set x to 5). Push for WHY comments.
🚪 Exit Ticket (5 min)
- Project this code:
def calc(a,b):x=a+b;return x. Ask: "Rewrite this in clean Python style. Make at least 4 improvements." - Looking for: snake_case function name (
calc_totalor similar), descriptive parameter names (price,tax), 4-space indent on the body, return on its own line, single space around the+, drop the unnecessaryxintermediate. A docstring is bonus.
⚠️ Watch For — Common Misconceptions
# Add 1 to count = count + 1, repeating what the code already says.🎯 Differentiation
For early finishers
Have them refactor one of their OWN Unit 2 or Unit 3 labs to PEP 8 standards. Then write a 1-paragraph reflection: "What was wrong with my old code, and what's better now?" Bonus: read a section of the actual PEP 8 document and pick one rule we didn't cover that they think is interesting.For struggling students
Skip the bonus docstring. Focus only on snake_case renaming + indentation in Lab 4.1A. The win: every variable name is descriptive and snake_case. Comments and PEP 8 details can be revisited.💬 Discussion Prompts
- If a computer doesn't care about clean code, why do humans bother? (Code is for humans. Computers translate it; humans maintain it. Every line of code is read by humans far more than it's written.)
- Have you ever read a recipe that was confusing — wrong ingredient names, vague steps? How is that like messy code? (Same problem: the AUTHOR knew what they meant; the READER had to guess. Clean code is like a clear recipe.)
- Imagine you joined a school project where one teammate wrote half the code in messy style, the other wrote half in clean style. Which half are you more excited to read? Which half catches more bugs? (Clean code makes bugs visible; messy code hides them.)
🌍 Real-World Connections
- Code reviews at every tech company. Before code ships, a teammate reads it. Bad style = rejected review = back to the author. Style isn't optional in pro environments — it's enforced by software (linters) AND humans.
- Open-source projects. Projects on GitHub like Django, NumPy, and TensorFlow have PEP 8 (or stricter) style guides. Your contribution gets rejected if it doesn't follow them.
- Banking and aerospace code. When code controls money or lives, style is mandatory. Stale comments and bad names are LITERALLY the cause of bugs that cost millions or kill people. Clean code is a safety practice.
- Your own future. The "messy code" you write today is the code your future self will inherit in 3 weeks — having forgotten everything. Clean code is a gift to your future self.
📖 Lesson-Specific Vocabulary
🛠️ Lesson 2 · Functions — The Power Move of Programming
Lesson 2 · Functions
Lesson PlanAt-a-Glance
def, call functions by name, distinguish parameters from arguments, and pass multiple arguments correctly. Students will recognize when code should be turned INTO a function (when the same logic appears more than once).def, Parameter, Argument, Function CallLesson Flow (50 minutes — single-day version)
🔥 Warm-Up (5 min)
- Project a Unit 1 program that prints a greeting in 3 places, with the same 4-line structure each time. Ask: "What's annoying about this code?"
- Take answers (repetitive, hard to update — change "Hello" once, you have to change it 3 times). Reveal: "Today we learn the tool that solves this — and the same tool turns 1,000-line programs into 100 lines you can actually read."
🎤 Direct Instruction — Defining & Calling (15 min)
- Open Lesson 4.2 on the projector. Walk through Section 1 ("The Problem Functions Solve") — connect to the warm-up.
- Walk through Section 2 ("Defining a Function"). Live-code:
def greet(): print("Hello!"). Run the file. NOTHING happens. Pause. Ask the class: "Why?" - Reveal: defining a function doesn't run it. Definition = recipe; Call = make the meal. Add
greet()on a new line and run again. Now "Hello!" appears. - Drill the four parts of a function definition: keyword
def, name, parentheses, colon, indented body. - Walk through Section 3 ("Calling a Function"). Show calling 5 times:
greet()5 times = "Hello!" 5 times. Ask: "What if we wanted to greet 1,000 times?" Connect to Unit 2 loops:for i in range(1000): greet(). Functions + loops together = power combo. - Walk through Section 4 ("Parameters & Arguments"). This is the biggest concept of the lesson. On the whiteboard, draw a function as a box with a "slot" labeled parameter at the top. The CALL site has a value being passed in — labeled argument. Use color: parameters are blue (in the def line), arguments are red (in the call).
- Live-code:
def greet(name): print(f"Hello, {name}!")then callgreet("Alex")andgreet("Sam"). Same function, different output. The light bulb moment. - Add multiple parameters:
def greet(name, age): print(f"Hi {name}, age {age}."). Callgreet("Alex", 13). Order matters.
🤝 Guided Practice (10 min)
- On the whiteboard, write a function definition with a blank parameter slot:
def double(___): print(___ * 2). Have students fill in the blank. Then trace: what doesdouble(5)print?double(7)? - Project Section 5 ("Why Functions Are a Superpower") — the four reasons: reusability, readability, debuggability, collaboration. Don't lecture; ask the class which reason resonates most.
💻 Independent Lab (15 min)
- Lab 4.2A — "Make a Function": students write a function
area_of_rectangle(width, height)that prints the area. Call it 3 times with different inputs. - Lab 4.2B — "Function Library": students write 3 small functions in one file:
greet(name),double(n),is_even(n). Call each. - Circulate intensely. Watch for: forgetting to call (defined but never invoked), mixing up parameter order (greet(13, "Alex") = "Hi 13, age Alex"), and the dreaded "function defined inside another function by accident due to indentation."
🚪 Exit Ticket (5 min)
- On paper: "Explain in your own words: what's the difference between a parameter and an argument?"
- Looking for: parameter is in the DEFINITION (the slot/placeholder); argument is in the CALL (the actual value passed in). If a student says "they're the same thing" — re-teach with the box-and-slot whiteboard diagram.
⚠️ Watch For — Common Misconceptions
def greet(): print("Hi") and expects "Hi" to appear when they run the file. It doesn't.greet() at the bottom of the file.greet takes a parameter called name. When I call greet("Alex"), the argument "Alex" fills that parameter."area_of_rectangle(5, 10) when they meant width=10, height=5. The output is technically still 50 — but on a function that DOES depend on order (like divide(a, b) → a/b), they'll get wrong answers.greet("Alex", 13) is NOT the same as greet(13, "Alex"). Drill this with a function where the order's effect is obvious: subtract(a, b) with subtract(10, 3) = 7 vs subtract(3, 10) = -7.greet("Alex") by 4 spaces, putting it INSIDE the function definition. Either the function never gets called (and silently does nothing), or worse — it accidentally recurses.def — top-level. Use color or whiteboard boxes to make this visual. Same skill as Unit 2's three-level indentation, but with functions as the new "container."greet() at the top of the file and expects it to run when the file runs. It doesn't — Python only RUNS code that's actually called.🎯 Differentiation
For early finishers
Challenge: write 3 functions that work together.get_input() asks for a number; double_it(n) doubles it; show(n) prints it. Call them in sequence: show(double_it(get_input())). This previews chaining (Lesson 3) and gives them a "wow" moment when they see the output.
For struggling students
Stay on Lab 4.2A only — one function with one parameter. Skip the multi-parameter and 3-function-library version for class time. Pair them with a stronger student. The win this lesson: define ONE function with ONE parameter and call it correctly twice with different arguments.💬 Discussion Prompts
- You've already used
print(),input(),range(),int(),sorted()in this course. What does that mean? (All of those ARE functions! Built into Python. Today, you joined the people who can WRITE functions, not just call them.) - If a function has 2 parameters and you only pass 1 argument when calling, what happens? (Python raises
TypeError: missing required positional argument. Strict — Python doesn't guess; you must provide every argument.) - Why do programmers say "DRY" — Don't Repeat Yourself? (Functions exist to enforce DRY. If the same logic appears twice, it should be a function called twice. Saves you from changing things in 2 places when something changes — preview of Lesson 5's maintenance topic.)
🌍 Real-World Connections
- Every app you use is built from functions. Tap a button → a function runs. Submit a form → a function runs. Functions are the unit of behavior in modern software.
- API endpoints. When an app talks to a server (loading your social feed, posting a message), it's calling a function on the server. Same idea, different machine.
- Math libraries. Python's
mathmodule has functions likemath.sqrt(16)= 4. Engineers, scientists, and finance pros use thousands of pre-built functions instead of re-deriving them. - Game development. Every game has functions like
jump(),shoot(),pick_up_item(item). The game ENGINE calls these as the player acts. Without functions, games would be impossible.
📖 Lesson-Specific Vocabulary
↩️ Lesson 3 · Return Values & Scope
Lesson 3 · Return Values & Scope
Lesson PlanAt-a-Glance
return to send a value out of a function, distinguish return from print (the most-confused distinction in functions), chain functions together, and explain scope — why variables inside one function don't leak into another.return-vs-print distinction is the most confused concept in beginning Python — and the most-tested. Build flex time. The 2-day pacing version of this lesson is the right call for most classes.
Lesson Flow (50 minutes — single-day version)
🔥 Warm-Up (5 min)
- Live-code two functions on the projector:
def add_print(a, b): print(a + b)def add_return(a, b): return a + b
- Call each:
x = add_print(3, 4);y = add_return(3, 4). Then printxandy. - Result:
xisNone;yis7. Class is confused. PERFECT — that confusion IS the lesson. Today we untangle return vs print.
🎤 Direct Instruction — return (15 min)
- Open Lesson 4.3 on the projector. Walk through Section 1 ("return vs print"). Drill the distinction:
- print = show the value to the human. The value disappears after.
- return = send the value back to the calling code. The value can be saved into a variable, used in math, passed to another function.
- Use the "drive-thru window" analogy: print is yelling the order to the kitchen (informational, no payback). return is the kitchen handing food back through the window (you actually GET something).
- Walk through Section 2 ("How return Works"). Live-code:
def square(n): return n * n. Thenresult = square(5). Printresult= 25. Thensquare(5) + square(3)= 34. The return value can be USED. Print can't. - Walk through Section 3 ("Chaining Functions"). Live-code:
def double(n): return n * 2 def square(n): return n * n print(double(square(3))) # square(3)=9, double(9)=18
🎤 Direct Instruction — Scope (12 min)
- Walk through Section 4 ("Scope — Where Variables Live"). On the whiteboard, draw a big box labeled "GLOBAL" and a small box inside labeled "FUNCTION."
- Live-code:
def f(): x = 5;f();print(x). Crash:NameError. Why?xonly existed insidef. The function ended;xis gone. - Now:
x = 5;def g(): print(x);g(). Works! Outerxis visible insideg. - Define local variable (inside the function, dies with the function) and global variable (defined outside, visible everywhere).
- Walk through Section 5 ("Why Scope Is a Feature"). The class might think scope is annoying — reframe it. Scope is what makes modular code possible. If every function's variables leaked into every other function, you couldn't have two functions both using
ias a counter. Scope = isolation = freedom to name things naturally.
💻 Independent Lab (13 min)
- Lab 4.3A — "Return Practice": students write 3 functions that RETURN values:
square(n),tax(price)(returns price * 0.07),longer(a, b)(returns the longer of two strings). Use the return values: assign to a variable, print it, pass to another function. - Lab 4.3B — "Scope Detective": given 4 buggy snippets each demonstrating a scope confusion, fix each. Sample bugs: variable defined inside a function but used outside; function tries to modify global without
globalkeyword (advanced — flag if a student wants to know). - Circulate. Common bug 1:
x = my_func()whenmy_funcusesprintnotreturn—xends upNone. Common bug 2: function references a variable that was never passed in OR defined globally.
🚪 Exit Ticket (5 min)
- On paper, two questions:
- "What does
print()do thatreturndoesn't?" (Answer: shows a value to the human / displays it on screen) - "What does
returndo thatprint()doesn't?" (Answer: sends a value back so the calling code can save or use it)
- "What does
- If a student writes "they're basically the same" — they need re-teaching before the capstone. Schedule 5 minutes one-on-one.
⚠️ Watch For — Common Misconceptions
print in functions where they should use return, then can't figure out why x = my_func() gives None.return returns nothing useful."None.return, every function returns None implicitly. None is Python's "nothing useful here" placeholder. The fix is always: replace print(x) at the end with return x.return ends the function."return immediately exits the function — they put code AFTER return expecting it to run. It doesn't.return on the same path will never execute (it's "dead code"). Some IDEs warn about this. Use it intentionally for early exits: if invalid: return.i would clash. Scope is what makes modular code possible. The frustration is just the cost of a system that lets you have 100 functions without naming conflicts. Section 5 of the lesson makes this explicit.🎯 Differentiation
For early finishers
Challenge: write a functionanalyze(numbers) that takes a list and returns BOTH the maximum and minimum (using return max_val, min_val — Python returns a tuple). Stretch: research the global keyword and explain in 2 sentences why pros AVOID it most of the time. Stretch: write nested function calls — print(double(square(square(3)))) = 162.
For struggling students
Skip Lab 4.3B. Stay on Lab 4.3A — write functions that return values and assign the return to a variable. Skip scope entirely for class time; come back to it the next day. The single win: a function withreturn n * 2 can have its return value saved with x = double(5). That's enough for now.
💬 Discussion Prompts
- If
printexists, why do we needreturnat all? (Print only shows a value. Return makes a value USABLE — saveable, passable to another function, included in math. Most real-world functions return; print is for end-of-program display only.) - You've used
int(input())in many labs. What's that doing in terms of return values? (Mind-blow moment:input()RETURNS a string;int()RETURNS an integer. The chain works because both are returning. You've been chaining return values all year — you just didn't know the words for it.) - If two functions both use
xinternally, do they conflict? (NO — that's the whole point of scope. Each function has its ownx. They don't see each other's. Scope = privacy.)
🌍 Real-World Connections
- Every API call. When your app fetches the weather, the weather server's function RETURNS the data. Without return, no app could ever talk to a server.
- Microservices. Modern web apps are dozens of small services that talk via function returns. Scope at the function level scales up to scope at the service level — same principle.
- Math & science. A function like
celsius_to_fahrenheit(c)RETURNS a number you can use. Without return, scientific computing is impossible. - Privacy. Scope is the foundation of "encapsulation" in OOP (Unit 7). It's what lets a banking system have a function
get_balance()that doesn't accidentally expose the user's password — they live in different scopes.
📖 Lesson-Specific Vocabulary
return. Lets one function's output be used by other code.🐛 Lesson 4 · Debugging Like a Pro
Lesson 4 · Debugging Like a Pro
Lesson PlanAt-a-Glance
Lesson Flow (50 minutes)
🔥 Warm-Up (5 min)
- Project a multi-line traceback like
Traceback (most recent call last): File "game.py", line 12 ... ZeroDivisionError: division by zero. Ask: "Where does this error actually occur? What's broken?" - Most students will look at the TOP. Reveal: read the BOTTOM first. The error type and message tell you what; the last "File" line tells you where. Today is the day students stop fearing tracebacks.
🎤 Direct Instruction (15 min)
- Open Lesson 4.4 on the projector. Walk through Section 1 ("Three Kinds of Bugs"). Drill the three:
- Syntax Error: code won't run. Python tells you the line and what's missing. Easiest to fix.
- Runtime Error: code starts running but crashes mid-flight. Python tried something it couldn't do (divide by zero, access a missing list index, etc).
- Logic Error: code runs without complaining but gives the WRONG answer. Sneakiest. No error message — you have to notice the wrong output yourself.
- Walk through Section 2 ("Reading a Traceback"). Project a traceback. Click each part to reveal what it means. Drill: read bottom-up. Last "File" line = scene of the crime. Last line = error type and message.
- Walk through Section 3 ("The 4-Step Debugging Strategy"). On the whiteboard, write: 1. Reproduce 2. Read 3. Hypothesize 4. Fix & Verify. Drill: change ONE thing at a time. The golden rule.
- Walk through Section 4 ("Print-Debugging — Your Best Friend"). Live-demo: take a buggy function, add 3 strategic
print(f"DEBUG: ...")lines at function boundaries, run, see what's actually happening, fix the bug, REMOVE the debug prints. The "remove when done" step is critical. - Walk through Section 5 ("Isolating Bugs in Functions"). Functions make bugs FINDABLE. Test each function alone with sample inputs. Use the "binary search" trick — if there are 4 functions, test the 2nd one to halve the search space.
🎮 Bug Hunt Challenge (10 min)
- Use the Bug Hunt Challenge in the lesson. Project. Three buggy snippets — one syntax, one runtime, one logic. Class votes on which line is broken; reveal.
- This is the most engaging part of the unit. Don't shortcut it. The hands-on hunting is what builds the muscle memory.
💻 Independent Lab (15 min)
- Lab 4.4A — "Fix the Buggy Functions": students download a file with 3 buggy functions (one of each type). For each, they (1) IDENTIFY the bug type, (2) APPLY the 4-step strategy on paper, (3) FIX the code. Submit fixed code AND a 1-line bug-type label per function.
- Bonus: Lab 4.4B — "Add Strategic Debug Prints": students take a working function and add 3 well-placed debug prints — one at entry, one in the middle, one at exit. Demonstrate they can print-debug intentionally, not just spam.
- Circulate. The most common pattern: students try fix #1, run, doesn't work, try fix #2, run, doesn't work — instead of READING the error each time. Stop them. Ask: "What did the error message say after fix #1?" If they didn't read it, they're guessing — that's the anti-pattern this lesson exists to break.
🚪 Exit Ticket (5 min)
- On paper: "List the 4 steps of the debugging strategy IN ORDER. Why is changing one thing at a time the golden rule?"
- Looking for: Reproduce → Read → Hypothesize → Fix & Verify. Reasoning: if you change five things and the bug goes away, you don't know which fix worked — and you might have introduced new bugs.
⚠️ Watch For — Common Misconceptions
average([10, 20]) should be 15. If your code gives 30, that's a logic error — even though Python didn't crash.🎯 Differentiation
For early finishers
Challenge: write a "buggy program generator" — pick a Unit 2 lab, deliberately introduce one of each bug type, and challenge a partner to find them. The act of CREATING bugs deepens understanding of how they happen. Stretch: research how IDEs like VS Code use a "debugger" with breakpoints — the next-level evolution beyond print-debugging.For struggling students
Focus only on syntax and runtime errors — skip logic errors for class time. The win: read a traceback, identify the line and message, and apply step-by-step the 4-step strategy on a single bug. Logic errors are best taught after they hit one in their own capstone.💬 Discussion Prompts
- If senior engineers spend most of their time debugging (they do), what does that tell you about software development? (Writing code is the easy part; getting it RIGHT is the hard part. Debugging is the central skill of the profession.)
- Have you ever had a phone or app freeze, crash, or give a wrong answer? Which type of bug do you think it was? (Frozen = often infinite loop, runtime, or memory bug. Crashed = runtime. Wrong answer = logic. The user only sees the symptom; engineers diagnose the type.)
- Why is print-debugging called "primitive" by some pros — and yet still the most common debugging tool? (It's primitive because it requires editing the code; debuggers don't. But it works in EVERY language, EVERY environment, with no special tools. Universal beats fancy.)
🌍 Real-World Connections
- Bug bounties. Companies pay people for finding bugs in their software. Apple has paid up to $1 million for a single critical bug discovery. Bug-finding is a real, paid career.
- Stack Overflow. The internet's largest debugging support site. Most questions are about specific tracebacks — students will use it for the rest of their careers.
- The Mars Climate Orbiter. NASA lost a $327 million spacecraft in 1999 due to a logic error — one team used metric units, another used imperial. No syntax/runtime error; the code "worked." Wrong answer destroyed the spacecraft.
- Therac-25. A 1980s radiation therapy machine had a logic error that gave patients massive overdoses. Six confirmed deaths. The lesson: in medical/safety code, logic errors can kill. Testing matters.
📖 Lesson-Specific Vocabulary
print() statements to make the invisible visible.🔄 Lesson 5 · SDLC + Mad Libs 4.0 — Modular Capstone
Lesson 5 · SDLC + Mad Libs 4.0
Project PlanAt-a-Glance
Project Flow (90 minutes across 2 days)
📅 Day 1 — SDLC Intro + Plan + Code (45 min)
- Warm-up (5 min): Project the Mad Libs 3.0 student code from Unit 3 — one big block, no functions. Ask: "If we wanted three different teams to work on this at once, could they?" Universal answer: no, they'd step on each other. Reveal: today we make it modular so 3 teams CAN work on it independently.
- Introduce the SDLC (10 min): Walk through Section 1 of the lesson. Five stages: Plan, Code, Test, Fix, Maintain. Project the cycle diagram. Note: this expands Unit 2's 4-stage SDLC by adding Maintain — the longest phase in real software, often years.
- Mnemonic: "Please Code The Future Manually" or any silly phrase students invent. Students remember silly mnemonics.
- SDLC Stage 1 — Plan (10 min): Distribute paper. Students answer 4 questions in writing: (1) What does the program DO? (2) What 3 jobs does it do — each becoming a function? (3) What inputs does it need? (4) What's the final output? No CodeSkills Lab until paper is filled.
- SDLC Stage 2 — Code (20 min): Students copy the starter code into CodeSkills Lab. They build the 3 functions:
get_words()— collects 5 words from the user, returns themtell_story(words)— takes the words, returns a story stringshow_results(story)— displays the final story
- Their plan from Stage 1 goes at the top as a comment block. PEP 8 style throughout.
📅 Day 2 — Test + Fix + Maintain + Showcase (45 min)
- SDLC Stage 3 — Test (10 min): Students apply the testing mindset from Lesson 4. They run their program with: (1) normal happy-path inputs, (2) empty inputs, (3) very long inputs, (4) special characters, (5) numbers where strings expected. They WRITE DOWN any bugs they find as a "test case worksheet" at the bottom of the file.
- SDLC Stage 4 — Fix (15 min): Apply the 4-step debugging strategy to each bug found. Students pair up — they test EACH OTHER's programs and report bugs. Peer testing surfaces edge cases the author didn't think of. Critical 4-step rule: ONE change at a time.
- SDLC Stage 5 — Maintain (10 min): Students add the polishing touches that make the code maintainable: header comment block (name, date, what it does), docstring on each function, version notes at the bottom, file saved as
mad_libs_4_modular.py. - Showcase & Submit (10 min): Pick 3–5 volunteers to project their Mad Libs 4.0 in front of the class. Class supplies the words. The OTHER students project their CODE structure briefly so peers can see different valid approaches to the same project.
- Submit through CodeSkills Lab + reflection.
⚠️ Watch For — Common Project Pitfalls
def main(): ... with 60 lines inside. Technically a function, but it does everything — defeating the lesson.get_words() uses print(words) instead of return words. Then tell_story() can't use the words because they were never returned.return them — print just shows them. Walk the student to the line: change print(words) → return words. Also catch any tell_story calls that aren't passing the words: story = tell_story(get_words()).words = [] at module level, has each function modify it as a global. Avoids parameters and returns entirely.🎯 Differentiation
For students who finish early
Direct them to the stretch goals from the lesson: random story selection (4th functionpick_template() with import random), play-again loop (wrap with while), word validation (helper function rejects empty inputs), save story to file (preview Unit 5 file I/O). Each adds +5 pts (max +20).
For struggling students
It's OK if their version has 2 functions instead of 3 — for example, combine "tell story" and "show results" into one. They still demonstrated modular thinking. Hold them to the 3-function bar if possible, but a 2-function version with parameters and returns properly used is still a B-range submission. The PRIMARY watch-for: do they understand return vs print? If yes, the rest can be polished over time.💬 Discussion Prompts
- Why does Mad Libs 4.0 ask for AT LEAST 3 functions instead of one big block? (Functions break the program into testable, reusable, easy-to-debug pieces. With 3 functions, a bug is in one of three places — much faster to find than a bug in one giant 60-line function.)
- Which SDLC stage do you think most beginners SKIP? (Test. Most beginners code it, run it once, declare done. Pros spend MORE time testing than coding. The Mars Climate Orbiter and Therac-25 stories from Lesson 4 are why.)
- What's the difference between Mad Libs 1.0 (Unit 1) and Mad Libs 4.0? Is it more lines of code or fewer? (Often FEWER. Cleaner. The same behavior with better structure. That's the point of professionalization — same job, less mess.)
🌍 Real-World Connections
- The SDLC runs every modern software project. Every app you use is in some stage of this cycle right now — TikTok is planning v15, coding it, testing v14 internally, fixing v13's bugs, and maintaining v12 for users on older phones. All five stages, simultaneously, on every team.
- Modular code at scale. Real software has thousands of functions. Modularity is what makes it possible for hundreds of engineers to work on the same product without stepping on each other. Mad Libs 4.0 is the same idea, in miniature.
- Code reviews. Every modular function in Mad Libs 4.0 is small enough for one teammate to review in 5 minutes. A 60-line monolith would take an hour. Modularity = faster reviews = faster shipping.
- You can list this on a resume. "Applied SDLC methodology to a modular Python project with separated concerns and full test coverage." Not a stretch — that's literally what you did.
📋 Mad Libs 4.0 Project Rubric (100 points)
The rubric matches the one in the student lesson exactly. Share with students at the start of Day 1.
| Category | What to look for | Pts |
|---|---|---|
| Modular Functions | At least 3 well-named functions, each doing ONE clear job (collect, build, display). | 25 |
| Parameters & Returns | Functions accept inputs and use return. No relying on globals where parameters belong. | 20 |
| Clean Code Style | snake_case names, 4-space indent, spaces around operators, blank lines between functions. | 15 |
| Comments & Docstrings | Header comment block, function docstrings, "why" comments where useful. | 10 |
| SDLC Documentation | Plan comments at the top + test case worksheet at the bottom. | 15 |
| Works Correctly | Program runs without errors and produces a coherent story for normal inputs. | 15 |
| TOTAL | 100 | |
🎁 Stretch Goals (extra credit)
- Multiple stories — 4th function
pick_template()usingimport random: +5 pts - Play again — wrap the whole flow in a
whileloop with "Play again? (y/n)": +5 pts - Word validation — helper function that rejects empty inputs and re-prompts: +5 pts
- Save to file — preview Unit 5 file I/O by writing the finished story to
my_mad_libs.txt: +5 pts
Maximum stretch credit: +20 points. Document each stretch in version notes at the bottom of the file.
📖 Lesson-Specific Vocabulary
🛠️ Appendix · Common Python Errors in Unit 4
This appendix lists the most common Python error messages students will see in Unit 4. Functions introduce a new family of errors (TypeError on argument count, UnboundLocalError, missing return), and Lesson 4's debugging mindset is the operating system for all of them. Apply the 4-step strategy: Reproduce → Read → Hypothesize → Fix & Verify, ONE change at a time.
What it usually means: The function definition has 1 parameter, but the call passes 2 arguments. (Or the reverse: definition has 2, call passes 1.)
How to fix: Match the count. Read the def line and the call line side by side. Either add a parameter to the def, or remove an argument from the call.
What it usually means: Called the function without passing all required arguments. Often: greet() instead of greet("Alex").
How to fix: Provide every argument the def line specifies. Python is strict — every parameter needs a value (unless it has a default, which you'll learn in advanced lessons).
What it usually means in Unit 4: Trying to use a variable from inside a function in code outside the function. The variable was LOCAL to the function and died when the function returned.
How to fix: Have the function RETURN the value, then save it: x = my_func(). Now the value lives outside the function via the assignment.
What it usually means: A function is trying to MODIFY a global variable. Python sees the assignment and treats count as a NEW local variable — but you tried to read it before assigning.
How to fix: Either pass count as a parameter (preferred), OR use the global count keyword inside the function (not recommended — globals are usually a sign of bad design). Pass-and-return is almost always cleaner.
What it usually means: The function uses print at the end instead of return. Without an explicit return, every function returns None implicitly.
How to fix: Replace print(answer) at the end of the function with return answer. The most common bug in all of Unit 4. Echo of Lesson 3's central distinction.
What it usually means: The function tried to divide by 0. Often happens because a parameter that should be nonzero was passed in as 0 from outside.
How to fix: Add a guard at the top of the function: if denominator == 0: return 0 (or whatever default makes sense). This is "input validation" applied to function parameters — Lesson 5's stretch goal.
What it usually means: The body of a function isn't indented consistently. With functions, the indent rule is: every line of the function body is at +4 spaces from the def line. Mixing tabs and spaces also triggers this.
How to fix: Re-indent the entire body uniformly with 4-space steps. Most editors (CodeSkills Lab included) have a "convert tabs to spaces" command — use it.
What it usually means: The student wrote def my_func(): print("hi") but never wrote my_func(). The file runs without errors but produces no output.
How to fix: Add a call at the bottom of the file: my_func(). Definition is the recipe; call is making the meal.
Watch list — these still happen in Unit 4 capstones:
SyntaxError: expected ':'— missing colon on def, if, or for line.TypeError: '>' not supported between instances of 'str' and 'int'— student forgot toint()-wrap input. Same as Unit 1.- Infinite loops in stretch goals where students wrap with
while. Unit 2's checklist applies. IndexError: list index out of range— referencingwords[5]when only 5 words were collected (indices 0–4). Carryover from Unit 2.- The "list inside the loop" bug from Unit 3 —
words = []reset each iteration.
print() if needed. (4) Fix & Verify — change ONE thing, run, observe. This is the rhythm of professional debugging. Build the habit in Unit 4 and it carries you the rest of the year — and into a career.
— End of Unit 4 Teacher's Guide —
