A Python function groups a block of code under a name so you can call it as many times as needed without repeating the code. Writing a well-structured function — with parameters, a clear purpose, and a return value — is one of the core skills examiners look for at GCSE.

What is the anatomy of a Python function?

Every Python function has four key parts:

  1. The def keyword — signals the start of a function definition.
  2. The function name — follows Python's naming rules (lowercase, underscores for spaces, no spaces).
  3. The parameter list — inside parentheses; can be empty () or contain one or more parameters.
  4. The body — indented code that runs when the function is called.
  5. An optional return statement — sends a value back to the caller.
def greet(name):           # def keyword, function name, parameter
    message = "Hello, " + name + "!"  # body
    return message         # return value

Step 1 — Write the def line

The def line must end with a colon. The function name should describe what the function does:

def calculate_area(width, height):
  • calculate_area is the name.
  • width and height are parameters — placeholders for values that will be supplied when the function is called.
  • Common mistake: writing def calculate_area(width, height) without the colon — Python raises a SyntaxError.

Step 2 — Write the indented body

Everything inside the function must be indented by the same amount (4 spaces is the Python convention). The body runs only when the function is called:

def calculate_area(width, height):
    area = width * height
    return area

The body can contain any Python code: variables, IF statements, loops, calls to other functions. Keep the body focused — a good function does exactly one thing.

Step 3 — Add a return statement

The return statement sends a value back to wherever the function was called from. Without return, the function implicitly returns None:

def square(number):
    result = number ** 2
    return result          # sends the squared value back

answer = square(7)         # answer receives the return value: 49
print(answer)              # 49

A function can return any data type — an integer, string, list, or even another function. It can also return multiple values as a tuple: return x, y.

Step 4 — Call the function with arguments

Arguments are the actual values you pass in when calling the function. They are assigned to the parameters in order:

def calculate_area(width, height):
    return width * height

# Call the function with arguments 5 and 3
area = calculate_area(5, 3)   # width=5, height=3
print(area)                   # 15

# Call it again with different values — no code duplication
area2 = calculate_area(10, 4)
print(area2)                  # 40

Reusing the same function with different arguments is the main benefit of functions — write the logic once, use it many times.

Step 5 — Test the function in isolation

Before integrating a function into a larger program, test it with several inputs including boundary and erroneous cases:

def classify_bmi(bmi):
    if bmi < 18.5:
        return "Underweight"
    elif bmi < 25:
        return "Normal"
    elif bmi < 30:
        return "Overweight"
    else:
        return "Obese"

# Test with normal, boundary, and edge cases
print(classify_bmi(22.0))    # Normal
print(classify_bmi(18.5))    # Normal (boundary — 18.5 is NOT < 18.5)
print(classify_bmi(18.4))    # Underweight
print(classify_bmi(30.0))    # Obese

Working through boundary values confirms your < vs <= conditions are correct before the function is used elsewhere.

What are common mistakes to avoid?

Mistake Why it is wrong Fix
Missing colon on def line SyntaxError def my_func():
Wrong indentation in body IndentationError or logic error Use 4 consistent spaces
Printing instead of returning Caller gets None, not the value Use return, not print()
Calling function before defining it NameError Define functions above the code that calls them
Forgetting to assign the return value The returned value is lost result = my_func()

The printing-vs-returning confusion is the most common GCSE mistake. print(square(5)) and def square(n): print(n**2) look similar but behave very differently — the first uses return and lets the caller decide what to do with the value; the second forces an immediate print and makes the function useless in any computation.

Frequently asked questions

What is the difference between a parameter and an argument?

A parameter is the variable name in the function definition: def greet(name) — here name is a parameter. An argument is the actual value passed in when the function is called: greet("Amara") — here "Amara" is an argument. The argument is assigned to the parameter when the function runs. This distinction is tested in GCSE written papers.

Can a Python function have no parameters?

Yes. A function that performs the same action every time it is called needs no parameters: def display_menu(): simply prints a menu. Calling it is just display_menu() with empty parentheses. The parentheses must still be there — display_menu (without parentheses) refers to the function object itself rather than calling it.

What happens if I call a function with the wrong number of arguments?

Python raises a TypeError immediately. For example, calculate_area(5) when the function expects two parameters gives TypeError: calculate_area() missing 1 required positional argument: 'height'. This is caught at runtime, not at definition time — another reason to test every function before integrating it.

Should functions be placed at the top or bottom of a Python file?

Definitions must appear before the line that calls them. The standard Python convention is to define all functions near the top of the file (after any imports), then put the main program logic at the bottom — often wrapped in if __name__ == "__main__":. At GCSE, placing function definitions above the main code is sufficient and expected.


Write your first correctly structured Python functions with step-by-step coaching from Professor Turing at aitutors.me.