Python Tutorial

Functions:

Getting started

This page can be downloaded as interactive jupyter notebook

An additional quiz about the contents of this tutorial can be downloaded here (with solutions)

Functions in Python:

In Python a function is a sequence of statements doing a specific task.

You can use functions to segment your program in modular parts. Functions should in particular be used, whenever the same code is executed multiple times. It reduces the overall amount of code and makes it more organized and understandable for others.

You can see the syntax of functions in Python in the following:

def function_name(parameters):
     """docstring"""
     statement(s)
     return some_return_value

The syntax that is used to implement a function consists of the following parts:

  • def : A keyword that denotes the start of function header.
  • function_name : The name of the function. It follows the same rules like identifiers (Chapter 1).
  • (parameters) : Parameters are used is used to pass values to the function. The number of parameters is not limited and we can also have functions with no parameters.
  • : : In Python the end of function header is denoted by a colon (:).
  • """docstring""" : This is a (optional) way of commenting functions to explain them in a unified way.
  • statement(s) : The function body is a (indented) block of Python statements.
  • return : Defines what the function will return. If the return statement is not used (or used without argument), the function will return None by default.

Example: You can see an example below.

def square(num):
    """The function takes a number, computes 
    its square and prints the result"""
    
    result = num * num
    print("The square of {} is {}".format(num, result))

How to call a function

Once a function is defined it can be used (called) via the functions name and the according parameters.

Example: We use the function above to see if it works.

# you can input parameters directly as values

square(5)
The square of 5 is 25
# You can input parameters by using variables

number1 = float(input("Please enter a number: "))

square(number1)
Please enter a number: 2
The square of 2.0 is 4.0

Note: The return statement without a succeeding value can be used to exit a function and return to the place where it was called.

Example: This time, the function will not print but return the result.

def add(x, y):
    """The function inputs are 2 numbers
    and the output is the sum value of 
    the input numbers"""
    result = x + y
    return result
# Take 2 numbers from user, then calculate the sum value by calling the function

num1 = float(input("Please enter first number: "))
num2 = float(input("Please enter second number: "))

# call the function
sum_value = add(num1, num2)

# show the result
print("The sum of {} and {} is {}".format(num1, num2, sum_value))

Please enter first number: 2
Please enter second number: 3
The sum of 2.0 and 3.0 is 5.0

Exercise: Write a function that takes a number and return the number is even or odd. Then call it and test it with some numbers

# Define the function here


# Call the function here, and check if it works


Scope and Lifetime of variables

The scope of a variable corresponds to the parts in a program where the variable ‘exists’. For example, variables and parameters that are created inside a function are not visible outside of the function. Thus, their scope corresponds to the body of the function. Variables, that were defined outside (and before) a function are visible inside of the function, because they have global scope.

The lifetime of a variable denotes the time that the variable is in the memory. The lifetime of a variable inside a function ends, when we return from the function and the executing is finished. After that, the variables will automatically be deleted from the memory. Variables, defined in functions (or any other block), will be reinitialized with each new execution of the block.

Note: Variable scopes are never programmed explicitly. Nevertheless, it is important to keep track of variable scopes to know where they can be accessed. Additionally, variables in different scopes can have the same name, which makes it even more important to know their scopes.

Example: Let’s run the program below to get better the content of Scope and Lifetime of a variable inside a function.

x = 1

def function1():
    a = 500
    b = 999
    print("Value of a (in function):", a)
    print("Value of b (in function):", b)
    # x can only be accessed because it was defined before the function
    print("Value of x (in function):", x)  

# this creates a NEW variable, since 'a' doesn't exist in this scope yet
a = -20

# call the function to show the value of the variable inside of the function
function1()

# print the value of the variable outside of the function
print("Value of a (outside function):", a)
print("Value of x (outside function):", x)

# The next line would raise an error, since b is not defined in this scope
# print("Value of b (outside function):", b) 
Value of a (in function): 500
Value of b (in function): 999
Value of x (in function): 1
Value of a (outside function): -20
Value of x (outside function): 1

