Lesson 1 of 0
In Progress

Unit 4 – Teachers Guide

Unit 4 · Teacher's Guide | Knowledge Pillars · Code Quest
📚 Teacher's Guide Code Quest · Coding Fundamentals

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.

🧩 5 Lessons + Capstone
⏱️ 8–10 class periods
🎓 Florida Course #9009200

👋 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: NameError from scope, TypeError from 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 is the year's "second wall." Unit 2's loops were the first wall; Unit 4's functions are the second. The conceptual jump from "code runs top-to-bottom" to "code is broken into reusable named blocks with parameters and return values" is the biggest mental shift students experience all year. Lessons 2 (defining functions) and 3 (return + scope) are by far the densest in the unit. Build buffer. Pair students. The students who internalize Unit 4 well are the students who'll finish the year strong; the students who don't will struggle in every subsequent unit.

🗺️ 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() and return — 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
🎯 Course alignment. Unit 4 is the home of Florida CTE standards 06.03 (iterative SDLC), 07.05 (variable types deeper dive — local vs global), and 07.07 (debug). The capstone touches almost every standard in the framework. The unit also closes Exam Objectives 4 (Write and debug) and 7 (Debugging techniques) — these objectives have been previewed since Unit 1 and are now treated formally. See the Standards Crosswalk below for full lesson-by-lesson detail.

⏱️ 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

DayLessonFocusHomework
Day 1L1: Clean CodeWhat "clean" means. snake_case. Comments (good vs noisy). PEP 8 intro. Lab 4.1A.Finish Lab 4.1B (rewrite messy code)
Day 2L2: Functions (pt 1)The problem functions solve. def, calling. Parameters vs arguments. Lab 4.2A.Read L2 Sections 4–5 (parameters)
Day 3L2: 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 4L3: Return & Scope (pt 1)print vs return. How return works. Chaining functions. Lab 4.3A.Read L3 Sections 4–5 (scope)
Day 5L3: 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 6L4: 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 7L4: 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 8L5: 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 9L5: 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.

⏱️ Where the time usually goes. Lesson 1 (Clean Code) often runs 30–35 minutes — students get the rules quickly. Bank that extra time. Lesson 2 (Functions) ALWAYS runs over its allotted 50 minutes, especially the first day. Build buffer. Lesson 3 (Return + Scope) is the conceptual peak — many teachers extend this into 2 full days. Lesson 4 (Debugging) feels long but rewards the time — students leave with their first systematic strategy. Lesson 5 (SDLC + capstone) is the year's most ambitious project — the showcase moment is the single biggest emotional payoff in the course.

Suggested grading weights for Unit 4

ComponentWeightNotes
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 Project45%Capstone — see 100-pt rubric in Lesson 5 plan
Class participation10%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:

StandardDescriptionLessons
01.01Use specialized computer coding software to solve problems.All (CodeSkills Lab)
01.02Demonstrate proficiency using specialized computer software (e.g., Python).All
02.02Explain the components of programming languages.L1, L2, L3, L4, L5
05.06Recognize that more than one algorithm can solve a given problem.L4 (refactoring), L5
05.07Create a program that implements an algorithm to achieve a given goal.L5 (Mad Libs 4.0)
06.03Identify the iterative steps in the Software Development Life Cycle (Plan, Design, Code, Test, Deploy, Maintain).L5 — primary unit standard
07.01Describe the structure of a simple program; explain why sequencing is important.L1, L2, L5
07.04Describe selection programming structures (if/then, else); explain logic for if statements.L5 (capstone applies)
07.05Explain the types and use of variables in programming.L3 (local vs global scope) — primary deeper-dive
07.07Troubleshoot 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.

ObjTitleCoverage in Unit 4Lessons
1Core programming conceptsReinforced through capstoneL2, L3, L5
2Analyze and predict code behaviorTracebacks & isolating bugsL4
3Algorithm understanding & designDecomposition into functions = algorithm structureL2, L5
4Write and debug simple programsFull coverage — primary objective for L4 and L5L1, L2, L3, L4, L5
7Debugging techniquesFull coverage — explicit 4-step strategy + traceback readingL4, L5

Lesson-by-lesson alignment

