Functions#
Function definitions#
Functions are chunks of code that you can reference whenever you need.
This function just prints out a statement
def my_hello_function():
print('hello world')
We write def
to define the function, followed by the name we choose for the function, my_hello_function
, parentheses, a colon, and then an indented section.
To use the function we just created, simply run the following (yes we need the parentheses):
my_hello_function()
hello world
In fact, we can use it many times:
my_hello_function()
my_hello_function()
my_hello_function()
hello world
hello world
hello world
Function arguments and return values#
We can also pass arguments to functions. Think of arguments as inputs to the function.
This example takes two arguments: title_input
and name_input
:
def custom_hello(title_input, name_input):
print('Hello', title_input, name_input, '!')
And we can use it like this:
custom_hello(title_input='Professor', name_input='Beardsley')
Hello Professor Beardsley !
custom_hello(title_input='Señor', name_input='Loadenstein')
Hello Señor Loadenstein !
Functions can also return
or output values that you can store and later reference.
This function has three inputs and one output:
# define the function
def some_math(x_input, y_input, z_input):
# calculate the result
my_result = x_input**y_input - z_input
# return the result variable
return my_result
Reminder, this is just the function definition. We haven’t actually used the function yet. In order to use the function, we need to call it and pass it some arguments. When we do that, it will pass the output back to us.
Now let’s use our new function and store the output in answer_1
.
answer_1 = some_math(x_input=4, y_input=2, z_input=6)
answer_1
10
We do not need to explicitly name the inputs. If we are careful to pass the arguments in the correct order, then the following will also work.
answer_1 = some_math(4, 2, 6)
answer_1
10
However, that is not the recommended approach since it is easy to get the order of the arguments/inputs wrong. It is also easier to read and understand the code when we explicitly use the names of the arguments.
Another benefit of using the names of the arguments is that we can pass the arguments in any order we want.
answer_1 = some_math(y_input=2, z_input=6, x_input=4)
answer_1
10
Important
We can pass named arguments or unnamed arguments into functions. If we do not use the names of the arguments, then be careful to have the order of the arguments correct.
Arguments with default values#
If you want your function to have optional arguments with default values, you can include them in the function definition like this.
# define the function with default values
def calculate_sharpe(return_input=0.09, st_dev_input=0.04):
# calculate the sharpe ratio using the inputs
sharpe_ratio = return_input / st_dev_input
# print the result
print('Sharpe Ratio:', sharpe_ratio)
# this function does not "return" anything
Notice how we can include arguments when we use this function:
calculate_sharpe( return_input=0.12, st_dev_input=0.1 )
Sharpe Ratio: 1.2
But we don’t have to. In this case, the function will use the default values of 0.09 and 0.04.
calculate_sharpe()
Sharpe Ratio: 2.25
Example#
Below is a math function that combines several of the previous topics.
This is known as the \(3x+1\) problem.
pick any starting number
if the number is odd, multiply by 3 and add 1
if the number is even, divide by 2
repeat the process with the new number
you will always arrive at a value of 1 eventually
# define the function
def fun_function(starting_value):
# set some initial values
counter = 0
current_num = starting_value
max_value = starting_value
process_list = [current_num]
while current_num != 1:
# do something if the number is odd
if current_num % 2 == 1:
current_num = current_num * 3 + 1
# do something if the number is even
elif current_num % 2 == 0:
current_num = current_num / 2
else:
print('something went wrong')
counter = 'error'
break
counter = counter + 1
# if the current number is a new max, then update the max
if current_num > max_value:
max_value = current_num
# add the current number to the process list
process_list.append( int(current_num) )
print('Ended up at 1 after', counter, 'steps.')
print('Process reached max value of', int(max_value) )
print(process_list)
Now let’s use the function we just defined.
fun_function(10)
Ended up at 1 after 6 steps.
Process reached max value of 16
[10, 5, 16, 8, 4, 2, 1]
fun_function(500)
Ended up at 1 after 110 steps.
Process reached max value of 9232
[500, 250, 125, 376, 188, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]
fun_function(987654)
Ended up at 1 after 183 steps.
Process reached max value of 2222224
[987654, 493827, 1481482, 740741, 2222224, 1111112, 555556, 277778, 138889, 416668, 208334, 104167, 312502, 156251, 468754, 234377, 703132, 351566, 175783, 527350, 263675, 791026, 395513, 1186540, 593270, 296635, 889906, 444953, 1334860, 667430, 333715, 1001146, 500573, 1501720, 750860, 375430, 187715, 563146, 281573, 844720, 422360, 211180, 105590, 52795, 158386, 79193, 237580, 118790, 59395, 178186, 89093, 267280, 133640, 66820, 33410, 16705, 50116, 25058, 12529, 37588, 18794, 9397, 28192, 14096, 7048, 3524, 1762, 881, 2644, 1322, 661, 1984, 992, 496, 248, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]
Try to find a positive integer that does not eventually arrive at 1.
If you do, you’ll be famous (in the math community).