Loops repeat code; functions organize repeated code into named, reusable blocks. Every ML codebase is structured as functions: forward(), compute_loss(), train_epoch(), evaluate().
Volume 02 treated functions mathematically—f(x) maps inputs to outputs. Python def is the same idea made concrete: parameters in, return value out, body encapsulated for testing and reuse.
Learning Objectives
By the end of this lesson, students should be able to:
- Define functions with
def, parameters, andreturn. - Distinguish parameters from arguments and positional from keyword arguments.
- Write functions that compute loss, metrics, and preprocessing steps.
- Use default parameter values for configurable hyperparameters.
- Understand scope: local vs global variables in function bodies.
- Apply docstrings to document AI utility functions.
Defining Functions
A function is a named block of code that runs when called, accepts parameters (inputs), and optionally returns a result. Functions eliminate duplication and create testable units—the building blocks of ML pipelines.
Parameters and Return Values
| Concept | Role | Example |
|---|---|---|
| Parameter | Variable in function definition | def train(lr, epochs) |
| Argument | Value passed at call site | train(0.001, 50) |
| Return | Output sent back to caller | return val_loss |
| Default | Fallback if arg omitted | def train(lr=1e-3) |
Functions in a Training Pipeline
Data Functions
load_dataset(path)normalize_features(X)train_val_split(data, ratio)- Pure input→output transforms
Training Functions
forward_pass(x, weights)compute_loss(pred, target)train_epoch(model, loader)- Side effects: update weights, log metrics
Scope and None Returns
Variables assigned inside a function are local—invisible outside unless returned. A function without return implicitly returns None.
Local scope applies to names assigned inside a function. Global scope applies to module-level names. Functions should prefer returning values over mutating globals—essential for reproducible experiments.
Docstrings and Engineering Hygiene
A docstring (triple-quoted string as the first statement) documents purpose, parameters, and return values. In AI teams, clear function contracts reduce integration errors between data, training, and evaluation code.
Common Misconceptions
Why people believe it: Math functions always map to an output.
Reality: Functions like log_metrics() may return None intentionally after writing to a file. Callers should know which functions produce values vs side effects.
Why people believe it: Defaults look like constants.
Reality: def f(history=[]) shares one list across calls. Use history=None and create a new list inside the function.
Why people believe it: Configurability feels professional.
Reality: Functions with 10+ parameters are hard to test. Group related settings into dictionaries or config objects (covered later in this volume).
Quick Knowledge Check
- Short Answer: Keyword to define a function? Answer: def.
- True/False: A function without return gives None. Answer: True.
- Multiple Choice:
train(lr=0.01)uses: (a) positional only, (b) keyword argument, (c) global variable, (d) import. Answer: (b). - Short Answer: Difference between parameter and argument? Answer: Parameter is in definition; argument is value passed at call.
- True/False: Local variables inside a function are accessible outside it. Answer: False.
- Short Answer: Why document functions with docstrings? Answer: Clarify purpose, inputs, outputs for teammates and tools.
- Multiple Choice: Best return type for multiple metrics: (a) print only, (b) dict, (c) global vars, (d) None always. Answer: (b).
- True/False: Default parameters can make hyperparameters optional. Answer: True.
- Short Answer: Write a function signature for accuracy with predictions and labels. Answer: def accuracy(predictions, labels):
- Multiple Choice: Mutable default argument pitfall affects: (a) ints, (b) floats, (c) lists/dicts, (d) None. Answer: (c).
Key Takeaways
- Define functions with
def; return values withreturn. - Parameters define the interface; arguments supply values at call time.
- Default parameters configure hyperparameters with sensible fallbacks.
- Structure ML code as small, testable functions: loss, metrics, train, evaluate.
- Prefer returning results over mutating global state.
- Next: Lists as the workhorse sequence type for batches and records.
Hands-on idea: Refactor a monolithic training script into compute_loss, train_epoch, and evaluate functions.
Debugging exercise: Demonstrate the mutable default argument bug with a shared history=[] list.
Discussion prompt: Which functions in a pipeline should be pure (no side effects) vs impure (write logs, save checkpoints)?