## Pass arguments to functions

In the previous section we have seen how to define a function that generates the first 10 numbers of the Fibonacci sequence on output. If we analyze well the newly created function immediately results something that is not quite so efficient. In fact, the function has a **static** that is not well suited to this type of function.

In fact, the function we wrote always does the same thing: to generate the first 10 numbers of the Fibonacci series. But if we wanted to print Fibonacci numbers, and at the time of defining the function we do not know what values this n has?

Well you can pass the variable n as an argument of the function. It will then be up to the internal operations of the function to correctly manage this value. We have introduced the **dynamism** of a function.

At the time of the declaration of the function you do not know how many Fibonacci numbers to generate,

```
def fibonacci (n):
...
```

but only at the time of the call will you decide how many values to generate.

`fibonacci(7)`

or

```
n = 7
fibonacci(n)
```

Let’s see how to change the declaration of the previous function:

```
def fibonacci(x):
i = 1
n1 = 0
n2 = 1
print ( n1 + n2)
while i < x:
n = n1 + n2
print( n )
n1 = n2
n2 = n
i += 1
n = 7
fibonacci(n)
```

By executing the above code we will obtain the first 7 numbers of the Fibonacci series

```
>>>
1
1
2
3
5
8
13
```

## Variables Scope

Note: I have specifically used the variable n as an argument of the function to make you understand another fundamental concept. The variable n used outside the function has nothing to do with the variable n used within the Fibonacci number calculation function. This is related to the concept of **visibility of variables**. The variables defined outside the function also have value inside the function, the variables used internally to the function do not have visibility outside (they can not be used outside) and are destroyed as soon as the execution comes out of operations internal to the function. The variables defined within the function are created to be used only for the purpose of the function.

Let’s see this concept better:

The variables defined externally to the function are also visible inside (without being passed as arguments):

```
a = 3
def foo():
print(a)
foo()
>>>
3
```

but they can not be changed within the function

```
a = 3
def foo():
print(a)
a = 1
print(a)
print(a)
foo()
print(a)
>>>
1
3
```

At the moment that we are going to make an assignment on the variable a within the function, let’s create a new variable with the same name. In this way the value of the external variable remains unchanged.

### Interesting question

But if the externally defined variables also have visibility inside, why pass the arguments to a function? Can not we use them directly inside?

## Parameters and arguments

Generally these two terms are used indiscriminately, in reality there are differences. **Parameters** are the variables used in defining a function, and the **arguments** are the values placed in the call of a function.

**⇐ Go to Python Lesson 3.2 – Functions**

**Go to Python Lesson 3.4 – Values returned by the functions ⇒**