LessonFlorida StandardsExam Objectives
L1: Clean Code01.01, 01.02, 02.02, 07.011, 4
L2: Functions01.01, 01.02, 02.02, 07.01, 07.051, 3, 4
L3: Return & Scope01.01, 01.02, 02.02, 07.051, 4
L4: Debugging Like a Pro01.01, 01.02, 02.02, 07.072, 4 (primary), 7 (primary)
L5: SDLC + Mad Libs 4.001.01, 01.02, 05.06, 05.07, 06.03, 07.01, 07.04, 07.05, 07.071, 3, 4 (primary), 7
📋 What's not in Unit 4. These standards are NOT addressed in Unit 4 and appear in later units: 03.x (file types) — Unit 6 · 04.03 (sorting/filtering data sets) — Unit 10 · 07.02 (algorithms — depth) — Unit 9 (computational thinking) · 07.03 (loops — already covered) — applied throughout · 07.06 (pseudocode — already covered) — applied in capstone planning · 07.08 (databases) — Unit 10. The capstone APPLIES nearly everything; Unit 4 is integrative.

📖 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.

TermDefinitionExampleIntro
Clean CodeCode that's easy for another human to read, understand, and modify. The goal is communication, not just correctness.Clear names, consistent indentation, useful commentsL1
PEP 8Python's official style guide. The "manners" Python coders agree to follow so all Python code looks similar.4-space indent, snake_caseL1
snake_caseNaming convention: all lowercase, words separated by underscores. Used for variables and function names in Python.player_score, collect_wordsL1
CommentA line starting with # that Python ignores. Used to explain WHY the code does something.# Skip negative scoresL1
FunctionA named, reusable block of code that does ONE job. Defined once, called many times.def greet(name):L2
defThe Python keyword for defining a function. Always followed by the function name, parentheses, and a colon.def add(a, b):L2
Function CallRunning a function by writing its name with parentheses. The code inside runs once per call.add(3, 5)L2
ParameterA variable name listed in the function DEFINITION. The placeholder for the value the caller will provide.def greet(name): — name is the parameterL2
ArgumentThe actual value passed to a function when it's CALLED. Fills the parameter slot.greet("Alex") — "Alex" is the argumentL2
Default ValueA value a parameter takes if no argument is given. Defined with = in the parameter list.def greet(name="friend"):L2
returnKeyword that sends a value out of a function back to whoever called it. Stops the function immediately.return totalL3
Return ValueThe 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 8L3
NonePython's special "no value" object. What a function returns if it has no return statement.A function that just print()s returns NoneL3
ScopeThe region of code where a variable is "visible" (usable). Variables created inside a function aren't visible outside it.local vs globalL3
Local VariableA variable created inside a function. Disappears when the function ends. Can't be used outside.The name parameter inside greet()L3
Global VariableA variable created at the top level of the file. Visible everywhere in the file. Use sparingly.PI = 3.14 at top of fileL3
DocstringA triple-quoted string on the first line of a function. Documents what the function does. Best practice for every function."""Return n squared."""L3
BugAny defect in code: a syntax error, a crash, or a wrong result. Three flavors: syntax, runtime, logic.The reason your program doesn't workL4
TracebackThe error report Python prints when something crashes. Names the file, line, error type, and message.Traceback (most recent call last):L4
4-Step DebuggingStrategy: 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&VerifyL4
Print-DebuggingAdding print() statements to inspect variable values during execution. The most-used debugging tool in the world.print(f"DEBUG: x={x}")L4
SDLCSoftware Development Lifecycle. The five iterative stages every project cycles through: Plan → Code → Test → Fix → Maintain.The framework behind every shipped piece of softwareL5
📖 Teaching tip. 22 terms is a lot. The five students must own by end of unit: function, parameter, argument, return, scope. Drill those weekly — they're the load-bearing concepts for the rest of the year. Everything else is supporting cast. The 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 Plan

At-a-Glance

Objective
Students will apply Python style conventions — snake_case naming, 4-space indentation, blank lines between logical blocks, helpful comments, and basic PEP 8 rules — to refactor a messy program into clean, readable code.
Time
45 minutes
Materials
Computer, CodeSkills Lab, projector, optional printed PEP 8 quick-reference card
Vocabulary
Clean Code, snake_case, PEP 8, Comment, Docstring
FL Standards
01.01, 01.02, 02.02, 07.01
Exam Obj.
Objective 4 (primary)

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 x become final_score, n become num_students.
  • Walk through Section 3 ("Comments — When and How"). The rule: comments explain WHY, not WHAT. # Add 1 to count is bad (Python already says that). # Players asked us to track wins per session is 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, not x=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_total or similar), descriptive parameter names (price, tax), 4-space indent on the body, return on its own line, single space around the +, drop the unnecessary x intermediate. A docstring is bonus.

