# Functions¶

## Syntax¶

You now know how to run Python code, assign variables, and write control flow statements, which allows us to write programs that can do calculations. In fact, this is all you really need to write programs (except for being able to read in and write out data which we will talk about later). However, with only this, programs will quickly become very long and unreadable. So one very important rule in programming is to avoid repetition.

The syntax for a function is:

def function_name(arguments):
# code here
return values

Functions are the building blocks of programs - think of them as basic units that are given a certain input an accomplish a certain task. Over time, you can build up more complex programs while preserving readability.

Similarly to if statements and for and while loops, indentation is very important because it shows where the function starts and ends.

Note: it is a common convention to always use lowercase names for functions.

A function can take multiple arguments...

In [ ]:
def add(a, b):
result = a + b
return result



... and can also return multiple values:

In [ ]:
def double_and_halve(value):
return value * 2., value / 2.

print(double_and_halve(5.))


If multiple values are returned, you can store them in separate variables.

In [ ]:
d, h = double_and_halve(5.)

In [ ]:
print(d)

In [ ]:
print(h)


Functions can call other functions:

In [ ]:
def do_a():
'''
This is a function to do a
'''
print("doing A")

def do_b():
print("doing B")

def do_a_and_b():
do_a()
do_b()

In [ ]:
do_a_and_b()


Figuring out the right functions is half the trick behind a good program. A good function has a clear purpose that can, ideally, be described in one sentence of natural language.

Beginners typically err on the side of defining too few functions and writing monsters spanning a couple of screen pages. That's a clear indication that you're doing it wrong. A good function can be taken in (albeit perhaps not understood) at a glance.

## Exercise 1¶

Copy your code that finds prime numbers here and modify it so as to make it a function that given a number will return True or False depending on whether it is prime.

In [ ]:
# your solution here


## Exercise 2¶

Try and write a function that will return the factorial of a number (e.g. 5!=5*4*3*2*1). First you can try and write a function that uses a loop internally.

It is possible for functions to call themselves (recursive functions), so see if you can write a function that uses no loops!

In [ ]:
# enter your solution here


## Optional Arguments¶

In addition to normal arguments, functions can take optional arguments that can default to a certain value. For example, in the following case:

In [ ]:
def say_hello(first_name, middle_name='', last_name=''):
print("First name: " + first_name)
if middle_name != '':
print("Middle name: " + middle_name)
if last_name != '':
print("Last name: " + last_name)


we can call the function either with one argument:

In [ ]:
say_hello("Michael")


and we can also give one or both optional arguments (and the optional arguments can be given in any order):

In [ ]:
say_hello("Michael", last_name="Palin")

In [ ]:
say_hello("Michael", middle_name="Edward", last_name="Palin")

In [ ]:
say_hello("Michael", last_name="Palin", middle_name="Edward")


## Built-in functions¶

Some of you may have already noticed that there are a few functions that are defined by default in Python:

In [ ]:
x = [1,3,6,8,3]

In [ ]:
len(x)

In [ ]:
sum(x)

In [ ]:
int(1.2)


A full list of built-in functions is available from http://docs.python.org. Note that there are not that many - these are only the most common functions. Most functions are in fact kept inside modules, which we will cover later.

## Exercise 3¶

Write a function that takes a list, and returns the mean of the values. Test it with the following list:

In [ ]:
l = [1, 3, 4, 5, 6, 7]