Python 3.14 Β·
β verified by execution on 2026-07-22
As your programs grow, youβll find yourself writing the same steps again and again. A function lets you name a block of code once and then run it whenever you like, just by calling its name. You define one with the def keyword:
python
def say_hello(): print('Hello World')say_hello()
Output
Hello World
Your output
Passing Arguments
Functions become far more useful when you feed them data. The values you pass in are called arguments; inside the function they become parameters you can use by name.
Printing shows a value on screen; returning hands it back to the caller so the rest of your program can use it. The return statement does exactly that.
python
def add(a, b): return a + bresult = add(5, 3)print(result)
Output
8
Your output
Local Variables
The execution of a function introduces a new symbol table used for the local variables.
python
def scope_test(): x = 10 print(x)scope_test()
Output
10
Your output
Common Misconceptions
A function executes its code as soon as it is defined.
Defining a function only creates it. The code inside does not run until the function is called.
Variables created inside a function can be accessed outside of it.
Variables defined inside a function are local to that function and disappear when the function finishes.
A function must always have a return statement.
If a function doesnβt have a return statement, it implicitly returns None.
Edge Cases
Functions can be defined to take zero arguments, requiring empty parentheses () both when defining and calling.
Calling a function without parentheses passes the function object itself, rather than executing it.
Under the Hood
Watch how function calls, arguments, and local variables are managed in memory:
python Β· visualize
def square(num): result = num * num return resultval = square(4)
Check yourself
What keyword is used to define a function in Python?
Reveal answer
def β The def keyword is used to introduce a function definition.
If a function does not have a return statement, what does it return?
Reveal answer
None β If a function doesn't have a return statement, it implicitly returns None.
Where are variables that are assigned inside a function stored?
Reveal answer
In a local symbol table β Variables assigned inside a function are local to that function's execution.
Challenges
Challenge 1 +50 XP
Write a function called `multiply` that takes two parameters, multiplies them together, and returns the result. Then call it with 4 and 5 and print the result.
python
Test 1 β expects "20\n"
Need a hint? (β25% XP)
Use the def keyword, and remember to return a * b.
Show solution (0 XP)
def multiply(a, b): return a * bprint(multiply(4, 5))
Challenge 2 +100 XP
Create a function `say_goodbye` that takes a `name` parameter and prints 'Goodbye ' followed by the name. Call it with 'Bob'.
python
Test 1 β expects "Goodbye Bob\n"
Need a hint? (β25% XP)
Use an f-string to easily insert the name parameter into the printed string.
The Same Seven Numbers, Two Trees: Why Insert Order Decides Lookup Cost β Insert seven numbers into a binary search tree in sorted order and you get a seven-level chain. Insert the same seven in a different order and you get three levels. Build both here, and watch what the shape costs on every lookup afterwards.
A Rotation Is Just Re-Hanging Three Subtrees, and the Order Never Changes β Self-balancing trees are usually taught as four case names before anyone says what a rotation does. Insert the same values with rebalancing on and off here, and watch a tree that would be seven levels deep stay at three.
Why Databases Use B-Trees: Fewer Levels Beats Fewer Comparisons β A balanced binary tree of a billion keys is thirty levels deep. If every level is a disk read, that is thirty reads for one lookup. Drag the branching factor here and watch the same keys collapse from a tall thin tree into a short wide one.
A Heap Is a Tree You Can Store in a Flat Array β Heaps are taught as trees and implemented as arrays, and the join between the two is usually three index formulas nobody explains. Watch a value sift up and down here, moving in the tree and the array at the same time, one swap per click.
In a Trie, Lookup Cost Depends on the Word, Not on How Many Words β A trie stores words letter by letter, sharing every common prefix. Walk one here by clicking letters, and watch the reachable set shrink - that walk is exactly what an autocomplete box does while you type.
Breadth-First and Depth-First Are the Same Loop, One Line Apart β BFS and DFS get taught as two algorithms because one is usually written with a queue and the other with recursion. Run both here from one shared loop, changing only which end of the frontier the next node comes from, and watch the paths diverge.
Union-Find Has Two Optimisations Because It Has Two Different Failures β Union by size and path compression are usually presented as one improvement after another. They rescue unrelated cases - and each is useless against the other's. Toggle them independently here and watch which merge order defeats which.
Trim or Summarise: The Cheap Fix That Makes Your Agent Forget Why It Is Here β An agent's context grows until something stops it, and there are two ways to stop it. On the same schedule they cost within 60 tokens of each other, and one of them ends the run having lost every fact the job depended on. Run twenty turns here and choose.
What to Hand an AI and What to Keep: It Is Not About Difficulty β Delegating everything to an AI and checking it saves barely 13% of a working day. Choosing task by task saves 28%. Run ten jobs here and find the axis that decides - not how hard the work is, but how long it takes to check somebody else's answer.
Find the Wasted Calls: the Skill Behind Every Memoisation β Memoisation is easy to explain and hard to apply, because the difficult part is noticing that a subproblem repeats at all. Here the recursion tree is drawn and you have to find the repeats yourself, scored, with wrong clicks counted.