Unit-5 - Control Flow - Functions - File Handling
Unit-5 - Control Flow - Functions - File Handling
CONTROL FLOW:
Conditional execution
Conditional statements allow checking the conditions and changing the behavior of the program
accordingly.
The simplest form is the if statement:
if x > 0 :
print('x is positive')
Tab Spacing
The boolean expression after the if statement is called the condition. The if statement with a colon character
(:) and the line(s) after the if statement are indented (as indicated by the arrow tab spacing).
The statement consists of a header line that ends with the colon character (:) followed by an indented block.
These statements are called compound statements because they stretch across more than one line.
There is no limit on the number of statements that can appear in the body, but there must be at least one. If
body has no statements then pass statement may be used, which does nothing.
For Example:
x=100
if x>99:
x=x+500
if x < 101 and x>99:
y=x+100
x=x-50
x=x+y
print(x)
OUTPUT:
600
Alternative execution
A second form of if statement is alternative execution, in which there are two possibilities and the condition
determines which one gets executed. The syntax looks like this:
if x%2 == 0:
print('x is even')
else:
print('x is odd')
Ex. Write a program in python to accept an integer from the user and determine whether its even or
odd.
Solution:
num=input('Input a number:')
num=int(num)
if(num!=0):
if num%2!=0:
print(num,'is an Odd number')
else:
print(num,'is an Even number')
Chained conditionals
If there are more than two possibilities and we need more than two branches. This can be done by chained
conditional:
if x < y:
print('x is less than y')
elif x > y:
print('x is greater than y')
else:
print('x and y are equal')
elif is an abbreviation of “else if”. There is no limit on the number of elif statements.
Example:
Write a program in python to accept an integer from the user and determine whether its positive,
negative or zero.
Solution:
num=input('Input a number:')
num=int(num)
if num >0:
print(num,' is a positive number')
elif num<0:
print(num,’ is a negative number')
else:
print(num,’ is zero')
Nested conditionals
One conditional can also be nested within another. The three-branch examples could be written as:
if x == y:
print('x and y are equal')
else:
if x < y:
print('x is less than y')
else:
print('x is greater than y')
Example:
Write a program in python to accept three integers from the user and determine the largest of the
three.
n1=input('Input the first number:')
n1=int(n1)
n2=input('Input the second number:')
n2=int(n2)
n3=input('Input the third number:')
n3=int(n3)
if n1>n2:
if n1>n3:
print(n1, ' is the largest')
else:
print(n3, ' is the largest')
elif n2>n3:
print(n2, ' is the largest')
else:
print(n3, ' is the largest')
If we execute this code and give it invalid input, it simply fails with an unfriendly error message:
pythonfahren.py
python fahren.py
The above program can be rewritten using try and except feature in Python as follows:
inp = input('Enter Fahrenheit Temperature:')
try:
fahr = float(inp)
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)
except:
print('Please enter a number')
The short-circuit behavior leads to a clever technique called the guardian pattern. Consider the following
code sequence in the Python interpreter:
>>> x = 6
>>> y = 2
>>> x >= 2 and (x/y) > 2
True
>>> x = 1
>>> y = 0
>>> x >= 2 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and (x/y) > 2
>>> x = 1
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x >= 2 and (x/y) > 2 and y != 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
In the first logical expression, x >= 2 is False so the evaluation stops at the and. In the second logical
expression, x >= 2 is True but y != 0 is False so the program never reaches (x/y). In the third logical
expression, the y != 0 is after the (x/y) calculation, so the expression fails with an error. In the second
expression, y != 0 acts as a guard to insure that only (x/y) is executed if y is non-zero.
Debugging
Python displays an error message that contains a lot of information. The most useful parts are usually:
Syntax errors are usually easy to find, but there are few tricky errors such as Whitespace because spaces and
tabs are invisible and most ignore them.
>>> x = 5
>>> y = 6
File "<stdin>", line 1
y=6
^
IndentationError: unexpected indent
In this example, the problem is that the second line is indented by one space. But the error message points to
y, which is misleading. In general, error messages indicate where the problem was discovered, but the actual
error might be earlier in the code, sometimes on a previous line.
In general, error messages tell where the problem was discovered, but that is often not where it was caused.
Python Loops:
Python has two primitive loop commands:
1. while loops:
while (expression):
statement(s)
2. for loop:
Syntax:
for variable_name in sequence:
Statement(s)
Example:
S=”Hello”
for I in S:
print(i)
Output:
H
e
l
l
o
range function:
Syntax:
range(start, stop, step) where The start and step arguments are optional.
Example1:
# create a sequence from 0 to 3 (4 is not included)
numbers = range(4)
print(numbers)
Output:
0
1
2
3
Example2:
for i in range(1,5):
print(i)
Output:
1
2
3
4
Example3:
for i in range(1,10,2):
print(i)
Output:
1
3
5
7
9
Break statement:
#using while loop
for i in range(10):
print(i)
if i == 2:
break
Output:
0
1
2
#using for loop
num = 0
for i in range(10):
num += 1
if num == 8:
break
print("The num has value:", num)
print("Out of loop")
# Python program to demonstrate break statement using for loop
print(letter)
# break the loop as soon it sees 'e'
# or 'a'
if letter == 'e' or letter == 'a':
break
Continue statement :
The continue statement skips the current iteration of the loop and the control flow of the program goes to
the next iteration.
for i in range(5):
if i == 3:
continue
print(i)
Output:
0
1
2
4
pass statement: The Python pass statement is a null statement. But the difference between pass and
comment is that comment is ignored by the interpreter whereas pass is not ignored.
n = 10
for i in range(n):
pass
Lists
A list is a sequence Like a string, a list is a sequence of values. In a string, the values are characters;
in a list, they can be any type. The values in list are called elements or sometimes items.
OUTPUT:
['Ram', 'Ramses', 'Ramesh'][22,1941][ ]
Unlike strings, lists are mutable because the order of items in a list can be changed or an item in a list can
be reassigned.
The syntax for accessing the elements of a list is the same as for accessing the characters of a string: the
bracket operator.
The expression inside the brackets specifies the index.
When the bracket operator appears on the left side of an assignment, it identifies the element of the list that
will be assigned.
List has a relationship between indices and elements. This relationship is called a mapping; each index “
maps to” one of the elements.
Traversing a list
The most common way to traverse the elements of a list is with a for loop. The syntax is the same as for
strings:
for name in names:
print(name)
for i in range(len(numbers)):
numbers[i] = numbers[i] * 2
This loop traverses the list and updates each element. len returns the number of elements in the list. range
returns a list of indices from 0 to n − 1, where n is the length of the list. Each time through the loop, i gets
the index of the next element. The assignment statement in the body uses i to read the old value of the
element and to assign the new value.
for x in empty:
print('This never happens.')
Although a list can contain another list, the nested list still counts as a single element. The length of this list
is four:
List operations
List slices
>>> t[:4]
['a', 'b', 'c', 'd']
>>> t[3:]
['d', 'e', 'f']
If the first index s skipped, the slice starts at the beginning. If second index is kipped, the slice goes to the
end. So if both indices are skipped, the slice is a copy of the whole list.
>>> t[:]
['a', 'b', 'c', 'd', 'e', 'f']
Since lists are mutable, it is often useful to make a copy before performing operations that fold, spindle, or
mutilate lists.
A slice operator on the left side of an assignment can update multiple elements:
List methods
Python provides methods that operate on lists. For example, append adds a new element to the end of a list:
extend takes a list as an argument and appends all of the elements while it leaves t2 unmodified:
>>> t1 = ['a', 'b', 'c']
>>> t2 = ['d', 'e']
>>> t1.extend(t2)
>>> print(t1)
['a', 'b', 'c', 'd', 'e']
Sorting a list:
Most list methods are void; they modify the list and return None.
Deleting elements
There are several ways to delete elements from a list. If the index of the element to be deleted is known, pop
can be used:
pop modifies the list and returns the element that was removed. If an index is not provided, it deletes and
returns the last element.
If value removed is not desired, then the del operator can be used:
remove():
If the element to be removed is known (but not the index), remove can be used:
To remove more than one element, del can be used with a slice index:
>>> t = ['a', 'b', 'c', 'd', 'e', 'f']
>>> del t[1:5]
>>> print(t)
['a', 'f']
As usual, the slice selects all the elements up to, but not including, the second index.
Practice Questions
1. Write a Python program that accepts a list and modifies it by removing the first and last elements
and then first prints those deleted items and then it prints the rest of the list.
2. Write a Python program that accepts a list and modifies it by removing the first and last elements
and then copies the remaining list to a new list. Print the new list.
PYTHON FUNCTIONS
1. Creating a Function
In Python a function is defined using the def keyword:
EXAMPLE:
def fun():
• Function blocks begin with the keyword def followed by the function name and parentheses (()).
• Any input parameters or arguments should be placed within these parentheses. We also define
parameters inside these parentheses.
• The code block within every function starts with a colon (:) and is indented.
• The statement return [expression] exits a function, optionally passing back an expression to the
caller.
• A return statement with no arguments is the same as return None.
FUNCTION SYNTAX
EXAMPLE:
return
2. Parameters in function
The information into the functions can be passed as the parameters. The parameters are specified in
the parentheses. We can give any number of parameters separated by comma.
Example 1:
# A simple Python function to check whether x is even or odd
def evenOdd(x):
if (x % 2 == 0):
print("even")
else:
print("odd")
# Driver code to call the function
evenOdd(2)
evenOdd(3)
Output:
Even
Odd
sample_str = "Gra@phic2Era&#Hi5ll@univer&$sity"
print("total counts of chars, Digits, and symbols \n")
find_digits_chars_symbols(sample_str)
Example 5:
# Python function to return sum and multiplication of two numbers
def cal(a,b):
sum=a+b
mul=a*b
return sum,mul
# Driver code to call the function
a=int(input(“Enter first number: ”))
b= int(input(“Enter second number: ”))
c,d=cal(a,b)
print(f”Sum of {a} and {b} is {c} and multiplication is {d}”)
Output:
Enter first number: 5
Enter second number: 6
Sum of 5 and 6 is 11 and multiplication is 30
FILES
Stored on a Persistence storage device Ex. Secondary Memory, Pen drive, Hard Drive etc. Secondary
memory is not erased when the power is turned off. The main focus will be on reading and writing text
files such as those created in a text editor.
Opening files
When file has to be read or written (onto the hard drive), first it must be opened. Opening the file
communicates with the operating system running on that computer, which knows where the data for each
file is stored. When a file is opened, the operating system finds the file by name and makes sure the file
exists.
General syntax:
filehandle= open(“filename”,mode)
The modes are:
‘r’ – Read mode is used when the file is only being read.
‘w’ – Write mode is used to edit and write new information to the file (any existing
files with the same name will be erased when this mode is activated).
‘a’ – Append mode, is used to add new data to the end of the file; that is new
information is automatically appended to the end.
‘r+’ – Special read and write mode, is used to handle both actions when working
with a file.
‘x’ – Create - will create a file, returns an error if the file
exist.
In this example, the file mbox.txt is opened, which should be stored in the same folder as that off when
Python was started.
If the open call is successful, the operating system returns a file handle. The file handle is not the actual data
contained in the file, but instead it is a “handle” that can be used to read the data. A handle is successfully
returned if the requested file exists and has the proper permissions to read the file.
If the file does not exist, open will fail with the message Traceback, and the handle is not available to access
the contents of the file:
try and except model can be used to handle the situation of opening a file that does not exist.
A text file can be thought of as a sequence of lines, much like a Python string can be thought of as a
sequence of characters. For example, this is a sample of a text file which records mail activity from various
individuals in an open source project development team:
Please Note that the files used in this document have been downloaded from www.py4e.com/code3/
Reading files
While the file handle does not contain the data for the file, it is quite easy to construct a for loop to read
through and count each of the lines in a file:
fhand = open('mbox-short.txt')
count = 0
for line in fhand:
count = count + 1
print('Line Count:', count)
The file handle can be used as the sequence in the for loop. The above for loop counts the number of lines
in the file and prints them out. The meaning of the for loop into English is, “for each line in the file
represented by the file handle, add one to the count variable.”
The reason that the open function does not read the entire file is that the file might be quite large with many
gigabytes of data. The open statement takes the same amount of time regardless of the size of the file. The
for loop actually causes the data to be read from the file. When the file is read using a for loop in this
manner, Python takes care of splitting the data in the file into separate lines using the newline character.
Python reads each line through the newline and includes the newline as the last character in the line variable
for each iteration of the for loop. Because the for loop reads the data one line at a time, it can efficiently
read and count the lines in very large files without running out of main memory to store the data. The above
program can count the lines in any size file using very little memory since each line is read, counted, and
then discarded.
If the file is relatively small compared to the size of your main memory, it can be read as the whole file into
one string using the read method on the file handle.
When the file is read in this manner, all the characters including all of the lines and newline characters are
one big string in the variable inp. This form of the open function should only be used if the file data will fit
comfortably in the main memory of your computer. If the file is too large to fit in main memory, one should
write program to read the file in chunks using a for or while loop.
When you are searching through data in a file, it is a very common pattern to read through a file, ignoring
most of the lines and only processing lines which meet a particular condition. We can combine the pattern
for reading a file with string methods to build simple search mechanisms.
For example, if we wanted to read a file and only print out lines which started with the prefix “From:”, we
could use the string method startswith to select only those lines with the desired prefix:
fhand = open('mbox-short.txt')
count = 0
for line in fhand:
if line.startswith('From:'):
print(line)
The rstrip method which strips whitespace from the right side of a string as follows:
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if line.startswith('From:'):
print(line)
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if line.startswith('From:'):
print(line)
The loop can be modified to follow the pattern of skipping uninteresting lines as follows:
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
# Skip 'uninteresting lines'
if not line.startswith('From:'):
continue
# Process our 'interesting' line
print(line)
The find string method can be used to simulate a text editor search that finds lines where the search string is
anywhere in the line. Since find looks for an occurrence of a string within another string and either returns
the position of the string or -1.
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if line.find('@uct.ac.za') == -1: continue
print(line)
Letting the user choose the file name
We really do not want to have to edit our Python code every time we want to process a different file. It
would be more usable to ask the user to enter the file name string each time the program runs so they can
use our program on different files without changing the Python code. This is quite simple to do by reading
the file name from the user using input as follows:
The file name is read from the user and placed in a variable named fname and then that file is opened. Now
we can run the program repeatedly on different files.
python search6.py
Enter the file name: mbox-short.txt
There were 27 subject lines in mbox-short.txt
filehandle.writelines( list1 )
For a list of string elements, each string is inserted in the text file. Used to insert multiple strings at a single
time.
# Reads and returns the characters until the end of the line is reached as a string.
print(fh.readline())