Key Takeaways: Functions — Writing Reusable Code
One-Sentence Summary
Functions let you name a chunk of behavior, define its inputs and outputs, and reuse it without thinking about its internals — this is abstraction, the single most important concept in computer science.
Function Anatomy
def function_name(param1, param2="default"): # Definition
"""One-line description of what this function does."""
# body — the code that runs when called
return result # Output
value = function_name(arg1, arg2) # Call
Key Distinctions
| Concept | Meaning |
|---|---|
| Parameter | Variable name in the function definition (a placeholder) |
| Argument | Actual value passed when calling the function |
def |
Defines the function (doesn't execute it) |
| Calling | Executes the function (uses parentheses) |
| Local variable | Exists only inside the function that creates it |
| Global variable | Exists at the module level, accessible everywhere (for reading) |
Return vs. Print
return |
print() |
|
|---|---|---|
| Sends data to | The calling code | The screen |
| Can be stored in a variable | Yes | No (returns None) |
| Can be used in calculations | Yes | No |
| Use when | Computing a result | Displaying output to the user |
Parameter Types
| Type | Example | When to Use |
|---|---|---|
| Positional | greet("Alice") |
Simple functions with few parameters |
| Keyword | greet(name="Alice") |
Clarity when calling functions with many parameters |
| Default | def greet(name, greeting="Hello"): |
Providing sensible fallbacks |
*args |
def average(*scores): |
Accepting any number of arguments |
Scope (LEGB Rule)
Python looks up variables in this order:
1. Local — inside the current function
2. Enclosing — inside enclosing functions (nested functions)
3. Global — at the module level
4. Built-in — Python's built-in names (print, len, etc.)
Critical rule: Assigning to a variable inside a function makes it local. If you need to read a global, that works. If you need to modify a global, pass it as a parameter and return the new value — don't use global.
Function Design Checklist
- [ ] Does the function have a clear, descriptive name (verb + noun)?
- [ ] Does it do exactly one thing (single responsibility)?
- [ ] Does it return its result rather than printing it (when computing)?
- [ ] Does it have a docstring explaining what it does?
- [ ] Are its parameter names descriptive?
- [ ] Does it avoid mutable default arguments?
- [ ] Can it be tested independently?
The Three Most Common Bugs
- Forgetting
return— function prints instead of returning, caller getsNone - Mutable default argument —
def f(items=[])shares the list across calls; useNoneinstead - Scope confusion — assigning to a name inside a function creates a local, potentially shadowing a global
Threshold Concept: Abstraction Through Functions
- Before: "I write one big block of code that does everything."
- After: "I build programs from small, reusable, well-named pieces."
This shift in thinking is the most important takeaway from this chapter. Abstraction through functions is the foundation that everything in the rest of this course builds on — data structures, modules, classes, APIs, and testing all rely on the idea that you can hide complexity behind a meaningful name.
What's Next
Chapter 7: Strings — text processing with indexing, slicing, and string methods. TaskFlow v0.6 adds keyword search, using the function-based architecture you built in this chapter.