Types of functions

In Python, we can divide functions in two types:

  • Built-in function : Functions that are built in Python (by default). For example len()
  • User-defined function : Functions that are defined and implemented by the programmer. All functions, implemented in the previous steps are of the second type.

Arguments

Arguments define the input for a function that we want to call. For example, the function SUM that we define before, has two arguments. As, when we are calling this function we have to input two values corresponding to these arguments.

In Python programming, we have three different types of arguments:

  • Default arguments: Arguments can have default values, that are used when no other value was set in the function call. We can define default values for any argument using the assignment operator =.

Example: You can see an example of a function with a default argument in the function below.

def POW(x, y=2):
    """The function computes x^y 
    where y defaults to 2"""
    
    result = x ** y
    return (result)

num1 = float(input())
result = POW(num1)

print("result of POW(", num1, ") with default value: ", result)
4
result of POW( 4.0 ) with default value:  16.0
  • Keyword arguments: When we call a function providing several values, these values are assign to the arguments according to their position. For example, in function SUM, when we call it with this script SUM(10,20), we assign the value 10 to the first argument and value 20 to the second argument in the function. However, it is also possible to explicitly assign values to arguments, as shown in the next example:
r1 = POW(y=2,x=3) # Explicit argument adressing ...
r2 = POW(x=3,y=2) # ... (order no longer relevant) 


print("result 1: ", r1)
print("result 2: ", r2)
result 1:  9
result 2:  9
  • Arbitrary arguments: Somtimes, we do not how many numbers of arguments will assign to the function. In this situation, we can define and call the function with arbitrary arguments. In this definition of functions, we use an asterisk (*) before the input parameter name to denote this kind of argument.

Example: You can see an example of arbitrary argument in the function below.

def combine(*values, delimiter=' '):
    """The function combines multiple strings"""
    result = ""
    for value in values:
        result = result + value + delimiter
    return result[:-len(delimiter)]

combined = combine("Hello", "World") # here the default delimiter is used
print(combined)

combined = combine("B", "", "as c", " d", "ce", delimiter='an')
print(combined)
Hello World
Bananas can dance

Recursion

Recursion means, that some code (usually a function) is calling itself (which causes another call and so on).

Example: Let’s see how the recursive functions can be used to compute the factorial of a number.

# The function calculates the sum value from 0 to the input number

def factorial(num):
    """This is a recursive function
    to calculate the factorial of a number"""
    if num == 1:
        return 1
    else:
        return num*factorial(num-1)

# Let's call the function and check the application

number = int(input("please enter your number: "))

print("The factorial of ", number, "is: ", factorial(number))
please enter your number: 4
The factorial of  4 is:  24

In the above example, factorial() is a recursive function that calls itself. This recursive function calls end when the function is asked to compute the factorial of 1, which is 1 by definition. An recursive function must have such a base condition that stops the recursion.

Anonymous/Lambda Function

In Python, we can define a function without name. Such a functions is called anonymous function. In normal functions, we use def keyword to define a function, but in anonymous function, we use the lambda keyword. Because of that, anonymous functions are usually called lambda functions.

How to use lambda functions:

We can use recursive functions wherever function objects are required. You can see the syntax of lambda function below:

lambda arguments: expression

Lambda function can have any number of arguments, but only one expression.

Example: In this example you can see how the lambda function works.

# Program to show how the lambda function works

power_2 = lambda num: num * num

# call the function
print(power_2(10))
100

In the above program, lambda num: num * num is the lambda function. The num is the argument in this function and the num * num is the expression in this function. In order to use the function it is stored as variable here.

Use of Lambda function

In Python, we usually use lambda functions when we need a simple function only a few times, e.g. as an argument to a higher-order function (a function that is an argument in other function). Examples for functions that take other functions as arguments are the built-in functions filter() and map().

