Functions

Have already seen functions in action, such as len and max.

These are functions that Python provides for us.

We can use functions in modules. One is example is the random function from the random module. This returns random number between 0 and 1.

>>> import random
>>> random.random()
0.88990060071...
>>> random.random()
0.96023181107...

We can also write our own functions.

We will use a function to contain the logic for deciding whether the next chlild is a boy or a girl. Call our new function girl_or_boy1. Like random.random our function girl_or_boy will accept no arguments. It will return a G 50% of the time and a B 50% of the time.

Remember, we have already imported random.

We make a function like this:

>>> def girl_or_boy1():
...     # Return 'G' or 'B' with 50% chance
...     return random.choice('GB')

The function starts with the word def which tells Python we are defining a function. Next follows the name of the function, followed by, in our case, parentheses. You specify what arguments the function should have, in the parentheses. In our case, our function as no arguments, so there is nothing between the parentheses.

Next there follows one or more indented statements. These statements are the body of the function. They are the code that gets run when the function gets called.

We return the result with the return statement. Here we are returning "G" or "B", each with a 0.5 probability.

Test it:

>>> # Notice, we pass no arguments
>>> girl_or_boy1()
'B'
>>> girl_or_boy1()
'G'

So far all we have done is moved a single line of code into a function, but functions allow us to put more logic into the function, without making the call any more complicated. For example, let’s imagine we wanted to write our function to allow for the possibility that the probability of a girl was not exactly 0.5:

>>> def girl_or_boy2():
...     # Return 'G' or 'B' with (for now) 50% chance.
...     # Make a random number between 0 and 1
...     random_no = random.random()
...     # Calculate the return value
...     if random_no < 0.5:  # We might want to change this later
...         our_result = 'G'
...     else:
...         our_result = 'B'
...     # Send back the result
...     return our_result

Let’s call the function a few times to see if the results are plausible:

>>> girl_or_boy2()
'G'
>>> girl_or_boy2()
'B'
>>> girl_or_boy2()
'G'

Exercise

Up until now, we’ve assumed that the chance that a child is a boy is 0.5. Now assume the proportion of boys born in the UK is 0.513 [1].

Here’s a copy of the girl_or_boy2 function above, renamed as girl_or_boy3. Modify the function to return "B" (for a boy) 51.3% of the time, and "G" (for a girl) 48.7% of the time.

>>> def girl_or_boy3():
...     # Return 'G' with probability 0.487, 'B' with p=0.513.
...     # Make a random number between 0 and 1
...     random_no = random.random()
...     # Calculate the return value
...     if random_no < 0.5:  # We might want to change this later
...         our_result = 'G'
...     else:
...         our_result = 'B'
...     # Send back the result
...     return our_result

You can try your function out a few times with the cell below:

>>> girl_or_boy3()
'G'

If you’ve got that done, use a for loop to run this function 10000 times, and record what proportion of times it returns "G". Is the answer close to 0.487? It should be …

[1]Official UK government statistics give the birth ratio as 105.3. This the number of boys born for every 100 girls.