⚠️ Watch For — Common Misconceptions

1. "Style doesn't matter — code that works is code that works."
What you'll see: A student dismisses the lesson because their messy code passes the labs.
How to address: Reframe with the read-vs-write ratio: every line of code is written once but read DOZENS of times — by your future self, by teammates, by graders, by the next person to extend the project. Cleanliness pays off the moment someone (including you in 3 weeks) needs to change something. Use this exact line: "Code is for humans. Computers don't care."
2. "Comments should explain every line."
What you'll see: A student adds # Add 1 to count = count + 1, repeating what the code already says.
How to address: The rule: comments explain WHY, not WHAT. The code itself shows what. The comment should add information the code can't — business reason, edge-case warning, future TODO, why a non-obvious approach was chosen. If a comment just narrates the code, delete it.
3. "snake_case looks ugly compared to camelCase."
What you'll see: A student uses camelCase from another language they've seen (often JavaScript or Java).
How to address: Different languages have different conventions. JavaScript uses camelCase. Python uses snake_case. They're equally valid — but in Python class, we follow Python's rules. Frame this as professional respect: when you write code in a language, you follow that language's conventions. Like how British English uses "colour" and American English uses "color" — both correct, depending on context.
4. "All comments are good comments."
What you'll see: A student keeps obsolete comments after refactoring — the code does X but the comment still says Y.
How to address: Stale comments are WORSE than no comments because they actively mislead. Rule: when you change code, update or delete the comment. Comments are part of the code; they need maintenance too.

🎯 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

Clean Code — Code that's easy for other humans to read. Clear names, consistent style, helpful comments.
snake_case — Naming convention: lowercase words separated by underscores. Python's standard.
PEP 8 — The official Python style guide. Defines snake_case, 4-space indent, blank-line rules.
Docstring — Triple-quoted string at the top of a function explaining what it does. Different from a comment — Python tools can read docstrings.
↑ Back to top

🛠️ Lesson 2 · Functions — The Power Move of Programming

Lesson 2 · Functions

Lesson Plan

At-a-Glance

Objective
Students will define functions using 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).
Time
50 minutes (often runs 60 — typically split into two days)
Materials
Computer, CodeSkills Lab, projector, whiteboard
Vocabulary
Function, def, Parameter, Argument, Function Call
FL Standards
01.01, 01.02, 02.02, 07.01
Exam Obj.
Objectives 1, 4 (primary)
⚠️ The biggest conceptual leap of the course. Functions are where students go from "writing scripts" to "designing programs." Some students click immediately; others need 2–3 days. Don't rush. The pacing guide allocates two class periods to this lesson for a reason — Day 2 (parameters) is when the concept usually solidifies for most students.

