4. Functions
So far you have being using existing functions like list and type, but how about defining your own functions? Turns out that’s very easy with Python:
[1]:
def addmult(x, y):
adding = x + y
multiplying = x * y
return multiplying / adding
z = addmult(10.2, 30.0)
z
[1]:
7.611940298507462
That’s it, but just notice the spacing after the first line of the function. That’s the way Python functions (and as we’ll see, conditionals and loops) works: using indentation. A single whitespace or tab is enough, however, the most common usage is to have 4 whitespace in Python scripts.
4.1. Return value
Functions in Python can either return you “something" like the one above, or just return “nothing":
[2]:
def print_and_return(x, y):
adding = x + y
multiplying = x * y
print(multiplying)
return
print_and_return(10.2, 30.0)
306.0
In the above case, you actually didn’t need the return, statement; once a function goes to its last line (i.e.: indentation decreases), it will return automatically:
[3]:
def print_and_return(x, y):
adding = x + y
multiplying = x * y
print(multiplying)
print_and_return(10.2, 30.0)
306.0
But, you could use return to make the function return immediately:
[4]:
def print_and_return():
print("This will be printed")
return
print("This will never be printed")
print_and_return()
This will be printed
This will prove itself useful together with conditionals in the next section.
4.1.1. An optional lookahead
In case of a function returning “nothing", you actually get something: a None object which happens to have Nonetype type:
[5]:
def print_and_return(x, y):
adding = x + y
multiplying = x * y
print(multiplying)
somevar = print_and_return(10.2, 30.0)
somevar is None
somevar
type(somevar)
306.0
[5]:
NoneType
4.1.2. Exercise
What’s wrong with the code bellow, why does the doesn’t z equals 60.0?:
[6]:
def mult(x, y):
multiplying = x * y
multiplying
z = mult(2.0, 30.0)
z
4.2. Variable Scope
Here there’s three points to make, first that variables defined inside a function only exist within the scope of the function, so the code below:
def addmult(x, y):
adding = x + y
ddf
multiplying = x * y
return multiplying / adding
ddf = 342
addmult(10.2, 30.0)
adding
Will give you an error message:
NameError: name 'adding' is not defined
Second, that once you declare a variable inside a function it will not overwrite a variable defined outside of it which happens to have the same name, so:
[7]:
def somefunc():
somevar = 421
print("Value inside somefunc()", somevar)
return
somevar = 123
somefunc()
print("Value outside somefunc()", somevar)
Value inside somefunc() 421
Value outside somefunc() 123
Third, if you did not defined the variable inside the function, but it does exists outsize of it, then Python will use it, so:
[8]:
def somefunc():
print("Value inside somefunc()", something)
return
something = 482
somefunc()
print("Value outside somefunc()", something)
Value inside somefunc() 482
Value outside somefunc() 482
So here’s a summary of it: when you ask Python to get you a variable inside a function, it will first attempt to get the one defined inside the function and then if not found, it will try outside the function.
If you ask it to set a variable, it will always set it on local scope of the function (it will not overwrite a variable defined outsize with the same name).
4.3. Named arguments and default values
To make things easier, Python also accepts you to pass the arguments of a function by name:
[9]:
def somefunc(x, y, z):
adding = 2 * x + y + z
return adding * z
somefunc(x=10.2, y=30.0, z=3.1)
somefunc(y=30.0, z=3.1, x=10.2)
somefunc(10.2, y=30.0, z=3.1)
somefunc(10.2, z=3.1, y=30.0)
somefunc(10.2, y=3.1, z=30.0)
[9]:
1605.0
You can also provide some default value for an argument (effectively making it optional):
[10]:
def somefunc(x, y, z=1):
adding = 2 * x + y + z
return adding * z
somefunc(10.2, 30.0)
somefunc(10.2, 30.0, 1)
somefunc(y=30.0, x=10.2)
somefunc(y=30.0, x=10.2, z=1.4)
somefunc(10.2, 30.0, 1.4)
[10]:
72.52
4.4. Lambda and function redefinitions
In Python, a function can also be seems as a object or as variable like any other else (with the special property of being callable), and as such, you can redefine it as usual:
[11]:
def somefunc(x, y):
adding = 2 * x + y
return adding * 4
somefunc(10.2, 30.0)
somefunc = "Something else"
def somefunc(x):
return x*2
somefunc(43.2)
[11]:
86.4
You can also create a function in a single line using the lambda syntax:
[12]:
somefunc = lambda x, y: 2 * x + y
somefunc(10.2, 30.0)
[12]:
50.4
This will prove itself useful in the future…