Functions (Slideshow)

Why Functions?

What is a function?

  • Sequence of statements

  • Parameterizabe

  • Can have a return value

  • ⟶ Can be used as an expression

Why would one want to do this?

  • Code structuring

  • Readability

  • Maintainability

  • Code reuse

  • ⟶ Libraries

An Example

def maximum(a, b):
    if a < b:
        return b
    else:
        return a

maximum(42, 666)
666
  • def: introduces function definition

  • maximum: function name

  • a and b: parameters

  • return: ends the function — the value when used as expression

Sidenote: Pure Beauty

There is nothing special about functions

  • def is a statement

  • Evaluated during regular program flow, just like other statements

  • Creates a function object

  • Points a variable to it - the function’s name

type(maximum)
function
a = maximum
a(1,2)
2

Parameters and Types

There is no compile-time type check

  • For good or bad

  • maximum(a,b): can pass anything

  • … provided that a and b can be compared using <

  • Late binding ⟶ runtime error

  • ⟶ More testing required

  • ⟶ Unit testing, module unittest

maximum(1, '1')    # <--- comparing apples and oranges
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 maximum(1, '1')    # <--- comparing apples and oranges

Cell In[1], line 2, in maximum(a, b)
      1 def maximum(a, b):
----> 2     if a < b:
      3         return b
      4     else:

TypeError: '<' not supported between instances of 'int' and 'str'

Default Parameters

For the most common case, default values may be specified …

def program_exit(message, exitstatus=0):
    print(message, file=sys.stderr)
    sys.exit(exitstatus)

program_exit('done')

Default parameters must come at the end of the parameter list …

Syntax error
def program_exit(exitstatus=0, message):
    ...

Mutable Default Parameters: Attention!

Attention: mutable default parameters may not do what one expects …

def f(i, x=[]):
    x.append(i)
    return x

print(f(1))
print(f(2))
[1]
[1, 2]

Will produce …

[1]
[1, 2]
[1, 2]

Reason:* default value for a parameter is part of the function object ⟶ retains its value across calls

f.__defaults__
([1, 2],)

Keyword Arguments

Long parameter lists

  • Easy to confuse parameters

  • Unreadable

  • Unmaintainable

Function call with keyword arguments
def velocity(length_m, time_s):
    return length_m / time_s

v = velocity(2, 12) # what?
v = velocity(time_s=2, length_m=12)

⟶ Very obvious to the reader!