Writing Function

Function Definition

How to write a function?

A function is defined using the def keyword.

E.g., a simple function that prints “Hello, World!” can be defined as follows:

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

To make a function more powerful and solve different problems,

  • 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.

Documentation

How to document a function?

# Author: John Doe
# Last modified: 2020-09-14
def increment(x):
    """Increment by 1.

    A simple demo 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 the beginning of the function body

  • delimited using triple single/double quotes.

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

increment(x)
    Increment by 1.
    
    A simple demo 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. See 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:
    """Increment by 1.

    A simple demo 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
    Increment by 1.
    
    A simple demo of
    - parameter passing,
    - return statement, and
    - function documentation.

Annotations make the code easier to understand and can be used by editor with type-checking tools. However, annotations are not enforced by the Python interpreter.

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

The types can also be described in the docstring following the Numpy or Google style.

# Author: John Doe
# Last modified: 2020-09-14
def increment(x: float) -> float:
    """Increment by 1.

    A simple demo of
    - parameter passing,
    - return statement, and
    - function documentation.

    Parameters
    ----------
    x: float
        Value to be incremented.

    Returns
    -------
    float:
        Value of x incremented by 1.
    """
    return x + 1  # + operation is used and may fail for 'str'


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

increment(x: float) -> float
    Increment by 1.
    
    A simple demo of
    - parameter passing,
    - return statement, and
    - function documentation.
    
    Parameters
    ----------
    x: float
        Value to be incremented.
    
    Returns
    -------
    float:
        Value of x incremented by 1.

There are tools such as sphinx to generate documentation in html format and compile the docstrings automatically into an API reference.

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 an argument 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.

In other languages such as C++, there is a way to pass the argument by reference so that the local parameter points to the same location as the global parameter.