Summer-2022 Examination Subject Name: Programming With Python Model Answer Subject Code: 22616
Summer-2022 Examination Subject Name: Programming With Python Model Answer Subject Code: 22616
Subject Name: Programming with Python Model Answer Subject Code: 22616 length
List operations are more error Tuples operations are safe
Important Instructions to examiners: prone.
1. The answers should be examined by key words and not as word-to-word as given in Lists can be used to store Tuples are used to store only
the model answer scheme. homogeneous and heterogeneous elements.
heterogeneous elements.
2. The model answer and the answer written by candidate may vary but the examiner
List is useful for insertion and Tuple is useful for readonly
may try to assess the understanding level of the candidate.
deletion operations. operations like accessing
3. The language errors such as grammatical, spelling errors should not be given more elements.
Importance (Not applicable for subject English and Communication Skills. List iteration is slower and is Tuple iteration is faster.
4. While assessing figures, examiner may give credit for principal components time consuming.
indicated in the figure. The figures drawn by candidate and model answer may vary. d) Explain Local and Global variable 2M (1m each)
The examiner may give credit for any equivalent figure drawn. Local Variables: Local variables are those which are initialized
5. Credits may be given step wise for numerical problems. In some cases, the assumed inside a function and belongs only to that particular function. It
constant values may vary and there may be some difference in the candidate’s cannot be accessed anywhere outside the function
answers and model answer. Example:
def f():
6. In case of some questions credit may be given by judgement on part of examiner of
# local variable
relevant answer based on candidate’s understanding. s = "I love Python Programming"
7. For programming language papers, credit may be given to any other program based print(s)
on equivalent concept. # Driver code
f()
8. As per the policy decision of Maharashtra State Government, teaching in
Output
English/Marathi and Bilingual (English + Marathi) medium is introduced at first year I love Python Programming
of AICTE diploma Programme from academic year 2021-2022. Hence if the students
in first year (first and second semesters) write answers in Marathi or bilingual Global Variables: The global variables are those which are defined
language (English +Marathi), the Examiner shall consider the same and assess the outside any function and which are accessible throughout the
answer based on matching of concepts with model answer. program i.e. inside and outside of every function.
Example:
# This function uses global variable s
Q. Sub Answer Marking Scheme
def f():
No. Q. N.
print("Inside Function", s)
1 Attempt Any FIVE of the following 10
a) Name different modes of Python 2M (1m each)
# Global scope
Python has two basic modes:
s = "I love Python Programming"
• Script (Normal Mode)
f()
• Interactive Mode print("Outside Function", s)
b) List identity operators in python 2M (1m each)
Identity operators in Python are Output:
• is Inside Function I love Python Programming
• is not Outside Function I love Python Programming
c) Give two differences between list and tuple 2M (1m for each e) Define class and object in python 2M (Any suitable
List Tuple difference, any 2 Class: A class is a user-defined blueprint or prototype from which definition: 1M
Lists are mutable Tuples are immutable difference) objects are created. Classes provide a means of bundling data Each)
Lists consume more memory Tuple consume less memory and functionality together.
as compared to the list
Lists have several built-in Tuple does not have many Object: An object is an instance of a class that has some
methods built-in methods. attributes and behavior. Objects can be used to access the
The unexpected changes and In tuple, it is hard to take attributes of the class.
errors are more likely to occur place.
Page 1 of 23 Page 2 of 23
f) How to give single and multiline comment in Python 2M (1m each)
Single line comment: Single-line comments are created simply by
beginning a line with the hash (#) character, and they are
automatically terminated by the end of line.
Example:
# print is a statement
print(‘Hello Python’)
Page 3 of 23 Page 4 of 23
statements Example: For number data types are integers.
. >>>a=10
. >>>b -10
Example: To determine the type of a variable type() function is used.
def square( x ):
>>>type(a)
print("Square=",x*x)
>>> <class 'int'>
# Driver code
square(2) 2. Boolean (Bool Data Type: The simplest build-in type in
Output: Python is the bool type, it represents the truth values False
Square= 4 and True. Internally the true value is represented as 1 and
d) Write a program to create class EMPLOYEE with ID and NAME 4M (for correct false is 0.
and display its contents. program and For example
class employee : logic) >>>a = 18 > 5
id=0 >>>print(a)
name="" True
def getdata(self,id,name): b=2>3
self.id=id
print(b)
self.name=name
def showdata(self):
False
print("ID :", self.id)
print("Name :", self.name) 3. Floating-Point/Float Numbers (Float Data Type): Floating-
point number or Float is a positive or negative number with
e = employee() a fractional part. A floating point number is accurate up to 15
e.getdata(11,"Vijay") decimal places. Integer and floating points are separated by
e.showdata() decimal points. 1 is integer, 1.0 is floating point number.
Example: Floating point number.
Output: x=10.1
ID : 11 type(x)
Name : Vijay
<class 'float'>
3 Attempt any THREE of the following 12
a) List data types used in Python. Explain any two with 4M (2m for list, 4. Complex Numbers (Complex Data Type): Complex
example and 2m for two numbers are written in the form, x + yj, where x is the real
Data types in Python programming includes: example) part and y is the imaginary part.
• Numbers: Represents numeric data to perform Example:
mathematical operations. Complex number.
• String: Represents text characters, special symbols or >>>x = 3+4j
alphanumeric data. >>>print(x.real)
• List: Represents sequential data that the programmer 3.0
wishes to sort, merge etc. >>>print(x.imag)
• Tuple: Represents sequential data with a little 4.0
difference from list.
• Dictionary: Represents a collection of data that 5. String Data Type: String is a collection of group of
associate a unique key with each value. characters. Strings are identified as a contiguous set of
• Boolean: Represents truth values (true or false). characters enclosed in single quotes (' ') or double quotes ("
"). Any letter, a number or a symbol could be a part of the
1. Integers (int Data Type): An integer is a whole number string. Strings are unchangeable (immutable). Once a string
that can be positive (+) or negative (−). Integers can be of any is created, it cannot be modified.
length, it is only limited by the memory available. Example: For string data type.
Page 5 of 23 Page 6 of 23
>>> s1="Hello" #string in double quotes 8. Dictionary: Dictionary is an unordered collection of key-
>>> s2='Hi' #string in single quotes value pairs. It is the same as the hash table type. The order
>>> s3="Don't open the door" #single quote string in double of elements in a dictionary is undefined, but we can iterate
quotes over the following:
>>> s4='I said "yipee"' #double quote string in single quotes o The key
>>>type(s1) o The value
<class 'str'> o The items (key-value pairs) in a dictionary.
When we have the large amount of data, the dictionary data
6. List Data Type: List is an ordered sequence of items. It is type is used. Items in dictionaries are enclosed in curly braces
one of the most used datatype in Python and is very flexible. { } and separated by the comma (,). A colon (:) is used to
List can contain heterogeneous values such as integers, separate key from value. Values can be assigned and
floats, strings, tuples, lists and dictionaries but they are accessed using square braces ([]).
commonly used to store collections of homogeneous Example: For dictionary data type.
objects. The list datatype in Python programming is just like >>> dic1={1:"First","Second":2}
an array that can store a group of elements and we can refer >>> dic1
to these elements using a single name. Declaring a list is {1: 'First', 'Second': 2}
pretty straight forward. Items separated by commas ( , ) are >>> type(dic1)
enclosed within brackets [ ]. <class 'dict'>
Example: For list. >>> dic1[3]="Third"
>>> first=[10, 20, 30] # homogenous values in list >>> dic1
>>> second=["One","Two","Three"] # homogenous values in {1: 'First', 'Second': 2, 3: 'Third'}
list >>> dic1.keys()
>>> first dict_keys([1, 'Second', 3])
[10, 20, 30] >>> dic1.values()
>>> second dict_values(['First', 2, 'Third'])
['One', 'Two', 'Three'] >>>
>>> first + second # prints the concatenated lists b) Explain membership and assignment operators with 4M: 2m for
[10, 20, 30, 'One', 'Two', 'Three'] example membership
Membership Operators: The membership operators in Python are operators and
7. Tuple Data Type: Tuple is an ordered sequence of items used to find the existence of a particular element in the sequence, 2m for
same as list. The only difference is that tuples are immutable. and used only with sequences like string, tuple, list, dictionary etc. assignment
Tuples once created cannot be modified. It is defined within Membership operators are used to check an item or an element operators
parentheses ( ) where items are separated by commas ( , ). that is part of a string, a list or a tuple. A membership operator
reduces the effort of searching an element in the list. Python
A tuple data type in python programming is similar to a list
provides ‘in’ and ‘not in’ operators which are called membership
data type, which also contains heterogeneous operators and used to test whether a value or variable is in a
items/elements. sequence.
Example: For tuple. Sr. Operator Description Example
>>> a=(10,'abc',1+3j) No
>>> a
(10, 'abc', (1+3j)) 1 in True if value is >>> x="Hello
found in list or in World"
>>> a[0]
sequence, and false >>> print('H' in x)
10
it item is not in list True
>>> a[0]=20 or in sequence
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module> 2 not in True if value is not >>> x="Hello
found in list or in World"
sequence, and false
Page 7 of 23 Page 8 of 23
it item is in list or in >>> print("Hello" c=c%a
sequence. not in x)
False 7 **= Performs exponential c **= a is
(power) calculation on equivalent to
Assignment Operators (Augmented Assignment Operators): operators and assign
value to the left operand. c = c ** a
Assignment operators are used in Python programming to assign
values to variables. The assignment operator is used to store the 8 //= Performs exponential c //= a is
value on the right-hand side of the expression on the left-hand side (power) calculation on equivalent to
variable in the expression. operators and assign
For example, a = 5 is a simple assignment operator that assigns the value to the left operand. c = c // a
value 5 on the right to the variable a on the left.
There are various compound operators in Python like a += 5 that c) Explain indexing and slicing in list with example 4M: (2m for
adds to the variable and later assigns the same. It is equivalent to Indexing: An individual item in the list can be referenced by indexing and 2m
a = a + 5. using an index, which is an integer number that indicates the for slicing)
Following table shows assignment operators in Python relative position of the item in the list.
programming: There are various ways in which we can access the elements
Sr. Operator Description Example of a list some as them are given below:
No.
1. List Index: We can use the index operator [] to access an
1 = Assigns values from right c=a+b item in a list. Index starts from 0. So, a list having 5 elements
side operands to assigns value will have index from 0 to 4.
of a + b Example: For list index in list.
left side operand.
into c >>> list1=[10,20,30,40,50]
>>> list1[0]
2 += It adds right operand to c += a is 10
the left operand and equivalent to >>> list1[3:] # list[m:] will return elements indexed from mth
assign the result to left c=c+a index to last index
operand. [40, 50]
>>>list1[:4] # list[:n] will return elements indexed from first
3 −= It subtracts right operand c −= a is index to n-1th index
from the left equivalent to
[10, 20, 30, 40]
operand and assign the c=c−a >>> list1[1:3] # list[m:n] will return elements indexed from m
result to left operand. to n-1.
[20, 30]
4 *= It multiplies right operand operand and
with the left assign the >>> list1[5]
result to left Traceback (most recent call last):
operand and assign the File "<pyshell#71>", line 1, in <module>
operand.
result to left operand. list1[5]
c *= a is IndexError: list index out of range
equivalent to
2. Negative Indexing: Python allows negative indexing for its
c=c*a sequences. The index of −1 refers to the last item, −2 to the
second last item and so on.
5 /= It divides left operand c /= a is
Example: For negative indexing in list.
with the right operand equivalent to
and assign the result to >>> list2=['p','y','t','h','o','n']
left operand. c=c/a >>> list2[-1]
'n'
6 %= It takes modulus using c %= a is >>> list2[-6]
two operands and assign equivalent to 'p'
the result to left operand.
>>> list2[-3:]
Page 9 of 23 Page 10 of 23
['h', 'o', 'n'] Ans:
>>> list2[-7] 1)
Traceback (most recent call last): >>> dict1={1:"Vijay",2:"Santosh",3:"Yogita"}
File "<pyshell#76>", line 1, in <module> >>>print(dict1)
list2[-7] {1: 'Vijay', 2: 'Santosh', 3: 'Yogita'}
IndexError: list index out of range
ii)
List Slicing: Slicing is an operation that allows us to extract >>>dict1[2]="Shreyas"
elements from units. The slicing feature used by Python to >>>print(dict1)
obtain a specific subset or element of the data structure {1: 'Vijay', 2: 'Shreyas', 3: 'Yogita'}
using the colon (:) operator.
The slicing operator returns a subset of a list called slice by iii)
specifying two indices, i.e. start and end. >>>dict1.pop(1)
Syntax: list_variable[start_index:end_index] ‘Vijay'
This will return the subset of the list starting from start_index >>>print(dict1)
to one index less than that of the endind {2: 'Shreyas', 3: 'Yogita'}
Example: For slicing list. b) Explain decision making statements If-else, if-elif-else with 4M (2m for if-
>>> l1=([10,20,30,40,50]) example else and 2m for
>>> l1[1:4] The if-else statement: if statements executes when the if-elif-else)
[20, 30, 40] conditions following if is true and it does nothing when the
>>>l1[2:5] condition is false. The if-else statement takes care of a true
[30,40,50] as well as false condition.
d) Write a program for importing module for addition and 4M (for correct Syntax-1: Or Syntax-2:
subtraction of two numbers logic and If condition: If condition:
calculation.py: program) Statement(s) If_Block
def add(x,y): else: else:
return (x+y) Statement(s) else_Block
def sub(x,y): Example:
return (x-y) i=20
if(i<15):
operation.py: print(" less than 15")
import calculation else:
print("greater than 15")
print(calculation.add(1,2))
print(calculation.sub(4,2))
output:
Output: greater than 15
3 Concept Diagram:
2
Page 11 of 23 Page 12 of 23
c) Explain use of format() method with example 4M (2m for use
if-elif-else (ladder) statements: Here, a user can decide among The format() method formats the specified value(s) and insert and 2m for
multiple options. The if statements are executed from the top them inside the string's placeholder. example)
down. As soon as one of the conditions controlling the if is true, The placeholder is defined using curly brackets: {}.
the statement associated with that if is executed, and the rest of The format() method returns the formatted string.
the ladder is bypassed. If none of the conditions is true, then the Syntax
final else statement will be executed. string.format(value1, value2...)
Syntax:
if (condition-1): Example:
statement #named indexes:
elif (condition-2): >>>txt1 = ("My name is {fname}, I'm {age}".format(fname =
statements "abc", age = 36))
. >>>print(txt1)
. My name is abc, I'm 36
elif(condition-n):
statements #numbered indexes:
else: >>>txt2 =( "My name is {0}, I'm {1}".format("xyz",36))
statements >>>print(txt2)
My name is xyz, I'm 36
Example:
Example: #empty placeholders:
i = 20 >>>txt3 = ("My name is {}, I'm {}".format("pqr",36))
if (i == 10): >>>print(txt3)
print ("i is 10") My name is pqr, I'm 36
elif (i == 15): d) Explain building blocks of python 4M
print ("i is 15") Character set: All characters that python can recognize. The
elif (i == 20): below table illustrates the Python character set along with
print ("i is 20") examples.
else: character Set Examples
print ("i is not present") Letters: Upper case and A-Z,a-z
lower case english
output: alphabets
i is 20 Digits: all digits 0-9
Special symbols space,+,-,**,*,%,//,/,==,!=,>,<
Concept Diagram: Whitespaces Blank space,tabs
Other unicode characters All ASCII and Unicode characters
Tokens: Tokens in python are building blocks of the Python
programming language. The role letters and words play for the
English language, Similar to role token play for a python
programming language.
Python has the following tokens:
1)keywords
2)identifiers
3)literals
a)String literals
b)Numeric literals
c)Boolean Literals
d)Special literal None
Tokens Example
Keywords: Words that are False,True,if,elif,else,for,
already defined and convey a while,pass,continue,lambda,
Page 13 of 23 Page 14 of 23
special meaning to the return,finally,import,def Syntax-2:
language from <module_name> import <name(s)>
compiler/interpreter Example:
Identifiers: names given to def square,num=20, >>> from pkg.mod1 import m1
different parts of program a_lst=[1,2,3]; >>> m1()
like variables, functions, here square,num and a_lst are First module
object, class, names given to identifiers. >>>
different datatypes.
Literals/Constants: Data String: ‘Mayank‘,’abc‘,’anish‘; Syntax-3:
items that have fixed values Numeric: 1,1.2,4,-3.95; from <module_name> import <name> as <alt_name>
Boolean: True,False Example:
Special literal None; meaning nothing >>> from pkg.mod1 import m1 as module
e) Write a program illustrating use of user defined package in 4M (2m for >>> module()
python defining first module
A package is a hierarchical file directory structure that defines a package and 2m
single Python application environment that consists of modules You can import modules with these statements as well:
for import from <package_name> import <modules_name>[,
and subpackages and sub-subpackages, and so on. package in <module_name> ...]
Packages allow for a hierarchical structuring of the module program) from <package_name> import <module_name> as <alt_name>
namespace using dot notation.
Creating a package is quite straightforward, since it makes use of Example:
the operating system’s inherent hierarchical file structure. >>> from pkg import mod1
Consider the following arrangement: >>> mod1.m1()
First module
Page 15 of 23 Page 16 of 23
Method overloading is a concept in which a method in a class alternatives available in python that make it possible to call
performs operations according to the parameters passed to the same method but with different number of arguments.
it. c) Write a program to open a file in write mode and append 6M for any
As in other languages we can write a program having two some content at the end of file program with
methods with same name but with different number of file1 = open("myfile.txt", "w") suitable logic
arguments or order of arguments but in python if we will try L = ["This is Delhi \n", "This is Paris \n", "This is London"]
to do the same we will get the following issue with method file1.writelines(L)
overloading in Python: file1.close()
# to calculate area of rectangle
def area(length, breadth): # Append-adds at last
# append mode
calc = length * breadth
file1 = open("myfile.txt", "a")
print calc
#to calculate area of square # writing newline character
def area(size): file1.write("\n")
calc = size * size file1.write("Today")
print calc
area(3) # without newline character
area(4,5) file1.write("Tomorrow")
Output:
9 file1 = open("myfile.txt", "r")
TypeError: area() takes exactly 1 argument (2 given) print("Output of Readlines after appending")
Python does not support method overloading, that is, it is print(file1.read())
not possible to define more than one method with the print()
same name in a class in Python. file1.close()
This is because method arguments in python do not have a
type. A method accepting one argument can be called with Output:
an integer value, a string or a double as shown in next Output of Readlines after appending
example. This is Delhi
class Demo: This is Paris
def method(self, a): This is London
print(a) TodayTomorrow
obj= Demo()
obj.method(50) 6 Attempt any TWO of the following 12
obj.method('Meenakshi') a) Explain package Numpy with example 6M (3m for
obj.method(100.2) • NumPy is the fundamental package for scientific explanation and
Output: computing with Python. NumPy stands for 3m for example)
50 "Numerical Python". It provides a high-performance
Meenakshi multidimensional array object, and tools for working
100.2 with these arrays.
Same method works for three different data types. Thus, we • An array is a table of elements (usually numbers), all
cannot define two methods with the same name and same of the same type, indexed by a tuple of positive
number of arguments but having different type as shown in integers and represented by a single variable.
the above example. They will be treated as the same NumPy's array class is called ndarray. It is also known
method. by the alias array.
It is clear that method overloading is not supported in python • In NumPy arrays, the individual data items are called
but that does not mean that we cannot call a method with elements. All elements of an array should be of the
different number of arguments. There are a couple of
Page 17 of 23 Page 18 of 23
same type. Arrays can be made up of any number of >>> type(arr)
dimensions. <class 'numpy.ndarray'>
• In NumPy, dimensions are called axes. Each >>> print("No. of dimension: ", arr.ndim)
dimension of an array has a length which is the total No. of dimension: 2
number of elements in that direction. >>> print("Shape of array: ", arr.shape)
• The size of an array is the total number of elements Shape of array: (2, 3)
contained in an array in all the dimension. The size of >> >print("size of array: ", arr.size)
NumPy arrays are fixed; once created it cannot be size of array: 6
changed again. >>> print("Type of elements in array: ", arr.dtype)
• Numpy arrays are great alternatives to Python Lists. Type of elements in array: int32
Some of the key advantages of Numpy arrays are that >>> print("No of bytes:", arr.nbytes)
they are fast, easy to work with, and give users the No of bytes: 24
opportunity to perform calculations across entire b) Write a program to implement the concept of inheritance 6M for any
arrays. in python suitable
• A one dimensional array has one axis indicated by • In inheritance objects of one class procure the example of
Axis-0. That axis has five elements in it, so we say it properties of objects of another class. inheritance
has length of five. • Inheritance provide code usability, which means that
• A two dimensional array is made up of rows and some of the new features can be added to the code
columns. All rows are indicated by Axis-0 and all while using the existing code.
columns are indicated by Axis-1. If Axis-0 in two • The mechanism of designing or constructing classes
dimensional array has three elements, so its length it from other classes is called inheritance.
three and Axis-1 has six elements, so its length is six. • The new class is called derived class or child class and
the class from which this derived class has been
Execute Following command to install numpy in window, inherited is the base class or parent class.
Linux and MAC OS: • In inheritance, the child class acquires the properties
python -m pip install numpy and can access all the data members and functions
To use NumPy you need to import Numpy: defined in the parent class. A child class can also
import numpy as np # alias np provide its specific implementation to the functions
of the parent class.
Using NumPy, a developer can perform the following Syntax:
operations: class A:
1. Mathematical and logical operations on arrays. # properties of class A
2. Fourier transforms and routines for shape manipulation. class B(A):
3. Operations related to linear algebra. # class B inheriting property of class A
4. NumPy has in-built functions for linear algebra and # more properties of class B
random number generation
Example 1: Inheritance without using constructor.
Example: class Vehicle: #parent class
For NumPy with array object. name="Maruti"
>>> import numpy as np def display(self):
>>> a=np.array([1,2,3]) # one dimensional array print("Name= ",self.name)
>>> print(a) class Category(Vehicle): #derived class
[1 2 3] price=2000
>>> arr=np.array([[1,2,3],[4,5,6]]) # two dimensional array def disp_price(self):
>>> print(arr) print("Price=$",self.price)
[[1 2 3] car1=Category()
[4 5 6]] car1.display()
Page 19 of 23 Page 20 of 23
car1.disp_price() • There can be one or more except blocks. Multiple
Output: except blocks with different exception names can be
Name= Maruti chained together.
Price=$ 2000 • The except blocks are evaluated from top to bottom
in the code, but only one except block is executed for
Example 2: Inheritance using constructor. each exception that is thrown.
class Vehicle: #parent class • The first except block that specifies the exact
def __init__(self,name): exception name of the thrown exception is executed.
self.name=name If no except block specifies a matching exception
def display(self): name then an except block that does not have an
print("Name= ",self.name) exception name is selected, if one is present in the
class Category(Vehicle): #derived class code.
def __init__(self,name,price): • For handling exception in Python, the exception
Vehicle.__init__(self,name) handler block needs to be written which consists of
# passing data to base class constructor set of statements that need to be executed according
self.price=price to raised exception. There are three blocks that are
def disp_price(self): used in the exception handling process, namely, try,
print("Price=$ ",self.price) except and finally.
car1=Category("Maruti",2000)
car1.display() 1. try Block: A set of statements that may cause error during
car1.disp_price() runtime are to be written in the try block.
car2=Category("BMW",5000) 2. except Block: It is written to display the execution details
car2.display() to the user when certain exception occurs in the program.
car2.disp_price() The except block executed only when a certain type as
Output: exception occurs in the execution of statements written in
Name= Maruti the try block.
Price=$ 2000 3. finally Block: This is the last block written while writing an
Name= BMW exception handler in the program which indicates the set of
Price=$ 5000 statements that many use to clean up to resources used by
c) Explain Try-except block used in exception handling in 6M (3m for the program.
python with example explanation and
• In Python, exceptions can be handled using a try 3m for program) Syntax:
statement. A try block consisting of one or more try:
statements is used by programmers to partition code D the operations here
that might be affected by an exception. ......................
• A critical operation which can raise exception is except Exception1:
placed inside the try clause and the code that handles If there is Exception1, then execute this block.
exception is written in except clause. except Exception2:
• The associated except blocks are used to handle any If there is Exception2, then execute this block.
resulting exceptions thrown in the try block. That is ......................
we want the try block to succeed and if it does not else:
succeed, we want to control to pass to the catch If there is no exception then execute this block.
block.
• If any statement within the try block throws an Example: For try-except clause/statement.
exception, control immediately shifts to the catch try:
block. If no exception is thrown in the try block, the fh = open("testfile", "w")
catch block is skipped. fh.write("This is my test file for exception handling!!")
Page 21 of 23 Page 22 of 23
except IOError:
print ("Error: can\'t find file or read data")
else:
print ("Written content in the file successfully")
fh.close()
Page 23 of 23