Chapter 3 · Junior Developer

Functions: def and return

A function is a named, reusable block of code. You define one with def name(params): and an indented body; you run it later by *calling* it — name(args). Defining a function doesn't run it; calling it does.

The single most important early distinction: return vs print. return sends a value *back to the caller* so the rest of your program can use it — store it, do maths on it, pass it on. print just shows text on the screen for a human; it gives nothing back.

A function that only prints returns None (Python's "nothing" value). So x = greet("Sam") where greet only prints leaves x as None — the greeting flashed on screen but was never handed back. If you want to *use* the result, the function must return it.

A return also ends the function immediately — any lines after the one that runs are skipped. A function can have several returns (one per branch); the first one reached wins.

Syntax

def function_name(param1, param2):
    # body
    return value      # hand a value back to the caller

result = function_name(1, 2)   # call it, capture what it returns

# return ends the function; code after the reached return is skipped

Worked examples

return hands the value back; print only shows it

def discounted(price, pct):
    return price - price * pct / 100

print(discounted(100, 10))   # 90.0
print(discounted(200, 25))   # 150.0

A print-only function returns None

def greet(name):
    print(f"Hi {name}")   # shows it, returns nothing

x = greet("Sam")
# Output:
# Hi Sam
print(x)   # None  — nothing was returned to capture

Multiple returns — the first one reached wins

def classify(n):
    if n > 0:
        return "positive"
    if n < 0:
        return "negative"
    return "zero"

print(classify(5), classify(-2), classify(0))
# Output:
# positive negative zero

Common mistakes & gotchas

Printing when you meant to return

The classic early bug. A function that print()s its answer can't be reused — you can't add up or combine values that were only printed. If another piece of code needs the result, return it. Print is for humans; return is for the program.

Forgetting to call the function

def discounted(...) only *defines* the function — it doesn't run. You have to call it with brackets: discounted(100, 10). Writing discounted on its own (no brackets) just refers to the function object and does nothing useful.

Code after return never runs

return exits the function on the spot. Anything below the return that actually executes is dead code. If you meant to do more before returning, move it above the return.

Why it matters

Functions are how you stop repeating yourself and start naming ideas. Almost all real code lives inside functions, and the return value is how those functions connect — one function's output becomes the next one's input. Getting return-vs-print right is the line between a throwaway script and code you can build on.