0% found this document useful (0 votes)
14 views

9 - Functions

Uploaded by

fersd2018
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

9 - Functions

Uploaded by

fersd2018
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

II.

Code reuse

9. Functions
Function:
• has a name to run this code block as many times as you want
– launch of function code is called a function call
• function parameters are usually defined when creating a function.
– function parameters determine which arguments a function can accept
– arguments can be passed to functions
– function code will be executed taking into account the specified arguments

Creation of functions
Creation of function:
• functions are created with a reserved word def
• def followed by function name and parentheses
• parameters that function accepts inside parentheses
• after parentheses goes colon and from a new line with indent there is a block of
code that function executes
• optionally, the first line can be docstring
• function can use return operator
– it is used to terminate and exit a function
– most often return operator returns some value
Example of function:
def configure_intf(intf_name, ip, mask):
print('interface', intf_name)
print('ip address', ip, mask)

Function call
When calling a function you must specify its name and pass arguments if necessary.
configure_intf('F0/0', '10.1.1.1', '255.255.255.0')

49
Operator return
Operator return is used to return a value, and at the same time it exits the function.
Function can return any Python object. By default, function always returns None.
def configure_intf(intf_name, ip, mask):
config = f'interface {intf_name}\nip address {ip} {mask}'
return config

result = configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')

Function can return multiple values. In this case, they are separated by a comma after
return operator. In fact, function returns tuple:
def configure_intf(intf_name, ip, mask):
config_intf = f'interface {intf_name}\n'
config_ip = f'ip address {ip} {mask}'
return config_intf, config_ip

result = configure_intf('Fa0/0', '10.1.1.1', '255.255.255.0')


# ('interface Fa0/0\n', 'ip address 10.1.1.1 255.255.255.0')

type(result) # tuple

Documentation (docstring)
The first line in function definition is docstring, documentation string. This is a comment
that is used to describe a function:
def configure_intf(intf_name, ip, mask):
'''
Function generates interface configuration
'''
config_intf = f'interface {intf_name}\n'
config_ip = f'ip address {ip} {mask}'
return config_intf, config_ip

print(configure_intf.__doc__)

Function parameter types


When creating a function you can specify which arguments must be passed and which
must not. Accordingly, a function can be created with:
• required parameters
• optional parameters (with default values)

50
Optional parameters (default parameters)
When creating a function you can specify default value for parameter in this way:
def check_passwd(username, password, min_length=8).
In this case, min_length option is specified with default value and may not be passed
when a function is called.

Function argument types


When a function is called the arguments can be passed in two ways:
• as positional - passed in the same order in which they are defined at creation of
function. That is, the order in which arguments are passed determines what value
each argument will receive.
Example:
def check_passwd(username, password):

check_passwd('nata', '12345')

• as keyword - passed with argument name and its value. In such a case,
arguments can be stated in any order as their name is clearly indicated.
Example:
def check_passwd(username, password):

check_passwd(password='12345', username='nata', min_length=4)

Variable length arguments


Sometimes it is necessary to make function accept not a fixed number of arguments, but
any number. For such a case, in Python it is possible to create a function with a special
parameter that accepts variable length arguments. This parameter can be both keyword
and positional.

Variable length positional arguments


Parameter that takes positional variable length arguments is created by adding an asterisk
before parameter name. Parameter can have any name but by agreement *args is the
most common name.

51
Example of a function:
def sum_arg(a, *args):
print(a, args)
return a + sum(args)

sum_arg(1, 10, 20, 30)


# 1 (10, 20, 30)
# 61

Function sum_arg is created with two parameters:


• parameter a
– if passed as positional argument, should be first
– if passed as a keyword argument, the order does not matter
• parameter *args
- expects variable length arguments
– all other arguments as a tuple
– these arguments may be missed

Keyword variable length arguments


Parameter that accepts keyword variable length arguments is created by adding two
asterisk in front of parameter name. Name of parameter can be any but by agreement
most commonly use name **kwargs (from keyword arguments).
def sum_arg(a, **kwargs):
print(a, kwargs)
return a + sum(kwargs.values())

sum_arg(a=10, b=10, c=20, d=30)


# 10 {'c': 20, 'b': 10, 'd': 30}
# 70

Function sum_arg is created with two parameters:


• parameter a
– if passed as positional argument, should be first
– if passed as a keyword argument, the order does not matter
• parameter **kwargs
- expects keyword variable length arguments
– all other keyword arguments as a dictionary
– these arguments may be missed

52
Unpacking arguments
In Python the expressions *args and **kwargs allow for another task - unpacking
arguments.

Unpacking positional arguments


For example, when formatting strings you often need to pass multiple arguments to format
method. And often these arguments are already in list or tuple. To pass them to format
method you have to use indexes:
items = [1, 2, 3]
print('One: {}, Two: {}, Three: {}'.format(items[0], items[1],
items[2]))
# One: 1, Two: 2, Three: 3

