CSC401: Functions

A Simple Function

# define function
def ave(x, y):
    return (x + y) / 2.0

# use function
print ave(20, 30)
25.0

The Rules

Define a new function using def

Really creating a function object, then assigning it to a variable

Argument names follow in parentheses

No types

Finish at any time with return

Functions without return statements return None

Scope

Functions created in a block are local to it

x = 123
def f(arg):
    x = arg
    def g():
        x = 2
        y = 1
        print "x in g is ", x
        print "y in g is ", y
    g()
    print "x in f is ", x
    print "y in f is ", y
f(999)

x in g is 2
y in g is 1
x in f is 999
y in f is NameError: global name 'y' is not defined

print x
123

Memory

Function arguments always copied

Which means structures are aliased

Just as in Java

def mutate(x, y):
    x = 0
    y[0] = 0
a = 1
b = [1, 1, 1]
mutate(a, b)
print a, b
1, [0, 1, 1]

Default Argument Values

Can provide defaults for arguments

Arguments without defaults must come first

def withTax(val, percent=15):
    return val * (1.0 + percent/100.0)
print withTax(10.00)       # default
print withTax(10.00, 7)    # explicit
11.5
10.7

Named Arguments

Can pass arguments in any order using names

def show(first, second):
    print first, second
show(1, 2)
1 2
show(second=9, first=0)
0 9

Mixing Defaults and Names

Matching rules are intuitive

Match left-to-right

Unnamed must precede named

def show(first, second, third=3):
    print first, second, third
show(second=9, first=0)
show(1, 2, 5)
0 9 3
1 2 5

Extra Arguments

Any extra unnamed arguments put in a tuple called *extra

A tuple is like a constant list

Uses () instead of []

Exercise for the reader: look up tuples in Python documentation

Only the * matters: could call the argument *fred

If no * argument present, extra values are illegal

def show(first, *extra):
    print first, extra
show(10, 20, 30, 40)
10 (20, 30, 40)

Extra Named Arguments

Any extra named arguments put in a dictionary called **named

Again, only the ** is important

def user(id, **named):
    print id, "=", named
user(0, name="Greg", age=40)
user(1, hair="some", eyes=2)
0 = {'age' : 40, 'name' : 'Greg'}
1 = {'hair' : 'some', 'eyes' : 2}

Extra Argument Example

def ex(a, b, c=3, d=4, *extra, **named)
Call a b c d extra named
ex(1, 2) 1 2 3 4 () {}
ex(1, 2, 8) 1 2 8 4 () {}
ex(1, 2, d=8) 1 2 3 8 () {}
ex(1, 3, 5, 7, 9) 1 3 5 7 (9,) {}
ex(1, 2, j=6) 1 2 3 4 () {'j':6}

Slides originally created by Greg Wilson. Adapted for CSC401 by David James, Revisions by Michelle Craig, Michael Szamosi, Karen Reid, and David James.