Phase 1: Programming Fundamentals I · ~40 minutes · Python · uv
Functions — Abstraction and Reuse
A function that print()s its answer looks like it works right up until something tries to use that answer — and gets None.
Hiring signal: Immediately recognizes a None-related TypeError as a missing return, not a mysterious failure
What you will learn
- Explain why wrapping code in a function is different from just running the same code inline
- Distinguish return from print, and explain why a function that only prints silently breaks anything that uses its result
- Use parameters, arguments, and default argument values correctly
- Explain local vs. global scope well enough to predict what a function can and can't affect outside itself
Introduction
Type: Learn Languages: Python Prerequisites: Lesson 03 (Control Flow — Loops) Time: ~40 minutes
Objective
Learning objectives
- Explain why wrapping code in a function is different from just running the same code inline
- Distinguish
return from print, and explain why a function that only prints silently breaks anything that uses its result - Use parameters, arguments, and default argument values correctly
- Explain local vs. global scope well enough to predict what a function can and can't affect outside itself
What you're building
Take this (deliberately repeated) block, copy-pasted three times with only the numbers changed:
quantity = 3
price = quantity * 4.50
tax = price * 0.08
total = price + tax
print(f"Total: ${total:.2f}")
quantity = 7
price = quantity * 4.50
tax = price * 0.08
total = price + tax
print(f"Total: ${total:.2f}")
quantity = 12
price = quantity * 4.50
tax = price * 0.08
total = price + tax
print(f"Total: ${total:.2f}")
A script (refactor_totals.py) that:
- Refactors this into one function,
calculate_total(quantity, price_per_item=4.50, tax_rate=0.08), using return (not print) for the computed total - Calls it three times with the original quantities (3, 7, 12) and prints each result at the call site, not inside the function
- Contains a comment showing the broken print-only version of the function and a one-sentence diagnosis of exactly what error calling it inside an expression would produce
A function is defined as:
def make_username(first_name, last_name, separator="."):
return f"{first_name}{separator}{last_name}".lower()
What does make_username("Ada", "Lovelace") return?
separator has a default value ("."), so omitting it is completely valid — it isn't an error, and this is precisely what default arguments are for. The function does have a return statement, so the "no explicit print" answer describes a different bug from Lesson 01-04's actual example, not this one — return (not print) is exactly the correct way to hand a value back, so this function is not broken. Tracing the actual computation: f"{first_name}{separator}{last_name}" produces "Ada.Lovelace", and .lower() converts every letter to lowercase, giving "ada.lovelace".
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers The Problem, Check Yourself, Key Terms & Next — plus a hands-on lab, quiz, and project artifact.
Create a free account to unlock Phase 0 and Phase 1 of every course — no credit card.
Browse all courses · View pricing · DeVenture Academy