Instead, you can take advantage of unpacking argument and do this:


items = [1, 2, 3]
print('One: {}, Two: {}, Three: {}'.format(*items))
# One: 1, Two: 2, Three: 3

Another example is config_interface function:


def config_interface(intf_name, ip_address, mask):
interface = f'interface {intf_name}'
no_shut = 'no shutdown'
ip_addr = f'ip address {ip_address} {mask}'
result = [interface, no_shut, ip_addr]
return result

interfaces_info = [['Fa0/1', '10.0.1.1', '255.255.255.0'],


['Fa0/2', '10.0.2.1', '255.255.255.0'],
['Lo0', '10.0.0.1', '255.255.255.255']]

for info in interfaces_info:


print(config_interface(*info))

'''
['interface Fa0/1', 'no shutdown', 'ip address 10.0.1.1 255.255.255.0']
['interface Fa0/2', 'no shutdown', 'ip address 10.0.2.1 255.255.255.0']
['interface Lo0', 'no shutdown', 'ip address 10.0.0.1 255.255.255.255']
'''

Python will unpack info list itself and pass list elements to function as arguments.

53
Unpacking keyword arguments
Similarly, you can unpack dictionary to pass it as keyword arguments.

Example:
def check_passwd(username, password, min_length=8,
check_username=True):
if len(password) < min_length:
print('Password is too short')
return False
elif check_username and username in password:
print('Password contains username')
return False
else:
print(f'Password for user {username} has passed all checks')
return True

username_passwd = [{'username': 'cisco', 'password': 'cisco'},


{'username': 'nata', 'password': 'natapass'},
{'username': 'user', 'password': '123456789'}]

for data in username_passwd:


check_passwd(**data)

Python unpacks dictionary and passes it to function as keyword arguments. The


check_passwd(**data) is converted to a check_passwd(username='cisco',
password='cisco').

54
Tasks

Task 9.1 :
Create generate_access_config function that generates configuration for access ports.

The function expects arguments:


• a dictionary with interface as a key and VLAN as a value (access_config or
access_config_2 dict)
• access ports configuration template as a list of commands
(access_mode_template list)

The function should return a list of all ports in access mode with configuration based on
the access_mode_template template.

In this task, the beginning of the function is written and you just need to continue writing
the function body itself.

An example of a final list (each string is written on a new line for readability):
[
"interface FastEthernet0/12",
"switchport mode access",
"switchport access vlan 10",
"switchport nonegotiate",
"spanning-tree portfast",
"spanning-tree bpduguard enable",
"interface FastEthernet0/17",
"switchport mode access",
"switchport access vlan 150",
"switchport nonegotiate",
"spanning-tree portfast",
"spanning-tree bpduguard enable",
...]

Check the operation of the function using the access_config dictionary and the list of
commands access_mode_template. If the previous check was successful, check the
function again using the dictionary access_config_2 and make sure that the final list
contains the correct interface numbers and vlans.

access_mode_template = [
"switchport mode access",
"switchport access vlan",
"switchport nonegotiate",
"spanning-tree portfast",
"spanning-tree bpduguard enable",
]

55
access_config = {"FastEthernet0/12": 10, "FastEthernet0/14": 11,
"FastEthernet0/16": 17}

access_config_2 = {
"FastEthernet0/3": 100,
"FastEthernet0/7": 101,
"FastEthernet0/9": 107,
}

def generate_access_config(intf_vlan_mapping, access_template):


"""
intf_vlan_mapping is a dictionary with interface-VLAN mapping:
{'FastEthernet0/12': 10,
'FastEthernet0/14': 11,
'FastEthernet0/16': 17}
access_template - list of commands for the port in access mode

Returns a list of commands.


"""

Task 9.1a :
Make a copy of the code from the task 9.1.
Add this functionality: add an additional parameter that controls whether port-security
configured
• parameter name ‘psecurity’
• default is None
• to configure port-security, a list of commands must be passed as a value
port-security (port_security_template list)

The function should return a list of all ports in access mode with configuration based on
the access_mode_template template and the port_security_template template, if passed.
There should not be a new line character at the end of lines in the list.

Check the operation of the function using the example of the access_config dictionary,
with the generation of the configuration port-security and without.

An example of a function call:


print(generate_access_config(access_config, access_mode_template))
print(generate_access_config(access_config, access_mode_template,
port_security_template))

56
access_mode_template = [
"switchport mode access",
"switchport access vlan",
"switchport nonegotiate",
"spanning-tree portfast",
"spanning-tree bpduguard enable",
]

port_security_template = [
"switchport port-security maximum 2",
"switchport port-security violation restrict",
"switchport port-security"
]

access_config = {"FastEthernet0/12": 10, "FastEthernet0/14": 11,


"FastEthernet0/16": 17}

57

You might also like