Python Unit 3
Python Unit 3
Python Unit 3
UNIT III
LISTS:
List is used to store the group of values & we can manipulate them, in list thevalues
are storesin index format starts with 0.
List is mutable object so we can do the manipulations.
A python list is enclosed between square ([]) brackets.
In list insertion order is preserved it means in which order we inserted elementsame
orderoutput is printed.
A list can be composed by storing a sequence of different type of values separatedby
commas.
The list contains forward indexing & backward indexing.
Example:
lst=[5,7,1,8,9,6]
del lst[3] # delete 3rd element from the list i.e., 8
print(lst) # [5,7,1,9,6]
If we want to delete entire list, we can give statement like del lst.
Concatenation of Two lists:
We can simply use „+‟ operator on two lists to join them. For example, „x‟ and „y‟ are two lists. Ifwe wrte
x+y, the list „y‟ is joined at the end of the list „x‟.
Example:
x=[10,20,32,15,16]
y=[45,18,78,14,86]
print(x+y) # [10,20,32,15,16,45,18,78,14,86]
Repetition of Lists:
We can repeat the elements of a list „n‟ number of times using „*‟ operator.
x=[10,54,87,96,45]
print(x*2) # [10,54,87,96,45,10,54,87,96,45]
Membership in Lists:
We can check if an element is a member of a list by using „in‟ and „not in‟ operator. If the element is a
member of the list, then „in‟ operator returns True otherwise returns False. If the element is not in the list,
then „not in‟ operator returns True otherwise returns False.
Example:
x=[10,20,30,45,55,65]a=20
print(a in x) # Truea=25
print(a in x) # Falsea=45
print(a not in x) # Falsea=40
print(a not in x) # True
Methods in Lists:
1. A.index(X): Returns the first occurrence of X in the list A.
PROGRAM Output
A=[1,3,13,45,56,62,45,58,89,13,3,56,1] 3
print(A.index(45))
Program Output
A=[1,3,13,45,56,62,45,58,89,13,3,56,1] [1, 3, 13, 45, 56, 62, 45, 58, 89, 13, 3, 56, 1, 97]
A.append(97)
print(A)
Program Output
program output
A=[1,2,3,4,5] 5
print(len(A))
Nested Lists:
A list within another list is called a nested list. We know that a list contains several elements. When we
take a list as an element in another list, then that list is called a nested list.
program output
a=[[1,2,3],[4,5,6],[7,8,9]] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(a) [4, 5, 6]
print(a[1]) 5
print(a[1][1]) [7, 8, 9]
print(a[2])
Range of Negative Indexes: Specify negative indexes if you want to start thesearch from
theend of the list.
Example: x = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(x[-4:-1])
Output: ['orange', 'kiwi', 'melon']
Check if Item Exists: To determine if a specified item is present in a list use the inkeyword.
Example: Check if "apple" is present in the list:
fruits= ["apple", "banana", "cherry"]if
"apple" in fruits:
print("Yes, 'apple' is in the fruits list")
Output: Yes, 'apple' is in the fruits list
Change Item Value:
To change the value of a specific item, refer to the index number.
Example: Change the second value by replacing it with two new values:
x = ["apple", "banana", "cherry"]
x[1] = ["blackcurrant", "watermelon"]
print(x)
Output: ['apple', ['blackcurrant', 'watermelon'], 'cherry']
Change a Range of Item Values
To change the value of items within a specific range, define a list with the new values, and
referto the range of index numbers where you want to insert the new values.
Example: Change the values "banana" and "cherry" with the values "blackcurrant" and
"watermelon":
x = ["apple", "banana", "cherry", "orange", "kiwi", "mango"]
x[1:3] = ["blackcurrant", "watermelon"]
print(x)
Output: ['apple', 'blackcurrant', 'watermelon', 'orange', 'kiwi', 'mango']
Loop Through a List:
We can loop through the list items by using a for loop.Print
all items in the list, one by one.
Use the range() and len() functions to print all items by referring to their index number:
Example – 1:
thislist = ["apple", "banana", "cherry"]
for x in thislist:
print(x)
Output:
apple banana
cherry
Using a While Loop: Use the len() function to determine the length of the list, then start at
0and loop your way through the list items by refering to their indexes. Remember to
increase theindex by 1 after each iteration.
Example – 1:
thislist = ["apple", "banana", "cherry"]i = 0
while i < len(thislist):
print(thislist[i]) i = i
+ 1 Output:
apple
banana
cherry
Customize Sort Function: we can also customize you own function by using the
keywordargument key = function. The function will return a number that will be used tosort
the list (thelowest number first):
Example -1: Sort the list based on how close the number is to 50:
def myfunc(n):
return abs(n - 50)
thislist = [100, 50, 65, 82, 23]
thislist.sort(key = myfunc) print(thislist)
Output:
[50, 65, 23, 82, 100]
Note: By default the sort() method is case sensitive, resulting in all capital letters being
sorted after lower case letters:
Example – 1:
List1 = ["banana", "Orange", "Kiwi", "cherry"]
List1.sort()
print(List1)
Output: ['Kiwi', 'Orange', 'banana', 'cherry']
Case Insensitive Sort: we can use built-in functions as key functions when sorting a list.So if
you want a case-insensitive sort function, use str.lower as a key function.
Example – 1:
List1 = ["banana", "Orange", "Kiwi", "cherry"]
List1.sort(key = str.lower)
print(List1)
Output: ['banana', 'cherry', 'Kiwi', 'Orange']
Output:
Empty Dictionary:
{}
Dictionary with the use of dict():
{1: 'Geeks', 2: 'For', 3: 'Geeks'}
Dictionary with each item as a pair:
{1: 'Geeks', 2: 'For'}
Accessing Values
To access dictionary elements, you can use the familiar square brackets along with the key to obtainits
value.
Example:
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}print
("Name:", dict['Name'])
print ("Age:", dict['Age'])
Output:
Name: ZaraAge:
7
If we attempt to access a data item with a key, which is not part of the dictionary, we get an error.
Example:
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}print
("Name:", dict['Alice'])
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module> print
("Name:", dict['Alice'])
KeyError: 'Alice'
There is also a method called get() that will also help in accessing the element from a dictionary.
Example:
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
print(dict.get('Class'))
Output:
First
print(dict)
# Updating existing Key's Valuedict[2]
= 'Welcome' print("\nUpdated key
value: ") print(dict)
# Adding Nested Key value to Dictionary dict[5]
= {'Nested' :{'1' : 'Good', '2' : 'Day'}}
print("\nAdding a Nested Key: ")
print(dict)
Output:
Empty Dictionary:
{}
Dictionary after adding 3 elements:
{0: 'Pragati', 2: 'Engineering', 3: 'College'}
Nested Dictionaries
A nested dictionary is a dictionary inside a dictionary. It's a collection of dictionaries into one single
dictionary.
nested_dict = { 'dictA': {'key_1': 'value_1'},
'dictB': {'key_2': 'value_2'}}
Here, the nested_dict is a nested dictionary with the dictionary dictA and dictB. They are two
dictionary each having own key and value.
Creating a Nested Dictionary:
Example:
people = {1: {'name': 'John', 'age': '27', 'sex': 'Male'},
2: {'name': 'Marie', 'age': '22', 'sex': 'Female'}}
print(people)
Output:
{1: {'name': 'John', 'age': '27', 'sex': 'Male'}, 2: {'name': 'Marie', 'age': '22', 'sex': 'Female'}}
In the above program, people is a nested dictionary. The internal dictionary 1 and 2 is assigned to people.
Here, both the dictionary have key name, age , sex with different values. Now, we print theresult of people.
Accessing elements of a Nested Dictionary:
To access element of a nested dictionary, we use indexing [] syntax in Python.
Example:
people = {1: {'name': 'John', 'age': '27', 'sex': 'Male'},
2: {'name': 'Marie', 'age': '22', 'sex': 'Female'}}
print(people[1]['name'])
print(people[1]['age'])
print(people[1]['sex'])
Output:
John27
Male
Adding element to a Nested Dictionary
people = {1: {'name': 'John', 'age': '27', 'sex': 'Male'},
2: {'name': 'Marie', 'age': '22', 'sex': 'Female'}}
people[3] = {}
people[3]['name'] = 'Luna'
people[3]['age'] = '24'
The indices of list are integers starting from 0. The keys of dictionary can be of any data type.
The elements are accessed via indices. The elements are accessed via key-values.
The order of the elements entered is maintained. There is no guarantee for maintaining order.
Dictionary Methods:
Python has a set of built-in methods that you can use on dictionaries.
Method Description
clear() Removes all the elements from the dictionary
copy() Returns a copy of the dictionary
fromkeys() Returns a dictionary with the specified keys and value
get() Returns the value of the specified key
items() Returns a list containing a tuple for each key value pair
keys() Returns a list containing the dictionary's keys
pop() Removes the element with the specified key
popitem() Removes the last inserted key-value pair
setdefault() Returns the value of the specified key. If the key does not exist:
insert the key, with the specified value
update() Updates the dictionary with the specified key-value pairs
values() Returns a list of all the values in the dictionary
1. Dictionary clear():
The clear() method removes all the elements from a dictionary.
Syntax: dictionary.clear()
Example: Remove all elements from the car list. car =
{
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
car.clear()
print(car)
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
Output: {}
2. Dictionary copy():
You cannot copy a dictionary simply by typing dict2 = dict1, because: dict2 will only beareference to
dict1, and changes made in dict1 will automatically also be made in dict2.
The copy() method returns a copy of the specified dictionary.
Syntax: dictionary.copy() Example:
Copy the car dictionary.car = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
x = car.copy()
print(x)
Output: {'brand': 'Ford', 'model': 'Mustang', 'year': 1964}
The view object will reflect any changes done to the dictionary.
Syntax: dictionary.items()
Example-1: Return the dictionary's key-value pairs:
car = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
x = car.items()
print(x)
Output: dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 1964)])
6. Dictionary keys():
The keys() method returns a view object. The view object contains the keys of the
dictionary, asa list.
The view object will reflect any changes done to the dictionary.
Syntax: dictionary.keys() Example
– 1: Return the keys.car = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
x = car.keys()
print(x)
Output: dict_keys(['brand', 'model', 'year'])
7. Dictionary pop():
The pop() method removes the specified item from the dictionary.
The value of the removed item is the return value of the pop() method.
Syntax: dictionary.pop(keyname, defaultvalue) Here,
keyname Required. The keyname of the item you want to remove
defaultvalue Optional. A value to return if the specified key do not exist. If this parameteris not
specified, and the no item with the specified key is found, an error is raised.
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
Example: 1 Remove "model" from the dictionary.
car = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
car.pop("model") print(car)
Output: {'brand': 'Ford', 'year': 1964}
8. Dictionary popitem():
The popitem() method removes the item that was last inserted into the dictionary. In
versionsbefore 3.7, the popitem() method removes a random item.
The removed item is the return value of the popitem() method, as a tuple.
Syntax: dictionary.popitem()
Example: 1 Remove the last item from the dictionary. car =
{
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
car.popitem()
print(car)
Output: {'brand': 'Ford', 'model': 'Mustang'}
9. Dictionary setdefault():
The setdefault() method returns the value of the item with the specified key. If the
key does not exist, insert the key, with the specified value.
Syntax: dictionary.setdefault(keyname, value) Here,
keyname Required. The keyname of the item you want to return the value from
value Optional. If the key exist, this parameter has no effect. If the
key does not exist, this value becomes the key's value Default
value None.
Example: 1 Get the value of the "model" item.car =
{
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
x = car.setdefault("model", "Bronco")
print(x)
Output: Mustang
The view object will reflect any changes done to the dictionary, see example below.
Syntax: dictionary.values()
Example: 1 Return the values.car =
{
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
x = car.values()
print(x)
Output: dict_values(['Ford', 'Mustang', 1964])
12.del
The del keyword removes the item with the specified key name.
Example: 1 thisdict =
{ "brand": "Ford",
"model": "Mustang",
"year": 1964
}
del thisdict["model"]
print(thisdict)
Output: {'brand': 'Ford', 'year': 1964}
Syntax of Function:
def function_name(parameters):
"""docstring"""
statement(s)
return
Above shown is a function definition that consists of the following components.
Pass by Value:
Pass by value represents that a copy of the variable value is passed to the function and any modifications to
that value will not reflect outside the function. In python, the values are sent to functions by means of
object references. We know everything is considered as an object in python.All numbers, strings, tuples,
lists and dictionaries are objects.
If we store a value into a variable as:
x=10
In python, everything is an object. An object can be imagined as a memory block where we can store some
value. In this case, an object with the value „10‟ is created in memory for which a name „x‟ is attached.
So, 10 is the object and „x‟ is the name or tag given to that object. Also, objects are created on heap
memory which is a very huge memory that depends on the RAM of our computer system.
Example:
def add(a,b): # a, b are formal arguments
c=a+b print(c)
x,y=10,15
add(x,y) # x, y are actual arguments
The actual arguments used in a function call are of 4 types:
a) Positional arguments
b) Keyword arguments
c) Default arguments
d) Variable length arguments
a) Positional Arguments:
These are the arguments passed to a function in correct positional order. Here, the number of arguments
and their position in the function definition should match exactly with the number and position of
argument in the function call.
def attach(s1,s2):
s3=s1+s2 print(s3)
attach("New","Delhi") #Positional arguments
This function expects two strings that too in that order only. Let‟s assume that this function attaches the
two strings as s1+s2. So, while calling this function, we are supposed to pass only two strings as:
attach("New","Delhi")
The preceding statements displays the following output NewDelhiSuppose, we passed "Delhi" first and then "New",
then the result will be: "DelhiNew". Also, if we tryto pass more than or less than 2 strings, there will be an error.
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
b) Keyword Arguments:
Keyword arguments are arguments that identify the parameters by their names. For example, thedefinition
of a function that displays grocery item and its price can be written as:
def grocery(item, price):
At the time of calling this function, we have to pass two values and we can mention which value is for
what. For example,
grocery(item=’sugar’, price=50.75)
Here, we are mentioning a keyword „item‟ and its value and then another keyword „price‟ and its value.
Please observe these keywords are nothing but the parameter names which receive these values. We can
change the order of the arguments as:
grocery(price=88.00, item=’oil’)
In this way, even though we change the order of the arguments, there will not be any problem as theparameter
names will guide where to store that value.
def grocery(item,price):
print("item=",item)
print("price=",price)
grocery(item="sugar",price=50.75) # keyword arguments
grocery(price=88.00,item="oil") # keyword arguments Output:
item= sugar price=
50.75item= oil
price= 88.0
c) Default Arguments:
We can mention some default value for the function parameters in the definition. Let‟s take thedefinition of
grocery( ) function as:
def grocery(item, price=40.00)
Here, the first argument is „item‟ whose default value is not mentioned. But the second argument
is „price‟ and its default value is mentioned to be 40.00. at the time of calling this function, if we do not
pass „price‟ value, then the default value of 40.00 is taken. If we mention the „price‟ value, then that
mentioned value is utilized.
So, a default argument is an argument that assumes a default value if a value is not provided in the function
call for that argument.
Example: def grocery(item,price=40.00):
print("item=",item) print("price=",price)
grocery(item="sugar",price=50.75)
grocery(item="oil")
Output:
item= sugar price=
50.75
item= oil
price= 40.0
d) Variable Length Arguments:
Sometimes, the programmer does not know how many values a function may receive. In that case,the
programmer cannot decide how many arguments to be given in the function definition. for example, if the
programmer is writing a function to add two numbers, he/she can write:
add(a,b)
But, the user who is using this function may want to use this function to find sum of three numbers. In that
case, there is a chance that the user may provide 3 arguments to this function as:
add(10,15,20)
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
Then the add( ) function will fail and error will be displayed. If the programmer want to develop a function
that can accept „n‟ arguments, that is also possible in python. For this purpose, a variable length argument
is used in the function definition. a variable length argument is an argument that canaccept any number of
values. The variable length argument is written with a „*‟ symbol before it in the function definition as:
def add(farg, *args):
here, „farg‟ is the formal; argument and „*args‟ represents variable length argument. We can pass 1 or
more values to this „*args‟ and it will store them all in a tuple.
Example:
def add(farg,*args):
sum=0
for i in args:
sum=sum+i
print("sum is",sum+farg)add(5,10)
add(5,10,20)
add(5,10,20,30)
Output:
sum is 15
sum is 35
sum is 65
The docstrings for classes should summarize its behavior and list the public
methods andinstance variables.
The subclasses, constructors, and methods should each have their own docstrings.
Example 5: Docstrings for Python class.
class Person:
"""
A class to represent a person.
...
Attributes
name : str
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
first name of the personage :
int
age of the person
"""
Methods
info(additional=""):
Prints the person's name and age.
"""
def info(self, additional=""): """
Prints the person's name and age.
If the argument 'additional' is passed, then it is appended after the main info.
Output:
>>> print(Person. doc )
Types of Functions:
Basically, we can divide functions into the following two types:
1. Built-in functions - Python has several functions that are readily available for use.
These functionsare called built-in functions.
Examples:
abs(),any(),all(),ascii(),bin(),bool(),callable(),chr(),compile(),classmethod(),delattr(),dir(),
divmod(),staticmethod(),filter(),getattr(),globals(),exec(),hasattr(),hash(),isinstance(),issu
bclass(),iter(),locals(), map(), next(),memoryview(),object(),property(),repr(),reversed(),vars(),
import (),super() Note: Refer this link https://www.programiz.com/python-
programming/methods/built- in/abs for detailed explanation of each function.
2. User-defined functions -
• Functions that we define ourselves to do certain specific task are referred as user-
definedfunctions.
• If we use functions written by others in the form of library, it can be termed as library
functions.
• All the other functions that we write on our own fall under user-defined functions. So, our
user-defined function could be a library function to someone else.
Advantages of user-defined functions:
• User-defined functions help to decompose a large program into small segments which
makesprogram easy to understand, maintain and debug.
• If repeated code occurs in a program. Function can be used to include those codes and
executewhen needed by calling that function.
• Programmars working on large project can divide the workload by making different
functions.
Example:
def add_numbers(x,y):
sum = x + y
return sum num1
=5
num2 = 6
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
print("The sum is", add_numbers(num1, num2))
Output:
The sum is 11
Recursive Function:
• A function that calls itself is known as Recursive Function.
• A physical world example would be to place two parallel mirrors facing each other. Any object
inbetween them would be reflected recursively.
• The following image shows the working of a recursive function called recurse.
Example:
• •Factorial of a number is the product of all the integers from 1 to that number.
• •the factorial of 6 (denoted as 6!) is 1*2*3*4*5*6 = 720.
def factorial(x):
if x == 1:
return 1else:
return (x * factorial(x-1))num =
3
print("The factorial of", num, "is", factorial(num))
Output:
The factorial of 3 is 6
This recursive call can be explained in the following steps. factorial(3)
# 1st call with 3
3 * factorial(2) # 2nd call with 2
3 * 2 * factorial(1) # 3rd call with 1
3 * 2 * 1 # return from 3rd call as number=1 3 * 2 #
return from 2nd call
6 # return from 1st call
Advantages of Recursion:
1.Recursive functions make the code look clean and elegant.
2.A complex task can be broken down into simpler sub-problems using recursion.
3.Sequence generation is easier with recursion than using some nested iteration.
Disadvantages of Recursion:
Example use with filter(): The filter() function in Python takes in a function and a list as arguments.#
Program to filter out only the even items from a list
my_list = [1, 5, 4, 6, 8, 11, 3, 12]
new_list = list(filter(lambda x: (x%2 == 0) , my_list))
print(new_list)
Output:
[4, 6, 8, 12]
Example use with map(): The map() function in Python takes in a function and a list.#
Program to double each item in a list using map()
my_list = [1, 5, 4, 6, 8, 11, 3, 12]
new_list = list(map(lambda x: x * 2 , my_list))
print(new_list)
Output: [2, 10, 8, 12, 16, 22, 6, 24]
• The lifetime of a variable is the period throughout which the variable exits in the memory. The
lifetimeof variables inside a function is as long as the function executes.
• They are destroyed once we return from the function. Hence, a function does not remember thevalue
VKR,VNB&AGK COLLEGE OF ENGINEERING
R20 Python Unit-3
ofa variable from its previous calls.
Example:
def my_fun():
x = 10
print("Value inside function:",x)x = 20
my_fun()
print("Value outside function:",x)
Output:
Value inside function: 10 Value
outside function: 20Explanation:
• Here, we can see that the value of x is 20 initially. Even though the function my_fun() changed
thevalue of x to 10, it did not affect the value outside the function.
• This is because the variable x inside the function is different (local to the function) from the one
outside.Although they have the same names, they are two different variables with different scopes.
Python Modules
• Modules refer to a file containing Python statements and definitions.We use modules to break
downlarge programs into small manageable and organized files. Furthermore, modules provide
reusability ofcode.
• We can define our most used functions in a module and import it, instead of copying their
definitionsinto different programs.
This does not import the names of the functions defined in example directly in the current symbol table. It
only imports the module name example there. Using the module name we can access the function using the
dot . operator.
Example:
>>> example.add(4,5.5)
9.5
Python has lots of standard modules. Refer standard modules in UNIT-1 Material. These files are
in the Lib directory inside the location where you installed Python. There
are various ways to import modules. They are listed below.. 1.Python
import statement
2.import with renaming
3.Python from...import statement
4.import all names
Example:
import math
print("The value of pi is", math.pi)
Output:
The value of pi is 3.141592653589793
Example:
import math as m
print("The value of pi is", m.pi)
3. Python from...import statement:
• We can import specific names from a module without importing the module as a whole. Here,
weimported only the pi attribute from the math module. In such cases, we don't use the dot operator.
Example:1
from math import pi
print("The value of pi is", pi)
• Importing everything with the asterisk (*) symbol is not a good programming practice. This can lead
toduplicate definitions for an identifier. It also hampers the readability of our code.
Example:
from math import * print("The
value of pi is", pi)
Python Package
• We don't usually store all of our files on our computer in the same location. We use a well-
organizedhierarchy of directories for easier access.
• Similar files are kept in the same directory, for example, we may keep all the songs in the
"music"directory. Analogous to this, Python has packages for directories and modules for files.
• As our application program grows larger in size with a lot of modules, we place similar modules in
onepackage and different modules in different packages. This makes a project (program) easy to
manageand conceptually clear.
• Similarly, as a directory can contain subdirectories and files, a Python package can have sub-
packagesand modules.
• Here is an example. Suppose we are developing a game. One possible organization of packages
andmodules could be as shown in the figure below.
• While importing packages, Python looks in the list of directories defined in sys.path, similar asfor
module search path.
print(shout('Hello'))
print(yell('Hello'))
Output:
HELLO
HELLO
Decorators
Decorators are the most common use of higher-order functions in Python. It allows
programmers to modify the behavior of function or class. Decorators allow us to
wrap another function in order to extend the behavior of wrapped function, without
permanently modifying it. In Decorators, functions are taken as the argument into
another function and then called inside the wrapper function.
Syntax:
@gfg_decorator
def hello_decorator():
.
.
.
def hello_decorator():
.
.
.
hello_decorator = gfg_decorator(hello_decorator)
In the above code, gfg_decoratoris a callable function, will addsome code on
the top of some another callable
function, hello_decoratorfunction and return the wrapper function.
Example:
# defining a decorator
def hello_decorator(func):
# inner function can access the outer local# functions like in this case
"func"
def inner1():
print("Hello, this is before functionexecution")
function_to_be_used()