Note: The filter() function takes a function and a list as input. The list is an argument for filter() function. The function is called with all items in the list, then it returns a new list which contains only the items that the function evaluates to True.

Note: The map() function takes a function and a list as input. The function is called with all items in the list, then it returns a new list which contains new items that returned by the input function for each item.

In the examples below, you can see how lambda function works in filter() and map() function.

Example: This program takes a list of number and returns just Odd numbers in a new list by using the filter() function

# Program to filter out odd items from the input list 

mixed_list = [5,9,44,36,27,159,3276]

odds = list(filter(lambda a:(a%2), mixed_list))

print('odd numbers:', odds)
odd numbers: [5, 9, 27, 159]

Example: This program takes a list of numbers and returns a new list with new items which are the power of two of the input items by using the map() function.

# Program to power of two each item in a list

my_list = [1,2,3,4,5,6,7,8,9]

new_list = list(map(lambda i: i * i , my_list))

print(new_list)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

Exercise: Complete the program. The program must take a list of numbers then filter the even numbers and returns a new list.

# Program to filter out only the even items from the input list

# take input list from user

number_list1 = 

# make new list with even number by using filter() and lambda function

even_list = 

# print result
print(even_list)

Exercise: Complete the program. The program must take a list of numbers then returns square root of them in a new list.

# Program to display power of two

# take input list from user

number_list2 = 

# store the power of two in new list by using map() and lambda function

new_list = 

# print result
print(new_list)

Global Variables

In Python, a global variable can be notified outside of the function or in global scope. It means, we have access to the global variables inside and outside of the functions.

Example: Let’s see the access and definition of global variables.

# Define a global variable x
num = 10

# Define a function
def fun():
    print("The number inside :", num)

# Call the function and show the variable inside of the function

fun()

# Show the gloabal variable outside of the function
print("The number outside:", num)
The number inside : 10
The number outside: 10

Local Variables

In Python, a local variable can be notified only inside a function or in the scope.

Example: Let’s run the programm bellow and see accessing local variables outside of the scope.

# Define a function and define a local variable inside of it

def function1():
    number1 = 100
    print("The number inside :", number1)

# Check the variable from outside of the function
function1()
print("The number outside:", number1)
The number inside : 100
The number outside: 2.0

When you run the program, the output will be:

The number inside : 100 NameError: name 'number1' is not defined

It shows, the variable (number1) is equal to 100 inside of the function but it is not defined outside of the function.

How to modify a global variable inside a function: In Python, we can define a variable as global inside of a function. We can do it by using this syntax:

global x

Assigning a value to x will then actually modify the global variable instead of creating a new, local one.

Example: In the following example, you can see how we define a global variable inside of the function.

# Define a variable outside of the function
x = "global"

# Define the function
def function2():
    global x  # define the variable as a global variable
    y = "local"   # define the variable as a local variable
    x = x * 2
    print("The variable 'y' inside of the function:", y)
    
function2()

print("The variable 'x' from outside of the function:", x)

The variable 'y' inside of the function: local
The variable 'x' from outside of the function: globalglobal

Nonlocal Variables

We are using nonlocal variables in nested fuctions when the local scope is not defined.It means, the variable can be neither in the local nor the global scope. The syntax to define a nonlocal variable is:

nonlocal x

Example: Let’s run the program to see hoe a nonlocal variable is defined. Then you can change nonlocal x to global x to see the difference between them.

def outer():
    x = "local"
    
    def inner():
        nonlocal x
        x = "nonlocal"
        print("inner:", x)
    
    inner()
    print("outer:", x)

outer()
inner: nonlocal
outer: nonlocal

In the above program, inner() is a nested function. The inner() function is defined in the scope of outer() function. In inner() function, we used nonlocal to define a nonlocal variable. This variable is accessible in inner() and outer() functions. But it is not accessible outside of the outer() function.

Global Keyword

In Python, the global keyword allows you to modify the variable outside of the current scope. We use it to create a global variable and make changes to the variable in a local context.

The basic rules of global keyword in Python are:

  • When we define a variable inside of a function, it is local variable by default.
  • When we define a variable outside of a function, it is global variable by default. It means, we do not need to use global keyword to create it as global.
  • When we define (read and write) a global variable inside of a function, we need to use global keyword.

Exercise: Modify the program below. The program must change the global variable from inside the function by using global keyword. The result of the the print inside and outside of the function must be same.

# Define a global variable
x = 0

# Define a function
def my_function():
    # your code goes here
    
    
    x = x * 2
    print("Inside function(): ",x)
    
my_function()
print("In main program: ",x)

Global Variable Across Python Modules

In Python, we can create a module variable.py and store global variables in it, then share the variables information across the module in the program.

Example: In this example, you can see how we share global variables via python modules.

Note: At first, we must create the module:

variable.py

And define variables in it.

x = 0 y = "empty"

Then import it in the program.

! echo x=0 >>variables.py & echo y="empty">>variables.py
import variables

print(variables.x)
print(variables.y)

variables.x = 100
variables.y = "Leibniz"

print(variables.x)
print(variables.y)
0
empty
100
Leibniz

Python Modules

Module is a file that contains Python code, statements and definitions. When we work on a large program, we can break down the program into small manageable and organized files by using Modules. We can define our most used functions in a module and import it to our new program instead of copying. Modules make our functions reuseable.

Exercise: Let’s create a module. Type the following code in a new file and save it as My_module.py.

# Create a Python Module

def add(x, y):
    """This program take two numbers
    as input, then add two numbers and
    return the result"""
    result = x + y
    
    return result

In this section, we defined a function inside of the module. We can import the module in our program, then call the function and use it.

Import a Module

We can import a module to a program or another module. We use the import keyword to import a module. You can see it in the following:

>>> import My_module

This syntax import the module name in our program, but does not enter the names of the functions which defined inside of the module.

After importing the module in a program, we can use the syntax below to call the function.

My_module.add()

Exercise: Enter the module that you create before (My_module.py) and add these two numbers 10 and 20 by calling the function.

# Enter the module


# call the function and save it in variable result

result = 

print(result)

Python standard modules

Python has a ton of standard modules available. You can check out the full list of standard modules and the applications. These modules files are in the Lib directory inside the location that you installed python in your computer.

You can import standard modules same way that we import our module (user-defined modules).

In python, we have several ways to import a module in our programm. You can see a list of them with example as follows.

import statement

Import a module using import statement and call the definition (functions) inside it using dot . operator.

Example:

import math

PI = math.pi

print("The value of pi is: ", PI)
The value of pi is:  3.141592653589793

Renaming

We can import a module by renaming it.

Example:

import math as m

PI_2 = m.pi

print("The value of pi is: ", PI_2)
The value of pi is:  3.141592653589793

From…import statement

We can import specific name, definition or function from a module without importing whole module.

Example:

from math import pi

print("The value of pi is: ", pi)

The value of pi is:  3.141592653589793

Import all names

We can import all names, definition or functions from the module.

Example:

from math import *

print("The value of e is: ", e)

The value of e is:  2.718281828459045

Python Package

In Python, we are using packages to make our application program’s modules well-organized. When our application programs grows too large with a lot of modules, we can keep similar modules in one package and different modules in different package. This makes our program project easy to manage. A directory must contain a file __init__.py in order for Python to consider it as a package. We can leave this file empty, but we generally place the initialization code for that package in this file. Here is an example of Pythons package structure.

PackageModuleStructure.jpg

Image Source: www.programize.com

Importing module from a package

We can import modules from packages using dot(.) operator.

For example:

import Game.Level.start

Now we can call the function from start,

start.function1()

Or, we can import it in this way,

from Game.Level import start

Then, we can call the function directly,

function1()


Author: Mohsen Soleymanighezelgechi
Last modified: 10.09.2019