# 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:

:

def addmult(x, y):
multiplying = x * y

z

:

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":

:

def print_and_return(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:

:

def print_and_return(x, y):
multiplying = x * y
print(multiplying)

print_and_return(10.2, 30.0)

306.0


:

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.

In case of a function returning “nothing", you actually get something: a None object which happens to have Nonetype type:

:

def print_and_return(x, y):
multiplying = x * y
print(multiplying)

somevar = print_and_return(10.2, 30.0)
somevar is None
somevar
type(somevar)

306.0

:

NoneType


### 4.1.2. Exercise¶

What’s wrong with the code bellow, why does the doesn’t z equals 60.0?:

:

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):
ddf
multiplying = x * y

ddf = 342


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:

:

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:

:

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:

:

def somefunc(x, y, z):
adding = 2 * x + y + 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)

:

1605.0


You can also provide some default value for an argument (effectively making it optional):

:

def somefunc(x, y, z=1):
adding = 2 * x + y + 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)

:

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:

:

def somefunc(x, y):
adding = 2 * x + y

somefunc(10.2, 30.0)

somefunc = "Something else"

def somefunc(x):
return x*2

somefunc(43.2)

:

86.4


You can also create a function in a single line using the lambda syntax:

:

somefunc = lambda x, y: 2 * x + y

somefunc(10.2, 30.0)

:

50.4


This will prove itself useful in the future…