Skip to content

Defining and calling functions

~20 min ยท prerequisite: Reading error messages, and the Part 3 lessons on strings, lists, and dictionaries

What you will be able to do

  • Define a function with def, give it parameters, and call it.
  • Send a result back to the caller with return, and store that result in a variable.
  • Give a parameter a default value, and pass an argument by its name.

The idea

A function is a named block of code. You write it once, give it a name, and run it whenever you need it by calling it with parentheses. A function lets you name one step, such as "add tax to a price", and reuse that step instead of copying the same lines again and again.

Think of a recipe card. It has a name, it lists what you must hand over, and it says what you get back. A function works the same way.

You create a function with the keyword def, followed by the name, a pair of parentheses, and a colon. The lines that belong to the function are indented below the def line. Python does not run those lines when it reads the def. It runs them when someone calls the function.

The names inside the parentheses are parameters. They are placeholders that receive values. The values you pass in when you call the function are arguments. In square(4), the parameter is number in the definition, and 4 is the argument.

A function sends a value back with return. The return statement ends the function and gives the value to the place where the function was called. If a function has no return statement, the call gives back the special value None. The word None means that there is no value.

A parameter can have a default value, written with an equals sign in the definition, such as rate=0.2. If the caller leaves that argument out, Python uses the default. A caller can also pass an argument by its parameter name, such as rate=0.5. This is a keyword argument. Naming the argument makes the call easier to read.

Many functions begin with a short docstring, which is a string in triple quotes on the first line of the body. Python stores it with the function, and readers and tools use it to explain what the function does.

Worked example

def greet(name, punctuation="!"):
    """Return a greeting for one person."""
    return "Hello, " + name + punctuation


message = greet("Ada")
print(message)
print(greet("Grace", punctuation="?"))

Expected output:

Hello, Ada!
Hello, Grace?

Line by line, this is what Python does:

  1. def greet(name, punctuation="!"): creates a function named greet. It has two parameters, and punctuation has the default value "!". Nothing else runs yet.
  2. The docstring is stored with the function. It is not printed.
  3. return "Hello, " + name + punctuation joins three strings and sends the result back to the caller.
  4. message = greet("Ada") calls the function. name receives "Ada". No punctuation is given, so punctuation uses "!". The returned text is stored in message.
  5. print(message) shows Hello, Ada!.
  6. greet("Grace", punctuation="?") passes the second argument by name. The result is Hello, Grace?, and print shows it.

Try it

The first block squares numbers. The second block uses a default value and a keyword argument. The third block shows a function with no return.

def square(number):
    return number * number


assert square(4) == 16
assert square(-3) == 9
def add_tax(price, rate=0.2):
    return round(price * (1 + rate), 2)


assert add_tax(10) == 12.0
assert add_tax(10, rate=0.5) == 15.0
def add_item(items, item):
    items.append(item)


basket = []
assert add_item(basket, "apple") is None
assert basket == ["apple"]

Common mistakes

  1. Forgetting the colon after def. The following code has no colon at the end of the first line:

    def greet(name)
        return "Hello, " + name
    

    Python reports:

    SyntaxError: expected ':'
    

    Add : at the end of the def line.

  2. Forgetting to indent the body. The following code has a return line that is not indented:

    def greet(name):
    return "Hello, " + name
    

    Python reports:

    IndentationError: expected an indented block after function definition on line 1
    

    Indent the body by four spaces.

  3. Using a function that has no return. The following code adds 1 to the result of a call:

    def add_five(number):
        total = number + 5
    
    result = add_five(2) + 1
    

    Python reports:

    TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
    

    The function computed total but never returned it. Add return total at the end of the body.

  4. Leaving out a required argument. The following call passes nothing to greet:

    def greet(name):
        return "Hello, " + name
    
    greet()
    

    Python reports:

    TypeError: greet() missing 1 required positional argument: 'name'
    

    Pass the value the parameter needs, such as greet("Ada").

Practice

  1. Define double(number) that returns twice its argument. Assert that double(7) equals 14.
  2. Define full_name(first, last) that returns the two names joined by one space. Assert that full_name("Ada", "Lovelace") equals "Ada Lovelace".
  3. Define celsius_to_fahrenheit(celsius) that returns celsius * 9 / 5 + 32. Assert that 100 gives 212.0 and 0 gives 32.0.
  4. Define repeat_word(word, times=2) that returns word repeated times times. Assert that repeat_word("ha") equals "haha" and that repeat_word("ho", times=3) equals "hohoho".
  5. Stretch: define largest(numbers) that returns the largest number in a non-empty list, without calling max. Assert that largest([3, 9, 4]) equals 9 and that largest([-5, -2]) equals -2.
Solution
  1. ```python def double(number): return number * 2

assert double(7) == 14 ```

  1. ```python def full_name(first, last): return first + " " + last

assert full_name("Ada", "Lovelace") == "Ada Lovelace" ```

  1. ```python def celsius_to_fahrenheit(celsius): return celsius * 9 / 5 + 32

assert celsius_to_fahrenheit(100) == 212.0 assert celsius_to_fahrenheit(0) == 32.0 ```

  1. ```python def repeat_word(word, times=2): return word * times

assert repeat_word("ha") == "haha" assert repeat_word("ho", times=3) == "hohoho" ```

  1. ```python def largest(numbers): best = numbers[0] for number in numbers: if number > best: best = number return best

assert largest([3, 9, 4]) == 9 assert largest([-5, -2]) == -2 ```

Recap

  • def creates a function. Its body runs only when the function is called.
  • return sends a value back to the caller. A function without return gives back None.
  • Parameters can have default values, and any argument can be passed by its name.

Sources