Lesson 11 of 26 · about 16 min
Decomposition and abstraction
Big problems become easy when you split them into small, named helper functions. Each helper hides its details behind a clear name.
🧭 What you need first: Scope and the call stack
Nobody “plans a wedding.” It’s too big. You break it down: venue, food, guests, music. Then “food” breaks down further: choose a caterer, pick the menu, count dietary needs. Eventually every piece is small enough that someone can just do it.
That’s decomposition. And once someone has handled “music,” you stop thinking about the playlist details. You just know “music: done.” Hiding details behind a simple name is abstraction.
These two ideas are the most important skills in programming. Experts aren’t people who can juggle more details; they’re people who are good at not having to.
Another way: driving a car
You press the gas pedal. You don’t think about fuel injection, spark timing or gear ratios. The pedal is an abstraction: a simple control that hides a complicated system. A good function is a pedal.
Another way: IKEA instructions
IKEA instructions are decomposed into numbered steps, and each step uses a few named parts (“attach panel B”). Nobody gets a single page that says “build a wardrobe.”
Teach Bit new words
Bit only knows turn_left(). But you can define turn_around() and turn_right_slowly() in terms of it, and then Bit “knows” them too. Run this, then add your own helper.
Bit can: move() turn_left() turn_right() paint(color) front_is_clear() get_color()
The second paint_row repaints the same row yellow on the way back. Now the main part of the program is just three readable lines.
The real words
- Decomposition means breaking a problem into sub-problems, each solved by its own function. Work top-down: write the main plan first using functions that don’t exist yet, then write each one.
- Abstraction means using something by its name and its promise, without knowing how it works inside.
print()is an abstraction you’ve used since lesson 1. - A specification (usually the docstring) is a contract:
- What it does (not how).
- Pre-conditions: what must be true before calling it (“Bit is facing the row”).
- Post-conditions: what will be true afterward (“Bit ends at the wall, facing the same way”).
- Helper functions are small functions that do one job. A good rule: if you can’t name it clearly, it’s doing too much.
- DRY (Don’t Repeat Yourself): if you’ve copy-pasted code, it probably wants to be a function.
Paint a whole field
Paint all 15 squares blue. Use helper functions: paint_row() for one row, and a way to get down to the start of the next row. Bit starts top-left facing right.
Bit can: move() turn_left() turn_right() paint(color) front_is_clear() get_color()
Good names
Which function name is the best abstraction?
What should a function's docstring describe?
Got it?
Finish the lesson to color it in on your map and collect its concept cards.
Did this lesson click?