Functions#

A function takes some number of inputs, and returns some number of outputs. Recall the keywords def, and return

import numpy as np

# function with no inputs
def random_float():
    return np.random.rand()

print(random_float())

# function with 1 input
def plus1(x):
    return x + 1

print(plus1(2))

# function with 2 outputs
def plus_times(a, b):
    return a + b, a * b

print(plus_times(2,3))
0.8935280147952379
3
(5, 6)

You can look up a function call signature and documentation with help()

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

plus_times(a, b)
    # function with 2 outputs

You can also use ? in ipython

?plus_times

If we want to provide a docstring, we can do so in the function declaration

# function with 2 outputs
def plus_times(a, b):
    """
    returns a + b, a * b
    """
    return a + b, a * b
?plus_times

Keyword Arguments#

You can provide keyword arguments by setting a default value

def kw_example(a, b=5, c=1):
    """
    returns a + b + c
    """
    return a + b + c

print(kw_example(3))

print(kw_example(3, b=4))

print(kw_example(3, c=2, b=10))
9
8
15
?kw_example

keyword arguments must come after regular arguments

def kw_example(b=5, a):
    return a + b
  Cell In[8], line 1
    def kw_example(b=5, a):
                        ^
SyntaxError: non-default argument follows default argument

Unpacking#

In Python, it is common to see function calls of the form

def myfun(*args, **kwargs):
    """
    Function that prints arguments and keyword arguments
    """
    print(args)
    print(kwargs)
    return

args is a tuple containing the arguments

kwargs is a dict containing keyword arguments

myfun(1,2, c=3, dog='cat')
(1, 2)
{'c': 3, 'dog': 'cat'}

You can also unpack containers in other contexts

a = [1,2,3]
print("unpacked list:")
myfun(*a)
print("list:")
myfun(a)
unpacked list:
(1, 2, 3)
{}
list:
([1, 2, 3],)
{}

This is very useful for passing along arguments to other functions without having to even know what the possibilities are.

import matplotlib.pyplot as plt

def plot_f(f, x, **kwargs):
    """
    plots f(x)
    
    passes keyword arguments to plt.plot()
    """
    y = f(x)
    return plt.plot(x, y, **kwargs)

def f(x):
    return x**2

x = np.linspace(-1,1,100)

plot_f(f, x, color='b')
plt.show()
../_images/8b94317c597b6232f87a9544d1db51727c46cadbb91eae043cd196c0ce6cfa83.png

A good way to extract keyword arguments from kwargs is to use the get method for Python dictionaries

dict.get?
def myfun(*args, **kwargs):
    """
    extract the "message" keyword
    """
    m = kwargs.get("message", "hello")
    print(m)
    return m

myfun()

myfun(message="goodbye")
hello
goodbye
'goodbye'

Helper Functions#

You can define helper functions inside the definition of a function

def alternate(x):
    """
    returns -x if x is odd, x if x is even
    """
    def is_odd(x):
        """
        returns true if x is odd
        """
        return x % 2 == 1 # % is mod operator
    
    # we now return to the function alternate
    if is_odd(x):
        return -x
    else:
        return x
    
for i in range(-5,5):
    print("{:+d}".format(alternate(i)))
    
+5
-4
+3
-2
+1
+0
-1
+2
-3
+4

Lambda Functions#

A Lambda Function is an anonymous function, meaning you don’t give it a name e.g. by declaring it in a def block.

f = lambda x : x*x
f(2)
4

lambda functions (and the lambda calculus) play an important role in the theory of computing. They can be found in a many languages other than Python.

The semantics of a lambda function are very similar to a function declared using def:

lambda *args : outputs

# here's the plus_times function we defined earlier
(lambda x, y : (x + y, x * y))(3,2)
(5, 6)
# using a lambda function in our plotting function
plot_f(lambda x: x**3, np.linspace(-1,1,100))
plt.show()
../_images/bbf1f28a0d1d6b062e93f2493bdf98734afdaa306b873928e59bd10a9c480b6d.png

Exercises#

  1. Define a lambda function that acts as the identity on input arguments

## your code here
Hide code cell content
I = lambda *args : args
  1. Define a function that plots a 2-dimensionsional function using plt.imshow. Pass along keyword arguments to the imshow function

# your code here
  1. Define a function that computes the sum of its arguments

# your code here
Hide code cell content
def sumfun(*args):
    return sum(args)

sumfun(1,2,3)
6