Functions

1. A function is a block of code that performs a specific task when the function is called (invoked). You can use functions to make your code reusable, better organized, and more readable. Functions can have parameters and return values.

2. There are at least four basic types of functions in Python:

  • built-in functions which are an integral part of Python (such as the print() function). You can see a complete list of Python built-in functions at https://docs.python.org/3/library/functions.html.
  • the ones that come from pre-installed modules.
  • user-defined functions which are written by users for users – you can write your own functions and use them freely in your code,
  • the lambda functions

3. You can define your own function using the def keyword and the following syntax:

You can define a function which doesn’t take any arguments, e.g.:

You can define a function which takes arguments, too, just like the one-parameter function below:

 

4. You can pass information to functions by using parameters. Your functions can have as many parameters as you need.

An example of a one-parameter function:

An example of a two-parameter function:

An example of a three-parameter function:

5. You can pass arguments to a function using the following techniques:

  • positional argument passing in which the order of arguments passed matters (Ex. 1),
  • keyword (named) argument passing in which the order of arguments passed doesn’t matter (Ex. 2),
  • a mix of positional and keyword argument passing (Ex. 3).

It’s important to remember that you have to put positional arguments before keyword arguments. Positional arguments mustn’t follow keyword arguments. That’s why if you try to run the following snippet:

Python will not let you do it by signalling a SyntaxError.

6. You can use the keyword argument passing technique to pre-define a value for a given argument:

 

7. You can use the return keyword to tell a function to return some value. The return statement exits the function, e.g.:

 

8. The result of a function can be easily assigned to a variable, e.g.:

 

Look at the difference in output in the following two examples:

 

9. You can use a list as a function’s argument, e.g.:

 

10. A list can be a function result, too, e.g.:

 

11. You can use the return keyword to tell a function to return some value. The return statement exits the function, e.g.:


 

12. The result of a function can be easily assigned to a variable, e.g.:

Look at the difference in output in the following two examples:


 

13. You can use a list as a function’s argument, e.g.:


 

14. A list can be a function result, too, e.g.:

 

15. A variable that exists outside a function has a scope inside the function body (Example 1) unless the function defines a variable of the same name (Example 2, and Example 3), e.g.:

Example 1:

Example 2:

 

Example 3:

 

16. A variable that exists inside a function has a scope inside the function body (Example 4), e.g.:

Example 4:

 

17. You can use the global keyword followed by a variable name to make the variable’s scope global, e.g.:


 

18. Is it worth checking how it works with lists (do you recall the peculiarities of assigning list slices versus assigning lists as a whole?).

The following example will shed some light on the issue:


The code’s output is:

output

It seems that the former rule still works.

Finally, can you see the difference in the example below:


We don’t change the value of the parameter my_list_1 (we already know it will not affect the argument), but instead modify the list identified by it.

The output may be surprising. Run the code and check:

Let’s explain it :

  • if the argument is a list, then changing the value of the corresponding parameter doesn’t affect the list (remember: variables containing lists are stored in a different way than scalars),
  • but if you change a list identified by the parameter (note: the list, not the parameter!), the list will reflect the change.

 

19. A function can call other functions or even itself. When a function calls itself, this situation is known as recursion, and the function which calls itself and contains a specified termination condition (i.e., the base case – a condition which doesn’t tell the function to make any further calls to that function) is called a recursive function.

20. You can use recursive functions in Python to write clean, elegant code, and divide it into smaller, organized chunks. On the other hand, you need to be very careful as it might be easy to make a mistake and create a function which never terminates. You also need to remember that recursive calls consume a lot of memory, and therefore may sometimes be inefficient.

When using recursion, you need to take all its advantages and disadvantages into consideration.

The factorial function is a classic example of how the concept of recursion can be put in practice:

Factorial without recursion:

 

Exercise 1

What is the output of the following snippet?

 

Exercise 2

What is the output of the following snippet?

 

Exercise 3

What is the output of the following snippet?

 

Exercise 4

What is the output of the following snippet?

A non-default arguments must be before a default arguments.

 

Exercise 5

What is the output of the following snippet?

 

Exercise 6

What is the output of the following snippet?

 

Exercise 7

What is the output of the following snippet?

 

Exercise 8

What is the output of the following snippet?

 

Exercise 9

What is the output of the following snippet?

the function will return an implicit None value

 

Exercise 10

What is the output of the following snippet?

True
False

None

Exercise 11

What is the output of the following snippet?

[0, 2, 4, 6, 8, 10]

 

Exercise 12

What is the output of the following snippet?

[1, 4, 9, 16, 25]

 

 

Exercise 1

What will happen when you try to run the following code?

The NameError exception will be thrown (NameError: name 'alt' is not defined)

Exercise 2

What is the output of the following snippet?

2

1

Exercise 3

What is the output of the following snippet?

2

3

Exercise 4

What is the output of the following snippet?

2

2

Exercise 1

What will happen when you attempt to run the following snippet and why?

The factorial function has no termination condition (no base case) so Python will raise an exception (RecursionError: maximum recursion depth exceeded)

 

Exercise 2

What is the output of the following snippet?

56

 

Scenario

Your task is to write and test a function which takes one argument (a year) and returns True if the year is a leap year, or False otherwise.

To determine if a year is a leap year, we apply a simple rule: if the year is divisible by 4, it’s a leap year, except for end-of-century years, which must also be divisible by 400. For instance, the year 2000 was a leap year, while 1900 was not.

Scenario

Your task is to write and test a function which takes two arguments (a year and a month) and returns the number of days for the given month/year pair (while only February is sensitive to the year value, your function should be universal).

The initial part of the function is ready. Now, convince the function to return None if its arguments don’t make sense.

 

Scenario

Your task is to write and test a function which takes three arguments (a year, a month, and a day of the month) and returns the corresponding day of the year, or returns None if any of the arguments is invalid.

 

Scenario

A natural number is prime if it is greater than 1 and has no divisors other than 1 and itself.

Complicated? Not at all. For example, 8 isn’t a prime number, as you can divide it by 2 and 4 (we can’t use divisors equal to 1 and 8, as the definition prohibits this).

On the other hand, 7 is a prime number, as we can’t find any legal divisors for it.

Your task is to write a function checking whether a number is prime or not.

The function:

  • is called is_prime;
  • takes one argument (the value to check)
  • returns True if the argument is a prime number, and False otherwise.

Hint: try to divide the argument by all subsequent values (starting from 2) and check the remainder – if it’s zero, your number cannot be a prime; think carefully about when you should stop the process.

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Fibonacci numbers

Are you familiar with Fibonacci numbers?

They are a sequence of integer numbers built using a very simple rule:

  • the first element of the sequence is equal to one (Fib1 = 1)
  • the second is also equal to one (Fib2 = 1)
  • every subsequent number is the the_sum of the two preceding numbers:
    (Fibi = Fibi-1 + Fibi-2)

Here are some of the first Fibonacci numbers:

fib_1 = 1
fib_2 = 1
fib_3 = 1 + 1 = 2
fib_4 = 1 + 2 = 3
fib_5 = 2 + 3 = 5
fib_6 = 3 + 5 = 8
fib_7 = 5 + 8 = 13

What do you think about implementing this as a function?

Let’s create our fib function and test it. Here it is:

Recursion version: