7. Writing Function

7.1. Function Definition

How to write a function?

A function is defined using the def keyword:

The following is a simple function that prints “Hello, World!”.

# Function definition
def say_hello():
    print('Hello, World!')
# Function invocation
say_hello()
Hello, World!

To make a function more powerful and solve different problems,
we can

  • use a return statement to return a value that

  • depends on some input arguments.

def increment(x):
    return x + 1


increment(3)
4

We can also have multiple input arguments.

def length_of_hypotenuse(a, b):
    if a >= 0 and b >= 0:
        return (a**2 + b**2)**0.5
    else:
        print('Input arguments must be non-negative.')
length_of_hypotenuse(3, 4)
5.0
length_of_hypotenuse(-3, 4)
Input arguments must be non-negative.

7.2. Documentation

How to document a function?

# Author: John Doe
# Last modified: 2020-09-14
def increment(x):
    '''The function takes in a value x and returns the increment x + 1.
    
    It is a simple example that demonstrates the idea of
    - parameter passing, 
    - return statement, and 
    - function documentation.'''
    return x + 1  # + operation is used and may fail for 'str'

The help command shows the docstring we write

  • at beginning of the function body

  • delimited using triple single/double quotes.

help(increment)
Help on function increment in module __main__:

increment(x)
    The function takes in a value x and returns the increment x + 1.
    
    It is a simple example that demonstrates the idea of
    - parameter passing, 
    - return statement, and 
    - function documentation.

The docstring should contain the usage guide, i.e., information for new users to call the function properly.
There is a Python style guide (PEP 257) for

Why doesn’t help show the comments that start with #?

# Author: John Doe
# Last modified: 2020-09-14
def increment(x):
    ...
    return x + 1  # + operation is used and may fail for 'str'

Those comments are not usage guide. They are intended for programmers who need to maintain/extend the function definition.

  • Information about the author and modification date facilitate communications among programmers.

  • Comments within the code help explain important and not-so-obvious implementation details.

How to let user know the data types of input arguments and return value?

We can annotate the function with hints of the types of the arguments and return value.

# Author: John Doe
# Last modified: 2020-09-14
def increment(x: float) -> float:
    '''The function takes in a value x and returns the increment x + 1.
    
    It is a simple example that demonstrates the idea of
    - parameter passing, 
    - return statement, and 
    - function documentation.'''
    return x + 1  # + operation is used and may fail for 'str'


help(increment)
Help on function increment in module __main__:

increment(x: float) -> float
    The function takes in a value x and returns the increment x + 1.
    
    It is a simple example that demonstrates the idea of
    - parameter passing, 
    - return statement, and 
    - function documentation.

The above annotations is not enforced by the Python interpreter.
Nevertheless, such annotations make the code easier to understand and can be used by editor with type-checking tools.

def increment_user_input():
    return increment(input())  # does not raise error even though input returns str
increment_user_input()  # still lead to runtime error

7.3. Parameter Passing

Can we increment a variable instead of returning its increment?

def increment(x):
    x += 1
x = 3
increment(x)
print(x)  # 4?
3

Does the above code increment x?

%%mytutor -h 350
def increment(x):
    x += 1


x = 3
increment(x)
print(x)
  • Step 3: The function increment is invoked with the argument evaluated to the value of x.

  • Step 3-4: A local frame is created for variables local to increment during its execution.

    • The formal parameter x in def increment(x): becomes a local variable and

    • it is assigned the value 3 of the actual parameter given by the global variable x.

  • Step 5-6: The local (but not the global) variable x is incremented.

  • Step 6-7: The function call completes and the local frame is removed.