Create reusable functions with clear parameters, returned results, bounded scope, and testable behavior.
What you will be able to do
- Explain the five core programming decisions involved in functions and reuse.
- Choose a small code or command method that matches a stated input and output need.
- Interpret execution output and errors before changing broader system state.
- Apply an inspect, implement, test, verify, and recover workflow to a realistic automation task.
01
Build the Execution Model
Create reusable functions with clear parameters, returned results, bounded scope, and testable behavior.
Reliable automation separates input, representation, decision, action, output, and failure behavior. Before writing a longer script, state the exact starting data, the intended transformation, the observable result, and which state the program is permitted to change.
Use a disposable project and small deterministic samples. Run read-only inspection first, keep the interpreter or shell and working directory visible, and preserve the exact input with its output. A reproducible example is more useful than a large script whose state is unknown.
02
Function contract
A function contract states accepted input, returned output, side effects, and failure behavior. It is one distinct part of functions and reuse, so keep its input and output visible instead of hiding them inside a larger unexplained script.
Write the contract before implementation and test it with one normal input. Start with this small method: Call the function with a known input. Record the code, interpreter or shell version, working directory, sample input, and visible result together.
The safety boundary is clear: A function name alone does not describe side effects. The expected evidence is The function contract result matches the documented input and expected state. If the result differs, keep the failure and reduce the example before changing unrelated code or system state.
03
Parameters
Parameters give names and constraints to values supplied by a caller. It is one distinct part of functions and reuse, so keep its input and output visible instead of hiding them inside a larger unexplained script.
Use required parameters for essential input and validate values at the boundary. Start with this small method: Call with valid and invalid arguments. Record the code, interpreter or shell version, working directory, sample input, and visible result together.
The safety boundary is clear: A permissive default can conceal missing required input. The expected evidence is The parameters result matches the documented input and expected state. If the result differs, keep the failure and reduce the example before changing unrelated code or system state.
04
Return values
A return value carries a result back to the caller instead of printing it as a side effect. It is one distinct part of functions and reuse, so keep its input and output visible instead of hiding them inside a larger unexplained script.
Return structured data and let the caller decide how to display or store it. Start with this small method: Assign the return value and inspect it. Record the code, interpreter or shell version, working directory, sample input, and visible result together.
The safety boundary is clear: Printed text is harder to reuse than a returned value. The expected evidence is The return values result matches the documented input and expected state. If the result differs, keep the failure and reduce the example before changing unrelated code or system state.
05
Local scope
Local scope limits temporary names to the function invocation that owns them. It is one distinct part of functions and reuse, so keep its input and output visible instead of hiding them inside a larger unexplained script.
Keep intermediate state local and pass dependencies explicitly. Start with this small method: Compare a local name before and after the call. Record the code, interpreter or shell version, working directory, sample input, and visible result together.
The safety boundary is clear: Hidden global state makes tests order-dependent. The expected evidence is The local scope result matches the documented input and expected state. If the result differs, keep the failure and reduce the example before changing unrelated code or system state.
06
Reusable composition
Small functions can be composed when each one has a stable input and output boundary. It is one distinct part of functions and reuse, so keep its input and output visible instead of hiding them inside a larger unexplained script.
Connect functions through returned values and test each function independently. Start with this small method: Test each function before composing them. Record the code, interpreter or shell version, working directory, sample input, and visible result together.
The safety boundary is clear: Do not combine unrelated actions into one large function. The expected evidence is The reusable composition result matches the documented input and expected state. If the result differs, keep the failure and reduce the example before changing unrelated code or system state.
07
Implement One Small Behavior
Translate the requirement into one input-output example before implementation. Name the target and side effects explicitly, validate input at the program boundary, and keep secrets and environment-specific configuration outside source code and ordinary logs.
Add the smallest code that makes the example work. Inspect intermediate values as structured data, not only formatted display text. When an operation can modify files, accounts, services, remote systems, or API resources, build a preview or disposable test path first.
Handle the expected failure that belongs to the operation. Preserve its type, message, target, and timing, then return a meaningful result or nonzero exit. Do not catch errors the program cannot explain merely to make the run appear successful.
08
Test and Handoff the Automation
Test a normal input, one boundary input, and one safe failure. Compare actual output with the written expectation and verify any changed state through an independent read-only query. A zero exit code or successful request is only part of the evidence.
Make the run reproducible. Record runtime version, dependencies, parameters, configuration source, sample data, output shape, and cleanup or reversal procedure. Remove temporary credentials, test files, sessions, and permissions after verification.
A useful handoff explains what the program accepts, what it returns or changes, how it reports failure, and where execution must stop for review. Escalate when authorization, data ownership, target scope, vendor contract, or safe recovery remains uncertain.
09
Recap Before Practice and Prove
Start with function contract. Write the contract before implementation and test it with one normal input. Verify that the function contract result matches the documented input and expected state.
Keep parameters explicit. Use required parameters for essential input and validate values at the boundary. Respect this boundary: a permissive default can conceal missing required input..
Use return values as a separate decision. Return structured data and let the caller decide how to display or store it. Preserve the exact input and output.
Before expanding the script, review local scope. Keep intermediate state local and pass dependencies explicitly. Stop when hidden global state makes tests order-dependent..
Finish with reusable composition. Connect functions through returned values and test each function independently. Record the final result, failure behavior, cleanup, and reproducible next step.