Addaly is in open beta. Things will change, and AI answers can be wrong — check anything that matters.

Functions, and the difference between printing and returning

Python, From Zero, For AI · lesson 6 of 10 · 7 min

Naming a piece of work

A function is a chunk of instructions with a name, so you can run it whenever you like without writing it out again.

python
def word_count(text):
    return len(text.split())

print(word_count("the rain in spain"))   # 4
print(word_count("hello"))               # 1

def starts a definition. word_count is the name. text is a parameter: a name that will be attached to whatever you pass in. The indented block is the body.

Defining a function does not run it. Python reads the def, remembers it, and moves on. The body only runs when you call it, with brackets: word_count("hello").

return hands a value back

python
def area(width, height):
    return width * height

space = area(3, 4)
print(space)          # 12
print(area(2, 5) + area(1, 1))   # 11

return does two things: it sends a value back to whoever called the function, and it ends the function immediately. Anything after a return that runs is never reached.

Because the call turns into a value, you can use it anywhere a value fits: store it, add it, pass it to another function.

print and return are not the same thing

This is the single biggest confusion at this stage, and it is worth being blunt about.

print puts characters on a screen for a human. return hands a value back to the rest of the program. They look the same when you are testing at the terminal, because in both cases you see 12 appear. They are completely different when the value has to be used.

python
def double_printed(n):
    print(n * 2)

def double_returned(n):
    return n * 2

a = double_printed(21)    # prints 42
b = double_returned(21)   # prints nothing

print(a)     # None
print(b)     # 42

A function with no return still gives something back: None, Python's word for "no value". So a is None, and a + 1 fails with TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'. When you see NoneType in an error, the usual cause is a function that printed instead of returning.

Rule of thumb: functions should return. Print at the outer edge of your program, where you are actually talking to a person.

Default values

python
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}"

print(greet("Ivan"))                   # Hello, Ivan
print(greet("Ivan", "Good morning"))   # Good morning, Ivan
print(greet(name="Fatima"))            # Hello, Fatima

A parameter with a default becomes optional. You can also pass arguments by name, which makes calls with several options readable.

Names inside stay inside

python
def tax_on(amount):
    rate = 0.18
    return amount * rate

print(tax_on(1000))   # 180.0
print(rate)
NameError: name 'rate' is not defined

rate lives only while tax_on is running. This is a feature. It means you can write a function without worrying about which names the rest of the program has already used.

A function you will reuse later

python
def build_messages(question, history=None):
    messages = list(history or [])
    messages.append({"role": "user", "content": question})
    return messages

convo = build_messages("Explain gravity in one sentence.")
convo = build_messages("Now in Hindi.", convo)
print(len(convo))            # 2
print(convo[1]["content"])   # Now in Hindi.

That is the exact structure lesson ten sends to an AI API, built by a function you wrote.

Try this now

Write average(numbers) that returns the mean of a list, and make it return 0 when the list is empty rather than crashing. Then call it and print the result from outside.

Before you move on

A file defines `def double(n):` whose only body line is `print(n * 2)`. Then it runs `result = double(21)` and `print(result + 1)`. What happens?

Pick the one you would defend. Nobody sees your answer.

No ads. No data sale. No public scores on people. Ever.

© 2026 Addaly