## Using Functions

### Calling functions

We often want to do things to our objects that are more complicated than just assigning them to variables.

For example, we might want to know the length of an object.

A string:

len("pneumonoultramicroscopicsilicovolcanoconiosis")


45

Here we have “called a function”.

The function len takes one input, and has one output. The output is the length of whatever the input was.

Programmers also call function inputs “parameters” or, confusingly, “arguments”.

Here’s another example:

sorted("python")


[‘h’, ‘n’, ‘o’, ‘p’, ‘t’, ‘y’]

Which gives us back a list of the letters in Python, sorted alphabetically.

Note that uppercase letters come before lowercase letters in a sort, for example:

sorted("Python")


[‘P’,’h’, ‘n’, ‘o’, ‘t’, ‘y’]

Which gives us back a list of the letters in Python, sorted alphabetically (more specifically, according to their Unicode order).

The input goes in brackets after the function name, and the output emerges wherever the function is used.

So we can put a function call anywhere we could put a “literal” object or a variable.

len('Jim')*8


24

Concatenating strings:

x = len('Mike')
y = len('Bob')
z = x+y


Or

print(z)


7

### Using methods

Objects come associated with a bunch of functions designed for working on objects of that type. We access these with a dot, just as we do for data attributes:

"shout".upper()


‘SHOUT’

These are called methods. If you try to use a method defined for a different type, you get an error:

x = 5

type(x)


int

x.upper()


—————————————————————————

AttributeError Traceback (most recent call last)

<ipython-input-9-5d563274bba7> in <module>()

1 x = 5

—-> 2 x.upper()

AttributeError: ‘int’ object has no attribute ‘upper’

If you try to use a method that doesn’t exist, you get an error:

x.wrong


—————————————————————————

AttributeError Traceback (most recent call last)

<ipython-input-10-131d304742ae> in <module>()

—-> 1 x.wrong

AttributeError: ‘int’ object has no attribute ‘wrong’

Methods and properties are both kinds of attribute, so both are accessed with the dot operator.

Objects can have both properties and methods:

z = 1+5j


Where 5j is an imaginary number.

z.real


1.0

z.conjugate()


(1-5j)

z.conjugate


<function complex.conjugate>

### Functions are just a type of object!

Now for something that will take a while to understand: don’t worry if you don’t get this yet, we’ll look again at this in much more depth later in the course.

If we forget the (), we realise that a method is just a property which is a function!

z.conjugate


<function complex.conjugate>

type(z.conjugate)


builtin_function_or_method

Consider the following:

somefunc = z.conjugate

somefunc()


(1-5j)

We can see that Functions are just a kind of variable, and we can assign new labels to them:

sorted([1,5,3,4])


[1, 3, 4, 5]

magic = sorted

type(magic)


builtin_function_or_method

magic(["Technology", "Advanced"])