Dr. Cho’s Website
Course Materials

Functions in Python

Dr. Huidae Cho
Institute for Environmental and Spatial Analysis...University of North Georgia

1   What is a function?

A function is a set of statements.

It can take arguments and return a value.

We mainly use functions to reduce redundancy in code.

We also use functions for better code readability.

Sometimes, we need them for recursive programming.

2   Defining a function

Define a simple function.

def f(x):
    y = 2*x
    return y
print(f(3))

Define it again.

def f(x): y = 2*x; return y
print(f(3))

3   Null function

Can you define a function with no body? Let’s try!

def nop():
nop()

Not working! Use the pass statement as a placeholder.

def nop(): pass # just do nothing
nop()

4   Functions are objects

A function is an instance of a class (object) with its name.

def foo():
    """ function document
    called doc string """
    return 'foo';
print(dir())    # lists all names in the current scope
print(dir(foo)) # lists all valid attributed for the foo object

Can you see the __class__ attribute? Try this.

def foo():
    """ function document
    called doc string """
    return 'foo';
print(dir())
print(dir(foo))
print(foo.__name__)
print(foo.__doc__)
print(foo.__call__())

5   Functions can be nested inside a function

We can limit the scope of a function to its parent function.

def some_math(x, y):
    def add(x, y):
        z = x + y
        print('{x}+{y}={z}'.format(x=x, y=y, z=z))
    def mul(x, y):
        z = x * y
        print(f'{x}*{y}={z}') # shorter way of formatting strings in Python 3.6
    add(x, y)
    mul(x, y)
some_math(10, 2)

6   Closures

Normally, any local variables defined inside a function do not persist.

def accum(x):
    total += x # well, there is even no way to initialize total
    return total
print(accum(1))
print(accum(2))

Use a nested function to make local variables persistent.

def accum_func():
    total = 0          # initialize it
    def add(x):
        nonlocal total # do you remember nonlocal? total is the total above
        total += x
        return total
    return add         # return the add function itself
accum = accum_func()
print(accum(1))
print(accum(2))

The above programming pattern is called closure.

7   Attributes

We can define function attributes.

def accum(x):
    accum.total += x
    return accum.total
accum.total = 0 # create a new attribute
print(accum(1))
print(accum(2))
print(accum.total)

8   Decorators

Add pre-/post-statements that wrap a function.

def decorator(func):
    def wrapper():
        print("before func")
        func()
        print("after func")
    return wrapper
def f():
    print("f")
f = decorator(f)
f()

# the "pie" syntax
# equivalent to g = decorator(g)
@decorator
def g():
    print("g")
g()

9   Revisit the persistent variable

We can use the decorator pattern to declare function attributes.

def static_decorator(name, val):
    def wrapper(func):
        setattr(func, name, val)
        return func
    return wrapper

# equivalent to accum = static_decorator('total', 0)(accum)
@static_decorator('total', 0)
def accum(x):
    accum.total += x
    return accum.total
print(accum(1))
print(accum(2))

10   Have you noticed this?

Functions can be variables.

def f(g):       # f takes a function and just returns it
    return g
def h(x):       # h takes an argument and prints it
    print(x)
a = f(h)        # a == h
a(12)           # calls h(12)

In C, we call them function pointers.

11   Homework: Rock paper scissors

Keywords: functions

Use the random(), print(), input(), and your own functions to implement the rock paper scissors game. There is one little problem. Your code has a bad habit of throwing a rock twice more likely than the other two.

  1. Generate a random number using random()
  2. Determine your rock (coded as 1), paper (2), or scissors (3) based on the random number
  3. Pass yours from step 3 to the play_once() function that does the following:
    1. Print “(r)ock, (p)aper, (s)cissors, (q)uit? ” and read a string input
    2. If the input is q, return 0
    3. Return 1 if the user won
    4. Return 2 if the user lost
    5. Return 3 if both players tie
  4. Get the return value of play_once()
  5. If the return value is 0, print Wins: **%, Losses: **%, Ties: **% and stop
  6. Print You won, You lost, or You tied and count wins, losses, and ties
  7. Go to step 1

12   Homework: Arithmetic calculator

Keywords: functions, keyboard input, looping, slicing, branching

Write a simple calculator that supports four basic arithmetic operations (+, -, *, and /) for two floating-point numbers.

  1. Print “? ” and read an expression
  2. Pass the expression to your function called evaluate()
    1. If the expression is quit, return None
    2. Split the expression into three parts: left operand, operator, and right operand
    3. Branch based on the operator
    4. Calculate the expression and return its result
  3. Take the return value of evaluate()
  4. If the return value is None, stop
  5. Print the result
  6. Go to step 1