Dr. Cho’s Website
Course Materials

# Functions in Python

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):
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
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
print(accum(1))
print(accum(2))``````

Use a nested function to make local variables persistent.

``````def accum_func():
total = 0          # initialize it
nonlocal total # do you remember nonlocal? total is the total above
total += x
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