Lesson 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 call greet("Alex") and greet("Sam"). Same function, different output. The light bulb moment.
  • Add multiple parameters: def greet(name, age): print(f"Hi {name}, age {age}."). Call greet("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 does double(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

1. "Defining is the same as calling."
What you'll see: A student writes def greet(): print("Hi") and expects "Hi" to appear when they run the file. It doesn't.
How to address: Use the recipe analogy hard. Definition = writing a recipe. Calling = cooking the meal. You can write 100 recipes; nothing happens until someone cooks. The fix is one line: add greet() at the bottom of the file.
2. "Parameter and argument are the same word."
What you'll see: Students use the words interchangeably and lose precision when discussing code.
How to address: Drill the distinction every time it comes up. Parameter = in the def line (the slot). Argument = in the call (the value). Many professional engineers DON'T distinguish carefully — but the exam does, and the precise mental model helps with debugging. Use a sentence frame: "The function greet takes a parameter called name. When I call greet("Alex"), the argument "Alex" fills that parameter."
3. "Argument order doesn't matter."
What you'll see: A student calls 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.
How to address: Order matters absolutely. Arguments fill parameters left-to-right. 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.
4. "All code goes inside the function."
What you'll see: A student indents the call 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.
How to address: Indentation determines membership. Code inside the function is indented 4 spaces. The CALL is at the same indent level as 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."
5. "Functions need to be called by Python automatically."
What you'll see: A student defines 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.
How to address: Reinforce: defining a function is just preparing it. The function body only runs when something explicitly calls the function. Show with a print statement before and after the def: the prints run; the function body doesn't until 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 math module has functions like math.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

Function — A named, reusable block of code that does one job.
def — Python keyword for defining a function.
Parameter — A variable name listed in a function's definition. The "slot" that receives a value.
Argument — The actual value passed into a function when called. Fills the parameter slot.
Function Call — Running a function by writing its name with parentheses (and arguments).
↑ Back to top

↩️ Lesson 3 · Return Values & Scope

Lesson 3 · Return Values & Scope

Lesson Plan

At-a-Glance

Objective
Students will use 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.
Time
50 minutes (often runs 60 — typically split into two days)
Materials
Computer, CodeSkills Lab, projector, whiteboard with multiple colors
Vocabulary
Return Value, return vs print, Scope, Local Variable, Global Variable
FL Standards
01.01, 01.02, 02.02, 07.05
Exam Obj.
Objectives 1, 2, 4 (primary)
⚠️ Highest-friction lesson of Unit 4. The 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 print x and y.
  • Result: x is None; y is 7. 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. Then result = square(5). Print result = 25. Then square(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? x only existed inside f. The function ended; x is gone.
  • Now: x = 5; def g(): print(x); g(). Works! Outer x is visible inside g.
  • 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 i as 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 global keyword (advanced — flag if a student wants to know).
  • Circulate. Common bug 1: x = my_func() when my_func uses print not return — x ends up None. Common bug 2: function references a variable that was never passed in OR defined globally.

🚪 Exit Ticket (5 min)

  • On paper, two questions:
    1. "What does print() do that return doesn't?" (Answer: shows a value to the human / displays it on screen)
    2. "What does return do that print() doesn't?" (Answer: sends a value back so the calling code can save or use it)
  • 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

1. "print and return are basically the same."
What you'll see: Students use print in functions where they should use return, then can't figure out why x = my_func() gives None.
How to address: The drive-thru analogy. Or: print = TV news (you see it; nothing comes back). Return = mail (you get something delivered to you). Make this distinction the heaviest-drilled idea of the unit. Worth re-teaching, re-quizzing, re-tracing as many times as needed.
2. "A function with no return returns nothing useful."
What you'll see: A student calls a function that only prints, expects to get a value back, and is confused that the variable is None.
How to address: Without 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.
3. "return ends the function."
What you'll see: Students don't realize return immediately exits the function — they put code AFTER return expecting it to run. It doesn't.
How to address: True — return ENDS the function. Anything after a 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.
4. "Variables inside functions persist."
What you'll see: A student references a function-local variable from outside the function and expects it to still exist.
How to address: Local variables die when the function returns. They're "born" when the function is called and "die" when it exits. To get a value out, return it. To keep it around, store it in a global or pass it on. Use the box-inside-box whiteboard diagram.
5. "Scope is just complication."
What you'll see: A student is frustrated by NameError when accessing a function's variable from outside.
How to address: Reframe scope as a FEATURE. Without scope, two functions both using 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 function analyze(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 with return n * 2 can have its return value saved with x = double(5). That's enough for now.

💬 Discussion Prompts

  • If print exists, why do we need return at 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 x internally, do they conflict? (NO — that's the whole point of scope. Each function has its own x. 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 Value — The value a function sends back using return. Lets one function's output be used by other code.
return vs print — Print shows a value to the human (and it's gone). Return sends a value back to the code (and it can be saved).
Scope — Where a variable is "visible." Local (inside one function) or global (outside any function).
Local Variable — Created inside a function. Only exists during that call. Born when the function starts, dies when it ends.
Global Variable — Defined outside any function. Visible everywhere — but use sparingly.
↑ Back to top

🐛 Lesson 4 · Debugging Like a Pro

Lesson 4 · Debugging Like a Pro

Lesson Plan

At-a-Glance

Objective
Students will identify the three kinds of bugs (syntax, runtime, logic), read a Python traceback to find the actual scene of the crime, apply the 4-step debugging strategy (Reproduce → Read → Hypothesize → Fix & Verify), use print-debugging strategically, and use the binary-search trick to isolate which function contains a bug.
Time
50 minutes
Materials
Computer, CodeSkills Lab, projector, whiteboard, optional printed traceback dissection worksheet
Vocabulary
Syntax Error, Runtime Error, Logic Error, Traceback, 4-Step Debugging
FL Standards
01.01, 01.02, 06.03, 07.07
Exam Obj.
Objectives 2, 4, 7 (primary)

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

1. "Read the traceback top-down."
What you'll see: Students start at the top of a multi-line traceback and get overwhelmed by file names and line numbers they don't recognize.
How to address: Drill the rule: read bottom-up. The last line is the error TYPE and MESSAGE — read this FIRST. Then look at the last "File" line above it — that's where the bug actually happened. Everything between is just the call chain that got Python there.
2. "Logic errors aren't really errors."
What you'll see: Students think "no error message = working code." They submit programs that compute the wrong average, the wrong total, the wrong winner — but Python didn't complain.
How to address: Logic errors are the WORST kind of bug because they're invisible. The code is "happy" but the answer is wrong. The fix: ALWAYS test with values where you know the answer. average([10, 20]) should be 15. If your code gives 30, that's a logic error — even though Python didn't crash.
3. "Change five things and see what works."
What you'll see: Students panic-edit. They change a variable name, an operator, an indent, an argument — all at once. Bug goes away. They have no idea which change fixed it.
How to address: The golden rule: ONE change at a time. After each change, run again. If the bug persists, undo that change BEFORE trying another. This discipline feels slow at first but is the fastest debugging method ever invented. Use the analogy of fixing a recipe: change one ingredient at a time and taste — don't change five and hope.
4. "Leave debug prints in production."
What you'll see: A student fixes a bug using debug prints, then submits the code with all the DEBUG lines still in.
How to address: Debug prints are scaffolding. Remove them before submitting. The "DEBUG:" prefix exists exactly so you can find and delete them all (Find & Replace "DEBUG"). Submitting code with DEBUG prints is like leaving the construction tape up after the building is done.
5. "If it works for my input, ship it."
What you'll see: A student tests with their own happy-path input, sees it works, declares victory.
How to address: Real testing means trying edge cases — empty input, negative numbers, very long strings, weird characters. The "happy path" is the easiest case. The bugs hide in the cases the developer didn't think to try. Preview Lesson 5's testing stage.

🎯 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

Syntax Error — Bug type 1: violates Python's grammar. Won't run at all.
Runtime Error — Bug type 2: starts running but crashes. Python tried something it couldn't do.
Logic Error — Bug type 3: runs but gives the wrong answer. Sneakiest.
Traceback — The multi-line error message Python prints when something crashes. Read bottom-up.
4-Step Debugging — Reproduce → Read → Hypothesize → Fix & Verify. Change ONE thing at a time.
Print-Debugging — Adding strategic print() statements to make the invisible visible.
↑ Back to top

🔄 Lesson 5 · SDLC + Mad Libs 4.0 — Modular Capstone

Lesson 5 · SDLC + Mad Libs 4.0

Project Plan

At-a-Glance

Objective
Students will explain the five SDLC stages (Plan, Code, Test, Fix, Maintain), then apply every stage to build Mad Libs 4.0 — a fully modular game with at least 3 well-named functions, parameters, return values, clean PEP 8 style, docstrings, and full SDLC documentation.
Time
Two class periods (60–90 minutes total)
Materials
Computer, CodeSkills Lab, projector, paper for SDLC plan stage
Vocabulary
SDLC, Plan, Code, Test, Fix, Maintain, Modular Code, plus all prior Unit 4 vocabulary
FL Standards
01.01, 01.02, 02.02, 05.06, 05.07, 06.03, 07.01, 07.02, 07.05, 07.07
Exam Obj.
Objectives 1, 3, 4 (primary), 7 — comprehensive Unit 1–4 application
⚠️ The biggest project of the year so far. Mad Libs 4.0 integrates EVERY skill from Units 1–4: variables, conditionals, loops, lists, functions, parameters, return values, scope, debugging, and the SDLC. It's the unit's culminating performance task. Don't compress it. The 2-day pacing exists because the project genuinely needs both days — Day 1 for Plan + Code; Day 2 for Test + Fix + Maintain + Showcase.

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 them
    • tell_story(words) — takes the words, returns a story string
    • show_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

1. The "one giant function" submission.
What you'll see: A student writes def main(): ... with 60 lines inside. Technically a function, but it does everything — defeating the lesson.
How to address: The rubric requires AT LEAST 3 functions, each doing ONE clear job. Push the student back to their Stage 1 plan: what were the 3 jobs they identified? Each one is a function. Refactor by cutting the giant function at logical boundaries.
2. The "print instead of return" bug.
What you'll see: get_words() uses print(words) instead of return words. Then tell_story() can't use the words because they were never returned.
How to address: The classic Lesson 3 carryover. Functions that produce values must 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()).
3. The "global variable shortcut" bug.
What you'll see: A student defines words = [] at module level, has each function modify it as a global. Avoids parameters and returns entirely.
How to address: This works but defeats the lesson — the entire point of functions is parameters & returns, not shared globals. The rubric explicitly mentions "no relying on globals where parameters belong." Refactor: pass the data through parameters and returns. This is the discipline the unit exists to build.
4. "Ship it as soon as my happy-path test passes."
What you'll see: A student tests with their own well-formed inputs, sees it works, declares done. Skips Stage 3 entirely.
How to address: Stage 3 testing is a rubric requirement (15 of 100 pts). Show the test cases worksheet. Try empty input. Try very long input. Try numbers when strings are expected. The bugs are in the cases the author didn't think of — that's why peer testing matters.
5. Skipping the docstring + maintenance step.
What you'll see: A student finishes coding, runs it once, submits without docstrings, version notes, or final styling.
How to address: Stage 5 (Maintain) is 15 rubric points. Add: header comment, function docstrings, version notes at bottom. Frame it as the difference between "homework" and "professional code." This is the polish that turns a B project into an A project.

🎯 Differentiation

For students who finish early
Direct them to the stretch goals from the lesson: random story selection (4th function pick_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.

CategoryWhat to look forPts
Modular FunctionsAt least 3 well-named functions, each doing ONE clear job (collect, build, display).25
Parameters & ReturnsFunctions accept inputs and use return. No relying on globals where parameters belong.20
Clean Code Stylesnake_case names, 4-space indent, spaces around operators, blank lines between functions.15
Comments & DocstringsHeader comment block, function docstrings, "why" comments where useful.10
SDLC DocumentationPlan comments at the top + test case worksheet at the bottom.15
Works CorrectlyProgram runs without errors and produces a coherent story for normal inputs.15
TOTAL100

🎁 Stretch Goals (extra credit)

  • Multiple stories — 4th function pick_template() using import random: +5 pts
  • Play again — wrap the whole flow in a while loop 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.

💡 Showcase tip. The Day-2 showcase serves a different purpose than prior units' showcases. In addition to running their Mad Libs 4.0, ask 1–2 students to also project their CODE briefly. Different students will have organized the 3 functions differently — different parameter choices, different naming, different return values. Show the class that the SAME problem can have multiple valid modular solutions. Standard 05.06 (recognize multiple algorithms) made visible.

📖 Lesson-Specific Vocabulary

SDLC (Software Development Lifecycle) — The 5-stage cycle every real software project follows: Plan → Code → Test → Fix → Maintain.
Plan stage — Decide what to build BEFORE coding. Comments at the top of your file.
Code stage — Implement the plan. Use functions. Apply clean code rules.
Test stage — Try edge cases that might break the program. Empty input, special characters, weird types.
Fix stage — Apply the 4-step debugging strategy to each bug found in testing. ONE change at a time.
Maintain stage — Polish for the long term. Docstrings, version notes, clear file naming. The phase real software spends most of its life in.
Modular Code — Code organized into small, named pieces (functions) — each doing one job.
↑ Back to top

🛠️ 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.

ERRORTypeError: greet() takes 1 positional argument but 2 were given

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.

ERRORTypeError: greet() missing 1 required positional argument: 'name'

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).

ERRORNameError: name 'x' is not defined

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.

ERRORUnboundLocalError: local variable 'count' referenced before 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.

SILENT(function returns None instead of expected value)

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.

ERRORZeroDivisionError: division by zero

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.

ERRORIndentationError (in function body)

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.

SILENT(function defined but never called)

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.

CARRYOVERCarryover errors from Units 1–3

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 to int()-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 — referencing words[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.
🛟 The 4-step debugging strategy applies to every error above. (1) Reproduce the bug — make sure you can trigger it. (2) Read the traceback bottom-up — error type and last "File" line tell you what and where. (3) Hypothesize what's wrong; verify with a 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.
📘 Companion document. A Unit 4 Answer Key with Knowledge Check answers and lab solutions can be authored separately on request. The Teacher's Guide + Answer Key are designed to be used together.

— End of Unit 4 Teacher's Guide —

↑ Back to top