Sanet - ST 1683923537python PDF
Sanet - ST 1683923537python PDF
Sanet - ST 1683923537python PDF
BASICS
LICENSE, DISCLAIMER OF LIABILITY, AND LIMITED WARRANTY
By purchasing or using this book (the “Work”), you agree that this license grants permission to use the
contents contained herein, but does not give you the right of ownership to any of the textual content in the
book or ownership to any of the information or products contained in it. This license does not permit
uploading of the Work onto the Internet or on a network (of any kind) without the written consent of the
Publisher. Duplication or dissemination of any text, code, simulations, images, etc., contained herein is
limited to and subject to licensing terms for the respective products, and permission must be obtained from
the Publisher or the owner of the content, etc., in order to reproduce or network any portion of the textual
material (in any media) that is contained in the Work.
MERCURY LEARNING AND INFORMATION (“MLI” or “the Publisher”) and anyone involved in the
creation, writing, production, accompanying algorithms, code, or computer programs (“the software”), and
any accompanying Web site or software of the Work, cannot and do not warrant the performance or results
that might be obtained by using the contents of the Work. The author, developers, and the Publisher have
used their best efforts to insure the accuracy and functionality of the textual material and/or programs
contained in this package; we, however, make no warranty of any kind, express or implied, regarding the
performance of these contents or programs. The Work is sold “as is” without warranty (except for defective
materials used in manufacturing the book or due to faulty workmanship).
The author, developers, and the publisher of any accompanying content, and anyone involved in the
composition, production, and manufacturing of this work will not be liable for damages of any kind arising
out of the use of (or the inability to use) the algorithms, source code, computer programs, or textual material
contained in this publication. This includes, but is not limited to, loss of revenue or profit, or other
incidental, physical, or consequential damages arising out of the use of this Work.
The sole remedy in the event of a claim of any kind is expressly limited to replacement of the book and only
at the discretion of the Publisher. The use of “implied warranty” and certain “exclusions” vary from state to
state, and might not apply to the purchaser of this product.
PYTHON
BASICS
H. Bhasin
This publication, portions of it, or any accompanying software may not be reproduced in any way, stored in
a retrieval system of any type, or transmitted by any means, media, electronic display or mechanical
display, including, but not limited to, photocopy, recording, Internet postings, or scanning, without prior
permission in writing from the publisher.
The publisher recognizes and respects all marks used by companies, manufacturers, and developers as a
means to distinguish their products. All brand names and product names mentioned in this book are
trademarks or service marks of their respective companies. Any omission or misuse (of any kind) of service
marks or trademarks, etc. is not an attempt to infringe on the property of others.
Our titles are available for adoption, license, or bulk purchase by institutions, corporations, etc. For
additional information, please contact the Customer Service Dept. at 800-232-0223(toll free).
All of our titles are available in digital format at authorcloudware.com and other digital vendors. The sole
obligation of MERCURY LEARNING AND INFORMATION to the purchaser is to replace the book,
based on defective materials or faulty workmanship, but not based on the operation or functionality of the
product.
To
My Mother
CONTENTS
Bibliography
Index
CHAPTER
1
INTRODUCTION TO PYTHON
After reading this chapter, the reader will be able to
• Understand the chronology of Python
• Appreciate the importance and features of Python
• Discover the areas in which Python can be used
• Install Anaconda
1.1 INTRODUCTION
Art is an expression of human creative skill, hence programming is an art. The
choice of programming language is, therefore, important. This book introduces
Python, which will help you to become a great artist. A. J. Perlis, who was a
professor at the Purdue University, and who was the recipient of the first Turing
award, stated
“A language that doesn’t affect the way you think about programming is
not worth knowing.”
Python is worth knowing. Learning Python will not only motivate you to do
highly complex tasks in the simplest manners but will also demolish the myths
of conventional programming paradigms. It is a language which will change the
way you program and hence look at a problem.
There are many third party modules for accomplishing the above tasks. For
example Django, an immensely popular Web framework dedicated to clean and
fast development, is developed on Python. This, along with the support for
HTML, E-mails, FTP, etc., makes it a good choice for web development.
Third party libraries are also available for software development. One of the
most common examples is Scions, which is used for build controls. When joined
with the inbuilt features and support, Python also works miracles for GUI
development and for developing mobile applications, e.g., Kivy is used for
developing multi-touch applications.
Python also finds its applications in scientific analysis. SciPy is used for
Engineering and Mathematics, and IPython is used for parallel computing. Those
of you working in statistics and machine learning would find some of these
libraries extremely useful and easy to use. SciPy provides
MATLABMATLABMATLAB like features and can be used for processing
multidimensional arrays. Figure 1.1 summarizes the above discussion.
This chapter introduces the Python programming language. The chapter has been
organized as follows. Section 1.2 discusses the features of Python, Section 1.3
discusses the paradigms and Section 1.4 discusses the development and uses.
The installation of Anaconda has been introduced in Section 1.5. The last section
concludes the chapter.
1.2.1 Easy
Python is easy to learn and understand. As a matter of fact, if you are from a
programming background you will find it elegant and uncluttered. The removal
of braces and parentheses makes the code short and sweet. Also, some of the
tasks in Python are pretty easy. For example, swapping numbers in Python is as
easy as writing (a, b)= (b, a).
It may also be stated here that learning something new is an involved and
intricate task. However, the simplicity of Python makes it almost a cake walk.
Moreover, learning advanced features in Python is a bit intricate, but is worth the
effort. It is also easy to understand a project written in Python. The code, in
Python, is concise and effective and therefore understandable and manageable.
In most projects, testing something new requires scores of changes and therefore
recompilations and re-runs. This makes testing of code a difficult and time
consuming task. In Python, a code can be run easily. As a matter of fact, we run
scripts in Python.
As we will see later in this chapter, Python also provides the user with an
interactive environment, in which one can run independent commands.
1.2.3 Syntax
The syntax of Python is easy; this makes the learning and understanding process
easy. According to most of authors, the three main features which make Python
attractive are that it’s simple, small, and flexible.
1.2.4 Mixing
If one is working on a big project, with perhaps a large team, it might be the case
that some of the team members are good in other programming languages. This
may lead to some of the modules in some other languages wanting to be
embedded with the core Python code. Python allows and even supports this.
Python has its own way of managing memory associated with objects. When an
object is created in Python, memory is dynamically allocated to it. When the life
cycle of the object ends, the memory is taken back from it. This memory
management of Python makes the programs more efficient.
As we will see in the next chapter Python has built in object types. This makes
the task to be accomplished easy and manageable. Moreover, the issues related
to these objects are beautifully handled by the language.
1.2.8 Portable
1.2.9 Free
Python is not propriety software. One can download Python compilers from
among the various available choices. Moreover, there are no known legal issues
involved in the distribution of the code developed in Python.
1.3 THE PARADIGMS
1.3.1 Procedural
1.3.2 Object-Oriented
This type of language primarily focuses on the instance of a class. The instance
of a class is called an object. A class is a real or a virtual entity that has an
importance to the problem at hand, and has sharp physical boundaries. For
example in a program that deals with student management, “student” can be a
class. Its instances are made and the task at hand can be accomplished by
communicating via methods. Python is object-oriented. Section 2 of this book
deals with the object-oriented programming.
1.3.3 Functional
1.4.1 Chronology
Python is written in C. It was developed by Guido Van Rossum, who is now the
Benevolent Director for Life of Python. The reader is expected to take note of
the fact that Python has got nothing to do with pythons or snakes. The name of
the language comes from the show “Monty Python’s Flying Circus,” which was
one of the favorite shows of the developer, Guido van Rossum. Many people
attribute the fun part of the language to the inspiration.
Python is easy to learn as the core of the language is pretty concise. The
simplicity of Python can also be attributed to the desire of the developers to
make a language that was very simple, easy to learn but quite powerful.
1.4.2 Uses
Python is being used to accomplish many tasks, the most important of which are
as follows:
If you are working in Unix or Linux, you don’t need to install Python. This is
because in Unix and Linux systems, Python is generally pre-installed. However,
if you work in Windows or Mac then you need to download Python. Once you
have decided to download Python, look for its latest version. The reader is
requested to ensure that the version he/she intends to download is not an alpha or
a beta version. Reference 1 at the end of the book gives a brief overview of
distinctions between two of the most famous versions. The next section briefly
discusses the steps for downloading Anaconda, an open source distribution
software.
Many development environments are available for Python. Some of them are as
follows:
There are some more options available. However, this book uses IDLE and
Anaconda. The next section presents the steps involved in the installation of
Anaconda.
First of all, one must choose the installer (32 bit or 64 bit). In order to do so,
click on the selected installer and download the .exe file. The installer will ask
you to install it on the default location. You can provide a location that does not
contain any spaces or Unicode characters. It may happen that during the
installation you might have to disable your anti-virus software. Figures 1.2(a) to
1.2(g) take the reader through the steps of installation.
FIGURE 1.2(a) The welcome screen of the installer, which asks the user to close all running
applications and then click Next
FIGURE 1.2(b) The license agreement to install Anaconda3 4.3.0 (32 bit)
FIGURE 1.2(c) In the third step, the user is required to choose whether he wants to install
Anaconda for a single user or for all the users
FIGURE 1.2(d) The user then needs to select the folder in which it will install
FIGURE 1.2(e) The user then must decide whether he wants to add Anaconda to path
environment variable and whether to register Anaconda as the default Python 3.6
The installation then starts. After installation, the following screen will appear:
Once Anaconda is installed, you can open Anaconda and run your scripts. Figure
1.3 shows the Anaconda navigator. From the various options available you can
choose the appropriate option for you. For example, you can open the
QTConsole and run the commands/ scripts. Figure 1.4 shows the snapshot of
QTConsole. The commands written may appear gibberish at this point, but will
become clear in the chapters that follow.
1.6 CONCLUSION
Before proceeding any further, the reader must take note of the fact that some
things in Python are different when compared to any other language. The
following points must be noted to avoid any confusion.
Choice at every step is good but can also be intimidating. As stated earlier,
Python’s core is small and therefore it is easy to learn. Moreover, there are some
things like (if/else), loops and exception handling which are used in almost all
the programs.
The chapter introduces Python and discusses the features of Python. One must
appreciate the fact that Python supports all three paradigms: procedural, object-
oriented, and functional. This chapter also paves the way for the topics presented
in the following chapters. It may also be stated that the codes presented in this
book will run on versions 3.X.
GLOSSARY
PEP: Python Enhancement Project
POINTS TO REMEMBER
Python is a strong procedural, object-oriented, functional language crafted
in late 1980s by Guido Van Rossum.
Python is open source.
The applications of Python include software development, web
development, desktop GUI development, education and scientific
applications.
Python is popular due to its simplicity and robustness.
It is easy to interface with C++ and Java.
SciPy is used for engineering and mathematics, IPython for parallel
computing etc., Scions is used for build control.
The various development environments for Python are PyDev with Eclipse,
Emacs, Vim, TextMate, Gedit, Idle, PIDA (Linux)(VIM Based), NotePad++
(Windows), and BlueFish (Linux).
RESOURCES
To download Python, visit www.python.org
The documentation is available at www.python.org/doc/
EXERCISES
MULTIPLE CHOICE QUESTIONS
5. Python has
(a) Built in object types
(b) Data types
(c) Both
(d) None of the above
6. Python is a
(a) Procedural language
(b) object-oriented Language
(c) Fictional
(d) All of the above
9. PEP is
(a) Python Ending Procedure
(b) Python Enhancement proposal
(c) Python Endearment Project
(d) none of the above
10. PSF is
(a) Python Software Foundation
(b) Python Selection Function
(c) Python segregation function
(d) None of the above
11. What can be done in Python
(a) GUI
(b) Internet scripting
(c) Games
(d) All of the above
4. What is PEP?
5. What is PSF?
PYTHON OBJECTS
After reading this chapter, the reader will be able to
• Understand the meaning and importance of variables, operators, keywords, and objects
• Use numbers and fractions in a program
• Appreciate the importance of strings
• Understand slicing and indexing in strings
• Use of lists and tuples
• Understand the importance of tuples
2.1 INTRODUCTION
To be able to write a program in Python the programmer can use Anaconda, the
installation of which was described in the previous chapter—or you can use
IDLE, which can be downloaded from the reference given at the end of the
Chapter 1. IDLE has an editor specially designed for writing a Python program.
As a matter of fact you can add, subtract, multiply, divide and perform
exponentiation in the command line. Multiplication can be done using the *
operator, the division can be performed using the / operator, the exponentiation
can be done using the ** operator and the modulo can be found using the %
operator. The modulo operator finds the remained if the first number is greater
than the other, otherwise it returns the first number as the output. The results of
the operations have been demonstrated as follows:
>>> 2*3
6
>>> 2/3
0.6666666666666666
>>> 2**3
8
>>> 2%3
2
>>> 3%2
1
>>>
In the above case, the Python interpreter is used to execute the commands. This
is referred to as a script mode. This mode works with small codes. Though
simple commands can be executed on the command line, the complex programs
can be written in a file. A file can be created as follows:
Sequences: These are ordered collections of elements. There are three types of
sequences in Python:
String
Tuples
Lists
These types have been discussed in the sections that follow.
Keywords: These are words having special meanings and are understood by the
interpreter. For example, and, del, from, not, while, as, elif, global,
else, if, pass, Yield, break, except, import, class, raise,
continue, finally, return, def, for, and try are some of the keywords
which have been extensively used in the book. For a complete list of keywords,
the reader may refer to the Appendix.
Operators: These are special symbols which help the user to carry out
operations like addition, subtraction, etc. Python provides following type of
operators:
This chapter deals with the basic data types in Python and their uses. The chapter
has been organized as follows: Section 2 of this chapter deals with the
introduction to programming in Python and basic data types, and Section 3 deals
with strings. Section 4 deals with lists and tuples. The last section of this chapter
concludes the chapter. The readers are advised to go through the references at the
end of this book for comprehensive coverage of the topic.
The data types provided by Python are not only powerful but also can be nested
within others. In the following discussion the concept of nested lists has been
presented, which is basically a list within a list. The power of data types can be
gauged by the fact that Python provides the user with dictionaries, which makes
mapping easy and efficient.
Numbers are the simplest data types. Numbers comprise of integers, floats,
decimals, and complexes in Python. The type of numbers and their explanations
have been summarized in Table 2.1. The operators supported by numbers have
been presented in Table 2.2.
Numbers Explanation
Integers Which do not have any fractional part
Floating point numbers That do have a fractional part
Complex numbers The numbers having a real and an imaginary part
Decimal Those having fixed precision
Rational Those having a numerator and a denominator
Sets Abstraction of a mathematical set
+ Addition
– Subtraction
* Multiplication
** Power
% Modulo
In addition to the above, Python is practically free from the problems of C and
C++ and can calculate very, very large integers. Let us now have a look at how
to use these operators. For example if one needs to calculate the square root of a
number, then importing math and using math.sqrt() is a solution. Some of the
most important functions have been explained in the following sneak peek.
Sneak Peek
1. Ceil: The ceiling of a given number is the nearest integer greater than or
equal to that number. For example, the ceiling of 2.678 is 3.
>>> import math
>>>math.ceil(2.678)
3
That of 2 is 2.
>>>math.ceil(2)
2
>>>
2. Copy sign: The sign of the second argument is returned along with the result
on the execution of this function.
math.copysign(x, y)
Return x with the sign of y.
On a platform that supports signed zeros, copy sign (1.0, – 0.0) returns –1.0.
3. Fabs: The absolute value of a number is its positive value; that is if the
number is positive then the number itself is returned. If, on the other hand,
the number is negative then it is multiplied by –1 and returned.
It returns the factorial of the number x. Also if the given number is not an
integer or is negative, then an exception is raised.
5. Floor: The floor of a given number is the nearest integer smaller than or
equal to that number. For example the floor of 2.678 is 2 and that of 2 is also
2.
>>> import math
>>>math.floor(2.678)
2
>>>math.floor(2)
2
>>>
2.2.1 Fractions
Python also provides the programmer the liberty to deal with fractions. The use
of fractions and decimals has been shown in the following listing.
Listing
from fractions import Fraction
print(Fraction(128, -26))
print(Fraction(256))
print(Fraction())
print(Fraction('2/5'))
print(Fraction(' -5/7'))
print(Fraction('2.675438 '))
print(Fraction('-32.75'))
print(Fraction('5e-3'))
print(Fraction(7.85))
print(Fraction(1.1))
print(Fraction(2476979795053773, 2251799813685248))
from decimal import Decimal
print(Fraction(Decimal('1.1')))
>>>
Output
========== RUN C:/Python/Chapter 2/Fraction.py ==========
-64/13
256
0
2/5
-5/7
1337719/500000
-131/4
1/200
4419157134357299/562949953421312
2476979795053773/2251799813685248
2476979795053773/2251799813685248
11/10
>>>
2.3 STRINGS
In Python a string is a predefined object which contains characters. The string in
Python is non-mutable; that is, once defined the value of a string cannot be
changed. However, as we proceed further, the exceptions to the above premise
will be discussed. To begin with, let us consider a string containing value
“Harsh,” that is:
name = 'Harsh'
The value of this string can be displayed simply by typing the name of the object
(name in this case) into the command prompt.
>>>name
Harsh
The value can also be printed by using the print function, explained previously.
print(name)
It may be stated here that the index of the first location is 0. So, name[0] would
print the first letter of the string, which is “H.”
print(name[0])
H
Negative indexing in a string refers to the character present at the nth position
beginning from the end. In the above case, name[-2] would generate “s.”
print(name[-2])
s
The length of a string can be found by calling the len function. len(str) returns
the length of the string “str.” For example, len(name) would return 5, as
'harsh' has 5 characters.
The last character of a given string can also be printed using the following.
print(name[len(name)-1])
After concatenation, if the first and the second last characters are to be printed
then the following can be used.
print(name[0])
print(name[-2])
print(name[len(name)-1→2])
H
S
s
The * operator, of string, concatenates a given string the number of times, given
as the first argument. For example, 3*name would return “harsharshharsharsh.”
The complete script as follows:
Listing
name = 'Harsh'
print(name)
print(name[0])
print(name[-2])
print(name[len(name)-1])
name = name + 'arsh'
print(name)
print(name[0])
print(name[-2])
print(name[len(name)-1])
>>>
Output
=========== RUN C:/Python/Chapter 2/String.py ===========
Harsh
H
s
h
Harsharsh
H
s
h
>>>
>>>name = 'Sonam'
>>>name
'Sonam'
Here, if we intend to extract the portion after the first letter we can write [1:].
>>> name1=name[1:]
>>> name1
'onam'
In the same way the portion of the string after the first two letters can be
extracted as follows.
>>>name = name[2:]
>>>name
'nam'
Now, we modify the string by adding “man man”
>>>name = “man”+name
>>>name
'mannam'
It may be noted that the last two characters cannot be removed in the same way
as the first two. Observe the following output in order to understand the concept.
>>>name = name[:2]
>>>name
'ma'
>>>name = “man manam”
>>>name
'manmanam'
>>> name2 = name[:-2]
>>> name2
'man man'
>>>
Immutability of Strings
we don’t actually change the string; as a matter of fact we create a new string
having the value 'Hello' concatenated with the value stored in name. The
concept can be understood by the fact that when we try to change the value of a
particular character in a string, an error crops up.
>>>name='Anupam'
>>>name
'Anupam'
>>>name[2]='p'
Traceback (most recent call last):
File “<pyshell#17>”, line 1, in <module>
name[2]='p'
TypeError: 'str' object does not support item assignment
>>>
2.4.1 List
A list, in Python, is a collection of objects. As per Lutz “It is the most general
sequence provided by the language.” Unlike strings, lists are mutable. That is, an
element at a particular position can be changed in a list. A list is useful in dealing
with homogeneous and heterogeneous sequences.
For example, the following list of authors has elements “Harsh Bhasin,” “Mark
Lutz,” and “Shiv.” The list can be printed using the usual print function. In the
following example, the second list in the following listing contains a number, a
string, a float, and a string. “list 3” is a null list and list-of-list contains list as its
elements.
Listing
authors = ['Harsh Bhasin', 'Mark Lutz', 'Shiv']
print(authors)
combined =[1, 'Harsh', 23.4, 'a']
print(combined)
list3= []
print(list3)
listoflist = [1, [1,2], 3]
print(listoflist)
>>>
Output
============ RUN C:/Python/Chapter 2/Lists.py ===========
['Harsh bhasin', 'Mark Lutz', 'Shiv']
[1, 'Harsh', 23.4, 'a']
[]
[1, [1, 2], 3]
>>>
Listing
list1 = [1, 2, 3]
print(list1[1])
print(list1[-1])
>>>
Output
=========== RUN C:/Python/Chapter 2/list2.py ============
2
3
>>>
A list can also contain list(s). The topic has been discussed in Chapter 4. Lists
also support slicing.
2.4.2 Tuples
Listing
tup1= (2, 3)
print(tup1)
(a, b) = tup1
print('The first element is ',a)
print('The second element is ',b)
tup2=(101, 'Hari')
tup3=(102,'Shiv')
(code1, name1)=tup1
(code2, name2)=tup2
print('The code of ', name1,' is ',code1,'\nThe code of
',name2, ' is ',code2)
>>>
Output
=========== RUN C:/Python/Chapter 2/tuple.py ============
(2, 3)
The first element is 2
The second element is 3
The code of 3 is 2
The code of Hari is 101
>>>
Tuples are extremely useful in operations like swapping etc. Swapping in Python
is as simple as assigning (a, b) to (b, a). The program for swapping two numbers
using tuples has been given as follows.
Solution:
Output
============ RUN C:/Python/Chapter 2/swap.py ============
Enter the first number :
2
Enter the second number :
3
The numbers entered are 2& 3
The numbers now are 3& 2
>>>
2.5 CONCLUSION
In a program, instructions are given to a computer to perform a task. To be able
to do so, the operators operate on what are referred to as “objects.” This chapter
explains the various types of objects in Python and gives a brief overview of the
operators that act upon them. The objects can be built in or user defined. As a
matter of fact, everything that will be operated upon is an object.
The first section of this chapter describes various built-in objects in Python. The
readers familiar with “C” must have an idea as to what a procedural language is.
In “C,” for example, a program is divided into manageable modules, each of
which performs a particular task. The division of bigger tasks into smaller parts
makes parts manageable and the tracking of bugs easy. There are many more
advantages of using modules, some of which have been stated in Chapter 1.
These modules contain a set of statements, which are equivalent to instructions
(or no instruction, e.g. in case of a comment). The statements may contain
expressions, in which objects are operated upon by operators. As stated earlier,
Python gives its user the liberty to define their own objects. This will be dealt
with in the chapter on classes and objects. This chapter focuses on the built in
objects.
In C (or for that matter C++), one needs to be careful not only about the built-in
type used but also about the issues relating to the allocation of memory and data
structures. However, Python spares the user of these problems and can therefore
focus on the task at hand. The use of built-in data types makes things easy and
efficient.
GLOSSARY
None: This represents the absence of value.
Numbers: Python has three types of numbers: integers, floating point, complex.
Sequences: These are ordered collections of elements. There are three types of
sequences in Python:
String
Tuples
Lists
POINTS TO REMEMBER
In order to store values, we need variables.
Everything in Python is an object.
Each object has identity, a type, and a value.
EXERCISES
(a) 7.7
(b) 7
(c) None of the above
(d) An exception is raised
2. >>> a = 5
>>> b = 2
>>> a/b
(a) 2
(b) 2.5
(c) 3
(d) None of the above
3. >>> a = 5
>>> b = 2
>>> c = float (a)/b
>>> c
(a) 2
(b) 2.5
(c) 3
(d) An exception is raised
4. >>> a = 2
>>> b = 'A'
>>> c = a + b
>>> c
(a) 67
(b) 60
(c) None of the above
(d) An exception is raised
5. >>> a = 'A'
>>> 2*A
(a) ‘AA’
(b) 2A
(c) A2
(d) None of the above
6. >>> a = 'A'
>>> b = 'B'
>>> a + b
(a) A + B
(b) AB
(c) BA
(d) None of the above
(a) (2, 5)
(b) (5, 2)
(c) (5, 5)
(d) None of the above
8. >>> a = 5
>>> b = 2
>>> a = a + b
>>> b = a - b
>>> a = a - b
>>> a
(a) 5
(b) 2
(c) None of the above
(d) An exception is raised
9. >>> a = 5
>>> b * b = a
>>> b
(a) 2.7
(b) 25
(c) None of the above
(d) An exception is raised
(a) (6, 8)
(b) (2, 3, 4, 5)
(c) (8, 6)
(d) None of the above
(a) arsh
(b) hars
(c) harsh
(d) None of the above
(a) rsh
(b) arsh
(c) harsh
(d) None of the above
15. >>>b
>>>a = 'tar'
>>>b = 'rat'
>>>2*(a + b) is
(a) tarrattarrat
(b) rattarrattar
(c) tarratrattar
(d) None of the above
PROGRAMS
1. Write a program to swap two numbers.
2. Ask the user to enter the coordinates of a point and find the distance of the
point from the origin.
3. Ask the user to enter two points (x and y coordinates) and find the distance
between them.
4. Ask the user to enter three points and find whether they are collinear.
5. In the above question, if the points are not collinear then find the type of
triangle formed by them (equilateral, isosceles or scalene).
6. In the above question, check if the triangle is right angled.
8. Ask the user to enter two points and find if they are at equal distances from
the origin.
9. In question number 8, find the angle between the line joining the points and
the origin.
10. Ask the user to enter 4 points and arrange them in order of their distances
from the origin.
11. In question 10, arrange the above points in order of their x co-ordinates.
CHAPTER
3
CONDITIONAL STATEMENTS
After reading this chapter, the reader will be able to
• Use conditional statements in programs
• Appreciate the importance of the if-else construct
• Use the if-elif-else ladder
• Use the ternary operator
• Understand the importance of & and |
• Handle conditional statements using the get construct
3.1 INTRODUCTION
The preceding chapters presented the basic data types and simple statements in
Python. The concepts studied so far are good for the execution of a program
which has no branches. However, a programmer would seldom find a problem
solving approach devoid of branches.
Before proceeding any further let us spare some time contemplating life. Can
you move forward in life without making decisions? The answer is NO. In the
same way the problem solving approach would not yield results until the power
of decision making is incorporated. This is the reason one must understand the
implementation of decision making and looping. This chapter describes the first
concept. This is needed to craft a program which has branches. Decision making
empowers us to change the control-flow of the program. In C, C++, Java, C#,
etc., there are two major ways to accomplish the above task. One is the ‘if’
construct and the other is ‘switch’. The ‘if’ block in a program is executed if
the ‘test’ condition is true otherwise it is not executed. Switch is used to
implement a scenario in which there are many ‘test’ conditions, and the
corresponding block executes in case a particular test condition is true.
The chapter has been organized as follows. The second section introduces the
‘if’ construct. Section 3.3 introduces ‘if-elif’ ladder. Section 3.4 discusses the
use of logic operators. Section 3.5 introduces ternary operators. Section 3.6
presents the get statement and the last section concludes the chapter. The reader
is advised to go through the basic data types before proceeding further.
General Format
1. if
if <test condition>:
<block if the test condition is true>
2. if-else
if <test condition>:
<block if the test condition is true>
else:
<block if the test condition is not true>
...
3. If else ladder (discussed in the next section)
if <test condition>:
<block if the test condition is true>
elif <test 2>:
<second block>
elif <test 3>:
<third block>
else:
<block if the test condition is true>
Illustration 3.1: Ask the user to enter the marks of a student in a subject. If the
marks entered are greater than 40 then print “pass,” if they are lower print “fail.”
Program
>>>a = input("Enter marks : ")
if int(a)> 40:
print('Pass')
else:
print('Fail')
...
Output 1
Enter Marks : 50
Pass
Output 2
Enter Marks : 30
Fail
Let us have a look at another example. In the problem, the user is asked to enter
a three digit number to find the number obtained by reversing the order of the
digits of the number; then find the sum of the number and that obtained by
reversing the order of the digits and finally, find whether this sum contains any
digit in the original number. In order to accomplish the task, the following steps
(presented in Illustration 3.2) must be carried out.
Illustration 3.2: Ask the user to enter a three digit number. Call it 'num'. Find
the number obtained by reversing the order of the digits. Find the sum of the
given number and that obtained by reversing the order of the digits. Finally, find
if any digit in the sum obtained is the same as that in the original number.
Solution:
When the user enters a number, check whether it is between 100 and 999,
both inclusive.
Find the digits at unit’s, ten’s and hundred’s place. Call them 'u', 't' and
'h' respectively.
Find the number obtained by reversing the order of the digits (say, ‘rev’)
using the following formula.
Number obtained by reversing the order of the digits, rev = h + t × 10 + u ×
100
Find the sum of the two numbers.
Sum = rev + num
The sum may be a three digit or a four digit number. In any case, find the
digits of this sum. Call them 'u1', 't1', 'h1' and 'th1' (if required).
Set 'flag=0'.
Check the following condition. If any one is true, set the value of flag to 1.
If “sum” is a three digit number
u = = u1
u = = t1
u = = h1
t = = u1
t = = t1
t = = h1
h = = u1
h = = t1
h = = h1
If “sum” is a four digit number the above conditions need to be checked
along with the following conditions:
u = = th1
h = = th1
t = = th1
The above conditions would henceforth be referred to as “set 1.” If the
value of “flag” is 1, then print 'true' else print 'false'.
The above process has been depicted in the following figure (Figure 3.2).
Program
Output: First run
>>>
========= RUN C:/Python/Conditional/Problem 2.py =========
Enter a three digit number :4
You have not entered a number between 100 and 999
>>>
Tip
One must be careful regarding the indentation, failing which the program would
not compile. The indentation decides the beginning and ending of a particular
block in Python. It is advisable not to use a combination of spaces and tabs in
indentation. Many versions of Python may treat this as a syntax error.
The if-elif ladder can also be implemented using the get statement, explained
later in the chapter. The important points regarding the conditional statements in
Python are as follows:
Illustration 3.3: Write a program to find the greatest of the three numbers
entered by the user.
Solution: First of all, three variables (say num1, num2, and num3) are needed.
These variables will get their values from the user. This input will be followed
by the condition checking as depicted in the following program. Finally, the
greatest number will be displayed. The listing is given as follows:
Program
Syntax
if <test condition 1>:
# The task to be performed if the condition 1 is true
elif <test condition 2>:
# The task to be performed if the condition 2 is true
elif <test condition 3>:
# The task to be performed if the condition 1 is true
else:
# The task to be performed if none of the above condition
is true
The flow of the program can be managed using the above construct. Figure 3.3
shows the diagram depicting the flow of the program which uses the above
constructs.
In the figure, the left edge depicts the scenario where the condition C is true and
the right edge depicts the scenario where the condition is false. In the second
graph, conditions C1, C2, C3, and C4 lead to different paths [Programming in
C#, Harsh Bhasin, 2014].
The following section has programs that depict the use of the elif ladder. It may
be noted that if there are multiple else statements, then the second else is taken
along with the nearest if.
The truth table of 'and' and 'or' is given as follows. In the tables that follow
“T” stands for “true” and “F” stands for “false.”
a b a&b
t T T
t F F
F T F
F F F
a b a|b
t T T
t F T
F T T
F F F
if((a>b)&(a>c))
print('The value of a greatest')
In the same way, the condition of ‘b’ being greatest can be crafted. Another
example can be that of a triangle. If all the three sides of a triangle are equal,
then it is an equilateral triangle.
if((a==b)||(b==c)||(c==a))
//The triangle is equilateral;
Syntax
<Output variable> = <The result when the condition is true>
if <condition> else <The result when the condition is not
true>
For example, the conditional operator can be used to check which of the two
numbers entered by the user is greater.
Finding the greatest of the three given numbers is a bit intricate. The following
statement puts the greatest of the three numbers in “great.”
The program that finds the greatest of the three numbers entered by the user
using a ternary operator is as follows.
Illustration 3.4: Find the greatest of three numbers entered by the user, using a
ternary operator.
Program
a = int(input('Enter the first number\t:'))
b = int(input('Enter the second number\t:'))
c = int(input('Enter the third number\t:'))
big = (a if (a>c) else c) if (a>b) else (b if (b>c) else c)
print('The greatest of the three numbers is '+str(big))
>>>
Output
========== RUN C:/Python/Conditional/big3.py ==========
Enter the first number 2
Enter the second number 3
Enter the third number 4
The greatest of the three numbers is 4
>>>
In the example that follows there are three conditions. However, in many
situations there are many more conditions. The contact can be used in such
cases. The syntax of the construct is as follows:
Syntax
<dictionary name>.get('<value to be searched>', 'default
value>')
Here, the expression results in some value. If the value is value 1, then block 1
is executed. If it is value 2, block 2 is executed, and so on. If the value of the
expression does not match any of the cases, then the statements in the default
block are executed. Illustration 5 demonstrates the use of the get construct.
Illustration 3.5: This illustration has a directory containing the names of books
and the corresponding year they were published. The statements that follow find
the year of publication for a given name. If the name is not found the string
(given as the second argument, in get) is displayed.
Program
hbbooks = {'programming in C#': 2014, 'Algorithms': 2015,
'Python': 2016}
print(hbbooks.get('Progarmming in C#', 'Bad Choice'))
print(hbbooks.get('Algorithms', 'Bad Choice'))
print(hbbooks.get('Python', 'Bad Choice'))
print(hbbooks.get('Theory Theory, all the way', 'Bad
Choice'))
Output
>>>
========== RUN C:/Python/Conditional/switch.py ==========
Bad Choice
2015
2016
Bad Choice
>>>
Note that in the first case the “P” of “Programming” is capital, hence “Bad
Choice” is displayed. In the second and the third cases, the get function is able to
find the requisite value. In the last case the value is not found and so the second
argument of the get function appears. Note that it is similar to the default of the
“C” type switch statement. The flow diagram given in Figure 3.4 shows a
program that has many branches.
In Python, dictionaries and lists form an integral part of the language basics. The
use of the get construct was not explained in Chapter 2 of this book, as it
implements the concept of conditional selection. It may be noted that this
construct greatly reduces the problems of dealing with the situations where
mapping is required and is therefore important.
3.7 EXAMPLES
The 'if' condition is also used for input validation. The process will be
explained in the following sections of this book. However, the idea has been
used in the example that follows. The program asks the user to enter a character
and checks whether its ASCII value is greater a certain value.
Illustration 3.6: Ask the user to enter a number and check whether its ASCII
value is greater than 80.
Program
inp = input('Enter a character :')
if ord(inp) > 80:
print('ASCII value is greater than 80')
else:
print('ASCII value is less than 80')
Output 1:
>>>Enter a character: A
ASCII value is less than 80
...
Output 2
>>>Enter a character: Z
ASCII value is greater than 80
>>>
The construct can also be used to find the value of a multi-valued function. For
example, consider the following function:
The following example asks the user to enter the value of x and calculates the
value of the function as per the given value of x.
Illustration 3.7: Implement the above function and find the values of the
function at x = 2 and x = 4.
Program
Output
========== RUN C:\Python\Conditional\func.py ==========
Enter the value of x :4
Value of function f(x) = 39
>>>
========== RUN C:\Python\Conditional\func.py ==========
Enter the value of x :1
Value of function f(x) = 4
>>>
The 'if-else' construct, as stated earlier, can be used to find the outcome based
on certain conditions. For example two lines are parallel if the ratio of the
coefficients of x’s is same as that of those of y’s.
For a1x + b1y + c1 = 0 and a2x + b2y + c2 = 0. Then the condition of lines being
parallel is:
The following program checks whether two lines are parallel or not.
Illustration 3.8: Ask the user to enter the coefficients of a1x + b1y + c1 = 0 and
a2x + b2y + c2 = 0 and find out whether the two lines depicted by the above
equations are parallel or not.
Program
Output
>>>
========== RUN C:\Python\Conditional\parallel.py ==========
Enter Coefficients of the first equation [a1x + b1y + c1 =
0]
Enter the value of a1: 2
Enter the value of b1: 3
Enter the value of c1: 4
Enter Coefficients of second equation [a2x + b2y + c2 = 0]
The above program can be extended to find whether the lines are intersecting or
overlapping: two lines intersect if the following condition is true.
a1x + b1y + c1 = 0 and a2x + b2y + c2 = 0. Then the lines intersect if:
The following flow-chart shows the flow of control of the program (Figure 3.5).
FIGURE 3.5 Checking whether lines are parallel, overlapping, or if they intersect
Illustration 3.9: Ask the user to enter the values of a1, a2, b1, b2, c1, and c2 and
find whether the lines are parallel, or if they overlap or intersect.
Program
Output
>>>
========== RUN C:/Python/Conditional/Lines.py ==========
Enter Coefficients of the first equation [a1x + b1y + c1 =
0]
Enter the value of a1: 2
Enter the value of b1: 3
Enter the value of c1: 4
Enter Coefficients of second equation [a2x + b2y + c2 = 0]
Enter the value of a2: 1
Enter the value of b2: 2
Enter the value of c2: 3
Lines intersect
>>>
3.8 CONCLUSION
As stated in the first chapter, we write a program with a purpose. The purpose to
be accomplished by a program generally requires making decisions. This
decision making capacity also empowers a programmer to write a code that
requires branching. Python greatly reduces unnecessary clutter when compared
to C or C++. In a Python code there is hardly a need for braces, or for that matter
handling obvious conditions. Python also provides us with a switch-like
construct to handle multiple conditions. This chapter discusses the basics of
conditional statements and presents ample illustrations to make things clear.
These conditional statements are used everywhere; from a basic program to
decision support systems and expert systems. The reader is required to go
through the points to remember, and implement the problems given in the
exercise for better understanding of this. One must also understand that the
conditional statements are the first step towards programming. However
understanding conditional statements, though essential, is just the beginning.
Your journey of becoming a programmer has just started.
GLOSSARY
1. The syntax of “if” is as follows.
if <test condition>:
<block if the test condition is true>
2. The “if else” construct is written as follows.
if <test condition>
<block if the test condition is true>
else:
<block if the test condition is not true>
...
3. The syntax of the “if else ladder”
if <test condition>:
<block if the test condition is true>
elif <test 2>:
<second block>
elif <test 3>:
<third block>
else:
<block if the test condition is true>
POINTS TO REMEMBER
The 'if' statement implements conditional branching.
The test condition is a Boolean expression which results in a true or a
false.
The block of 'if' executes if the test condition it true.
The else part executes if the test condition is false.
Multiple branches can be implemented using the if-elif ladder.
Any number of if-elif can be nested.
A ternary if can be implemented in Python.
Logical operators can be used in implementing conditional statements.
EXERCISES
2. a = 5
b = 7
c = 9
if a>b:
if b>c:
print(b)
else:
print(c)
else:
if b>c:
print(c)
else:
print(b)
(a) 7
(b) 9
(c) 34
(d) None of the following
3. a = 34
b = 7
c = 9
if a>b:
if b>c:
print(b)
else:
print(c)
else:
if b>c:
print(c)
else:
print(b)
(a) 7
(b) 9
(c) None of the above
(d) The code will not compile
4. a = int(input('First number\t:'))
b = int(input('Second number\t'))
c = int(input('Third number\t:'))
if ((a>b) & (a>c)):
print(a)
elif ((b>a) &(b>c)):
print(b)
else:
print(c)
(a) The greatest of the three numbers entered by the user
(b) The smallest of the three numbers entered by the user
(c) None
(d) The code will not compile
(a) Hi
(b) Bye
(c) None of the above
(d) The code will not compile
6. In the above question, if the number entered is 545, what would the answer
be?
(a) Hi
(b) Bye
(c) None of the above
(d) The code will not compile
(a) same
(b) Different
(c) No output
(d) The code would not compile
8. hb1 = ['Programming in C#','Oxford University Press', 2014]
hb2 = ['Algorithms', 'Oxford University Press', 2015]
if (hb1[0][3]==hb2[0][3]):
print('Same')
else:
print('Different')
(a) Same
(b) Different
(c) No output
(d) The code will not compile
9. In the snippet given in question 8, the following changes are made. What
will the output be?
hb1 = ['Programming in C#','Oxford University Press', 2014]
hb2 = ['Algorithms', 'Oxford University Press', 2015]
if (str(hb1[0][3])==str(hb2[0][3])):
print('Same')
else:
print('Different')
(a) Same
(b) Different
(c) No output
(d) The code will not compile
10. Finally, the code in question 8 is changed to the following. What will the
output be?
hb1 = ['Programming in C#','Oxford University Press', 2014]
hb2 = ['Algorithms', 'Oxford University Press', 2015]
if (char(hb1[0][3])==char(hb2[0][3])):
print('Same')
else:
print('Different')
(a) Same
(b) Different
(c) No output
(d) The code will not compile
PROGRAMMING EXERCISE
1. Ask the user to enter a number and find the number obtained by reversing
the order of the digits.
2. Ask the user to enter a four digit number and check whether the sum of the
first and the last digits is same as the sum of the second and the third digits.
3. In the above question if the answer is true then obtain a number in which the
second and the third digit are one more than that in the given number.
Example: Number 5342, sum of the first and the last digit = 7 that of the
second and the third digit = 7. New number: 5452
4. Ask the user to enter the concentration of hydrogen ions in a given solution
(C) and find the PH of the solution using the following formula.
PH = log10 C
5. If the PH is <7 then the solution is deemed acidic, else it is deemed as basic.
Find if the given solution is acidic.
7. The centripetal force acting on a body (mass m), moving with a velocity v,
in a circle of radius r, is given by the formula mv2/r. The gravitational force
on the body is given by the formula (GmM)/R2, where m and M are the
masses of the body and earth and R is the radius of the earth. Ask the user to
enter the requisite data and find whether the two forces are equal or not.
8. Ask the user to enter his salary and calculate the TADA, which is 10% of the
salary; the HRA, which is 20% of the salary and the gross income, which is
the sum total of the salary, TADA and the HRA.
9. In the above question find whether the net salary is greater than $300,000.
10. Use the Tax Tables of the current year to find the tax on the above income
(question number 8), assuming that the savings are $100,000.
11. Find whether a number entered by the user is divisible by 3 and 13.
12. Find whether the number entered by the user is a perfect square.
13. Ask the user to enter a string and find the alphanumeric characters from the
string.
15. In question 13, find all the components of the string which are not digits or
alphabets.
CHAPTER
4
LOOPING
After reading this chapter, the reader will be able to
• Understand the importance and use of loops
• Appreciate the importance of the while and for
• Use range
• Process list of lists
• Understand nesting of loops and design patterns
4.1 INTRODUCTION
When we were young, we were taught tables of numbers. The table of a number
had a pattern. Writing a table in an examination required writing, say, “n×”
followed by “i” (i varying from 1 to n) and then the result of calculations (that is
n × 1, n × 2 and so on). Many such situations require us to repeat a given task
many times. This repetition can be used to calculate the value of a function, to
print a pattern or to simply repeat something. This chapter discusses loops and
iterations, which are an integral part of procedural programming. Looping means
repeating a set of statements until a condition is true. The number of times this
set is repeated depends on the test condition. Also, what is to be repeated needs
to be chalked out with due deliberation. In general, repeating a block requires the
following (Figure 4.1).
FIGURE 4.1 Looping
Python provides two types of loops: for and while (Figure 4.2).
While loop is one of the most general constructs in any programming language.
If you come from a “C” background, you must be equipped with the above
construct. While loop retains most of its features in Python as well, however,
there are notable differences too.
The while loop repeats a block, identified by indentation, until the test condition
remains true. As we will see in the following discussion, one can come out of the
loop using break and continue. Also, to decide if the loop repeats as per the test
condition after which the else condition executes. This is an additional feature
in Python.
The use of for in Python is a bit different to “C”-like languages. The for
construct in Python is generally used for lists, tuples, strings, etc. The chapter
presents range, which will help the programmer to select a value from a given
range. The reader is advised to go through the discussion of lists and tuples
presented in Chapter 2 of this book before starting with the for loop.
The chapter has been organized as follows. Section 4.2 of this chapter presents
the basics of the while loop. Section 4.3 uses looping to create patterns. Section
4.4 introduces the concept of nesting and presents the processing of lists and
tuples using for loops. The last section concludes the chapter.
4.2 WHILE
In Python, the while loop is the most commonly used construct for repeating a
task over and over again. The task is repeated until the test condition remains
true, after which the loop ends and if the exit occurs without a break, then the
else part of the construct executes. The syntax of the loop is as follows:
Syntax
while test:
...
...
else:
...
It may be stated here that the body of the loop is determined by indentation. This
is the reason why you must be extremely careful with indentation. Also, the else
part is an addition in Python when compared to “C”-like languages. In order to
understand the concept, let us go through the following illustrations.
Illustration 4.1: Ask the user to enter a number and calculate its factorial.
factorial = 1 × 2 × 3 × … × n
Program
n = input('Enter number whose factorial is required')#ask
user to enter number
m = int(n)#convert the input to an integer
factorial = 1#initialize
i=1# counter
while i<=m:
factorial =factorial*i
i=i+1
print('\factorial of '+str(m)+' is '+str(factorial))
Output
>>>
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/factorial.py
Enter number whose factorial is required6
Factorial of 6 is 720
Illustration 4.2: Ask the user to enter two numbers “a” and “b” and calculate
“a” to the power of “b.”
power = a × a × a × .. × a (b times)
That is, the power of a number “a” raised to “b” is the product of the number
“a,” “b” times. To calculate the power, first of all the user is asked to input two
numbers. The numbers are then converted into integers. This is followed by the
initialization of 'power' by 1. Then a while loop successively multiplies 'a' to
'power' (note that after each iteration the value of i increases by 1). The
following program implements the above logic.
Program
>>>
a = int(input('Enter the first number'))
b = int(input('Enter the second number'))
power=1
i = 1
while i < = b:
power = power*a
i=i+1
else:
print(str(a)+' to the power of '+str(b)+' is
'+str(power))
Output
>>>
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/power.py
Enter the first number4
Enter the second number5
4 to the power of 5 is 1024
>>>
T (i) = a + (i – 1) × d
Ask the user to enter the value of “a,” “d,” and “n” (the number of terms), and
find all the terms of the AP. Also, find the sum of all the terms.
Solution: The following program asks the user to enter the values of “a,” “d,”
and “n.” Note that the input is converted into integers. Also, since all the terms
are to be calculated, this evaluation is done inside a loop. The 'sum' is initialized
to 0 and the terms are added to 'sum' in each iteration.
Program
>>>
a = int(input('Enter the first term of the Arithmetic
Progression\t:'))
d = int(input('Enter the common
difference\t:')) n = int(input('Enter the number of
terms\t:')) i = 1
sum = 0#initialize
while i<=n:
term = a +(i-1)*d
print('The '+str(i)+'th term is '+str(term))
sum = sum + term
i=i+1
else:
print('The sum of '+str(n)+' terms is\t:'+str(sum))
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/AP.py
Enter the first term of the Arithmetic Progression :5
Enter the common difference :6
Enter the number of terms :7
The 1th term is 5
The 2th term is 11
The 3th term is 17
The 4th term is 23
The 5th term is 29
The 6th term is 35
The 7th term is 41
The sum of 7 terms is :161
Ask the user to enter the value of 'a', 'r', and 'n'(the number of terms), and
find all the terms of the GP. Also, find the sum of all the terms.
Solution: The following program asks the user to enter the values of 'a', 'r',
and 'n'. Since all the terms are to be calculated, this evaluation is done inside a
loop. The 'sum' is initialized to 0 and the terms are added to 'sum' in each
iteration.
Program
>>>
a = int(input('Enter the first term of the Geometric
Progression\t:'))
r = int(input('Enter the common ratio\t:'))
n = int(input('Enter the number of terms\t:'))
i = 1
sum = 0#initialize
while i<=n:
term = a * (r**(i-1))
print('The '+str(i)+'th term is '+str(term))
sum = sum + term
i=i+1
else:
print('The sum of '+str(n)+' terms is\t:'+str(sum))
Output
>>>
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python 35-
32/Tools/scripts/GP.py
Enter the first term of the Arithmetic Progression :5
Enter the common ratio 3
Enter the number of terms 5
The 1th term is 5
The 2th term is 15
The 3th term is 45
The 4th term is 135
The 5th term is 405
The sum of 5 terms is 605
>>>
4.3 PATTERNS
Have you ever wondered why quizzes and riddles form an integral part of any
intelligence test? The following incident will help the reader to understand the
importance of patterns. During World War II, the British were striving hard to
break Enigma, the machine used by the Germans for encrypting their messages.
The army somehow recruited Alan Turing, who was never in his lifetime
recognized, for the above task. He wanted a team to help him, for which he
conducted an exam. Many of you would be amazed to know what he asked in
that exam which would determine the destiny of a country! He asked the
candidates to solve the given puzzles in a given time. This incident underlines
the importance of comprehending patterns. What happened thereafter is history.
Decoding patterns and solving puzzles helps to judge the intellect of a person.
This is much more important than learning a formula. This section presents the
designing of patterns using loops to help the reader understand the concept of
nesting. Moreover, this book also intends to inculcate the problem solving
approach in the reader. Therefore this section becomes all the more important.
The following illustrations show how to assign values to the counters of the
inner and the outer loops to carry out the given task. The patterns, as such, may
not be very useful. However, doing the following program would help the reader
to comprehend the concept of nesting. The methodology of making a pattern has
been explained in each of the following programs.
Solution: The number of rows n, will determine the value of the counter (from 0
to n). The value of i denotes the row number in the following program. In each
row, the number of stars is equal to the row number. The values of j, in each
iteration, denotes the number of stars in each row. This loop is therefore nested.
Also, note that after the inner loop ends a new line is printed using the print()
function.
Program
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/loop2.py
Enter the number of rows 5
*
* *
* * *
* * * *
1
2 2
3 3 3
4 4 4 4
Solution: The number of rows will determine the value of the counter i, (from 0
to n). The value of i denotes the row number in the following program. In each
row, the number of elements is equal to the row number. The values of j in each
iteration denote the number of elements in each row. This loop is therefore
nested. The element printed is the value of i+1. Also, note that after the inner
loop ends a new line is printed using the print() function.
Program
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/loop2.py
Enter the number of rows5
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
2
2 3
2 3 4
2 3 4 5
Solution: The number of rows, entered by the user, will determine the value of i
(from 0 to n). The value of i denotes the row number in the following program.
In each row, the number of elements is equal to the row number. The values of j
in each iteration denote the number of elements in each row. This loop is
therefore nested. The element printed is the value of j+1. Also note that after the
inner loop ends a new line is printed using the print() function.
Program
Output
>>>
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/loop3.py
Enter the number of rows5
2
2 3
2 3 4
2 3 4 5
2 3 4 5 6
1
2 3
4 5 6
7 8 9 10
Solution: The value of i denotes the row number in the following program. In
each row, the number of elements is equal to the row number. The values of i in
each iteration will denote the number of elements in each row. This loop is
therefore nested. The element printed is the value of k, which starts from 1 and
incrementally increases in each iteration. Also note that after the inner loop ends
a new line is printed using the print() function.
Program
Output
>>>
RUN C:\Users\ACER ASPIRE\AppData\Local\Programs\Python\
Python35-32\Tools\scripts\loop1.py
Enter the number of rows7
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27 28
Solution: The value of i denotes the row number in the following program. In
each row, the number of stars is equal to the row number. The values of k in each
iteration denote the number of stars in each row, which ranges from 0 to (2*i
+1). This loop is therefore nested. The leading spaces are governed by the value
of j, which ranges from 0 to (m-i-1). This is because if the value of i is 0, the
number of spaces should be 4 (if the value of n is 5). In case the value of i is 1,
the number of spaces should be 3 and so on. Also note that after the inner loop
ends a new line is printed using the print() function.
Program
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/loop5.py
Enter the number of rows 6
*
***
*****
*******
*********
ai, j = 5 × (i + j)2
Note that in the following illustration, two loops have been used. The outer loop
runs n times where n is the number of rows, and the inner loop runs m times
where m is the number of columns. The number of columns can be perceived as
the number of elements in each row.
The inner loop has one statement, which calculates the element. At the end of
each iteration (of the outer loop) a new line is printed using the print()
function.
ai, j = 5 × (i + j)2
Solution: The concept has been explained in the above discussion. There will be
two loops; the outer loop for the number of rows and the inner loop for the
number of columns.
Program
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/matrixgeneartion.py
Enter the number of rows3
Enter the number of columns3
0 5 20
5 20 45
20 45 80
>>>
It may be noted that in the following chapters, this nesting is used to deal with
most of the operations of matrices. As a matter of fact addition and subtraction
of two matrices requires two levels of nesting, whereas multiplication of two
matrices requires three levels of nesting.
Illustration 4.11: Handling list of lists: Note that in the following program the
first list’s second element is itself a list. Its first element can be accessed by
writing hb[0][1] and the first letter of the first element of the nested list would
be hb[0][1][0].
Program
Output
The following two illustrations handle the list of lists using nested loops. Kindly
note the output and the corresponding mappings.
Illustration 4.12: Handling list of lists using loops: The elements of nested
lists can also be dealt with using nested loops as shown in this illustration.
Program
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/listfor.py
[['Programming in C#', ['Oxford University Press', 2015]],
['SE is everything', ['Obscure Publishers', 2015]]]
0 0 Programming in C#
0 1 ['Oxford University Press', 2015]
1 0 SE is everything
1 1 ['Obscure Publishers', 2015]
>>>
Program
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/listfor.py
[['Programming in C#', ['Oxford University Press', 2015]],
['SE is everything', ['Obscure Publishers', 2015]]]
0 0 0 P
0 0 1 r
0 0 2 o
0 0 3 g
0 0 4 r
0 0 5 a
0 0 6 m
0 0 7 m
0 0 8 i
0 0 9 n
0 0 10 g
0 0 11
0 0 12 i
0 0 13 n
0 0 14
0 0 15 C
0 0 16 #
0 1 0 Oxford University Press
0 1 1 2015
1 0 0 S
1 0 1 E
1 0 2
1 0 3 i
1 0 4 s
1 0 5
1 0 6 e
1 0 7 v
1 0 8 e
1 0 9 r
1 0 10 y
1 0 11 t
1 0 12 h
1 0 13 i
1 0 14 n
1 0 15 g
1 1 0 Obscure Publishers
1 1 1 2015
4.5 CONCLUSION
Repeating a task is an immensely important job. This is needed in a whole
variety of situations to accomplish different tasks. This chapter introduces the
two most important looping constructs in Python. The chapter demonstrated the
use of these looping constructs by showing simple examples. Having a loop
within a loop is called nesting. The nesting of loops has been explained using
patterns and lists of lists. Chapter 6 revisits one of the constructs and compares
the use of iterators and generators. The reader is expected to solve the problems
given at the end of the chapter for better understanding. However, Python
provides us with other constructs which greatly simplify program writing. At the
moment try various permutations and combinations, observe the outputs and
learn.
GLOSSARY
1. Looping means repeating a task a certain number of times.
EXERCISES
(a) 8, 6, 3
(b) 8, 6, 3, –1
(c) 8, 6, 3, –1, ...
(d) None of the above
2. a=8
i=1
while a:
print(a)
i=i+1
a=a/2
print(i)
(a) 8, 4, 2, 1
(b) 8, 4, 2, 1, 0
(c) 8, 4, 2, 1, 0.5
(d) Infinite loop
4. Which loop can be used when the number of iterations is not known?
(a) while
(b) for
(c) both
(d) None of the above
6. n = int(input('Enter number'))
for i in (0,7):
print('i is '+str(i))
i = i+1;
else:
print('bye')
How many values would be printed?
(a) 2
(b) 3
(c) 6
(d) None of the above
7. n = int(input('Enter number'))
for i in range(n, 1, -1):
for j in range(i):
print(i, j)
#value entered by the user is 5
(a) (5, 0), (5, 1), ...(2, 1)
(b) (5, 1), (5,2),...(2, 0)
(c) (0,1), (0,2), ...(5, 2)
(d) None of the above
PROGRAMMING
1. Ask the user to enter a number and find whether it is a prime number.
2. Ask the user to enter a number and find all its factors.
4. Ask the user to enter two numbers and find the lowest common multiple.
Example: If numbers are 30 and 20, then LCM is 60, as both 20 and 30 are
factors of 60
5. Ask the user to enter two numbers and find the highest common factor.
Example: If numbers are 30 and 20, the HCF is 10
7. Find the variance and standard deviation of the numbers entered by the user.
8. Ask the user to enter the values of a and b and find aba.
11. In the above question, what happens if we have four numbers in place of
three?
13. Ask the user to enter n numbers and find the minimum of the numbers
without using arrays.
14. Ask the user to enter n numbers and find the maximum of the numbers
without using arrays.
15. Create a list of authors in which the record of each author is itself a list
consisting of the name of the book, publisher, year of publication, ISSN, and
the city. Now process the list using for loop.
CHAPTER
5
FUNCTIONS
After reading this chapter, the reader will be able to
• Appreciate the importance of modular programming
• Define and classify functions
• Understand the concept of the scope of a variable
• Understand and use recursion
5.1 INTRODUCTION
If you have to perform a bigger task, then it is advisable to divide it into smaller,
more manageable tasks. This division has many advantages, which are discussed
in the following sections. The units of programs, which can be called on as its
basis, take some input, process it and may generate some output which i referred
to as functions.
Functions are units which perform a particular task, take some input, and
which may give some output.
This concept is the soul of procedural programming. The readers familiar with C
(or for that matter C++, Java, C#, etc.) will be familiar with the idea and use of
functions. However, a brief discussion on the futures and advantages of
functions follows in the next section.
This chapter introduces the concept of functions. The chapter has been organized
as follows. The next section briefly explains the features of a function; the third
section explains the basic terminology, and the following section discusses the
definition and use of a function. The fifth section presents a brief discussion on
the scope of a variable. The sixth section presents recursion and the last section
of the chapter concludes.
5.2 FEATURES OF A FUNCTION
As discussed earlier, functions form the basis of procedural programming. One
of the most obvious advantages is the division of a program into smaller parts.
This section briefly discusses the advantages of dividing the program into
functions.
5.2.3 Manageability
Dividing a bigger task into smaller functions makes the program manageable. It
becomes easy to locate bugs and therefore make the program reliable. It also
becomes easy to carry out local optimization in a function. To summarize,
manageability leads to the following:
5.2.3.1 Easy Debugging
In order to understand why creating functions will make debugging easy, let us
consider White Box Testing. This type of testing, which uses code for testing,
requires elicitation of paths and crafting test cases catering to them. In this case
it becomes easy to effectively analyze smaller functions rather than the whole
task.
5.2.3.2 Efficient
The above factors point to the fact that dividing the task into functions is good
practice. It may be noted here that even object-oriented programming, described
in Section 2 of this book, relies on functions for implementing the behavior of a
class.
5.3.2 Arguments
The arguments of a function denote the input given to a function. A function can
have any number of arguments. As a matter of fact, it is possible that a function
may not have any argument.
In Python a function can be made in the command prompt. This implies that
unlike C (or for that matter C++, Java, or C#) a function need not be a part of a
program. Moreover, the return type as described in this section need not be
mentioned. This inculcates flexibility in the procedures.
Body of the function: The body of the function contains the code that
implements the task to be performed by the function.
Figure 5.1 shows the name of the function (fun), the list of parameters in the
parentheses following the name of the function (in this case there are no
parameters) and the body of the function.
It may also be noted that the closing parentheses containing the parameters is
followed by a colon. The body of a function starts with a proper indentation.
The invocation of a function can be at any place after the definition. However,
exceptions to this premise are found in the case of recursion.
Syntax
5.4.1 Working
Consider a function which multiplies two numbers passed as parameters.
def product(num1, num2):
prod= num1*num2
print('The product of the numbers is \t:'+str(prod))
The name of this function is product. It takes two arguments as input (num1 and
num2), calculates the product and displays the results.
Here calling product shifts the control to the function, inside which the product
is calculated and the result is displayed. The control then comes back to the
calling function (Figure 5.3).
FIGURE 5.3 Calling a function
A function can be called any number of times. The following example shows a
function which does not take any input and does not return anything. The
function called just prints the lines of Ecclesiastes. The following listing shows
the function, and the output of the program follows.
Listing
def Ecclesiastes_3():
print('To everything there is a season\nA time for every
purpose under Heaven')
print('A time to be born\nand a time to die\nA time to
plant\nand a time to reap')
print('A time to kill\nand a time to heal\nA time to
break down\nand a time to build up')
print('A time to cast away stones\nand a time to gather
stones\nA time to embrace\nand a time to refrain')
print('A time to gain\nand a time to lose\nA time to
keep\nand a time to cast away')
print('A time of love\nand a time of hate\nA time of war\
nand a time of peace')
print('Calling function\n')
Ecclesiastes_3()
print('Calling function again\n')
Ecclesiastes_3()
>>>
Output
Calling function
The second type of function takes parameters but does not return anything.
Illustration 5.2 is an example of a function. The third type of function takes
parameters and returns an output. The example that follows adds two numbers
using functions. The task has been accomplished in three different ways – in the
first function (sum1) the input is taken inside the function and the result is
displayed in a print statement, which is also present inside the function.
The second function takes the two numbers as input (via parameters), adds them
and prints the result inside the function itself. The third function (sum3) takes
two parameters and returns the sum.
Illustration 5.2: Write a program to add two numbers using functions. Craft
three functions, one of which does not take any parameters and does not return
anything. The second function should take parameters and not return anything.
The third function should take two numbers as parameters and should return the
sum.
Program
>>>
def sum1():
num1=int(input('Enter the first number\t:'))
num2=int(input('Enter the second number\t:'))
sum= num1+num2
print('The sum of the numbers is \t:'+str(sum))
Output
RUN C:/Users/ACER
ASPIRE/AppData/Local/Programs/Python/Python35-
32/Tools/scripts/sum_of_numbers.py
Calling the first function...
Enter the first number 3
Enter the second number 4
The sum of the numbers is 7
Enter the first number 2
Enter the second number 1
Calling the second function...
The sum of the numbers is 3
Calling the third function...
3
>>>
Listing 1
Output
>>> sum1(3,2)
5
>>> sum1('hi', 'there')
'hithere'
>>>
Listing 2
>>>
def sum1(num1, num2):
return (num1+num2)
print('Calling function with integer arguments\t: Result:
'+str(sum1(2,3)))
print('Calling the function with string arguments\t: Result:
'+sum1('this',' world'))
Output
Calling function with integer arguments : Result: 5
Calling the function with string arguments : Result: this
world
>>>
Solution:
Output
Position 5
Not found
>>>
The above search strategy works well. However, there is another strategy of
search called binary search. In binary search, the input list must be sorted. The
algorithm checks whether the item to be searched is present at the first position,
at the last position or at the middle position. If the requisite element is not
present at any of these positions and it is less than the middle element, then the
left part of the list becomes the input of the procedure; else the right part of the
element becomes the input to the procedure. The reader is advised to implement
binary search.
5.7 SCOPE
The scope of a variable in Python is the part of the program wherein its value is
legal or valid. It may be seated here that although Python allows a global
variable, the value of a local variable must be assigned before being referenced.
Illustration 5.5 exemplifies this concept. The illustration has three listings. In the
first listing the value of 'a' has been assigned outside the function as well as
inside the function. This leads to a problem as a variable cannot be referenced
before being assigned.
In the second case this contention is resolved. Finally, the last listing shows that
global variables are very much allowed in Python for some strange reason. As an
active programmer, I firmly believe that should not have been allowed and there
are multiple reasons for not allowing global variables in a programming
language.
Listing 1
# Note that a = 1does not hold when function is called
a = 1
def fun1():
print(a)
a=7
print(a)
def fun2():
print(a)
a=3
print(a)
fun1()
fun2()
>>>
Output
============ RUN C:/Python/Functions/scope.py ===========
Traceback (most recent call last):
File "C:/Python/Functions/scope.py", line 12, in
<module> fun1()
File "C:/Python/Functions/scope.py", line 3, in fun1
print(a)
UnboundLocalError: local variable 'a' referenced before
assignment
>>>
Listing 2
a = 1
def fun1():
a=1
print(a)
a=7
print(a)
def fun2():
a=1
print(a)
a=3
print(a)
fun1()
fun2()
Output
>>>
=========== RUN C:/Python/Functions/scope.py ===========
1
7
1
3
>>>
Also, note that had “a” been not assigned in the functions, the global value
would have sufficed.
Listing 3
Output
>>>
=========== RUN C:/Python/Functions/scope.py ============
1
1
>>>
5.8 RECURSION
At times a function needs to be called within itself. Calling a function in itself is
referred to as recursion. The concept is used to accomplish many tasks easily and
intuitively. For example, consider the following series:
1, 1, 2, 3, 5, 8, 13, ...
Note that each term is the sum of the previous two terms; the first and the second
term being 1 and 1 respectively. This series is referred to as the Fibonacci series.
The series is due to a famous rabbit problem which has been described as
follows in mathematics.
Note that in the above series, each term is the sum of the two preceding terms.
The series can be represented as follows:
Illustration 5.6: Ask the user to enter the value of n and find the nth Fibonacci
term.
Solution:
Output
========== RUN C:/Python/Functions/factoorial.py ==========
Enter the number:5
The nth fib term is 5
Note that the calculation of Fibonacci uses the Fibonacci term calculated earlier.
For example, the calculation of the 5th Fibonacci term requires the following
calculations: fib(5) requires fib(4) and fib(3), fib(4) requires fib(3) and fib(2) and
fib(3) requires fib(2) and fib(1) (Figure 5.4).
The next example calculates the factorial of a number using recursion. The
factorial of a number n (positive, integer) is the product of all the integers from 1
to n. That is:
n! = 1 × 2 × 3 × ... × n
Note that since (n – 1)! = 1 × 2 × 3 ... × (n – 1)
Therefore, n! = n × (n – 1)!
Also the factorial of 1 is 1, that is, 1! = 1 which can be used as the base case
while implementing factorial using recursion. The program has been depicted in
Illustration 5.7.
Illustration 5.7: Ask the user to enter the value of n and calculate the factorial
of n using recursion.
Solution:
Output
>>>
========== RUN C:/Python/Functions/factoorial.py ==========
Enter the number 5
Factorial of 5 is 120
>>>
The power of a number raised to the power of another can also be calculated
using recursion. Since that is power (a, b) = a*power (a, b – 1). Also, a1,
that is power (a, 1) = 1. The above logic has been implemented in the
illustration that follows.
Illustration 5.8: Ask the user to enter the values of a and b and calculate a to the
power of b, using recursion.
Program
def power(a, b):
if b==1:
return a
else:
return (a*power(a, b-1))
a = int(input('Enter the first number\t:'))
b = int(input('Enter the second number\t:'))
p = power(a,b)
print(a, ' to the power of ',b,' is ', p)
Output
>>>
========== RUN C:/Python/Functions/power.py ==========
Enter the first number 3
Enter the second number 4
3 to the power of 4 is 81
>>>
>>>
Similarly, the recursive procedures in divide and conquer also require a huge
amount of time. In addition to the above problem, there is another flip side.
Recursion requires a lot of memory. Though a portion of the memory is reserved
for stacks, a recursive procedure may eat up all the available memory. However,
recursion is fun so let’s enjoy recursion.
5.9 CONCLUSION
The chapter introduces the concept of functions. The idea of dividing the given
program into various parts is central to manageability. The chapter forms the
foundation stone of the chapters that follow. It may also be stated that function
implements the behavior of a class; therefore before moving to the object-
oriented paradigms, one must be familiar with functions and procedures.
GLOSSARY
Function: Functions accomplish a particular task. They help with making a
program manageable.
Argument: Arguments are the values passed in a function.
Recursion: A function may call itself. This is referred to as recursion.
POINTS TO REMEMBER
A function can have any number of arguments.
A function may return a maximum of one value.
A function may not even return a value.
A function may call itself.
A function can be called any number of times.
A function needs to be called in order to be able to accomplish a particular
task.
EXERCISES
PROGRAMMING EXERCISE
1. Write a function that calculates the mean of numbers entered by the user.
2. Write a function that calculates the mode of numbers entered by the user.
3. Write a function that calculates the median of numbers entered by the user.
5. Write a function that finds the maximum of the numbers from a given list.
6. Write a function that finds the minimum of the numbers from a given list.
7. Write a function that finds the second maximum of the numbers from a
given list.
8. Write a function that finds the maximum of three numbers entered by the
user.
10. Write a function that searches for an element from a given list.
12. White a function that takes two lists as input and returns the merged list.
13. Write a function that finds all the factors of a given number.
14. Write a function that finds common factors of two given numbers.
15. Write a function that returns a number obtained by reversing the order of
digits of a given number.
3. Given two numbers, find the first number to the power of the second.
4. Given two numbers, find the greatest common divisor of the numbers.
5. Given two numbers, find the least common multiples of the numbers.
THEORY
1. What are the advantages of using functions in a program?
EXTRA QUESTIONS
1. What will be the output of the following program?
(a) 1
(b) 5
(c) 3
(d) Maximum iteration depth reached
(a) 5
(b) 100
(c) 25
(d) Maximum iteration depth reached
(a) I am in main
I am in fun 1
I am in fun 2
I am back in fun 1
I am back in main
(b) Reverse of the above
(c) None of the above
(d) The program does not execute
6.1 INTRODUCTION
So far basic data types, operators and control structures have been covered.
These are essential part of any procedural language. Python also provides the
programmers with lists, strings, tuples, dictionary, and files, which makes it a
powerful language. However, one should be able to efficiently access and
manipulate these elements to accomplish the given task. For example if the
formula of the ith element of a list is known, then the whole list can be
generated/accessed in one go. To accomplish this task, for loop comes to our
rescue. However, Python also comes with better options like iterators, which
help us to do the said task easily. One can also define iterable objects in Python.
There is another marvel in Python that facilitates the generation of lists and
sequences, which is generator. This chapter also introduces comprehension.
The chapter has been organized as follows. The second section of this chapter
revisits for. The iterators have been introduced in the third section of this
chapter. The fourth section explains so as to how to define your own iterable
objects. The generators are introduced and explained in section five of this
chapter. The sixth section of this chapter deals with comprehensions, which
makes the task of generating specific lists, etc., easy and the last section
concludes the chapter.
The chapter assumes importance as it forms the foundation stone of many of the
difficult tasks presented in the following chapters. Also, the knowledge of these
will make the day to day tasks easy and spare the programmer from the horror of
writing long codes.
A for loop can be used to iterate through a list, tuple, string, or a dictionary. This
section briefly explains how to use the loop for the above iterable objects. Let us
start with the syntax of for.
Syntax
for i in L:
#do something
When one writes " i in L", where L is a list, i becomes the first element of the
list and as the iteration progresses, i becomes the second element, the third
element and so on. These elements can be then independently manipulated. The
concept has been exemplified in Illustration 6.1. The illustration shows the
manipulation of a list using the for loop. In the illustration the given list
contains a set of numbers, some of them positive and some negative. The
negative numbers are appended to a list called N, where the positive numbers are
appended in a list called P.
Illustration 6.1: From a given list, put all the positive numbers in one list and
negative numbers in the other list.
Solution: Create two lists, P and N. Initialize both of them to []. Now check each
number in the list. If the number is positive put it in P and if the number is
negative put it in N.
Program
Output
========== RUN C:/Python/Iterations/for list.py ==========
The list of positive numbers : [1, 2, 5, 7, 3, 7]
The list of negative numbers : [-1, -6]
>>>
A for loop can also be used to manipulate strings. When one writes " i in
str", where str is a string, i becomes the first character of the string and as the
iteration progresses, i becomes the second character, the third character and so
on. These characters can be then independently manipulated. The concept has
been exemplified in Illustration 6.2, in which the vowels and consonants of a
given string are put in two strings.
Illustration 6.2: Ask the user to enter a string and put all the vowels of the
string in one string and the consonants in the other string.
Solution: Create two strings: str1 and str2. Initialize both to "". Now, check
each character in the given string. If it is a vowel, concatenate it with str1
otherwise concatenate it with str2.
Program
Similarly, a for loop can be used to iterate through a tuple and keys of a
dictionary as shown in Illustrations 6.3 and 6.4.
Illustration 6.3: This illustration demonstrates the use of for for iterating
through a tuple.
Solution:
T=(1, 2, 3)
for i in T:
print(i)
print(T)
>>>
Output
========== RUN C:/Python/Iterations/forTuple.py ==========
1
2
3
(1, 2, 3)
>>>
Illustration 6.4: This illustration demonstrates the use of for for iterating
through a dictionary.
Solution:
Dictionary={'Programming in C#': 499, 'Algorithms Analysis
and Design':599}
print(Dictionary)
for i in Dictionary:
print(i)
>>>
Output
========== RUN C:/Python/Iterations/for dic.py ==========
{'Programming in C#': 499, 'Algorithms Analysis and Design':
599}
Programming in C#
Algorithms Analysis and Design
>>>
6.3 ITERATORS
The above tasks (Illustrations 6.1-6.4) can also be accomplished using iterators.
The "iter" function returns the iterator of the object passed as an argument. The
iterator can be used to manipulate lists, strings, tuples, files, and dictionary, in
the same way as a for loop. However, the use of an iterator ensures flexibility
and additional power to a programmer. This will be established in the following
sections.
The iterator can move to the next element, using the _next_() method. An
iterator, as stated earlier, can iterate through any iterable object including lists,
tuples, strings or a directory. When there are no more elements then a
StopIteration exception is raised.
The following illustration shows the manipulation of a list using iterators. In the
illustration, the given list contains a set of numbers, some of them positive and
some negative. The negative numbers are appended to a list called N, whereas
the positive numbers are appended in a list called P. The same problem was
solved using the for loop in Illustration 6.1.
Illustration 6.5: Using iterators the program puts the positive and negative
numbers of a list into two separate lists and raises an error at the end of the
program.
Solution:
The next example deals with a string. The iterator is set to the first element of
the string and is then set to the second element, third element and so on. If the
character is a vowel it is appended to vow, otherwise it is appended to cons. The
following illustration uses the same problem as that stated in Illustration 6.2.
Illustration 6.6: Write a program that uses iterators to separate the vowels and
consonants of a given string and raises an error at the end of the program.
Solution: The vow and cons strings are initialized to "" and each character of the
given list is checked. If the character is a consonant it is concatenated to cons,
otherwise it is concatenated to vow.
A slightly more complex application of iterators has been shown in the following
illustration.
Solution:
#The program concatenates two lists into one by iterating
over individual elements of the lists using the list
function and then sorts the concatenated list.
l1 = [ 3, 6, 1, 8, 5]
l2 = [ 7, 4, 6, 2, 9]
i1 = iter(l1)
i2 = iter(l2)
l3 = sorted( list(i1) + list(i2) )
print( 'List1 - ', l1, '\nList2 - ', l2, '\nSortedCombn - ',
l3 )
Solution:
Output
=========== RUN C:/Python/Iterations/Class.py ===========
Enter the first term :1
Enter the common differnce :2
<class ' main .yrange'>
1
3
5
>>>
6.5 GENERATORS
Generators are functions that generate the requisite sequences. However, there is
an inherent difference between a normal function and a generator. In a generator,
the values are generated as and when we proceed. So, if one comes back to the
function once a particular value is generated, then instead of starting from the
beginning the function starts from the point where we left off.
The task seems difficult but has an advantage. The concept can help the
programmer to generate lists containing the desired sequences. For example if
one wants to generate a list containing the terms of an arithmetic progression in
which each term is “d” more than the first term, generators come to the rescue.
Similarly, the sequences like geometric progression, Fibonacci series, etc., can
be easily generated using generator.
Python comes with 'yield', which helps to start from the point where we left
off. This is markedly different from 'return' used in normal functions which
does not save the state where we left off. If the function having 'return' is
called again, it starts all over again.
Solution:
Output
========= RUN C:/Python/Iterations/generator 1.py =========
Enter the first term of the arithmetic progression :3
Enter the common difference of the arithmetic progression :5
Enter the number of terms of the arithmetic progression :8
<generator object arithmetic_progression at 0x031C2DE0>
3
8
13
18
23
28
33
38
>>>
Solution:
Output
======== RUN C:/Python/Iterations/generators gp.py ========
Enter the first term of the geometric progression :3
Enter the common ratio of the geometric progression :4
Enter the number o0f terms of the geometric progession :7
3
9
27
81
243
729
2187
>>>
Solution:
In order to understand the concept, let us go through the following illustration.
Illustration 6.12: This illustration demonstrates the effect of yield on the value
of the counter.
Solution: The reader is expected to note the change in the value after and before
yield.
Program
Output
========== RUN C:/Python/Iterations/generator. py ==========
Start
Value of i before yield : 0
0
Value of i after yield : 0
Value of i before yield : 1
1
Value of i after yield : 1
Value of i before yield : 2
2
Value of i after yield : 2
Value of i before yield : 3
3
Value of i after yield : 3
Value of i before yield : 4
4
Value of i after yield : 4
Value of i before yield : 5
5
Value of i after yield : 5
Value of i before yield : 6
6
Value of i after yield : 6
Value of i before yield : 7
7
Value of i after yield : 7
Value of i before yield : 8
8
Value of i after yield : 8
Value of i before yield : 9
9
Value of i after yield : 9
Value of i before yield : 10
10
Value of i after yield : 10
Value of i before yield : 11
11
Value of i after yield : 11
Value of i before yield : 12
12
Value of i after yield : 12
Value of i before yield : 13
13
Value of i after yield : 13
Value of i before yield : 14
14
Value of i after yield : 14
Value of i before yield : 15
15
Value of i after yield : 15
Value of i before yield : 16
16
Value of i after yield : 16
Value of i before yield : 17
17
Value of i after yield : 17
Value of i before yield : 18
18
Value of i after yield : 18
Value of i before yield : 19
19
Value of i after yield : 19
End
>>>
6.6 COMPREHENSIONS
The aim of a programming language should be to make things easy for a
programmer. A task can be performed in many ways but one which requires the
least coding is the most appealing to a coder. Python has many features which
facilitate programming. Comprehensions are one of them. Comprehensions
allow sequences to be built from other sequences. Comprehensions can be used
for lists, dictionary and set comprehension. In the earlier version of Python
(Python 2.0) only list comprehensions were allowed. However, in the newer
versions comprehensions can be used with dictionary and sets also.
In the fourth comprehension the comprehension takes the words of the sentence
“Winter is coming” and generates a list containing the word in caps, in running
and the length of the word.
x3, i from 0 to 9
3x, i from 2 to 10
All the multiples of 5 from the previous list
The caps, running version and the length of each word in the sentence
“Winter is coming”
Solution:
L1 = [x**3 for x in range(10)]
print(L1)
L2 = [3**x for x in range(2, 10, 1)]
print(L2)
L3 = [x for x in L2 if x%5==0]
print(L3)
String = "Winter is comming".split()
print(String)
String_cases=[[w.upper(), w.lower(), len(w)] for w in
String]
for i in String_cases:
print(i)
list1 = [1, '4', 9, 'a', 0, 4]
square_int = [ x**2 for x in list1 if type(x)==int]
print(square_int)
>>>
Output
>>>
====== RUN C:/Python/Iterations/Comprehensions 1.py ======
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[9, 27, 81, 243, 729, 2187, 6561, 19683]
[]
['Winter', 'is', 'comming']
['WINTER', 'winter', 6]
['IS', 'is', 2]
['COMMING', 'comming', 7]
[1, 81, 0, 16]
>>>
A comprehension contains the input sequence along with the expression that
represents the members. A comprehension may also have an optional predicate
expression.
In order to understand the concept let us consider one more illustration. The list
of temperatures in Celsius is given and the corresponding list containing the
temperatures in Kelvin is to be generated. It may be stated here that the
temperatures in Celsius and Kelvin are related as follows.
Solution: The list L_kelvin, is a list where in each element is 273.16 more than
the corresponding element in L_cel. Note that the task has been accomplished in
the definition of the list L_Kelvin itself.
Program
L_Cel = [21.2, 56.6, 89.2, 90,1, 78.1]
L_Kelvin = [x +273.16 for x in L_Cel]
print('The output list')
for i in L_Kelvin:
print(i)
Output
>>>
====== RUN C:/Python/Iterations/comprehension_cel.py ======
The output list
294.36
329.76000000000005
362.36
363.16
274.16
351.26
>>>
Solution:
A= ['a', 'b', 'c']
B= [1, 2, 3, 4]
AXB = [(x, y) for x in A for y in B]
for i in AXB:
print(i)
>>>
Output
======== RUN C:/Python/Iterations/cross_product.py ========
('a', 1)
('a', 2)
('a', 3)
('a', 4)
('b', 1)
('b', 2)
('b', 3)
('b', 4)
('c', 1)
('c', 2)
('c', 3)
('c', 4)
>>>
The above program is important because the concept of relations and therefore
functions in mathematics originates from the cross product. As a matter of fact
any subset of A × B is a relation from A to B. There are four types of relations in
mathematics: one to one, one to many, many to one, and many to many. Out of
these relations, one to one and many to one are referred to as functions.
6.7 CONCLUSION
The chapter explains the use of for for iterating over a list, string, tuple, or a
dictionary. It may be stated here that in C or C++, for is generally used for the
same purpose as while. However in Python, for can be used to visit each
element individually. Note that this can also be done in Java or C#. In order to
define an iterable object, _iter and _next need to be defined for the requisite
class. The reader is also expected to take note of the fact that yield and return
perform different tasks in Python. The use of these two has been demonstrated in
the illustrations presented in this chapter. Finally, while defining a list each
element can be crafted as per the need of the question. This can be done with the
help of comprehensions. The chapter, though easy, becomes important in the
light of excessive use of these techniques in machine learning and pattern
recognition tasks which are introduced in the last section of this book.
GLOSSARY
Iterator takes an iterable object and helps to traverse the object.
_next_(): The next function helps in iterating over the value of the iterable
object.
_iter_(): It helps in creating a user defined iterable object.
yield(): It does not return anything.
POINTS TO REMEMBER
for statement can be used for looping over a list, string, tuple, file, and
dictionary
iter takes an object and returns the corresponding iterator
The _next_ gives us the next element
Built in functions, lists, etc., accept iterator as arguments
A generator produces a sequence of results
Yield is used when many values are to be produced from a
function/generator
EXERCISES
(b) yield
(c) Both
(d) None of the above
5. Which of the following does not transfer the control to the calling function?
(a) return
(b) yield
(c) Both
(d) None of the above
(b) return
(c) Both
(d) None of the above
10. Which of the following behaves in the same manner as the combination of
_iter()_ and _next()_?
(a) for
(b) if
(c) Both
(d) None of the above
THEORY
1. Explain how a for can be used to iterate over an iterable object.
7. Do you believe that iter improves the time complexity vis-a-vis for?
PROGRAMMING EXERCISE
1. Write a generator that produces the terms of arithmetic progression.
7. Write a generator that produces all the prime numbers up to a given number.
10. For the above question write the corresponding iterator class.
12. For the above question write the corresponding iterator class.
13. Write a generator that produces Pythagoras triples in the range (1, 20).
14. For the above question write the corresponding iterator class.
15. Write a generator that produces all the multiples of 6 up to the given
number.
16. For the above question write the corresponding iterator class.
17. Write a list comprehension that produces all the numbers that are multiple of
2 or 5.
18. Write a list comprehension that converts a list containing the temperature in
degrees Celsius to that in Fahrenheit.
19. Write a list comprehension that produces all the prime numbers.
20. Write a list comprehension that produces all the numbers which leave
remainder 1 when divided by 5.
21. Write a list comprehension that produces all the vowels of a given string.
22. Write a list comprehension that produces the fourth power of numbers of a
given list.
23. Write a list comprehension that produces the absolute values of numbers in a
given list.
CHAPTER
7
FILE HANDLING
After reading this chapter, the reader will be able to
• Understand the importance of file handling
• Appreciate the mechanisms of file handling in Python
• Learn various file access modes and the open function
• Understand various functions for file handling in Python
• Implement the concepts studied in the chapter
7.1 INTRODUCTION
The data types and control structures discussed so far will help us to accomplish
many simple tasks. The problem so far is that we have not been able to store the
data or the results obtained for future use. Moreover, at times the results
produced by a program are voluminous. In such cases it becomes difficult to
store data in the memory or even to read the data. In such cases file handling
comes to our rescue.
The reader will also appreciate the fact that the main memory is volatile. The
data produced by a program cannot be used for future endeavors. Many times it
is required to store the data for use in future. For example, if one develops a
student management system, the user should be able to retrieve the data as and
when required.
Python provides many functions to carry out operations related to file handling.
The creation of a file, writing data to a file, reading the data, appending
something to the file and standard directory operations are discussed in this
chapter. Moreover, to make things interesting the use of the above operations in
encryption has also been discussed.
The chapter has been organized as follows. The second section discusses the
general file handling mechanism. The third section discusses the open() function
and the various modes in which a file can be opened. The fourth section
discusses the functions for reading and writing to the file. This section also
introduces the functions to get and set the position of a cursor in a file. The
fourth section also discusses some important factions to carry out various tasks
and the fifth section briefly discusses the command line arguments. The last
section of this chapter concludes.
The file handling mechanism in Python is simple. The file needs to be opened
first. As in, the file is hooked to an Object [1]. This is done with the help of the
open() function. The function takes the name of the file and the mode as its
arguments. In fact, the function can have three arguments. The third is discussed
in the next section. The open function returns an object of the file. The object
then uses the library functions to read the file, write into it or append it. Finally,
the memory space occupied by the object is freed using the close() function.
The mechanism has been depicted in the following figure (Figure 7.1).
Having discussed the mechanism of handling a file, now let us move on to the
file access modes and the open function in Python.
The open function takes three arguments. The first argument is the name of the
file, the second the mode in which the file is opened and the third indicates the
buffer string. As a matter of fact, the third will rarely be used. The first argument
is a string of characters, which is either a valid filename or a path. The path can
be relative or absolute. The access mode is the mode in which the file will be
opened (Figure 7.2). The various modes have been presented in Figure 7.3. The
modes open the file in read, write or append mode. In the read mode (“r”) the
file is opened, if it exists. The write mode (“w”) opens the file for writing. If the
file already exists, the existing contents of the file are truncated. The append
mode (“a”) opens the file for writing but does not truncate the existing contents.
In this mode if the file does not exist, it will be created.
The modes can be suffixed with a letter “b” indicating binary access. The “+”
suffix can be used to grant read and write access to the file. Table 7.1 presents
the various modes and the corresponding operations that can be performed.
The function reads bytes in a string. It may take an integer argument indicating
the number of bytes to read. If the argument is -1, the files must be read to the
end. Also if no argument is given, the default is taken as -1.
Tip
If the content of the file is larger than the memory then only the content which
can fit into the memory will be read. Moreover, when the read operation ends a “
“(an empty string) is returned.
The readline() method is used to read a line until the newline character is read.
It may be stated here that the newline character is retained in the string that is
returned. The readlines() method reads all the lines from a given file and
returns a list of strings.
The write() method writes the string in a given file. The method is
complementary to the read() method. The writelines() method writes a list of
strings to the file.
Tip
seek()
The seek() method takes the cursor to the starting position in the given file. The
position is decided with respect to the offset given. The offset can be 0, 1, or 2.
“0” indicates the beginning of the file. The value “1” indicates the current
position and the value “2” indicates the “end of the file.”
tell()
close()
The close() function closes the file. The object should be assigned to another
file after it is closed. Though Python closes a file after a program finishes (see
garbage collection in the following chapters), it is advisable to close the file
when the required task is accomplished. The repercussions of not closing the file
can be observed at the most unexpected times.
fileno()
The fileno() function returns a descriptor for the file. For example, the
descriptor of the file named “Textfile.txt,” in the following snippet is 3.
>>> f=open('Textfile.txt')
>>> f.fileno()
3
>>>
os method Function
linesep string used to separate lines in a file
sep used to separate file pathname components
pathsep delimit a set of file pathnames
curdir current directory
pardir parent directory
For more such functions, the reader may refer to the Appendix of this book.
File attributes
It may also be stated here that the file attributes help the programmer to see the
state of a file and its features like the name, mode, and the softspace. Table 7.3
presents some of the most important file attributes.
Illustration 7.1: Open a file called “Textfile.txt” in the read mode. Check the
name of the file, its mode, and find whether it is closed using the file attributes.
Solution:
f=open('Textfile.txt','r')
print('Name of the file\t:',f.name)
print('Mode\t:',f.mode)
print('File closed?\t:',f.closed)
f.close()
print('Mode\t:',f.mode)
print('File cloased?\t:',f.closed)
Output
>>>
========= RUN C:/Python/file handling/fileattar.py =========
Name of the file : Textfile.txt
Mode : r
File closed? : False
Mode : r
File closed? : True
>>>
Illustration 7.2: Display the number of command line arguments and the
individual arguments.
Solution:
import sys
print('The number of arguments',len(sys.argv))
print('Arguments\n')
for x in sys.argv:
print('Argument\t:',x)
Output
>>>
======= RUN C:/Python/file handling/commandLine.py =======
The number of arguments 1
Arguments
Argument : C:/Python/file handling/commandLine.py
>>>
The following example presents the bubble sort which takes the numbers entered
at the command line as the input.
Illustration 7.3: Sort the numbers (using bubble sort) entered as the command
line arguments.
Solution:
A file can be renamed using the rename function of OS. The rename function
takes two arguments: the first being the name of the original file and the second
being the new name of the file. In the following snippet, a file called
“TextFile.txt” is renamed to “TextFile1.txt” and read into “str” using the open
function.
>>> import os
>>> os.rename('TextFile.txt','TextFile1.txt')
>>> f=open('TextFile1.txt','r')
>>> str=f.read()
>>> str
'Hi thereHow are you'
>>>
As stated earlier, a list of strings can be written into a file using the
writelines() function. The use of the function has been illustrated as follows.
In the following snippet, the lines entered by the user are put into a list, L, and
this list is then written into the file f.
Illustration 7.4: Write a program to ask the user to enter lines of text. The user
should be able to enter any number of lines. In order to stop, he must enter “\e.”
The lines should be appended to an empty list (say L). This list should then be
written to a file called lines.txt. The program should then read the lines of
lines.txt.
Solution:
Output
========== RUN C:/Python/file handling/Write.py ==========
Enter text, press '\e' to exit
Line number1 :Hi there
Line number2 :How are you
Line number3 :I am good
Line number4 :\e
['Hi there', 'How are you', 'I am good']
Hi there How are youI am good
>>>
The use of the read(n) function, which reads the first “n” characters of the file
has been demonstrated in the following illustration (Illustration 7.5). Note that
the tell function tells the position of the cursor, which is why the value of pos
changes as and when we move forward. The seek() function takes two
parameters, the first being the offset and the second the position. Note that
seek(0, 0) positions the cursor at the first position from the beginning.
Illustration 7.5: Open a file TextFile.txt and write a few lines in it. Now open
the file in the read mode and read the first 15 characters from the file. Then read
the next five characters. In each step show the position of the cursor in the file.
Now, go back to the first position in the file and read 20 characters from the file.
Solution:
f=open('TextFile.txt','w')
f.writelines(['Hi there', 'How are you'])
f.close()
f = open('TextFile.txt', 'r+')
str = f.read(15)
print('String str\t: ', str)
pos = f.tell()
print('Current position\t:', pos)
str1=f.read(5)
print('Str1\t:',str1)
pos = f.seek(0, 0)
print('Current position\t:',pos)
str = f.read(20);
print('Again read String is : ', str)
f.close()
Output
>>>
========= RUN C:\Python\file handling\Position.py =========
String str : Hi thereHow are
Current position : 15
Str1 : you
Current position : 0
Again read String is : Hi thereHow are you
>>>
One can also create directories in Python using the mkdir() function. The
function takes the name of the directory as one of the essential arguments. The
reader is advised go through the appendix of this book for a detailed description.
The chdir() function changes the current directory and the getpwd() function
prints the name (along with the path) of the current working directory. The use of
these functions has been demonstrated as follows:
'>>> import os
>>> os.mkdir('PythonDirectory')
>>> os.chdir('PythonDirectory')
>>> os.getcwd()
'C:\\Python\\file handling\\PythonDirectory'
>>>
An example of encryption
The following illustration uses the ord(c) function which prints the ASCII value
of the character “c,” and that of the chr(n) function which returns a character
corresponding to the ASCII value n.
Illustration 7.6: Write “Hi there how are you” in a file called “TextFile.txt.”
Now, read characters from the file, one by one and write the character obtained
by adding k (entered by the user) to the ASCII value of the character. Also,
decrypt the string in the second file by subtracting “k” from the ASCII values of
the characters in the second file.
Solution:
Output
Enter a number4
Character H Ascii value : 72
Character i Ascii value : 105
Character Ascii value : 32
Character t Ascii value : 116
Character h Ascii value : 104
Character e Ascii value : 101
Character r Ascii value : 114
Character e Ascii value : 101
Character Ascii value : 32
Character h Ascii value : 104
Character o Ascii value : 111
Character w Ascii value : 119
Character Ascii value : 32
Character a Ascii value : 97
Character r Ascii value : 114
Character e Ascii value : 101
Character Ascii value : 32
Character y Ascii value : 121
Character o Ascii value : 111
Character u Ascii value : 117
Lm$xlivi$ls{$evi$}sy
Character L Ascii value : 76
Character m Ascii value : 109
Character $ Ascii value : 36
Character x Ascii value : 120
Character l Ascii value : 108
Character i Ascii value : 105
Character v Ascii value : 118
Character i Ascii value : 105
Character $ Ascii value : 36
Character l Ascii value : 108
Character s Ascii value : 115
Character { Ascii value : 123
Character $ Ascii value : 36
Character e Ascii value : 101
Character v Ascii value : 118
Character i Ascii value : 105
Character $ Ascii value : 36
Character } Ascii value : 125
Character s Ascii value : 115
Character y Ascii value : 121
Hi there how are you
>>>
7.7 CONCLUSION
File handing provides the user with the power of persistence. The user must be
equipped with the knowhow of the file access modes, the open(), close()
functions and the functions which help in reading a file and writing to it. The
chapter briefly explains the most essential functions used for file handling in
Python. The chapter also introduces the user to OS methods and the essential file
attributes to help the user achieve the task at hand. The chapter includes ample
illustrations and explanations to make the concept clear in the simplest manner.
The reader is advised to go through the appendix for a detailed explanation of
the different types of files in Python and a detailed write up on command line
arguments.
POINTS TO REMEMBER
The open function takes three arguments.
The mode of opening file decides the tasks that can be accomplished.
The file should be closed after the required task has been completed.
The seek method helps to move the cursor within a file.
The file name attribute prints the name of the file.
The file mode attribute gives the file access mode.
The os.getpwd function returns the present working directory.
The os.chdir function changes the directory.
EXERCISES
2. In which of the formats is the end of the line denoted by “\n” and “\r”?
(a) Text
(b) Binary
(c) Both
(d) None of the above
12. The integer argument in the read() function denotes the number of bytes to
be read; if no argument is given, which of the following is the default
argument?
(a) –1
(b) 0
(c) len(file)
(d) None of the above
13. To read all the lines in a file, which of the following functions can be used?
(a) readline ()
(b) readlines ()
(c) Both
(d) None of the above
14. Which of the following methods can be used to write a list of strings in a
file?
(a) writeline ()
(b) writelines ()
(c) write ()
(d) None of the above
15. Which of the following arguments in the seek() function denotes the end of
the file?
(a) 1
(b) 2
(c) 0
(d) None of the above
19. In which of the following variables is the command line argument saved?
(a) argv
(b) argc
(c) Both
(d) None of the above
21. Which of the following functions helps to change the current directory?
(a) os.mkdir()
(b) os.chdir()
(c) os.getpwd()
(d) None of the above
22. Which of the following functions helps to print the name of the current
directory?
(a) os.mkdir()
(b) os.chdir()
(c) os.getpwd()
(d) None of the above
THEORY
1. What is the importance of file handling? Explain the mechanism of file
handling in Python.
4. What are file attributes? Explain the file attributes provided by Python.
PROGRAMMING
1. Write a program to copy the contents of one file to another.
9. Write a program to find the word used the minimum number of times in a
given file.
10. Write a program to change the name of a file to the name entered by the
user.
11. Write a program to create a directory and then create a new file in it.
12. Write a program to print the name, number of characters, and number of
spaces in a file.
13. Write a program to convert the characters of a given file to binary format.
14. Write a program to find the words starting with a vowel from a given file.
15. Write a program to implement any substitution cipher on the text of a given
file.
CHAPTER
8
STRINGS
After reading this chapter, the reader will be able to
• Understand the concept and importance of strings
• Understand various string operators
• Learn about the built in functions to manipulate strings
• Learn how to solve problems using strings
8.1 INTRODUCTION
Strings are a sequence of characters. These data structures are used to store text.
For example if one wants to store the name of a person, or for that matter his
address, then string is the most appropriate data structure. As a matter of fact, the
knowledge of strings is essential in the development of many applications like
word processor and parser.
This chapter examines the above issues and provides examples of them. The
chapter has been organized as follows. The second section of the chapter
explores the use of standard 'for' and 'while' loops in strings. The third
section deals with the operators that can be used with strings. The built-in
functions used for accomplishing various tasks have been dealt with in the fourth
section and the last section concludes the chapter.
The traversal of a string has already been discussed in Chapter 4 of this book.
This section revisits the 'for' and 'while' and their applications in strings.
As stated in the second and the fourth chapter, strings are iterable objects. The
standard loops (read 'for' and 'while') can be used to iterate over a string. The
'for' loop helps to iterate through each character by storing the character in
some variable. The following illustration depicts the use of a for loop to iterate
the string.
The examples that follow use the for loop to carry out some basic and some
intricate tasks. Basic tasks like calculating the length of a given string have been
exemplified in Illustration 8.2. Illustrations 8.3, 8.4, and 8.5 implement
transposition and substitution.
Listing
str1= input('Enter a string\t:')
for i in str1:
print('Character \t:',i)>>>
Output
=============== RUN C:/Python/String/str2.py ===============
Enter a string :harsh
Character :h
Character :a
Character :r
Character :s
Character :h
The above methodology can also help us to find the length of string. Note that
there is a built-in function to accomplish the said task. However, the purpose
here is to be able to use the 'for' loop in order to imitate the len function. In
the following illustration, a variable called length is initialized to 0 and is
incremented as we proceed.
Illustration 8.2: Write a program to find the length of the string entered by the
user.
Solution: The concept has already been explained in the above discussion. The
code follows.
Listing
name=input('Enter your name\t');
length=0
for i in name:
length=length +1
print('The length of ',name,' is ',length)
Output
=============== RUN C:/Python/String/str1.py ===============
Enter your name harsh
The length of harsh is 5
>>>
The ability to handle each character individually in a string gives the power to
manipulate a given string. One of the exciting tasks can be to implement basic
cryptography techniques. The example that follows displaces the characters two
positions to the right. This is referred to as transposition. The next example shifts
the characters by “k” positions, “k” being entered by the user.
Illustration 8.3: Ask the user to enter a string and displace two characters to the
right.
Solution: Note that in each iteration, the position of the characters is shifted by
two positions. The code follows:
str1=input('Enter the string\t:')
i=0
str2=""
while i<len(str1):
str2[i]=str1[(i+2)%len(str1)]
print(str2)
Illustration 8.4: Ask the user to enter a string and displace k characters to the
right.
Solution: Note that in each iteration, the position of the characters is shifted by k
positions. The code follows:
str1=input('Enter the string\t:')
k=int(input('Enter the value of k\t:'))
i=0
str2=""
while i<len(str1):
str2+=str1[(i+k)%len(str1)]
print(str2)
i+=1
print(str2)
>>>
Output
========== RUN C:/Python/String/transposition.py ==========
Enter the string :harsh
Enter the value of k 4
h
hh
hha
hhar
hhars
hhars
>>>
Illustration 8.5: Ask the user to enter a string. Replace each character by that
obtained by adding two to the ASCII value of that character.
Solution:
str1=input('Enter the string\t:')
k=int(input('Enter the value of k\t:'))
i=0
str2=""
while i<len(str1):
str2+=str((ascii(str1[i])+k))
print(str2)
i+=1
print(str2)
Note that the same operator is used for adding two integers.
Output
>>>
============= RUN C:/Python/String/operato2.py =============
Enter your name :harsh
Hi harsh
Enter a string :abc
Enter a number 4
abcabcabcabc
>>>
It may be noted here that this operator is also used for manipulating iterations.
The reader is advised to go through Chapter 4 of this book for a detailed
discussion regarding the use of “in” in for. It may also be noted that the operator
can also be used in tuples. In the listing that follows, the string “Hari” is present
in the given tuple and hence True is returned.
>>> 'Hari' in ('Hari', 'Har')
True
>>>
The reader may also note that corresponding to the “in” operator, there is a “not
in” operator which works in the exactly opposite manner vis-a-vis “in.”
A string in Python can span over many lines. This can be accomplished by
putting a “\” at the end of the line. For example, str2 is "Harsh Bhasin Author
Delhi". However, it has been written in three lines using the “\” character.
8.4.1 len()
Usage:
>>> len()
Explanation:
Example (s):
>>> str1 ='Harsh Bhasin'
>>> len(str1)
12
>>>
>>> len('Harsh Bhasin')
12
>>>
>>> len('')
0
8.4.2 Capitalize()
Usage:
>>> capitalize()
Explanation:
The function capitalizes the first character of the string. Note that only the first
character will be capitalized. If one wants to capitalize the first characters of all
the words in the string the title() function can be used.
Example (s):
>>> str2='harsh bhasin'
>>> str2
'harsh bhasin'
>>> str2.capitalize()
'Harsh bhasin'
8.4.3 find()
Usage:
>>><name of the string>.find(<parameter(s)>)
Explanation:
The location of a given sub-string in a given string can be found by using the
function find. Also, if the location of a sub-string after a particular position (and
before a particular index) is to be determined, then three arguments can be
passed to the function: the sub-string, initial index, and the final index. The
following examples show the usage of the function.
Example(s):
>>> str2.find('ha')
0
>>>
>>> str2.find('ha',3,len(str2))
7
8.4.4 count
Usage:
>>><name of the string>.count(<parameter(s)>)
Explanation:
The number of occurrences of a particular substring can be found with the count
function. The function takes three arguments: the sub-string, the initial index,
and the final index. The following examples show the usage of the function.
Example(s):
>>> str3.count('ha',0,len(str3))
1
>>> str3.count('ka',0,len(str3))
0
8.4.5 Endswith()
Explanation:
One can determine if a string ends with a particular sub-string. This can be done
using the endswith() function. The function returns a 'True' if the given string
ends with the given sub-string, otherwise it returns a 'False'.
Example(s):
>>> str3.endswith('n')
True
8.4.6 Encode
Usage: <name of the string>.encode(<parameter(s)>)
>>>
Explanation:
Example(s):
>>> str3.encode(encoding='utf32',errors='strict')
b'\xff\xfe\x00\x00H\x00\x00\x00A\x00\x00\x00R\x00\x00\
x00S\x00\x00\x00H\x00\x00\x00\x00\x00\x00b\x00\x00\
x00h\x00\x00\x00a\x00\x00\x00s\x00\x00\x00i\x00\x00\
x00n\x00\x00\x00'
8.4.7 Decode
Usage:
>>><name of the string>.decode(<parameter(s)>)
Explanation:
List:
1. isanum()
2. isalpha()
3. isdecimal()
4. isdigit()
5. isidentifier()
6. islower()
7. isupper()
8. swapcase()
9. isspace()
10. lstrip()
11. rstrip()
12. replace()
13. join()
Explanation:
The contents of a given string can be checked using the following functions. The
isalnum() function if the given string is alphanumeric. The other functions like
isalpha() and isdecimal() also check the type of contents in a given string.
Whether a given string contains only digits can be checked using the isdigit()
function. Similarly, whether a given string is an identifier can be checked using
the isidentifier() function. The islower() function checks if the given string
contains only lower case characters and the isupper() function checks if the
given string contains only upper case characters. The swapcase() function
swaps the case of the given string, as in converts the upper case to lower and
lower to upper. The presence of spaces (only) can be checked using the
isspace() function. Extra spaces can be removed from the left and the right
hand sides by using the lstrip() and rstrip() functions. The replace()
function replaces the instances of the first argument by the string in the second
argument. The split function splits the given strings into tokens. Illustration 8.6
depicts the use of this function for splitting the string into constituent words. The
function of join() is exactly the opposite as that of split.
Example(s):
>>> str3.isalnum()
False
>>> str3.isalpha()
False
>>>
>>> str3.isdecimal()
False
>>>
>>> str3.isdigit()
False
>>>
>>> str3.isidentifier()
False
>>>
>>> str3.islower()
False
>>>
>>> str3.isnumeric()
False
>>>
>>> str3.replace('h','p')
'HARSH bpasin'
>>>
Illustration 8.6: A string str4 contains a sentence “I am a good boy.” Split the
string and also display each token using a for loop.
Solution:
>>> str4='I am a good boy'
>>> str4.split()
['I', 'am', 'a', 'good', 'boy']
>>>
>>> for i in str4.split():
print('Token\t:',i)
Output
Token : I
Token : am
Token : a
Token : good
Token : boy
8.5 CONCLUSION
In C and C++, strings used to be character arrays. They were a special type of
arrays with a “\0” character at the end. Strings in “C” came with a set of built-in
functions. However, there were two problems. Firstly string was not an
independent data type, and secondly an individual character could be changed.
In Python, the importance of strings has been duly recognized by creating an
object type. Moreover strings, in Python, are non-mutable. Strings come with a
wide range of built-in functions. Also there are useful operators to help the
programmer accomplish a given task easily and efficiently. This chapter
introduces the concept, operators and functions of strings. However, the reader is
expected to complete the end-chapter exercise to be able to understand and use
strings.
GLOSSARY
String: Strings are a sequence of characters. These data structures are used to
store text.
IMPORTANT POINTS
Strings in Python are non-mutable.
The negative index denotes the characters from the right hand.
Strings are iterable objects.
EXERCISES
MULTIPLE CHOICE QUESTIONS
(b) chr('C')
(c) both
(d) None of the above
(b) chr(67)
(c) Both
(d) None of the above
(b) 'AB'
(c) 131
(d) None of the above
(b) titlecase()
(c) toupper()
19. Which function checks whether all the characters in a given string are in
lower case?
(a) lower()
(b) islower()
(c) istitle()
20. Which function checks whether all the characters in a given string are in
upper case?
(a) upper()
(b) isupper()
(c) istitle()
21. Which function removes the whitespaces from the right hand of a given
string?
(a) rstrip()
(b) strip()
(c) lstrip()
22. Which of the following functions convert a given string into a list of words?
(a) split()
(b) break()
(c) breakup()
23. Which of the following helps in breaking a string into two substrings of
desirable length?
(a) Slicing
(b) Splitting
(c) Both
(d) None of the above
24. Which of the following functions combines the strings given as the
argument?
(a) Split
(b) Join
(c) Slice
(d) None of the above
25. Which of the following is illegal in Python (assume that str1 is a string,
having initial value 'hari')?
(a) str1= 'Harsh'
(c) str1[0]=str[2]
THEORY
1. What is a string? Explain non-mutability. Is there any difference between a
string in double quotes and that in triple quotes?
PROGRAMMING PROBLEMS
1. Write a program to reverse a string.
6. Write a program to check which of the tokens obtained in the above question
are keywords.
7. Write a program to check how many alphanumeric strings there are in the
tokens obtained in question 5.
8. Write a program to check how many alpha strings there are in the tokens
obtained in question 5.
9. Write a program to check how many numeric strings there are in the tokens
obtained in question 5.
11. Implement the first phase of compiler design (for “C”). Please refer to the
following link for a brief overview of compiler design.
12. In the above question design deterministic finite acceptors for the keywords.
USEFUL LINKS
Strings and regular expressions are extensively used in developing the first phase
of a compiler. The following links will be helpful to understand the topic:
https://www.cs.cmu.edu/~fp/courses/15411-f13/lectures/07-lex.pdf
http://www.iith.ac.in/~ramakrishna/Compilers-Aug15/slides/02-lexical-
analysis-part-1.pdf
https://www.cs.utexas.edu/users/novak/cs375contents.html
CHAPTER
9
INTRODUCTION TO OBJECT
ORIENTED PARADIGM
After reading this chapter, the reader will be able to
• Understand procedural, modular and object oriented paradigm
• Understand the concept of class
• Design a class
• Understand the elements of object oriented programming
9.1 INTRODUCTION
In the preceding chapters, the control structures of Python were discussed. The
first section discussed loops, conditional statements, etc. However, these
constructs were an integral part of C as well, which is a procedural language. The
procedural programming is one that uses procedures. Each procedure is a set of
instructions where each instruction directs the computer what is to be done.
Python also supports object-oriented programming (OOP). This chapter
introduces the principles of OOP and explains the need and importance of
classes and objects. The chapter also discusses the difference between OOP and
procedural programming to give an insight of why OOP is needed.
It may be stated here that the topics discussed in this chapter will be discussed in
detail in the following chapters. Some of the readers not familiar with C++ (or
for that matter C# or Java) may find the discussion abstract, but things will
become clear as we proceed.
This strategy is good if the program is very small. Often telling the computer
what to do, step by step, works if the task to be accomplished is not very
complex. In such cases no other paradigm is needed.
In case of a moderately large program, division into functions makes the task
easier. The division of a larger program into functions makes the program
manageable and helps to achieve reusability of code. The functions generally
accomplish a clearly defined task and become handy whenever that particular
task is to be accomplished. The reader is advised to go through the chapter on
functions in order to understand the advantages of functions. The clubbing
together of functions on some basis give rise to what are commonly referred to
as modules. The programming paradigm is called modular programming.
The problem with this paradigm is that the accidental clubbing together of
unrelated functions, far from the real world situations, become a source of
problems at some point in time. Moreover, the approach does not restrict the
access of data in any module and may jeopardize the sanctity of the data.
It may be noted that the data should not be accessible to all the modules. The
accessibility of data must be managed with utmost care otherwise a module,
which should not have alerted the data as per the program logic, might change
the data.
The solution to the above problem is to model the software in such a way that
the design is conceptually as close to the real world as possible. This modelling
of real world situations requires the creation of entities having both attributes
and behavior. The clubbing together of data and the functions that manipulate
the data are be helpful in crafting the above entities. These entities will
henceforth be referred to as classes. The instances of classes are objects and
the paradigm is called object oriented paradigm. Various programming
paradigms and their disadvantages have been summarized in Figure 9.1.
Integer is a pre-defined type. Most of the languages also allow the user to create
custom types and hence extend the power of built-in types. This is essential as
the ability to create new data types will help us to create programs which are
near to the real world. For example if one has to design an inventory
management system then a type called “item” would make the matters
uncomplicated. This item can have variables which are of predefined types, like
integers and strings.
A new type can be created by declaring a class. A class has many components,
most important of which are attributes and functions. This clubbing together of
functions and data forms the basis of OOP. The functions, as we will see later,
generally manipulate the data members of a class. Before proceeding any further
let us have an overview of attributes and functions.
9.3.1 Attributes
The attributes here depict the characteristics of the entity that we are concerned
with. For example, when creating a website that gives the details of movies, a
class 'movie' will be needed. Say after detailed deliberations it was decided that
this class would have attributes like name, year, genre, director, producer, actors,
music director, and story writer.
Note that for the said purpose, only the above details are needed. Storing
unnecessary details will not only make data management difficult, but will also
violate one of the core principles - that of including only the details pertaining to
the problem at hand. These attributes are generally shown in the second section
of the class diagram. In Figure 9.3, the attributes of "movie" class have been
shown.
9.3.2 Functions
The next step will be to include functions in the above class. In our example
there are two functions - getdata() and putdata(). The getdata() function
asks for the values of the variables from the user and the putdata() function
will display the data. Functions implement the behavior of a class. The
functions, as stated earlier, accomplish a particular task. In a class there can be
any number of functions, each accomplishing a particular task. As a matter of
fact we have special functions for initializing the data members of a class as
well. The functions of a class will henceforth be referred to as member
functions. The functions (or behavior) are shown in the third section of a class
diagram. In Figure 9.4, the functions of the “movie” class (getdata()and
putdata()) have been shown in the third box.
The class has two functions - getdata(), which asks the user to enter the values
of the data members and putdata(), which displays the values of the variables.
In order to call the functions getdata() and putdata(), an instance of the
employee class is created ('m'). As we will see later, the functions are called
using the dot operator. The details regarding the syntax will be explained in the
following chapter.
The following code implements the above class. Though the syntax etic.. has not
been discussed as of yet, the code has been given to give an idea of how things
actually work.
Code
Output
============ RUN C:/Python/Class/class_basic2.py============
Enter name :Kapoor
Enter year :2016
Enter genre :Drama
Enter the name of the director :ABC
Enter the producer :Karan
Enter the name of the actor :Siddarth
Press 'y' for more 'n' to quity
Enter the name of the actor :Fawad
Enter 'y' for more 'n' to quitn
Enter the name of the music director :XYZ
Name :Kapoor
Year 2016
Genre :Drama
Director :ABC
Producer :Karan
Music_director :XYZ
Actors :['Siddarth', 'Fawad']
>>>
One can create a default constructor in a class, which does not take any
parameters. The parameterized constructor, on the other hand, takes
arguments and initializes the data members using those arguments. The
implementation of constructors and their uses will be dealt with in the next
chapter.
Tip
A constructor acts when an object is created and a destructor is called when the
lifetime of an object ends.
9.4.1 Class
A class is a real or a virtual entity, which has relevance to the problem at hand
and has sharp physical boundaries. A class can be a real entity. For example,
when one develops software for a car wash company, then 'Car', is central to
the software and therefore there will be a class called 'Car'. A class can also be
a virtual entity. Another example is that when developing a student management
system, a 'student' class is crafted which is a virtual entity. In both the
examples, the entity was crafted as it was important to the problem at hand.
The example of the 'student' class can be taken further. The class will have
attributes, which are needed in the program. The selection of attributes will
decide on the physical boundaries of the class. The fact of the matter is we will
not be needing unnecessary details like the number of cars a student has or
where he went last evening in an educational institute for which we are making
the student management system, so there is no point storing those details.
Examples of some of the classes that are central to the stated software are as
follows (Table 9.1).
9.4.2 Object
Consider a student management system that stores the data of each student of a
school. Note that while entering data the operator would deal with an individual
student, not the idea of a student. The idea of a student is a class, whereas each
student is an instance of class or an object.
An object is an instance of a class. The objects interact with each other and get
the work done. Generally, a class can have any number of objects. One can even
form an array of objects. The example of 'movie' had 'm' as an object. As a
matter of fact, we make an object and call the methods of a class (those which
can be called).
9.4.3 Encapsulation
The class is an entity, which has both data and functions. The clubbing together
of the data and the functions that operate on the data is called encapsulation.
Encapsulation is one of the core principles of object-oriented paradigm.
Encapsulation not only makes it easier to handle objects but also improves the
manageability of the software.
In C++, for example, the data in a class is generally kept private. That is, only
the member functions of the class can access the data. This ensures that the data
is not accidently changed. The functions, on the other hand, are public in C++.
The public functions can be accessed anywhere in the program (Figure 9.5). In
C++, Java, C#, etc., there is another access specifier, which is protected. If a
member is to be accessed in the class and the derived class, then a protected
specifier is used. C# and Java also have some other specifiers like internal.
FIGURE 9.5 Access specifiers, public and private
Having discussed the data access, it must be clarified that deciding what is
private and what is public is up to the discretion of the design and development
team of the project. There is no hard and fast rule as to what should be private
and what should be public. The designers must decide on the accessibility of a
member based on their needs.
This protection of data is not related to the security of data but to accidental
change. This is needed so that the data can be changed only via the functions
which have the authority to change data.
9.4.5 Inheritance
Classes are made so that they can be sub-classed. This art of dividing the class
into subclass(es) is inheritance. For example, the movie class can be sub-classed
into various classes like art_movie, commercial_movie, etc. Likewise, the
student class can be sub classed into 'regular student' and
'part_time_student'. In both the examples the subclass has many things which
are there in the base class (the class from which the sub-class has been derived)
in common. In addition, each subclass can have functions and data that belongs
to the sub-class only.
For example, the student class can have attributes namely name, date_of_
birth, address etc. The subclass regular student will use all the above data
members and can also have attributes like attendance associated with it. The
class from which classes will be sub-classed is referred to as the base class and
the subclasses would be called derived classes.
For example in Figure 9.6, movie is the base class and commercial_movie and
art_movie are the sub-classes.
FIGURE 9.6 Deriving classes from other classes is inheritance. There are many types of
inheritance. The above figure shows hierarchical inheritance
9.4.6 Polymorphism
Poly means many and morphism is forms, so polymorphism means many forms.
Polymorphism can be implemented in many ways. One of the simplest examples
of polymorphism is operator overloading. Operator overloading means using the
same operator in more than one way. For example “+” is used between integers
to add, with strings for concatenation and even can be used in user defined data
types as explained in Chapter 12 of this book.
Likewise function overloading means having more than one function with the
same name in a class with different arguments. Various forms of polymorphism
are explained in Chapters 10 and 11 of this book.
9.4.7 Reusability
The procedural programming came with almost no reusability. Modular
programming allowed reusability but only to certain extend. The functions could
be used on an “as is basis” in modular programming. In object-oriented
programming, the concept of reusability can be used in its full force. The
concept of inheritance, introduced above and explained in Chapter 10 of this
book, helps the programmer to reuse a code as per their requirements. a matter of
fact, reusability is one of the USPs of the object-oriented paradigm.
However, there is a catch. Lately, some researchers have cast doubts on the
ability of OOP vis-a-vis reusability.
9.5 CONCLUSION
While designing software, one must keep in mind the entities he is going to work
on. The nitty-gritty can be decided at a later stage. As a matter of fact, popular
literature does not consider the details of the operation as a matter of concern for
the object-oriented programming. Hiding unnecessary details are, therefore, an
important part of object-oriented programming.
For example, while developing a website for movies, the entity central to the
problem is “Movie.” So, one starts with an empty class called "movie". The
designer must then decide on the attributes needed to implement the functions.
The attributes constitute the data members of the said class. The behavior of the
entity is then deliberated upon. The member function determines the behavior of
a class. The functions are then designed. The things like inheritance and
polymorphism, discussed later in this section, come into play. And finally the
system is created.
This journey of the formation of a class has been depicted in the following figure
(Figure 9.7).
GLOSSARY
Class: A class is a real or a virtual entity that has relevance to the problem
at hand and has sharp physical boundaries.
Object: An object is an instance of a class.
Encapsulation: The clubbing together of the data and the functions that
operate on the data is called encapsulation.
Inheritance: The art of dividing the class into subclass(es) is inheritance.
Operator overloading: Operator overloading, in general, means using the
same operator in more than one way.
Function overloading: This means having more than one function with the
same name in a class with different arguments.
POINTS TO REMEMBER
Telling the computer what to do, step by step, works if the task to be
accomplished is not very complex. In such cases no other paradigm is
needed.
In the case of a moderately large program, division into functions makes the
task easier.
The division of a larger program into modules makes the program
manageable and helps to achieve reusability of code.
The clubbing together of functions, on some basis, gives rise to what is
commonly referred to as modules. The programming paradigm is called
modular programming.
A class has two important components: attributes and behavior.
A constructor initializes the members of a class.
The destructor frees the memory occupied by an object.
EXERCISES
8. The clubbing together of data and the functions that operate on the data is
called
(a) Abstraction
(b) Encapsulation
(c) Overloading
(d) None of the above
9. Allowing the selective access of data members in a class is the same as
(a) Data Hiding
(b) Encapsulation
(c) Abstraction
(d) None of the above
11. “+” can be used for adding two number types. However, a programmer can
use “+” for the addition of two user defined data types (for example,
complex numbers).
This is
(a) Method overloading
(b) Operator overloading
(c) Encapsulation
(d) None of the above
13. If a function in the base class is extended in the derived class, then it is
(a) Overloading
(b) Abstraction
(c) Encapsulation
(d) None of the above
THEORY
1. Briefly explain the various paradigms of programming.
In a class all data members are public in nature; that is they can be accessed
anywhere in the program. The member functions in a class are all virtual. In a
class all the member functions must have the first argument as the object
representing that class, from now on referred to as 'self'. Interestingly, all the
built in types are themselves classes in Python and they can be extended by the
programmer.
The reader is advised to revisit the chapter on lists. Note that multiple names can
be associated with the same object. Using pointers, for example, an object can be
passed to a function using just one argument and in addition to that, the change
done by the function is visible to the calling function also. In the case of Python,
aliasing (having multiple names for the same object) can be used to accomplish
the above task.
This chapter has been organized as follows. Section 10.2 presents the definition
of a class. Section 10.3 presents the concept of objects and discusses the
instantiation of a class. Section 10.4 discusses the scope of data members.
Section 10.6 discusses constructor overloading. Section 10.7 discusses
destructors and the last section concludes the chapter.
Syntax
For example the employee class having data members name and age and member
functions getdata() and putdata() can be defined as follows (testing). It was
stated earlier that every function in the class must have at least one argument,
self. The functions of this class have been defined in the traditional way. The
getdata() function here asks for the values of name and age from the user. The
data members are accessed via the self object as they belong to the class and
not just the function. Likewise the putdata() function displays the values of the
data members. Note that the members of a class are accessed via self.
Tip
A class definition has functions but can also have other members.
The attribute of an object is data attribute, and the function that belongs to
an object is method.
e1=employee()
Here, e1 is the name of the object and employee() is the constructor of the class.
An object can also be created using a parameterized constructor, as explained in
the following sections. The creation of an object is referred to as instantiation.
The function of a class can be called using the dot operator with a given class.
For example, to call the getdata() function of the employee class the following
statements are used.
e1.getdata()
Likewise, the other methods of a class can be called using the dot operator.
Code
Tip
The nonlocal statements rebind the variables in the global scope. In order to
understand the above concept, consider the following code. The following points
concerning the code are worth noting:
The value of a for all instances of the class is 5, until a function that changes
the value of a is called.
In putdata() a does not exist, a is local to getdata()
b can be accessed in both the functions as b is a data member of the class
(note that every time b is called, 'self.b' is used)
On the basis of the above discussion the reader is expected to decode the
following program.
Code
In the following code, 'a' is common for all the classes. 'b' is a member of the
class. Here,'self.b=b' means the data member 'b' of the class (self.b) is
assigned value 'b', which is the second argument of the function getdata().
'c' is local to getdata(), so 'c' of getdata() is not same as that of putdata().
An instance variable is one which is unique to each instance and a class variable
is one which is shared by all instances. For example, in the following code b can
be assigned a different value in each instance but c remains the same.
Code
In addition to the above a global data member can be made outside the class,
which is accessible to all the methods (until the scope of the data member is
changed). In the following code 'a' is common for all instances of the class, 'b'
is the data member of the class and 'c' is a local variable.
Code
10.5 NESTING
The designing of a class requires conceptualization of an entity, which has
attributes and behavior. The object of a class can be made in another class also.
That is, a class can also have the objects of another class as its members. This is
called nesting. Note that the attributes of a class can themselves be entities. For
example, in the following code an instance of the date class is created in the
student class. This makes sense, as student is an entity made up of other
entities (like date).
Code
10.6 CONSTRUCTOR
Note that each time a class is instantiated, a constructor (for example, e1=
employee()) is used. In C++ terminology, a constructor is a function which has
the same name as that of the class and initializes the data members. The above
examples used default constructors, which were not made by the programmer.
One can initialize the objects as per the need, by crafting constructors. The
following discussion focuses on two types of constructors: default and
parameterized. A default constructor does not take any argument (for example
the employee() constructor). In Python, the constructors are called using the
functions having the same name as that of the class. However, they are
implemented by making the _init_() function inside the class.
In the following code, the object e1 behaves as expected. The values entered by
the user in the getdata() function are displayed when putdata() is called. In
the case of e2 the function getdata() is not called, therefore the values assigned
in _init_() are displayed.
Code
Note that while defining the parameterized __init__, the first parameter is
always 'self' and the rest of the parameters are the values to be assigned to
different data members of the class. In the case of employee class, three
parameters 'self', 'name', and 'age' are given.
Code
The reason is that is one makes a parameterized _init_. Python looks for the
rest of the parameters in the instantiation.
Code
Having studied the importance and implementation of constructors, let us now
implement a constructor and let’s consider the "movie" class, discussed here.
The following code has a movie class, which contains a getdata() and
putdata() function and init (self) for initializing the variables. Note that the
object 'm' does not call the getdata() function but just putdata(). The values
assigned in the constructor are displayed.
Code
10.8 DESTRUCTORS
A constructor initializes the data members of a class and a destructor frees the
memory. The destructor is created using _del_ and called by writing the
keyword del and the name of the object. The following code exemplifies a
destructor in the employee class described in the previous sections.
Code
The next example is the same as the previous one. However, the following code
also demonstrates the use of _class_. _name_, which displays the name of the
object that calls the function. This is useful as the name of the object whose
destructor (or for that matter any method) is being called.
Code
Code
The above chapter discusses what is referred to as an instance method. However
another type of method can be created in a class, which is referred to as a class
method.
10.9 CONCLUSION
The last chapter introduced the concepts of object-oriented programming. This
chapter takes the topic further. The chapter introduces the syntax of a class and
the creation of objects. The concept of constructors, their creation, types and
implementation have also been discussed in the chapter. The chapter also
introduces the idea of destructors. Ample examples have been given in the
chapter, which explain the implementation of the concepts introduced earlier.
The following chapter will introduce the idea of inheritance and polymorphism,
which are essential to object-oriented programming. However to be able to
inherit a class or implement operator overloading, one must be versed with the
creation of a class and its use.
GLOSSARY
Data attribute and method: The attribute of an object is data attribute
and the function that belongs to an object is method.
Instance variable and class variable: An instance variable is one which is
unique to each instance and a class variable is one which is shared by all
instances.
Constructor: A constructor initializes the data members.
A parameterized constructor is one which takes arguments.
POINTS TO REMEMBER
The classes in Python can be sub-classed.
All types of inheritance including multiple inheritances are supported in
Python.
A class can be defined using the class keyword in Python.
An object is created by associating a name with an instance of the class,
initialized using the default constructor.
The function of a class can be called using the dot operator with a given
class.
While defining the parameterized init the first parameter is always 'self',
and the rest of the parameters are the values to be assigned to different data
members of the class.
A constructor initializes the data members of a class and a destructor frees
the memory.
The destructor is created using del and called by writing the keyword del
and the name of the object.
__class__.__name__ displays the name of the object that calls the function.
The docstring associated with the class can be accessed through doc.
EXERCISES
3. 'self' is
(b) __doc__
(c) __class
8. A global variable
(a) Can be accessed anywhere
(b) Can be accessed only in init__
(c) Both of the above
(d) None of the above
(b) def
(c) del
13. Which of the following is used to define a function that acts as a destructor?
(a) del
(b) init
(c) Both
(d) None of the above
15. Suppose e1 is an object, which of the following codes is used to call del?
(a) del e1
(c) Both
(d) None of the above
16. If the name of the object is to be displayed in a function of a class, then
which of the following can be used?
(a) __class . name__
(c) Both
(d) None of the above
PROGRAMMING EXERCISES
A start-up employs interns. The following details of interns are stored
first_name
last_name
address
mobile_number
e_mail
1. Create a class called Intern, which stores the above details. Craft two
functions getdata() which asks the user to enter data and putdata() to
display the data.
2. In the above program create init which takes only one parameter (self).
3. In question 1, create init, which takes 6 parameters - the first being “self”
and the rest the values of variables stated in question 1.
Name
Publisher
Year
ISBN
Authors
The authors, above, is a list consisting of all the authors of that book.
Create a class called Book, which stores the above details. Craft two
functions - getdata() which asks the user to enter data and putdata() to
display the data.
6. In the above program, create init which takes only one parameter (self).
7. In question 6, create init, which takes 6 parameters with the first being
“self” and the rest the values of variables stated in question 5.
9. Create a class called complex, having real_part and ima_part as its two
data members and getdata() and putdata() as its member functions.
11. Create a function called add, which takes two complex numbers as its
parameters and returns the sum of the two complex numbers.
12. Create a function called sub, which takes two complex numbers as its
parameters and returns the difference of the two complex numbers.
13. Create a function called multiply, which takes two complex numbers as its
parameters and returns the product of the two complex numbers.
14. Create a function called div, which takes two complex numbers as its
parameters and returns the result of division of the two complex numbers.
15. Create a class called date having day, month, and year as its data members
and getdata() and putdata() as its member functions. Instantiate the class,
ask user to enter data and display the data.
CHAPTER
11
INHERITANCE
After reading this chapter, the reader will be able to
• Understand the concept and importance of inheritance
• Differentiate between inheritance and composition
• Understand the types of inheritance
• Appreciate the role of ‘self’ in methods
• Understand the search in an inheritance tree
• Understand the concept and importance of super
• Appreciate the need of an abstract class
Object-oriented programming has its charms but also comes with its own
problems, it is like demonetization. So, use inheritance only if required. Also
remember never ever to use multiple inheritance. Remember that anything that
can be done using inheritance can be done also in another way too. Composition,
introduced later in the chapter, can be easily used to accomplish most of the
tasks that can be done using inheritance.
In hindsight, inheritance means a class would get features (all or some) from the
parent class. So, when one writes
class SoftwareDeveloper(Employee):
...
The class from which class(es) are derived from is called a base class and those
that inherit features from the base class are derived classes. In the above
example, Employee is the base class and SoftwareEmpolyee is the derived class.
Note that inheritance does not affect the base class. The derived class can use the
modules of the base class in a variety of ways which are discussed as follows.
The method is not present in the child class, but only in the parent class: In
such cases if an instance of the child class calls the said method, the parent
class’s method is called. For instance, in the following snippet the derived class
does not have a method called show() so calling show using an instance of the
derived class (consider, in this case) calls the method of the parent class.
Code
The method is present in both the parent class and in the derived class: In
such cases, if this method is invoked using an instance of the derived class then
the method of the derived class is called. If the method is called using an
instance of the base class, the method of the base class is called. Note that in
such cases, the derived class redefines the method. This overriding ensures that
the search of the method in the inheritance tree ends up invoking this method
only. For example, in the following snippet x.show() calls the show() method of
the derived class, whereas y.show() calls the method of the base class.
Code
The inherited class modifies the method of the base class and in this process
invokes the method of the base class inside the method of the derived class also.
Note that in the following snippet the show method of the derived class prints a
message, then calls the method of the base class and finally prints another
message. Note that in this case, the method of the base class can be called by
qualifying the name of the method with the name of the base class. For example
in the following snippet the show method of the base class can be called using
ABC.show(self). The importance of the self argument has been explained in
Section 11.3.
Code
The third type of inheritance is the most important and practical form of
overriding methods. This type of inheritance leaves the room of not making an
instance of the base class, if not required, still using the function.
Illustration 11.1: Create a class called Student having _init_ and show
methods. The Student class should have a data member called name. The _init_
should assign value to name and show should display the value. Create another
class called RegularStudent, which will be the derived class of the Student
class. The class should have two methods _init_ and show. The _init_ should
assign values to age and should call the _init_ of the base class and pass the
value of name to the base class. The show method must display the data of the
RegularStudent. In addition to the above both classes should have methods
called random, both of which should be independent of each other (Figure 11.1).
Find what happens when the methods of the base class and the derived classes
are called using the instances of the base and the derived classes.
Solution:
Code
11.1.2 Composition
Making an instance of another class inside a class makes things easy and helps
the programmer to accomplish many tasks. In order to understand the concept,
let us consider an example. Consider that a Student and his PhDguide are
subclasses of the person class. Also, the data of the PhD guide includes the list
of students guided by him/her. This is where composition comes into play. The
instantiation of the students in the PhDGuide class can be done as explained in
the following illustration.
Illustration 11.2: Create a class called Student, having name and email as its
data members and _init_(self, name, email) and putdata(self) as bound
methods. The _init_ function should assign the values passed as parameters to
the requisite variables. The putdata function should display the data of the
student. Create another class called PhDguide having name, email, and students
as its data members. Here, the students variable is the list of students under the
guide. The PhDguide class should have four bound methods: _init_, putdata,
add, and remove. The _init_ method should initialize the variables, the putdata
should show the data of the guide, include the list of students, the add method
should add a student to the list of students of the guide and the remove function
should remove the student (if the student exists in the list of students of that
guide) from the list of students.
Solution:
The details of the classes have been shown in Figure 11.2. It may be noted that
since students is a list therefore a for loop is needed to display the list of
students. Also, while adding the student to the list the data of the passed
parameter has been stored in s (an instance of Student) and s has been added to
the list of the students. The same procedure has been adopted to remove a
student. The code is as follows:
FIGURE 11.2 Details of classes for Illustration 11.2
Code
Output
11.2 INHERITANCE: IMPORTANCE AND TYPES
The concept of classes was introduced in the previous chapter. It was mentioned
that classes are real or conceptual entities which have sharp physical boundaries
and relevance to the problem at hand. A class has attributes (data members) and
behavior (class methods). However, at times these classes must be extended to
be able to solve some specific problem without having to meddle with the
original class. To be able to do so, the language should support inheritance. As a
matter of fact, the presence of classes in the language is primarily because it can
be inherited. Inheritance is, as per most of the authors, one of the most essential
features of object-oriented language.
Using inheritance one can create new classes (derived classes) from an existing
class (base class(es)). Note that a derived class can have even more than one
base class, referred to as multiple inheritance, which is one of the most
undesirable forms of inheritance. Also a base class can itself be a derived class
of some other class. The derived class will have all the allowed features of the
base class plus some features of its own.
name
authors
publisher
ISBN
year
The class methods of this class are getdata() and putdata(). The Text_Book
class has another attribute, course. Figure 11.5 shows the class browser showing
the two classes and the relation between them. The corresponding program is
presented in Illustration 11.3.
FIGURE 11.4 A class diagram generally has three components: the name of the class, the data
members, and the methods of the class. The book class and the textbook class have attributes
and methods as shown in the figure.
FIGURE 11.5 The book examples’ class hierarchy in the class browser of Python
11.2.2.1 Simple Inheritance
The simple inheritance has a single base class and a single derived class.
Illustration 11.3 exemplifies this type. The following illustration has two classes:
Book and Text_Book. The Book class has two methods: getdata and putdata.
The getdata method asks the user to enter the name of the book, number of
authors, the list of authors, publisher, ISBN, and year. The derived class
Text_Book has another attribute called course. The getdata and the putdata
methods extend the base class methods (refer to the previous section).
Illustration 11.3: Implement the following hierarchy (Figure 11.6). The Book
function has name, n (number of authors), authors (list of authors), publisher,
ISBN, and year as its data members and the derived class has course as its data
member. The derived class method overrides (extends) the methods of the base
class.
FIGURE 11.6 The class hierarchy for Illustration 11.3
Solution:
The following code implements the above hierarchy. The output of the program
follows.
Code
Output
11.2.2.2 Hierarchical Inheritance
In hierarchical inheritance, a single base class has at least two derived classes.
Illustration 11.4 exemplifies this type. The following illustration has three
classes: Staff, Teaching, and NonTeaching. Both Teaching and NonTeaching
are the derived classes of the Staff class. The Staff class has two methods:
getdata and putdata. The getdata method asks the user to enter the name and
the salary of the member of the staff. The derived class Teaching has another
attribute called subject. The getdata and the putdata methods extend the base
class methods. Similarly, the derived class NonTeaching has an attribute called
department. The getdata and the putdata methods extend the base class
methods.
Illustration 11.4: Implement the following hierarchy (Figure 11.7). The Staff
function has name and salary as its data members, the derived class Teaching
has subject as its data member and the class NonTeaching has department as its
data member. The derived class method overrides (extends) the methods of the
base class.
Solution:
The following code implements the above hierarchy. The output of the program
follows.
Code
Output
11.2.2.3 Multilevel Inheritance
Illustration 11.5: Implement the following hierarchy (Figure 11.8). The Staff
class has name and salary as its data members, the derived class Teaching has
subject as its data member and the class NonTeaching has department as its
data member. The derived class method overrides (extends) the methods of the
base class.
Solution:
The following code implements the above hierarchy. The output of the program
follows.
Code
Output
11.2.2.4 Multiple Inheritance and Hybrid Inheritance
In multiple inheritance a class can be derived from more than one base class.
This type of inheritance can be problematic as it can lead to ambiguity. It is
therefore advised to avoid this kind of inheritance as far as possible. However,
the following sections throw some light on this type and the problems associated
with this type.
A design may have a combination of more than one type of inheritance. In the
following figure (Figure 11.9) two classes B and C have been derived from class
A. However, for the class D, the classes B and C are the base classes. This is an
example of combining hierarchical and multiple inheritance. Such a type is
referred to as hybrid inheritance.
FIGURE 11.9 Classes B and C have been derived from A (hierarchical inheritance) and D is
derived from B and C (multiple inheritance)
FIGURE 11.10 Classes B and C have been derived from A (hierarchical inheritance) and D is
derived from B and C (multiple inheritance)
11.3 METHODS
The importance of functions and methods has already been stated in the first
section of this book. Methods are, as stated earlier, just functions with a special
positional parameter within a class. Methods, in fact, help the programmer to
accomplish many tasks. Methods can be bound or unbound. The unbound
methods do not have 'self' as a parameter. While calling such methods, the
first argument must be the instance of the class itself. It is worth mentioning here
that, in Python 3.X, the unbound methods are same as functions whereas in
Python 2.X they are a different type. The bound methods, on the other hand,
have 'self' as the first positional parameter when a method is accessed through
qualifying an instance of a class. Here, the instance of the class needs not to be
passed.
In spite of the above differences, the following similarities between the two
types may not be missed:
A method in Python is also an object. Both bound and unbound methods are
objects.
The same method can be invoked as a bound method and an unbound
method. The discussion and illustrations that follow will clarify the second
point.
This illustration has a class called student. The Student class has a display
method, which takes two arguments - the first being the positional parameter and
the second being a string that is printed. Note that the display method is a bound
method and hence is called through an instance of the class.
Code
Output
>>>
========= RUN C:\Python\Inheritance\BoundUnbound.py
=========
Hi I am Hari
Hi I am through X
Caling diaplay again
>>>
This illustration extends the previous illustration and adds the getdata method,
which does not take self as a parameter and therefore is called by the class itself.
Note that this is similar to the static methods in C++.
Code
Output
>>>
========= RUN C:/Python/Inheritance/BoundUnbound.py
=========
Enter the name of the student :Naved
Enter the age of the student :22
Traceback (most recent call last):
File "C:/Python/Inheritance/BoundUnbound.py", line 21, in
<module>
Naved.getdata(name,age)
>>>
Snippet 2:
Code
Output
>>>
======== RUN C:/Python/Inheritance/BoundUnbound1.py ========
Enter the name of the student :Naved
Enter the age of the student :22
Name : Naved
Age : 22
>>>
Code
Output
>>>
======= RUN C:/Python/Inheritance/CallableObjects.py =======
25
125
16
64
>>>
Code
Output
============ RUN C:/Python/Inheritance/Basic.py ============
name : Hari
name : Nakul
>>>
However, methods can also be crafted without the 'self' argument. These are
unbound methods. The concept has been discussed in Section 11.3.2 of this
chapter. A method of a class is an instance method by default. So, generally, the
method of a class can be called by creating an instance of the class and using the
dot operator to call the method. Note that this was the case in languages like C#,
Java, etc. Note that there are other ways of invoking a method, as discussed in
this chapter.
However, there are other types of methods as well. For example, the static
methods do not require the instance of a class as their first argument.
Code
Output
>>>
========== RUN C:/Python/Inheritance/superDemo.py ==========
Data of the base class : 4
Data of the base class : 5
Data of the derived class : 6
>>>
For example, in the following illustration the Derived1 class has been derived
from BaseClass. The show() method of this class displays the values of 'data1'
and 'data'. The former is in the class and therefore its value is displayed.
However the former is not in the class, so the inheritance tree is searched for the
object. Note that 'data' exists in the base class (BaseClass) and therefore its
value will be displayed. This is true for methods also. Even if the derived class
does not have a particular method, it can be invoked if it exists in the parent
class or in any other class up the inheritance tree. It may also be stated here that
the objects are generally searched from left to right in a particular level.
FIGURE 11.11 The class hierarchy for given illustration
Code
Output
======= RUN C:/Python/Inheritance/InheritanceTree.py =======
Data : 1
1
Data : 3
Base class data : 2
Data : 5
Base class data : 4
>>>
The BaseClass has two methods: method1 and method2. The first method has
some task associated with it, whereas the second wants the derived class to
implement it. The derived class should, to be able to call this method, have a
method called action. The first derived class (Derived1), replaces method1. So
if an instance of Derived1 calls method1, the version defined in Derived1 would
be called. The second method extends method1, it adds something to method1
and also calls the BaseClass version of method1. When method1 is called from
Derived2, the BaseClass version is called as the search in the inheritance tree
invokes the base class version of the method. The third derived class (Derived3)
also implements the action method defined in the base class. Note that when
method2 is called through an instance of Derived3, the base class version of
method2 is invoked. This version calls action and a new search is initiated, thus
resulting in the invocation of action of Derived3. Illustration 11.9 presents the
code.
Note that the above concept can be extended and a class may have methods that
would be implemented by the derived classes. Interestingly, Python has
provisions that such classes would not be instantiated until all such methods are
not defined. Such base classes are called abstract classes. The implementation of
abstract classes has been discussed in the appendix of this book.
Solution:
Output
>>>
============ RUN C:/Windows/System32/Abstract.py
============
Class : <class '_main__.Derived1'>
A new method, has got nothing to do with that of the base
class
Class : <class '_main__.Derived2'>
A method that extends the base class method
In BaseClass from method1
Class : <class '_main__.Derived3'>
In BaseClass from method1
Implementing the base class method
11.6 CONCLUSION
The chapter introduces the concept of inheritance, which is one of the most
important ingredients of object-oriented programming. Inheritance, as explained
in the chapter, helps the program in reusing the code and making the program
more structured. However it should be used wisely, as in many cases it leads to
problems like ambiguity. The reader must also appreciate that it is not always
necessary to use inheritance. Most of the tasks can be accomplished using
composition. However even if using inheritance becomes a necessity, be clear
about the type of inheritance required, the type of method calls required and the
use of bound methods. The discussion on object-oriented programming
paradigms continues in the next chapter also, where the concept of operator
overloading has been introduced. The last chapter, this chapter and the next one
will help the reader to successfully develop a software using OOP.
GLOSSARY
Inheritance: Inheritance is the process of creating subclasses from existing
classes.
Base class and derived class: The class from which other classes are derived is
the base class and the classes that inherit from the base class are the derived
classes.
Implicit inheritance: In this type, the method of the base class can be called
using an instance of the derived class.
Explicit overriding: In this type of inheritance, the derived class will redefine
the method of the base class and calling this method using an instance of the
derived class would invoke the method of the derived class.
POINTS TO REMEMBER
Inheritance provides reusability and increased reliability.
Types of inheritance are simple inheritance, multiple inheritance, multilevel
inheritance, hierarchical inheritance, and hybrid inheritance.
Multiple inheritance may lead to ambiguity.
A bound method has a “self” parameter whereas an unbound method does
not have “self” parameter.
A class can also be instantiated in another class.
Super can be used to access the base class methods.
The inheritance tree is searched to find the version of method to be invoked.
EXERCISES
1. A class that cannot be instantiated until all its methods have been defined by
its subclass(es) is called
(a) Abstract class
(b) Meta class
(c) Base class
(d) None of the above
A class called operation has an_init__, which takes a positional parameter
and an integer as an argument. Two instances of operations Num1 and Num2
have been defined as follows. The class has two functions; the first
calculates the square of a number and the second calculates the cube. A list
called List1 is created which contains the names of the four methods (two
of Num1 and two of Num2). A for loop is then used to call the methods as
shown in the following snippet:
Num1=operations(5)
Num2=operations(4)
List= [Num1.square, Num1.cube, Num2.square, Num2.cube]
for callable_object in List:
print(callable_object())
2. The program containing the above code (assume that the rest of the code is
correct)
(a) Has no syntax error but does not execute
(b) Has syntax error
(c) Has no syntax error and executes
(d) Insufficient information
3. In the above question, what would the output be (if the code is correct)?
(a) The code is not correct
(b) 25 125 16 64
(c) 125 25 64 16
(d) None of the above
4. The names of the methods in the list (question 2) are similar to (in ‘C#’)
(a) Meta classes
(b) Delegates
(c) Both
(d) None of the above
6. class Student:
def display(self, something):
print("\n"+something)
def getdata(name,age):
name=name
age=age
print("\nName\t:",name,"\nAge\t:",age)
In the above snippet, how would you invoke getdata? (assume that Hari is
an instance of Student).
(a) Student.getdata("Harsh", 22)
12. Which type of inheritance has just one base class and a single derived class?
(a) Simple
(b) Hierarchical
(c) Multiple
(d) None of the above
13. Which type of inheritance has more than one base class(es) and a single
derived class?
(a) Simple
(b) Hierarchical
(c) Multiple
(d) None of the above
14. Which type of inheritance has more than one derived class(es) and a single
derived class?
(a) Simple
(b) Hierarchical
(c) Multiple
(d) None of the above
THEORY
1. What is inheritance? Explain the importance of inheritance.
4. What are the problems in implementing multiple inheritance? How are they
resolved?
9. Explain the use of “super.” How can it be used to call methods of the base
class?
10. Are methods in Python objects? Justify your answer. What is meant by
callable object?
11. What is an abstract class? How does an abstract class help in achieving the
goals of OOPs?
12. What are bound methods? What are the various ways of invoking a bound
method?
PROGRAMMING EXERCISE
1. A class called Base1 has two methods: method1(self, message) and
method2(self). The first method prints the message passed as an argument
to the method. The second invokes another method called action1(self),
which would be defined by the sub-class (Derived2) of Base1. Derived1,
another derived class of Base1, redefines method1 and does nothing with
method2. Derived2, on the other hand, does nothing with method1.
Implement the hierarchy and find what happens in the following cases:
(a) An instance of Base1 calls method1
(b) An instance of Derived1 calls method1
(c) An instance of Derived2 calls method1
(d) An instance of Base1 calls method2
(e) An instance of Derived2 calls method2
(f) An instance of Derived1 calls method2
(g) An instance of Derived2 calls action
4. Create the following hierarchy and explain the search process of method
called "show".
CHAPTER
12
OPERATOR OVERLOADING
After reading this chapter, the reader will be able to
• Understand the importance of operator overloading
• Implement constructor overloading
• Understand and be able to use various methods used for overloading operators
• Implement operator overloading for complex numbers and fractions
• Understand the importance of destructors
12.1 INTRODUCTION
Operators are defined for primary data structures in all the languages. For
example, in Python the + operator adds two numbers or two floats or
concatenates two strings. However, for user defined data types the programmer
can't use these operators directly.
Operator overloading helps the programmer to define existing operators for user
defined objects. This makes the language powerful and the work simple. This
simplicity and intuitiveness in turn makes programming fun.
The _init_ function has already been explained in Chapter 10 of this book. The
function initializes the members of a class. Those of you from a C++ or Java
background will find it hard to ignore the similarity between the constructors
(which have the same name as that of the class in C++, etc.) and the _init_
function. Earlier it was stated that _init_ cannot be overloaded, which is partly
true. Though one cannot have two _init_ functions in the same class, there is a
way to implement constructor overloading as explained in the following
discussion.
As stated earlier the purpose of _init_ is to initialize the members of the class.
In the following example (Illustration 12.1), a class called complex has two
members: real and imaginary, which are initialized by the parameters of the
_init_ function. Note that the members of the class are denoted by self.real
and self.imaginary and the parameters of the functions are initialized by real
and imaginary. The example has a function called putData to display the values
of the members. In the _main_() function, c1 is an instance of the class complex.
The object c1 is initialized by 5 and 3 and the putData() of the class has been
invoked to display the 'Complex Number'.
Illustration 12.1: Create a class called complex, having two members - real and
imaginary. The class should have _init_, which takes two parameters to
initialize the values of real and imaginary respectively and a function called
putData to display the complex number. Create an instance of the complex
number in the _main_() function, initialize it by (5, 3) and display the number
by invoking the putData function.
Code
Output
=== RUN C:\Python\Operator Overlaoding\_init_\Example1.py
===
5 + i 3
>>>
Let us consider another example of _init_. The example (Illustration 12.2) deals
with the implementation of vectors. In the example, a class called Vector has
two data members called args and length. Since arg can contain any number of
items, the _init_ has *args as the parameter. The putData function displays the
vector and the _len_ function calculates the length of the Vector (as in the
number of arguments).
Illustration 12.2: Create a class called Vector, which can be instantiated with a
vector of any length. Design the requisite _init_ function and a function to
overload the len operator. The class should also have a putData function to
display the vector. Instantiate the class with a vector having:
no element
one element
two elements
three elements
Code
Output
>>>
=== RUN C:\Python\Operator Overlaoding\_init_\Example2.py
===
()
Length 0
(2,)
Length 1
(3, 4)
Length 2
(7, 8, 9)
Length 3
>>>
Note that in the above example, _init_ has the same effect as having many
constructors with different parameters. Although _init_ has not been
overloaded in the literal sense, the program has the same effect as that of one
having overloaded constructors.
Illustration 12.3: Construct a class called Complex having real and ima as its
data members. The class should have an _init_ for initializing the data members
and putData for displaying the complex number.
Code
Output
>>>
== RUN C:/Python/Operator Overlaoding/_init_/Example 10.py
==
5 +i 3
0 +i 0
>>>
12.3 METHODS FOR OVERLOADING BINARY OPERATORS
The following methods (Table 12.1) help in overloading the binary operators like
+, –, *, and /. The operators operate on two operands: self and another instance
of the requisite class. When an operator is used between objects, the
corresponding methods are invoked. For example for objects c1 and c2 of a class
called Complex, c1+c2 invokes the _add_ method. Similarly, the – operator
would invoke the _sub_ method, the * would invoke the _mul_ method and so
one. Table 12.1 shows the method and the operator due to which the method is
invoked.
The use of the above operators has been explained in the following section.
1. _init_
The _init_ initializes the class by setting the numerator to 0 and the
denominator to 1. The statement
x=fraction()
2. _add_
calls the _add_ of x and takes y as the “other” argument. Therefore, it must
have two arguments: a positional parameter (self) and a fraction (other).
The addition of two fractions is done as follows. The LCM of b1
and b2 becomes the denominator of the resultant fraction. The numerator is
calculated using the following formula.
Note that the resultant fraction is stored in another fraction (s). The method
_add_ returns s.
3. _sub_
calls the _sub_ of x and takes y as the “other” argument. Therefore, it must
have two arguments: a positional parameter (self) and a fraction (other).
The difference of two fractions is done as follows. The LCM of b1
and b2 becomes the denominator of the resultant fraction. The numerator is
calculated using the following formula.
Note that the resultant fraction is stored in another fraction (d). The method
_sub_ returns d.
4. _mul_
calls the _mul_ of x and takes y as the “other” argument. Therefore, it must
have two arguments: a positional parameter (self) and a fraction (other). The
product of two fractions is calculated as follows. The numerator is
calculated using the following formula.
numerator = a1 × a2
And the denominator is calculated as follows.
denominator = b1 × b2
Note that the resultant fraction is stored in another fraction (m). The method
_mul_ returns m.
5. _truediv_
+
–
*
/
Create LCM and GCD methods in order to accomplish the above tasks. The
LCM method should find the LCM of two numbers and the GCD method should
find the GCD of the two numbers. Note that LCM(x, y) × GCD(x, y) = x × y.
Solution: The implementation has already been discussed. The following code
performs the requisite tasks and the output follows.
Code
Output
== RUN C:/Python/Operator Overlaoding/Add/Fraction_add.py ==
Enter the numerator :2
Enter the denominator :3
First fraction :
2 / 3
Enter the numerator :4
Enter the denominator :5
Second fraction :
4 / 5
Sum :
22 / 15
Difference :
-2 / 15
Product
8 / 15
Division
10 / 12
>>>
Note that the above illustration has been included in the chapter to explain the
overloading of binary operators. Python, as such, provides addition, subtraction,
multiplication and division for fractions (refer to Chapter 2). The same task can
be done without overloading the operators as follows:
>>> from fractions import Fraction
>>> X=Fraction (20,4)
>>> X
Fraction (5, 1)
>>> Y=Fraction (3,5)
>>> Y
Fraction (3, 5)
>>> X+Y
Fraction (28, 5)
>>> X-Y
Fraction (22, 5)
>>> X*Y
Fraction (3, 1)
>>> X/Y
Fraction (25, 3)
>>>
However, in order to make it work for a user defined data type (or object), it
needs to be overloaded. The _idd_ helps in accomplishing this task. The
following illustration (Illustration 12.5) depicts the use of _idd_ for an object of
the complex class. A complex number has a real part and an imaginary part.
Adding another complex number to a given complex number adds their
respective real parts and imaginary parts. The program follows. Note that,
_iadd_ takes two arguments. The first being the positional parameter and the
second another object called “other.” The real part of “other” is added to the real
part of the object and the imaginary part of “other” is added to the imaginary
part. The _iadd_ returns “self.” Likewise, the reader may overload the _iadd_
operator for his class, as per the requirements.
Illustration 12.5: Overloading += for complex class (Illustrations 12.1 and 12.3)
Code
Output
The following example overloads the _gt_ and _lt_ for a class called Data. The
Data class has a data member called “value.” The _gt_ compares the value of
the instance (self) and that of another instance (other). If the value of the
instance is greater than that of the other instance then a true is retuned, otherwise
a false is returned. Similarly, The _lt_ compares the value of the instance (self)
and that of another instance (other). If the value of the instance is smaller than
that of the other instance then a true is returned, otherwise a false is returned.
Illustration 12.6: Write a program to create a class called Data having “value”
as its data member. Overload the (>) and the (<) operator for the class.
Instantiate the class and compare the objects using _lt_ and _gt_.
Solution: The mechanism of the _gt_ and _lt_ has already been discussed. The
program follows.
Code
Output
>>> `
==== RUN C:/Python/Operator Overlaoding/Comparision.py ====
True
False
>>>
print(X<Y)
Program
class Data:
def_len_(self): return 0
X=Data()
if X:
print("True returned")
else:
print("False returned")
Output
>>>
======== RUN C:/Python/Operator Overlaoding/len.py ========
False returned
>>>
Illustration 12.8: Another variant of the above example has 'value' as its data
member. If the 'value' is null a false is returned, otherwise a true is returned.
Program
Output
======== RUN C:/Python/Operator Overlaoding/len.py ========
True returned
False returned
>>>
Also note that if _bool_ is also defined in the class, then it takes precedence over
the _len_ method. The _bool_ returns a true or a false as per the given
condition. Although overloading _bool_ may not be of much use as every object
is either true or false in Python. Illustration 12.9 presents an example in which
both _bool_ and _len_ are defined.
Illustration 12.9: An example in which both _bool_ and _len_ are defined.
Program
Output
====== RUN C:/Python/Operator Overlaoding/_bool_.py ======
From Bool
True returned
From Bool
False returned
>>>
12.8 DESTRUCTORS
Destructors are called automatically when the space of an object of a class is
reclaimed. Destructors are complementary to constructors. Constructors are
called when a new object is created and the destructors are called when its space
is reclaimed. It may be noted that the destructors are not as important in Python
as they are in some other object-oriented languages. In fact, many programmers
consider the destructors as “obsolete.” The reasons for this are as follows.
No garbage collection: There is another reason for not using destructors. They,
at times, hinder garbage collection. This is good, if deliberate, but bad if not used
without due deliberation. Most of the time the garbage collection done by
Python is good. The following illustration (Illustration 12.10) presents a class
called Data, which has an explicit destructor (_del_). Note that when the
memory is reclaimed, a destructor is called.
Code
GLOSSARY
Operator overloading: This is the mechanism of assigning a new meaning
to an existing object.
POINTS TO REMEMBER
Operator overloading helps the programmer to define an existing operator
for user defined objects.
In Python all expression operators can be overloaded.
Operator overloading can be implemented using special methods.
_bool_ has higher priority over _len_.
EXERCISES
(c) _sum_
(b) _sub_
(c) _minus_
(b) _mul_
(c) Both
(d) None of the above
(b) _len_
(c) Both
(d) None of the above
THEORY
1. What is operator overloading? Explain its importance.
4. The membership can be tested using the 'in' operator. The contains
method can be used for testing the membership in Python. Create a class
having three lists and overload the membership operator for the class.
5. Explain the following methods and explain operator overloading using the
operators.
(a) _add_
(b) _iadd_
(c) _sub_
(d) _mul_
(e) _div_
(f) _len_
(g) _bool_
(h) _gt_
(i) _lt_
(j) _del_
6. The following methods have not been discussed in the chapter. Explore the
following and use them for complex class.
(a) _getitem_
(b) _setitem_
(c) _iter_
(d) _next_
PROGRAMMING
1. Create a class called Distance having meter and centimeter as its data
members. The member functions of the class would be putData(), which
takes the values of meter and centimeter from the user; putData(), which
displays the data members and add, which adds the two distances.
The addition of two instances of distances (say d1 and d2) would require
addition of corresponding centimeters (d1.centimeter +s2.centimeter), if the
sum is less than 100, otherwise it would be (d1.centimeter
+s2.centimeter)%100. The “meter” of the sum would be the sum of meters
of the two instances (d1.meter +d2.meter), if (d1.centimeter +d2.centimeter)
<100, otherwise it would be (d1.meter +d2.meter+1).
2. Overload the + operator for the above class. The + operator should carry out
the same task as is done by the add function.
The subtraction of two instances of distances (say d1 and d2) would require
the subtraction of corresponding centimeters (d1.centimeter -s2.centimeter).
The “meter” of the difference would be the sum of meters of the two
instances (d1.meter - d2.meter).
3. Overload the – operator for the distance class. Assume that d1-d2, would
always mean d1>d2.
6. Now, help the people of the country by developing a program having a class
called nat_currency and overload the + operator, which adds two instances
of nat_currency.
10. Create a class called date having members’ dd, mm, and yyyy (date, month,
and year). Overload the + operator, which adds the two instances of the date
class.
15. Create a class called vector having three data members a, b, and c. The class
must have the getData() function to ask the user to enter the values of a, b,
and c; the putData() function to display the vector.
EXCEPTION HANDLING
After reading this chapter, the reader will be able to
• Understand the concept of exception handling
• Appreciate the importance of exception handling
• Use try/except
• Manually throw exceptions
• Craft a program that raises user defined exceptions
13.1 INTRODUCTION
Writing a program is an involved task. It requires due deliberation, command
over the syntax and problem solving capabilities. In spite of all efforts, there is a
possibility of some error cropping up or of an unexpected output. These errors
can be classified as follows. The first types of errors are those due to syntax or
those which can be intercepted by the compiler. On compiling a program having
such errors, some standard message appears. These can be handled by learning
the syntax or changing the code as per the requirement of the problem at hand.
The following is an example of a code having syntax error. Note that the closing
parenthesis is missing in the statement funl('Harsh'. The code is followed by
the message that appears when executing the code.
Code
def fun1(a):
print('\nArgument\t:',a)
print('\nType\t:',type(a))
fun1(34)
fun1(34.67)
fun1('Harsh'
The second type is more complex. At times the program stops working or
behaves in an undesirable way on execution. This may be due to incorrect user
input, inability to open a file, accessing something which the program does not
have authority to do and so on. These are referred to as exceptions. Exceptions
are “events that modify the follow of the program”[1]. Python invokes these
events when errors occur, or the programmer can explicitly invoke them.
try/expect
try/expect/finally
raise
assert
This chapter concentrates on the first three. The chapter has been organized as
follows. Section 13.2 discusses the importance and mechanisms of exception
handling, Section 13.3 presents some of the built-in exceptions in Python,
Section 13.4 summarizes the process by taking an example, Section 13.5
presents another example of exception handling and the last section concludes
the chapter.
Python also has the try/finally statements to handle the termination condition.
Those of you from a Java background will be familiar with finally. It is for
handling the termination condition, whether or not an exception has occurred.
For example in designing software the concluding screen must appear, whether
or not an exception has occurred or for that matter the memory of objects must
be reclaimed at the end. For such type of situations finally is immensely helpful.
13.2.1 An Example of Try/Catch
A list contains an ordered set of students. The first location contains the name of
the students who got the highest marks, the second student’s name is at the
second position, and so on.
>>>L = ['Harsh', 'Naved', 'Snigdha', 'Gaurav']
In order to access an element at a given location, the user is asked to enter the
index
>>>Index=input('Enter the index')
Now, the element at that position is accessed using the following statement
>>>print(L[int(index)])
So, if the user enters 1, ‘Naved’ would be the output, if he enters 2, “Snigdha”
would be the output. However, the following message appears if he enters
anything above 3.
Code
Note that the try block contains the part of the code where the exception may
come up. If a runtime error is there, the except part handles it. Also note that the
except may have the name of the predefined exception. The statement after the
except always executes, whether or not an exception has been raised. The reader
is expected to take note of the fact that the control does not go back to the point
where the expectation really occurred. It can only handle the exception in the
requisite block, after which the normal execution continues. The syntax of the
exception handling mechanism is as follows.
Syntax
try:
##code where exception is expected
expect <Exception>:
##code to handle the exception
## rest of the program
Syntax
try:
raise <something>
expect <something>:
##code which handles the exception
##rest of the code
If such exceptions are not caught, they are handled in the same fashion as in the
above section. The examples in Section 13.4 present codes where the exceptions
have been raised and caught.
AssertionError
When an assert statement fails, the AssertionError is raised.
AttributeError
When an assignment fails, the AttributeError is raised
EOFError
When the last word of the file is reached and the program attempts to read
any further, the EOFError is raised.
FloatingPointError
This exception is raised when floating point operations fail.
ImportError
If the import statement written in the code cannot load the said module, this
exception is raised. This is same as the ModuleNotFoundError in the later
versions of Python.
IndexError
When the sequence is out of range, this exception is raised.
KeyError
If in a dictionary the key is not found, then this exception is raised.
OverflowError
Note that each data type can hold some value and there is always a
maximum limit to what it can hold. When this limit is reached, the
OverflowError is raised.
RecursionError
While executing a code that uses recursion, at times maximum iteration
depth is reached. At this point in time, the recursionError is raised.
RuntimeError
If an error occurs and it does not fall in any of the said categories, then this
exception is raised.
StopIteration
If one is using the _next_() and there are no more objects that can be
processed, then this exception is raised.
SyntaxError
When the syntax of the code is incorrect, this exception is raised. For
example, not writing the import statements or any such thing.
IntendationError
When incorrect use of indentation is done, then this exception comes up.
TabError
An inconsistent use of spaces or tabs leads to this type of error.
SystemError
If some internal error is found, then this exception is raised. The exception
displays the problem that was encountered due to which the exception is
raised.
NotImplementedError
If an object is not supported or the part that provides support has not been
implemented, then the NotImplementedError is raised.
TypeError
If an argument is passed and is not expected, the TypeError is raised. For
example, in a program that divides two numbers entered by the user, a
character is passed, then TypeError is raised.
ValueError
When an incorrect value is passed in a function (or an attempt is made to
enter it in a variable), the ValueError is raised. For example if a value which
is outside the bounds of an integer is passed then this exception is raised.
UnboundLocalError
This exception is raised when a reference is made to a variable which does
not have any value in that scope.
UnicodeError
This is raised when errors related to Unicode encoding or decoding come
up.
ZeroDivisionError
The division and the modulo operation has two arguments. If the second
argument is zero, this exception is raised.
The program can be made user friendly by printing a user friendly, easy to
understand message. This can be done by using exception handling.
Code
def divide(a,b):
result =a/b
print('Result is\t:',result)
divide(3,2)
divide(3,0)
>>>
Output
Output
======== RUN C:/Python/Exception handling/divide.py ========
Result is : 0.6666666666666666
Exception caught
>>>
Some of the common exceptions and their meanings have already been
presented in Section 13.3. However, there are many more. The list of such
exceptions can be found at the link provided in the references at the end of this
book.
Code
Output
===== RUN C:/Python/Exception handling/divide raise.py =====
Result is : 0.6666666666666666
Exception caught:ZeroDivisionError
>>>
Suppose there is a situation where a specific exception (as per the need of the
program) is to be raised. However, there is no predefined exception to handle
that situation. In such cases a class which would handle the exception that needs
to be created. The said class should be a subclass of the Exception class, so
that it can be used for raising exceptions. When the situation arises the exception
can be raised, as shown in the following illustration. In the illustration that
follows, a class called My Error, which is derived from Exception, is created.
The _init_ of this class may contain the message which will be printed when
the exception is raised. While raising the exception the keyword raise, followed
by the name of the class is written. The reader is expected to observe the output
and understand that first the message written in _init_ is printed, followed by
the message in the except block. Though this is just a dummy example, it gives
an idea as to how to craft classes that handle exceptions.
Code
Output
====== RUN C:\Python\Exception handling\MyException.py
======
Result is : 0.6666666666666666
My Error type error
Exception caught: My Error
>>>
Code
Output
==== RUN C:/Python/Exception handling/Example/findMax.py
====
Maximum : 89
>>>
Note that if the contents of L are strings (e.g. L=[“Harsh,” “Nakul,” “Naved,”
“Sahil”]), the strings would be compared as per the rules and the largest
(“Sahil”) would be printed. That is the program works for integers, strings or
floats. However, for the following list an exception would be raised:
L= [2, 'Harsh', 3.67]
Output
The problem can be handled by putting the part of the code where the problem is
likely to come in the try block. Moreover, if all the items of the list are to be
entered by the user then the possibility of a runtime error cropping up will be
higher. In such cases the programmer must make sure that everything, including
the input of items and calling the function, are in the try block. The following
code presents the version of the program where items are entered by the user and
exception handling is implemented. Note that the first run produces an excepted
result, whereas the second run results in a runtime error and hence the exception
handling mechanism is invoked.
Code
Code
13.7 CONCLUSION
The chapter presents a remarkable way to deal with exceptions. Though Python
has an inbuilt mechanism to deal with exceptions, the knowledge of exception
handling makes programming more effective, user friendly, and robust. The first
step will be to identify the part of the code where exceptions are likely to come,
and put that part in the try block. The exceptions can also be manually caught
and handled in the except block. The finally block handles the unhandled
exceptions and also executes even if there is no exception. The chapter also
presents some of the most common exceptions that can be caught in Python. The
reader is expected to use the concepts learned in this chapter in his/her programs.
Happy programming!
GLOSSARY
try/except :Syntax
try:
##code where exception is expected
expect <Exception>:
##code to handle the exception
## rest of the program
POINTS TO REMEMBER
At the runtime, if an error crops up then an exception is raised.
Exception handling in Python can be done using any of the following:
– try/catch
– try/finally
– raise
– assert
In Python, one can also manually raise the exceptions.
The part of the code where the exception is likely to be raised is put in the
try block. If an exception is raised, it will be handled in the except block.
The class that helps to raise user defined exceptions should be a subclass of
the Exception class.
The statements in finally are always executed, whether or not exceptions
occur.
EXERCISES
MULTIPLE CHOICE QUESTIONS
1. Exception handling
(a) Handles runtime errors
(b) Provides robustness in a program
(c) Both
(d) None of the above
5. Which of the following is raised in the case when an index outside the
bounds is accessed?
(a) Array index out of bound
(b) Out of bound
(c) Array
(d) None of the above
THEORY
1. What is the difference between compile time and runtime error?
4. Explain how to create a class that derives from the exception class. How is
this class used to raise exceptions?
PROGRAMMING
The roots of a quadratic equation ax2 + bx + c = 0 are given by the formula
. Write a program to ask the user to enter the values of a, b and
c and calculate the roots.
4. For the complex class defined in the previous question, use exception
handling to prevent the user from entering a non-real number (as real or
imaginary part).
5. In the complex class, create a function that converts complex numbers to the
polar form.
8. Implement the operations of linked list, and throw an exception when the
number entered by the user is negative. Assume that the data part of the
linked list would contain numbers only.
9. Write a program that takes the ppm of chorine in water from the user and
finds whether the ppm is within permissible limits. If it is not, the program
should raise an exception.
10. Write a program that finds the inverse of a given matrix. The program
should raise an exception when the determinant of the matrix is zero.
14
CHAPTER
INTRODUCTION TO DATA
STRUCTURES
After reading this chapter, the reader will be able to
• Understand the importance of data structures
• Classify data structures
• Define stack, queue, tree, and graph
• Define algorithms and appreciate the characteristics of an algorithm
• Understand abstract data types
• Differentiate between iterative and recursive algorithms
• Implement bubble sort, selection sort, merge, and merge sort
14.1 INTRODUCTION
The last two sections introduced procedural and object-oriented programming.
The concepts studied so far constitute the basis of programming. Having learned
the basic concepts, let us move towards becoming a programmer. To become a
programmer the knowledge of data structure is essential. In any project storing
data, its organization and ways to access the data are some of the most important
tasks. The organization of the data comes under what are generally referred to as
data structures. The knowledge of these not only help us to make an efficient
and effective program but also to solve various problems at hand by virtue of
their inherent characteristics. This chapter briefly introduces the concept of data
structures and discusses some of the algorithms of some of the most important
data structures.
The secondary data structures are formed from primary data structures. Stacks,
queues, trees, and graphs are some examples of secondary data structures. The
secondary data structures can further be classified as linear and nonlinear. Stacks
and queues are linear data structures whereas trees and graphs are nonlinear data
structures. The classification has been depicted in Figure 14.1.
We begin our discussion with one of the simplest data structures, an array. An
array consists of homogeneous elements at consecutive memory locations.
Arrays are used to store elements which are similar, and accessing many such
elements will take less time if they are stored in consecutive memory locations.
Arrays are an integral part of languages like C, C++, Java, and C. In Python,
however, arrays can be accessed using library. The formation, usage and
applications of multi-dimensional arrays have been discussed in the following
chapter - Chapter 18. Section 14.4 of this chapter discusses the various
algorithms related to arrays in detail.
Definition
A stack is a linear data structure, which follows the principle of Last In First Out
(LIFO). In order to understand the concept of stacks, consider opening a
document in Microsoft Word. When one opens a document using the “Open”
dialog and finds the document using the “Browse” window, he cannot close the
“Open” dialog until he closes the “Browse” window. Also the application can be
closed only if one closes the “Open” dialog. The “Browse” window, which was
opened at the end, has to be closed first. This is just like a pile of books, from
which only the book which was kept the end can be taken out. Stacks are used in
sub procedure calls and backtracking. The stacks are characterized by an index
called TOP, which is initially -1. The value of TOP increases as and when the
elements are added in the stack. The algorithms of stack and its applications are
discussed in Chapter 15.
Definition
Stack: A stack is a linear data structure that follows the principle of Last In First
Out (LIFO).
Queue is a data structure that follows the principle of First In First Out (FIFO).
Customer services use the idea of Queue. The person who enters first is served
earlier than the person who entered later. When we give many print commands
to a printer, the commands are stored in a queue and the corresponding
documents are printed in the order in which the command was given. Queues are
used in scheduling algorithms by the operating systems, in spooling (e.g. for
printer) and inapt many other places. The queues (static) are characterized by
two indices - REAR and FRONT. The initial value of both the indices is -1. The
value of REAR increases as elements are inserted in the queue and that of
FRONT increases when elements are removed from the queue. The algorithms
of insertion and deletion in a queue are presented in Chapter 15. The chapter also
presents some of the important applications of queue.
Definition
Queue: A queue is a linear data structure that follows the principle of First In
First Out (FIFO).
A graph may be defined as a set containing two finite sets: the set of vertices (V)
and the set of edges (E). They are represented using two-dimensional arrays or
linked lists. A graph can be weighted, in which case the corresponding matrix
would have weights at the requisite positions. Graphs are traversed using
methods like breadth first search or depth first search. Interestingly, these
traversals use linear data structures like stacks and queues. Graphs are
extensively used in many computational problems. In fact, there is a dedicated
branch of algorithms for solving problems using graphs. The concept of
algorithms and applications of graphs are discussed in Chapter 17 of this book.
Definition
Graph: A graph may be defined as G = (V, E), where V is a finite, non-empty
set of vertices and E is a finite, non-empty set of edges. Each element of E is (x,
y), where x and y belong to the set of vertices.
A tree is a graph which does not have any cycle or isolated vertex (or edges). A
tree is a graph and therefore it has vertices and edges. The absence of cycles and
isolated vertices makes it usable for many problems like searching, finding
complexity, and so on. A tree is generally used for representing a hierarchical
relationship. A special tree called a binary tree has only a maximum of two
children at each level. Trees have been discussed in Chapter 17 of this book.
Definition
Tree: A tree is a graph that does not have any cycle or isolated vertex or edge.
In the following chapters, the concepts related to trees and graphs have been
discussed. Trees are graphs and fall under the category of non-linear data
structures. As stated earlier these are extensively used in searching, sorting,
finding minimum spanning trees, and solving some of the most important
problems in the field of computer science.
As well as the above there are other data structures like Plex, which are beyond
the scope of this book. The concept of file has already been discussed in chapter
9 of this book. The organization of a file is a fascinating topic used in many
fields, including data base management system.
The chapter has been organized as follows. This section has introduced the
definitions of a data structures and their types. The definitions of linear data
structures like stacks and queues and nonlinear data structures like graphs and
trees have also been presented in this section. The second section discusses
Abstract Data Types (ADT) and the third section discusses the definition of
algorithms. Section 14.4 discusses arrays and Section 14.5 discusses iterative
and non-iterative algorithms. The topic has been discussed by taking examples
of three popular sorting techniques: selection sort, bubble sort, and merge sort.
The last section concludes the chapter.
Abstract Data Types contain elements along with the set of operations to
manipulate the elements. The operations tell us what is to be done, not how it is
to be done. That is, ADTs are not about implementation, as long as it is correct,
but about the tasks. The higher level abstraction of the task is important. As a
matter of fact, it is the designer’s decision as to what operations will constitute
the ADT. There is no hard and fast rule on the number of operations and the type
of operations. An example of ADT is a stack. A stack, as explained earlier, is a
linear data structure that follows the principle of Last In First Out (LIFO). A
stack can be described with the help of the following operations:
Note that in the above description, the various functions are clear about what is
to be done not how it is to be done. Other examples of ADTs include queues,
lists, trees, graphs, etc. The reader may also note that languages like C++, Java,
C#, Python, etc., support ADTs via classes.
For example, the stack data structure can be implemented using data structures
like:
Array
Linked list
Having studied the definitions of data structures, let us shift our focus to the way
a problem is solved. The next section introduces the notion of algorithms and the
following section presents arrays.
14.3 ALGORITHMS
In order to accomplish any task, one needs to plan the chain of action. For
example you are required to complete a task consisting of 4 subtasks, where each
subtask can be performed only on the completion of the previous subtask. You
would probably perform the first subtask, followed by the second, followed by
the third and finally the fourth. An example of such a process follows. In the
process, it is assumed that the person has ingredients required for the Indian
recipe (of kheer) that follows.
Ingredients: 1 L milk, ¼ cup rice, 6 tablespoon sugar, some dry fruits (almonds,
raisins, cashews).
The steps to make Indian “kheer” have been depicted in Figure 14.2.
Efficiency: The time required by the algorithm must be as low as possible, and
the space required must also be also be as low as possible.
Big Oh: The O (big Oh) notation depicts the upper bound of an algorithm.
Formally, for a function f (t), O(f (t) is defined as follows:
Theta: The θ(big Oh) notation depicts the tight bound of an algorithm. Formally,
for a function f (t), θ (f (t) is defined as follows:
14.4 ARRAYS
An array is a linear data structure that has the same type of elements. The
elements of an array are stored in consecutive memory locations. Those of you
from a C background will have already studied arrays. This section implements
insertion and deletion from an array. An insertion can be done at the beginning,
at the end and somewhere in-between. Likewise, a deletion can be done from the
beginning, from the end and from anywhere in-between. Inserting an element at
the beginning requires all elements to be shifted one position to the right, thus
making way for the “item.” After this, the element “item” is inserted at the first
position and the length of the array in incremented by unity. That is,
##Shift each element of the array one position to the right
arr[0] = item
length = length +1
The first step requires O(n) time and the second and the third would require O(1)
each. Therefore the complexity of inserting an element at the first position is
O(n). Inserting an element at the end requires increasing the length of the given
array by one. The task, thus becomes O(1), as we are keeping track of the
number of elements in the variable “length.”
arr[length] = item
length = length +1
Inserting an element after a certain position requires shifting all elements after
that position by one, followed by putting the element at that position and
increasing the length of the array by one.
#shift all elements after 'position' by one.
arr[pos] = item
length = length +1
The average case complexity of the above task would be O(n). Deleting an
element from the beginning requires shifting all the elements, starting from the
second element, to the right (by one) and then reducing the length of the array by
one. That is,
#shift all the elements to the right (starting from the
second element)
length = length -1
The complexity of shifting all the elements to one position to the right would be
O(n) and hence the complexity of the procedure would be O(n). Deleting an
element after a particular position requires shifting all the elements, starting from
(position +1), to the right (by one) and then reducing the length of the array by
one. That is,
#shift all the elements to the right (starting from position
+1)
length = length -1
The complexity of shifting all the elements to one position to the right would be
O(n) and hence the complexity of the procedure would be O(n). Deleting an
element from the end requires reducing the length of the array by one. This takes
O(1), time. That is,
length = length -1
The task can be done by using functions in C but it requires the use of pointers.
The C program to implement insertion and deletion in an array is as follows.
Inserting an element in a given array, deleting an element from a given array (In C)
Note that in C the modular approach used to accomplish the above task is
complex and intricate. It requires the use of pointers and passing of both the
address of the array and its length in each function. The insertion and deletion of
an element in an array is simple in Python. It requires the use of the array class.
The functions to accomplish different tasks have been presented in Table 14.1.
------------------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-20-e7f729e1f6ad> in <module>()
----> 1 arr.write(file)
AttributeError: 'array.array' object has no attribute
'write'.
Bubble Sort
In bubble sort the first element is compared with the second, the second with the
third and so on; if the element to be compared is smaller than the first, the
elements are swapped. After the first iteration, the maximum element is placed at
the last position. The process is repeated for the second element and so on. The
process has been presented in the following algorithm:
Analysis
The number of times each statement is executed has been presented in Table
14.2. The first statement is executed (n+1) times and the statements inside the
loop are executed n times. Each time the inner loop executes (n-i) times
therefore making the total number as n(n-i-1). The execution of the if block
depends on the data. Note that the total number of executions has n2 as the
highest degree term. Therefore the complexity of the algorithm is O(n2).
In selection sort the first element is compared with the rest of the elements and
whichever is smaller is replaced with the first. This results in the minimum
element coming at the first position. The process is repeated for the second
element and so on. The process has been presented in the following algorithm:
Analysis: Note that the algorithm has a nested loop. The outer loop executes n
times and the inner’s execution makes the complexity O(n2).
The process has been exemplified in Figure 14.3. The first position has 4, it is
compared with the second position and since the second position has 1, the
numbers are swapped. Now, 1 is compared with 6, 2, 8, and 3, one by one. Since
none of these is smaller than 1, the numbers remain at their respective positions.
FIGURE 14.4 An example of selection sort
Merge
Given two sorted lists a1 and a2, having n1 and n2 elements, the merged list is a
sorted list having at most (n1 + n2) elements. The procedure for merge is as
follows.
The two lists are merged as follows. The pointer i is kept at the first index of the
first list and j at the first index of the second list. The resultant array, c, is
initialized to [ ] and pointer k points to the first position of c. If the element at a
is less than that at b, the ith element of a is copied to c, and the pointers i and k
are incremented. If the element at a is greater than that at b, the jth element of b
is copied to c, and the pointers j and k are incremented. If the elements at a and
b are equal, the ith element of a is copied to c, and the pointers i, j and k are
incremented. The process is repeated till i becomes n1 or j becomes n2, after
which the elements of the first array (if i<n1) are copied to c. Otherwise (if
j<n2) the elements of the second array are copied to c.
Merge Sort
Merge sort works as follows. Low points to the first index of the array and high
points to the last index of the array to be sorted. If the value of low is equal to
that of high, there is only one element in the array and hence the array is
returned (an array having a single element is deemed to be sorted). Otherwise the
array is split into two halves, merge sort is recursively applied to the two parts
and the result is merged using the procedure explained above.
Analysis
The complexity of merge is O(n) (note that there are loops which run one after
another). The merge sort divides the array into two parts until a single element
array is formed. Therefore, if the number of elements is initially n, after the first
iteration the two parts will have n/2 elements each. In the next iteration, the
number of elements in the two parts will be n/4 and so on. The process
terminates if the number of elements becomes 1. That is . That is i = log2
n. The complexity of merge sort becomes O(n logn).
14.6 CONCLUSION
One of the most important things while designing a program is to do a task
efficiently. The efficiency must be both in terms of space and time. Managing
time complexity requires developing better algorithms whereas the space
complexity can be managed with various factors. This chapter introduces the
concept of data structures for efficient storage, management and access of data.
The classification of algorithms has been discussed and definitions of various
data structures have been presented. The chapter also introduces the concept of
complexity. The examples of iterative and recursive algorithms have been given
to explain the concept. The reader is expected to implement the concepts
presented here. The following chapters take the discussion forward and explain
various applications of stacks, queues, and implementation of linked lists. To
conclude “Bad programmers worry about the code, good programmers worry
about the data structures.”
GLOSSARY
Array: An array consists of homogeneous elements at consecutive memory
locations.
Stack: A stack is a linear data structure that follows the principle of Last In First
Out (LIFO).
Queue: A queue is a linear data structure that follows the principle of First In
First Out (FIFO).
Graph: A graph may be defined as G= (V, E), where V is a finite, non-empty set
of vertices and E is a finite, non-empty set of edges. Each element of E is (x, y),
where x and y belong to the set of vertices.
Tree: A tree is a graph that does not have any cycle or isolated vertex or edge.
Big Oh: The O (big Oh) notation depicts the upper bound of an algorithm.
Formally, for a function f (t), O(f (t) is defined as follows.
Theta: The θ(big Oh) notation depicts the tight bound of an algorithm. Formally,
for a function f (t), θ(f (t) is defined as follows.
EXERCISES
5. A linear data structure which follows the principle of First In First Out is
(a) Queue
(b) Stack
(c) File
(d) None of the above
6. A linear data structure which follows the principle of Last In First Out is
(a) Queue
(b) Stack
(c) File
(d) None of the above
11. A tree
(a) May have an isolated edge.
(b) May have a loop.
(c) May have an isolated vertex.
(d) None of the above.
12. A graph
(a) May have a loop
(b) May have an isolated edge
(c) May have an isolated vertex
(d) All of the above
THEORY
1. What is a data structure? Explain the importance of data structures.
2. Classify data structures on the basis of basic and non-basic. Give examples
of each type.
3. Classify data structures on the basis of linear and non-linear. Give examples
of each type.
6. State a few applications of stack. Explain how a stack can be used in blind
search.
10. What is an abstract data type? Explain with the help of an example.
15. Suggest a change in selection sort, so that the complexity can be improved
to O(n log n).
20. Which is better in terms of space complexity - merge sort or selection sort?
PROGRAMMING EXERCISE
1. Write a program to implement a stack.
9. Write a program to find the second maximum element from a given array.
15.1 INTRODUCTION
Stacks and queues were introduced in the previous chapter. This chapter takes
the topic forward and explains various implementations and applications of
stacks and queues. The data structures are important as they find applications in
recursive algorithms, conversion and evaluation of expressions, operating
systems, and in popular CPU scheduling algorithms like round robin, etc. It may
be stated here that Python provides libraries for both stacks and queues.
However, a programmer is expected to know the implementations of the said
data structures and to understand the advantages and problems associated with
various implementations.
This chapter also introduces infix, postfix, and prefix expressions. Conversion
and evaluation of expressions have been discussed in detail in this chapter. This
topic finds applications in compiler design too. The linked list based
implementation of stacks and queues have been deferred to the next chapter, as
linked lists have been formally introduced in the next chapter.
This chapter has been organized as follows. Section 15.2 presents the basic
terminology and array based implementation of stack. Section 15.3 discusses one
of the dynamic implementations of stack and the discussion continues in the next
section. Section 15.5 discusses two important applications of stacks: reversal of
string and infix, postfix and prefix expressions. Section 15.6 presents the basics
of queues and its implementation. The last section concludes the chapter. The
reader is expected to revisit Chapter 14 before proceeding any further.
15.2 STACK
A stack is a linear data structure that follows the principle of Last In First Out
(LIFO) or First In Last Out (FILO). A stack can be implemented using an array
which has a fixed capacity (say n). The TOP denotes the position at which the
element is to be inserted. Initially, the value of TOP is -1. As elements are
inserted onto the stack, the value of TOP is increased by one until its value
becomes (n-1), after which the 'Overflow' exception is raised. The insertion in
a stack is referred to as 'push'. The algorithm for push has been presented as
follows (Algorithm 15.1).
Algorithm 15.1
An element is deleted from the top of the stack if the value of TOP is not -1, in
which case an underflow exception is raised. Otherwise, the element at TOP is
returned and the value of TOP is decremented by 1. This operation is referred to
as 'pop'. The algorithm for pop is as follows (Algorithm 15.2).
Algorithm 15.2
The push and pop operations take O(1) time each. Supposing all the placeholders
of the given stack are full and each element is to be popped, the total time would
be n × O(1) = O(n).
Code
The implementation of stacks using linked lists has been dealt with in the next
chapter. We now move on to some of the applications of a stack.
FIGURE 15.1 A stack can be used to reverse the order of characters of a string
Illustration 15.1: Ask the user to enter a string and reverse the string using a
stack (use a list as stack).
Solution: The theory has already been discussed. The program is as follows.
Code
str= input('Enter a string\t:')
rev_string=''
a=[]
for i in str:
a.append(i)
i=0
while i<len(str):
x=a.pop()
rev_string=rev_string+ x
i=i+1
print(rev_string)
Output
>>>
========== RUN C:/Python/Data Structure/reverse.py
==========
Enter a string :harsh
hsrah
>>>
Illustration 15.2: Reverse a line entered by the user using stacks. The stack
need not be implemented. You can use a list as a stack.
Solution: The process remains same. However, to split a line into words the
split() function is used.
line=input('Enter a line\t:')
a=[]
rev_line=''
words=line.split()
print(words)
for i in words:
a.append(i)
i=0
while i<len(words):
rev_line+=a.pop()
rev_line+=' '
i+=1
print(rev_line)
Output
>>>
========== RUN C:/Python/Data Structure/revline.py
==========
Enter a line :I am Harsh
['I', 'am', 'Harsh']
Harsh am I
>>>
Infix: a + b
Postfix: ab +
Prefix: + ab
Evaluation of Postfix
Step 1: Initialize the postfix expression, P by NULL and let the stack be initially
empty.
Step 2: For an incoming symbol, s, in expression E
Repeat the following steps till there is a symbol in the given string
If it is a operand, put in the stack
Else if it is an operator pop two symbols from the stack (say x; and y, in
that order)
Apply the operator as x + y, and put the result in the stack.
In order to understand the above procedure, let us consider an
expression E
E = ab + c × d/
The steps of evaluation of this postfix expression have been depicted in Table
15.1, shown as follows.
Postfix Conversion
Prefix Conversion
15.6 QUEUE
As stated in the first section, a queue is a linear data structure that follows the
principle of First In First Out (FIFO). A queue is characterized by FRONT and
REAR. Initially, the value of FRONT and REAR are both -1. When a new element is
added to a queue, the value of REAR is incremented, if the value of REAR is not
(n-1). When an element is deleted from the queue, the value of FRONT is
incremented by 1 if FRONT is not -1. In the first insertion REAR and FRONT are both
incremented and the value of REAR (and FRONT) become 0. In the case of deletion
where the value of REAR and FRONT are same, the value of REAR and FRONT
become -1. The algorithms for insertion in a queue and deletion from a queue are
as follows:
The algorithm (both places) for the deletion from a queue is as follows. The
algorithm (both places) returns the value which is deleted from the queue. If a
“-1” is returned, it indicates an underflow.
The following illustration depicts the static implementation of a queue.
Solution: In the program that follows, the queue has been implemented using a
list called “a.” The initial values of FRONT and REAR are both -1.
Output
15.7 CONCLUSION
Many researchers consider data structures more important than the procedure.
Stacks and queues are the most important aspects of these important things. The
implementations of stacks and queues have been discussed in this chapter. The
conversion of a postfix expression to that in infix, infix to postfix, infix, to prefix
have not been implemented and have been left as an exercise for the reader. The
reader is also expected to visit the links provided at the end of this book to find
some more applications of stacks and queues and try to implement them. Lastly,
the linked list based implementation has been discussed in the next chapter.
GLOSSARY
Stack: A linear data structure which follows the principle of Last in First out
(LIFO).
Queue: A linear data structure which follows the principle of First in First out
(FIFO).
IMPORTANT POINTS
Complexity of insertion and deletion in both stack and queue is O(1).
If the value of TOP is -1, stack is empty.
In the static implementation, if the value of TOP is (n-1), the stack is full,
where n is the maximum number of elements a stack can hold.
On inserting an element, in a stack the value of TOP increases by 1.
On removing an element from a stack, the value of TOP decreases by -1.
Evaluation of postfix expression, conversion of infix to postfix, and that to
prefix requires stack.
Applications of queues include customer services, round robin, printer
spooling, etc.
EXERCISES
1. Books are kept one over another such that the book which is kept at the end
would be picked up first. Which data structure resembles this structure?
(a) Stacks
(b) Queues
(c) Graphs
(d) Trees
12. Round robin algorithm requires which of the following data structures?
(a) Stacks
(b) Queues
(c) Graphs
(d) Trees
13. What is the time complexity of the addition of an element in the static
implementation of a queue?
(a) O(1)
(b) O(n)
(c) O(n2)
(d) None of the above
14. The dynamic implementation of queue requires which of the following data
structures?
(a) Graphs
(b) Trees
(c) Linked lists
(d) None of the above
THEORY
1. Write an algorithm for static implementation of a stack. What are the
problems in the implementation?
NUMERICAL
1. Evaluate the following postfix expressions:
(a) ab – c ×
(b) ab – cd / ×
(c) ab + cd / – f +
(d) ab · c –
(e) xSin
USEFUL LINK
1. Lecture notes: https://www.cs.cmu.edu/~rjsimmon/15122-s13/09-
queuestack.pdf.
CHAPTER
16
LINKED LISTS
After reading this chapter, the reader will be able to
• Understand the need and importance of linked lists
• Insert and delete an item in a given linked list
• Implement stack and queue using a linked list
• Understand the problems associated with linked lists
16.1 INTRODUCTION
The previous chapter introduced two of the most important data structures;
namely stack and queue. Stacks follow the principle of Last In First Out (LIFO)
whereas queues are linear data structures which follow the principle of First In
First Out (FIFO). That is, an element can be added or removed only from a
specific position in these data structures. The data structure introduced in this
chapter is far more flexible in terms of the insertion and removal of elements.
The previous chapter also discussed the static implementation of stacks and
queues. But the discussion on the dynamic implementation using linked lists was
deliberately delayed. The linked list discussed in this chapter will help the user
in the dynamic implementation of stack and queue. Here, it may be stated that
Python provides functions for creation of linked lists and supported operations.
The purpose of this chapter is to make the user familiar with the mechanism of
the operations.
Linked list is a data structure whose basic unit is node. Each node has two parts
namely: DATA and LINK. The DATA part contains the value whereas the LINK
part has the address of the next node (Figure 16.1).
FIGURE 16.1 The basic unit of a linked list is a node. A linked list may have any number of
nodes. The last node has NULL in its LINK part.
Linked lists are used in many problems like the implementation of dynamic
stacks and queues and implementing non-linear data structures like trees and
graphs. It may be stated here that although the use of linked lists makes the
dynamic implementation easy, they come with their own problems. In some
cases linked lists are not used in the implementation of trees. In implementing
non-linear data structures the need of linked lists must be deliberated upon. For
example, if we have a balanced binary tree or a heap then the use of arrays is
much better than a linked list.
A linked list consists of nodes connected together via LINK. As stated earlier,
each node has data and a LINK, where data may be a primary or even a
secondary data structure and the LINK is a pointer to the next node. The first
node of a linked list will henceforth be denoted by HEAD. It may also be noted
that the LINK of the last node is NULL, indicating that there is no node after the
last node. Therefore it becomes easy to identify the first and the last node in a
linked list. The following operations can be carried out in a linked list:
1. Insertion at beginning
2. Insertion at middle
3. Insertion at end
4. Deletion at beginning
5. Deletion at middle
6. Deletion at end
The following section explains each of the above operations in detail. Each
algorithm is followed by a figure, which exemplifies the procedure explained in
the example.
16.2 OPERATIONS
A linked list can be used in various applications. However, to be able to use
them, one must be equipped with the procedures to insert and delete elements at
the beginning, at the end and at the specified position. The following discussion
throws light on the requisite procedures.
Insertion at beginning
In order to insert a node at the beginning, a new node (say TEMP) is created and
the data is inserted in the DATA part of the TEMP. Now, the NEXT of TEMP
would point to the HEAD of the linked list and finally, TEMP becomes the new
HEAD. The insert_beg(VALUE) presents the algorithm to insert a node at the
beginning and Figure 16.2 presents the implementation of this process.
Algorithm
insert_beg (VALUE)
{
//Create a node called TEMP.
TEMP = node()
//Now put the given value (VALUE) in the data part of TEMP.
TEMP->DATA = VALUE
//Set the LINK part of TEMP to FIRST.
TEMP->LINK = FIRST
Rename TEMP to FIRST.
}
The algorithm has been explained in the following figure (Fig. 16.2).
FIGURE 16.2 Inserting a node at the beginning
In order to insert a node after a particular node, a node pointer called PTR is
created. Initially PTR points to the HEAD. The LINK of PTR becomes the
LINK of the current node until the current node has the value after which we
intend to insert the new node. A new node called TEMP is created and VALUE
is inserted in its DATA part. Let the LINK of PTR be PTR1. Finally, the LINK of
PTR will point to TEMP and the LINK of TEMP will point to the PTR1. The
insert_middle(VAL, VALUE) presents the algorithm to insert a node after a
given node (having data VAL) and Figure 16.3 shows an example of this
process.
Algorithm
The algorithm has been explained in the following figure (Figure 16.3).
FIGURE 16.3 Insertion after a particular position
In order to insert a node at the end, a node pointer called PTR is created. Initially
PTR points to the HEAD. The LINK of PTR becomes the LINK of the current
node till the current node’s LINK is NULL. A new node called TEMP is created
and VALUE is inserted in its data part. Finally, the LINK of PTR will point to
TEMP and the LINK of TEMP will be NULL. The insert_end(VALUE) presents
the algorithm to insert a node after a given node and Figure 16.4 shows an
example of this process.
Algorithm
FIGURE 16.4 Insertion at the end
In order to delete a node from the beginning, the LINK of HEAD becomes the
new HEAD. Also, if required, the DATA of HEAD may be stored in some
memory location. The del_beg() presents the algorithm to delete the first node
of the linked list and Figure 16.5 shows an example of this process.
Algorithm
Delete_beg()
{
Set backup = HEAD->DATA
Rename HEAD->LINK as HEAD
}
Algorithm
In order to delete a node from the end, the following procedure is employed. A
node pointer PTR is created, which initially points to the HEAD. The LINK of
PTR becomes PTR->LINK till the PTR->LINK->LINK becomes NULL.
Finally, the LINK of PTR will point to NULL. If required the DATA of PTR-
>LINK can be saved. The del_end() presents the algorithm to accomplish the
above task and Figure 16.7 shows an example of this process.
Algorithm
FIGURE 16.7 Deleting a node from the end
Code: The algorithm of each operation has already been discussed. The
following code presents the Python implementation of the above code. Note that
the code has 6 functions (in the linked list class), each implementing the
corresponding algorithm.
Output
List
List
2
List
5 2
List
7 5 2
List
7 5 8 2
List
7 5 8 2 9
Length 5
List
5 8 2 9
List
5 8 9
List
5 8
List
Cannot delete
>>>
The above linked list is referred to as a singly linked list. There are other variants
as well, such as a doubly linked list. In a doubly linked list, each node has two
pointers PREVIOUS and NEXT along with the data part. The PREVIOUS
connects the node to the previous node and the NEXT connects the node to the
next node. Also the NEXT of the last node is NULL, indicating that this node is
not connected to any other node. The first node of a doubly linked list is also
given a special name.
For example, if A and B are connected as shown in the figure then the “NEXT”
of A is address of B and the “PREVIOUS” of B is the address of A (Figure
16.8).
FIGURE 16.8 Node of a doubly linked list are connected via two pointers: NEXT and PREV
1. Insertion at beginning
2. Insertion at middle
3. Insertion at end
4. Deletion at beginning
5. Deletion at middle
6. Deletion at end
Code
Output
>>>
========== RUN C:/Python/Data Structures/Queue.py ==========
Queue
Queue
2
Queue
2 5
Queue
2 5 7
Queue
5 7
Queue
7
>>>
16.5 CONCLUSION
A linked list contains connected nodes. Each node has two parts: the DATA part
and the LINK part. The DATA part may contain a basic or a complex data
structure. The LINK part contains the address of the next node. The last node,
therefore, has NULL in its LINK part. One can have linked lists of integers,
float, char, or even strings. The reader is expected to explore the linked lists of
user defined data structures and use them in solving problems. Problems related
to polynomial addition and subtraction have been discussed in the references
given at the end of the book. The reader is expected to go through the theory and
implement the operations using a linked list. Moreover, the algorithms of a
doubly and a circular linked list may be developed in a way similar to that of a
singly linked list given in the chapter. Having studied linked lists and arrays the
reader is also encouraged to find the advantages of using linked lists and also its
disadvantages (for example extra overhead, pointers, etc.). The most important
attribute of a linked list is its flexibility.
GLOSSARY
Node: A node is the basic unit of linked list. It has two parts: data and link. The
link points to the next node.
POINTS TO REMEMBER
The link of the last node of a linked is NULL
Complexities of operations, discussed in the chapter
Operation Complexity
Insertion at the beginning O(1)
Insertion at end O(n)
Insertion in the middle O(n)
O(1)
Deletion from the beginning
Deletion from the end O(n)
EXERCISES
10. When wasted space is concerned (pointers etc.), what is space complexity in
a linked list?
(a) O(1)
(b) O(n)
(c) O(n2)
(d) None of the above
11. When wasted space is concerned (pointers etc.), what is space complexity in
an array?
(a) O(1)
(b) O(n)
(c) O(n2)
(d) None of the above
12. When wasted space is concerned (pointers etc.), what is space complexity in
a dynamic table?
(a) O(1)
(b) O(n)
(c) O(n2)
(d) None of the above
13. Which is better in terms of time complexity for the operation that adds an
element in the middle?
(a) Array
(b) Linked List
(c) Both
(d) None of the above
14. Which is better in terms of time complexity for the operation that adds an
element in the middle?
(a) Array
(b) Linked List
(c) Both
(d) None of the above
THEORY
1. What is a linked list? Write an algorithm for the following
(a) Inserting an element at the beginning of a linked list
(b) Inserting an element at the end of a linked list
(c) Inserting an element after a given element of a linked list
(d) Deleting an element from the beginning of a linked list
(e) Deleting an element from the end of a linked list
(f) Deleting an element after a given element from a linked list
PROGRAMMING
Implement Q1, Q3, & Q5-Q10 of the above section.
EXPLORE
The chapter gives an introduction to linked lists. The reader is expected to read
and implement the algorithms of doubly linked lists and circular linked lists.
17.1 INTRODUCTION
Consider the hierarchical structure of your college. The college should have the
head under which the deans of various faculties work. The faculty is made up of
various departments, which have their respective heads. These heads take the
help of the chairs of various committees. This heretical structure can be viewed
as a tree with the head of the institute at the Oth level, the deans at the first level,
and the heads of the departments at the second level and so on.
Let us take another example, that of tic-tac-toe. At the beginning, the first player
may fill any of the 9 cells in a 3 × 3 grid. After this move the second user may
fill the other symbol in any of the remaining squares, keeping in mind the
constraints. The game can thus be represented as a tree. Likewise, a tournament
can be represented using a tournament tree.
In the case of machine learning, the decision trees help us to learn. The heap, a
type of tree, helps us to find the maximum or minimum in O(1) time.
There are numerous applications of trees and graphs. This chapter introduces
trees and graphs and concentrates on a specific type of tree called the binary
search tree, which is important in searching and is the basis of many other
important topics.
The chapter has been organized as follows. The second section presents the
definition, terminology, and representation of trees and graphs. The third section
discusses the binary search trees (BST) and the last section concludes the
chapter.
FIGURE 17.1 A graph G = (V, E), V = {A, B, C, D} and E= {(A, B), (A, D), (B, C), (B, D), (C, D)}
The edges of a graph may have weights, in which case the graph is referred to as
a weighted graph. A graph may be represented using a matrix or a linked list.
The element at the ith row and the jth column in the matrix will be 1, if an edge
exists between the vertex i and the vertex j, otherwise the element will be zero.
In the case of a weighted graph, these elements may represent the weights of the
corresponding edges. The matrix corresponding to the graph of Figure 17.1 is as
follows:
Note that the element at the first row and the second column is 1, as there is an
edge between the first vertex (A) and the second vertex (B). Likewise there is an
edge between A and D, hence the element at the first row and fourth column is 1.
Graphs may also be represented using a set of linked lists, in which each linked
list will point to the vertices connected to the corresponding vertex. The linked
list representation of the graph of Figure 17.1 is as follows (Figure 17.2). Note
that the list of A contains B and D as A is connected to B and D. Likewise, the
list of B contains A, C, and D.
FIGURE 17.2 The linked list representation of the graph presented in Figure 17.1
Graph is one of the most important data structures. This data structure has
applications in a wide variety of tasks like finding the shortest paths, ranking of
web pages, etc. As a matter of fact, there is a dedicated subject on graph
algorithms.
Trees can be classified on the basis of the number of children of a node. If each
node of a tree has a maximum of two children, it is called a binary tree. If each
node of a tree has two children except for the last level at which a node has no
child, it is called a complete binary tree. Figure 17.5 shows a complete binary
tree. The root of a tree is always at level 0, the children of the root at level 1 and
so on. The tree of Figure 17.4 is a binary tree, as each node has 0, 1, or 2
children. Note that the node A is at level 0, the nodes B and C are at level 1, and
the nodes D, E, and F are at level 2.
FIGURE 17.5 Complete binary tree; each node has 2 children except for the nodes at the last
level, at which each node has 0 children
The number of nodes in a complete binary tree having two levels is 3, that
having three levels is 7 and that having four levels is 15. A complete binary tree
having n levels has 2n nodes. In the tree shown in Figure 17.5, A is the root of
the tree as it is at level 0. The nodes B and C are siblings, as they have the same
parent (A). Also, the nodes D and E are siblings and so are F and G. The nodes
D, E, F, and G are the leaves, as they have no children. The following table
(Table 17.1) presents the terminology of a tree.
FIGURE 17.6 Calculation of index for the array representation of a binary search tree
For example, in the above tree (Figure 17.6) the root would be stored at the 0th
index.
The left child of the root (B) would be stored at the index, given by the
formula
2 × n + 1 = 2 × 0 + 1 = 1
The right child of the root would be stored at the index, given by the
formula
2 × n + 2 = 2 × 0 + 2 = 2
That is B would be stored at the 1st index and C at the 2nd index
Likewise the left child of C would be stored at the index, given by the
formula
2 × n + 1 = 2 × 2 + 1 = 5
The left child of D would be stored at the 11th index and the right child would be
stored at the 12th index. Finally, the left and the right child of F would be stored
at the 25rd and the 26th index. The array representation of the tree of Figure 17.6
is therefore as follows:
As is evident from the above array, this representation suffers from wastage of
space. That is a lot of space is wasted if the given tree is not a completely
balanced tree. Note that in the case of a completely balanced tree, no space
would be wasted in the array representation.
There is another way in which a binary tree can be stored, which is by using a
doubly linked list. In the representation, a node’s left child’s address is stored at
the previous pointer and its right child’s address is stored at the next pointer. The
following figure (Figure 17.7) shows the linked list representation of the tree in
Figure 17.6.
FIGURE 17.7 Doubly linked list representation of a binary tree
In the in-order traversal, the root of a tree is given as an input to the algorithm.
The algorithm works as follows. The left child of the root is given as the input to
the same algorithm (recursion). This is followed by the processing of the root,
following which the right child of the root is given as an input to the same
algorithm (recursion). The algorithm has been presented as follows. The
implementation has been presented in the next section. Though there is a
corresponding non-recursive procedure to accomplish the task, it has not been
discussed in this chapter. The reader may refer to the links at the end of this book
for a more detailed study.
In the pre-order traversal, the root of a tree is given as an input to the algorithm.
The algorithm works as follows. The data of the root is processed first. This is
followed by the output obtained by giving the left child of the root as an input to
the same algorithm (recursion), following which the right child of the root is
given as an input to the same algorithm (recursion). The algorithm has been
presented as follows. The implementation has been presented in the next section.
Though there is a corresponding non-recursive procedure to accomplish the task,
it has not been discussed in the chapter. The reader should refer to the links at
the end of this book for a more detailed study.
In the post-order traversal, the root of a tree is given as an input to the algorithm.
The algorithm works as follows. The output obtained by giving the left child of
the root to the algorithm itself is followed by the output obtained by giving the
right child of the root as an input to the same algorithm (recursion) after which
the root is processed. The algorithm has been presented as follows. The
implementation has been presented in the next section. Though there is a
corresponding non-recursive procedure to accomplish the task, it has not been
discussed in this chapter.
17.3 BINARY SEARCH TREE
One of the advantages of trees is that they help in efficient searches. One of the
variants of binary tree called binary search tree helps to find an element in O(log
n) time (average case). A binary search tree is a binary tree in which each node
satisfies the following property:
The tree shown in Figure 17.8 is a binary search tree, whereas that shown in
Figure 17.9 is not.
FIGURE 17.8 An example of a binary search tree; note that each node’s left child has value less
than the value in the data part and its right child has data greater than the node’s data
FIGURE 17.9 An example of a tree which is not a binary search tree, note that right child of node
having data 10 is less than 10
Solution: The process has been depicted in Figure 17.11 (a) to 17.11 (d). The
reader is expected to follow the steps and map them to those given in the
algorithm.
FIGURE 17.11(a) The search begins at the root. Since the value to be searched is greater than
that at root, the right sub tree is searched
FIGURE 17.11(b) The root of the right sub tree is 40. Since the value to be searched (47) is
greater than that at root, the right sub tree of this node is searched
FIGURE 17.11(c) The root of the right sub tree is 51. Since the value to be searched (47) is less
than that at ptr, the left is searched
Illustration 17.2: Write a program to insert the value entered by the user in the
binary search tree.
Program
Output
>>>
============ RUN C:\Python\Data Structure\BST.py
============
Tree :
10
Tree :
5 10 20
Tree :
1 2 5 10 15 17 20
>>>
17.3.2 Traversal
As stated in the previous section, a binary tree can be traversed in three ways:
In-order, pre-order, and post-order traversal. The following illustration
implements in-order, pre-order, and post-order traversal of a binary search tree.
Illustration 17.3: Write a program to implement pre-order, post-order, and in-
order traversal of a binary search tree.
Program
Output
>>>
====== RUN C:\Python\Data Structure\Tree Traversal.py ======
In-order Traversal of the BST :
1 2 5 10 15 17 20
Pre-order Traversal of the BST :
10 5 2 1 20 15 17
Post-order Traversal of the BST :
1 2 5 17 15 20 10
>>>
Illustration 17.4: Write a program to find the maximum and the minimum
element from a binary search tree.
Program
Output
>>>
========== RUN C:\Python\Data Structure\BST max.py
==========
Maximum : 20
Minimum : 1
>>>
17.4 CONCLUSION
The chapter introduces one of the most important data structures called a tree.
Since the set of trees is a subset of graphs, the definition and representation of
graphs have also been included in the chapter. Moreover, the programs given in
the chapter use linked list representations of a tree as the array based
implementation becomes inefficient in terms of space if the tree is not a
completely balanced tree. Trees can be traversed in variety of ways. The in-
order, post-order, and the pre-order traversal have been described in the chapter.
One of the most important trees called binary search trees has been introduced in
the chapter. The algorithm and the corresponding program for searching an
element in a binary search tree and insertion have also been included and
exemplified. The reader is expected to visit the links given at the end of the
chapter and explore the algorithm for deleting a node from a binary search tree.
The appendix of this book discusses some of the important graph algorithms
also. Moreover, this is just a beginning of the topic; explore trees and dive into
the exciting world of problem solving through trees.
GLOSSARY
Graph: A graph is a set (V, E), where V is a finite, non-empty set of vertices.
The set E is a set consisting of tuples (x, y), where x and y belong to the set V.
Tree: A tree is a non-linear data structure. It is basically a graph which does not
form any cycle and which does not have isolated edges or vertices.
Parent: A node from which the given node has been derived.
Root: A node which does not have a parent is called the root.
Degree of a tree: The degree of a tree is the maximum degree of any node of the
tree.
Level of a tree: The root of a tree is at level 0, the children of root are at level 1
and so on.
Binary Search Tree: It is a binary tree in which each node satisfies the
following property:
POINTS TO REMEMBER
The complexity of insertion in a binary search tree is O (log n), if the tree is
balanced.
A tree can be represented using arrays. In this representation, the root is
placed at the 0th index, the right child of a node at the nth index is at (2n +
2)th index and the left child at the (2n + 1)th index.
The linked list representation of a tree is efficient in terms of space.
From a binary search tree, the complexity of finding the
maximum/minimum element is O(log n), if the tree is balanced.
From a binary search tree, the complexity of finding the
maximum/minimum element is O(log n), if the tree is skewed.
EXERCISES
2. If G is the set of all the graphs, T is the set of all the trees and BST is the set
of all the binary search trees, then which of the following is false?
(a) G ⊆ T
(b) T ⊆ G
(c) BST ⊆ T
(d) BST ⊆ G
NUMERICAL
1. Create a BST out of the following list of numbers
(a) 2, 23, 14, 29, 35, 28, 19, 1, 3, 7, 16, 15
(b) 1, 2, 3, 4, 5, 6, 7
(c) 10, 8, 6, 4, 2, 1
(d) 10, 15, 18, 17, 16, 19, 14, 21
(e) 1, 2, 3, 4, 10, 9, 8, 7
4. The list (b) (Q1) is a sequence; find the nth element of the sequence and the
complexity to insert the nth element
9. In Q1, use the in-order and post-order traversal of (a) to recreate the tree.
10. In Q1, use the in-order and pre-order traversal of (b) to recreate the tree.
14. Write the level order traversal of the tree in Figure 17.12.
15. Insert the following in the tree in Figure 17.12 and show the new tree in
each step.
(a) 2
(b) 5
(c) 32
(d) 31
(e) 29
PROGRAMMING
1. Write a program to create a binary search tree from a list of numbers entered
by the user.
4. Write a program to find the maximum element from a binary search tree.
5. Write a program to find the minimum element from a binary search tree.
6. Write a program to find the second maximum element from a given binary
search tree.
10. Write a program to find the parent of an element from a binary tree.
11. Write a program to find all ancestors of a given element of a binary search
tree.
12. Write a program to find all children of a given node of a binary tree.
14. Write a program to find the rightmost child of the left sub tree of a node in a
given binary tree.
15. Write a program to find the leftmost child of the right sub tree of a node in a
given binary tree.
CHAPTER
18
INTRODUCTION TO NUMPY
After reading this chapter, the reader will be able to
• Understand the downside of Dynamic Typing
• Understand the importance of NumPy
• Create unidimensional and multi-dimensional arrays
• Understand broadcasting
• Understand the importance and creation of structured arrays
18.1 INTRODUCTION
One of the most important features of Python is dynamic typing. In C, the
programmer declares the type of variable and then starts working on it. Though
some amount of typecasting is possible, in general one cannot change the type of
the variable in the program. For example if the programmer declares a variable,
say num, of integer type, and assigns some value to it, he cannot assign a string
(say) to it.
int num;
num=5;
printf("%d", num);
num="Harsh";//error
However, in the case of Python, one needs not declare the type of variable. For
example, in the following code, 5 is assigned to num and the value of num is
printed. In the succeeding statements the string "Harsh" is assigned to num and
the value stored in num is printed. Note that the code executes just fine.
num = 5
print( num )
num = 'Harsh'
print( num )
This is due to dynamic typing, which makes Python stand apart from its other
counterparts. However, this comes at a cost. Each time the variable is assigned a
value the operations that can be applied to that variable must be elucidated,
which takes time. If in a particular situation the type of a variable would not
change, there is hardly any need for such maneuveration. This is also relevant
for procedures which deal with numbers and scientific and statistical
calculations. In such situations, the codes can be made efficient by casting them
to defined types and manipulating them. This chapter throws light on a package
which comes to our rescue in such situations. The package is NumPy.
The chapter has been organized as follows. The second section introduces
NumPy and discusses the creation of a basic array. The section also throws light
on the data types provided by the package. The third section discusses some of
the standard functions for generating sequences. The fourth section discusses
some important aggregate functions. The concept of broadcasting has been
introduced in the fifth section. The sixth section discusses structured arrays and
the last section concludes the chapter.
The ndarray is the most important object in NumPy, as it helps to create an array.
These arrays are zero based indexed. The elements of the array are assigned
consecutive memory locations. These elements are then arranged in the row
major style (as in the case of C) or column major style (as in the case of
FORTRAN). In Python a basic array can be created using the numpy.array
function. The function takes the following arguments:
In order to understand the concept, let us have a look at some simple examples.
In the code that follows, the NumPy package is imported as 'np'. The array
function of np is then used to create an array ([7, 14, 21, 28, 35]). Finally, the
value of the array1 is displayed:
>>>import numpy as np
>>>array1 = np.array([7, 14, 21, 28, 35])
>>>array1
array([ 7, 14, 21, 28, 35])
Let us have a look at another example. In the following code, the NumPy
package is imported as 'np'. The array function of np is then used to create a
two dimensional array ([1, 2, 3], [4, 5, 6], [7, 8, 9]). That is the first row
of the array is [1, 2, 3]; the second row is [4, 5, 6] and the third row is [7, 8,
9]. Finally, the value of the array2 variable is displayed:
>>>array2=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>>array2
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
An array of string type can be created by specifying the datatype (dtype = str) in
the array function of np. The procedure has been depicted in the following
snippet:
>>>array2=np.array([[1,2,3],[4,5,6],[7,8,9]], dtype=str)
>>>array2
array([['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9']],
dtype='<U1')
One of the most obvious questions is why the need to use these arrays in place of
those provided by Python? The first reason is the wide variety of data types
provided by NumPy. The variety of data types provided by the package makes
the task at hand easy.
bool_: Boolean
int_: default integer type
intc: Same as that of ‘C’
NumPy also provides int8, int16, int32, and int64 data types. The first (int8)
uses 8 bits and hence can store (-27) to (27-1) (that is -128 to +127). int16
takes 16 bits and hence can store values from -32,768 to +32,767. Likewise
int32 and int64 take 32 and 64 bits. The corresponding unsigned integers are
unit8, uint16, uint32, and uint64. The difference between int and uint is that
in the former, one bit is reserved for sign and in the latter all the bits are used for
storing the numbers, and hence the unsigned integers can store larger values. For
example unit8 can store values from 0 to 255. The data types for floating point
numbers are as follow:
float_
float16: It has 10 bit mantissa
float32: It has 23 bit mantissa
flaot64: It has 52 bit mantissa
Type of data
Size
Order
The shape and data type in case of a subarray
18.3.1 arange()
The arange function helps to print a sequence, having some initial value
(start), some final value (stop), the difference between the consecutive terms
(step), and the datatype (dtype). The syntax of the function is as follows. The
description of each of the parameters follows:
The above function has been exemplified in the following code which generates
an arithmetic progression having first term 3, the last term 23 (less than 25), and
the difference between the two consecutive terms 2. The data type of the
elements is 'int'.
>>a=np.arange(3,25,2, int)
>>a
array([3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23])
arange can also take a single argument. Writing np.arange(6) will generate a
sequence having first value 0, the difference between the consecutive terms as 1,
and the last term 5, that is:
>>b=np.arange(6)
>>b
array([0, 1, 2, 3, 4, 5)]
In the arange function one can also specify the data type along with the above,
in order to change the default data type of the elements.
>>c=np.arange(6, dtype=float)
>>c
array([0., 1., 2., 3., 4., 5.])
18.3.2 linspace()
The linspace function divides the given range into a specified number of
segregations and returns the sequence so formed. The function takes the
following parameters:
Example: In the sequence generated by the following code the first number of
the sequence is 1 and the last value is 27. The number of elements in the
sequence is 11.
>>d=np.linspace(11, 227, 11)
>>d
array([11., 12.6, 14.2, 15.8, 17.4, 19., 20.6, 22.2, 23.8,
25.4, 27.])
If the value of the “endpoint” argument is false, the last value (in this case, 27) is
not included.
>>e=np.linspace(11, 227, 11, endpoint=False)
>>e
array([11., 12.45454545, 13.90909091, 15.36363636,
16.01010102, 18.27272727, 19.72727273, 21.10101010,
22.63636364, 24.09090909, 25.54545455])
The value of the step can be viewed by assigning “True” to the retstep;
argument. For example, in the sequence generated by dividing the range 11-26 in
12 parts, the gap (the last argument of the result) is 1.45454545454546.
>>f=np.linspace(11, 227, 11, endpoint=False, retstep=True)
>>f
(array([11., 12.45454545, 13.90909091, 15.36363636,
16.01010102, 18.27272727, 19.72727273, 21.10101010,
22.63636364, 24.09090909, 25.54545455]), 1.4545454545454546)
18.3.3 logspace()
The logspace function generates a sequence which is equally spaced in the
logspace. That is the elements of the sequence will be between basestart and
basestop “,” where the value of the base is provided in the argument. The default
value of base is 10. The dtype signifies the data type of the elements. Like in the
case of the previous function, endpoint= False would exclude basestop NumPy.
numpy.sum This finds the sum of the elements of the argument (e.g. a list
or an array)
numpy.prod This finds the product of the elements of the argument (e.g. a
list or an array)
numpy.mean This finds the mean of the elements of the argument (e.g. a
list or an array)
numpy.std This finds the standard deviation of the elements of the
argument
numpy.var This finds the variance of the elements of the argument
numpy.max This finds the maximum element of the argument. In the case
of a list or a 1D array, the maximum element will be displayed. However, in
the case of a 2D array the axis along which the maximum element is desired
can also be mentioned. Here, axis=0 indicates columns and axis=1 indicates
rows.
numpy.min This finds the minimum element of the argument. In the case of
a list or a 1D array, the minimum element will be displayed. However, in
the case of a 2D array the axis along which the minimum element is desired
can also be mentioned. Here, axis=0 indicates columns and axis=1 indicates
rows.
numpy.argmin This finds the position (index) of the maximum element
numpy.argmax This finds the position of the minimum element
numpy.median This finds the median of the elements of the argument
numpy.percentile This finds the percentile of the elements of the argument.
The percentile (25 etc. ) is the second argument.
numpy.any This finds if any element of the given argument is there
numpy.all This finds if all the arguments of the given argument are there
Output
Output
The data can be visualized using the matplotlib module discussed in the next
chapter. The following code plots the histogram of the above data.
plt.hist(Values1)
plt.title('Values Generated')
plt.xlabel('Values')
plt.ylabel('Number')
plt.show()
Output
Max : 0.960839776764
Index : 3
Min : 0.0795636675955
Index : 1
Average : 0.533217195093
Stad Deviation : 0.345312622379
Variance : 0.119240807174
Median : 0.653392931307
Percentile 25 : 0.180674642779
Percentile 75 : 0.884705912786
Let us now apply the above functions to solving part of a popular problem.
Travelling salesman problem is a popular problem, which finds the shortest
circuit that covers all the vertices from a given graph. There are many ways to
solve the problem. Well, most of them require large amounts of time. However, a
method that uses dynamic programming finds the reduced matrix of the given
matrix. The reduced matrix can be found as follows. First of all, the minimum
element from all the columns is found. The minimum of a column is then
subtracted from the elements of that particular column. The result of this step
will be a matrix having at least one zero in each column. Likewise the minimum
element of each row is found. This element is then subtracted from each element
of the row. The result of this step will be a matrix having at least one zero in
each row. The resultant matrix will be henceforth referred to as the reduced
matrix. In Python this task can be accomplished easily. The first part of the
process has been shown in the following snippet. The reader is expected to
repeat the task for each row as well.
Min_Indeces_Col=np.argmin(B,axis=0)
Min_Col=np.min(B,axis=0)
print(Min_Col)
print(Min_Indeces_Col)
Output:
[ 0.18067464 0.07956367 0.14794398]
[0 0 2]
print(B-Min_Col)
print(np.sum(Min_Col))
Output
18.5 BROADCASTING
If two arrays of same dimensions are added together, an element of the resultant
array is the sum of the corresponding elements of the two arrays. For example, if
Likewise, if
It may be stated here that the above result is obvious. However, Python applies
the operations element by element not only in addition or subtraction, but also in
the case of multiplication and division. The following snippet shows the results
when two row arrays are added, subtracted, multiplied, or divided. (Note that in
each case the resultant array is obtained by applying the operation in the
corresponding elements).
import numpy as np
A=np.array([1,2,3])
B=np.array([7,8,9])
Sum=A+B
Diff=A-B
Prod=A*B
Div=A/B
print("Sum\t:",Sum,"\nDifference\t:",Diff,"\nProduct\
t:",Prod,"Div\t:",Div)
Output
Sum : [ 8 10 12]
Difference : [-6 -6 -6]
Product : [ 7 16 27] Div : [ 0.14285714 0.25 0.33333333]
The above examples give expected results as the dimensions of the arrays on
which the operations were applied had appropriate dimensions. What if two
arrays of different dimensions are added together? Python has a way to deal with
such situations. This is called broadcasting. It may be stated here that
broadcasting does not always work. It works in the situations discussed as
follows. For example, if a row array (say, [1, 2, 3]) is added to a column array
(say [[7], [8], [9]]), then the following procedure is employed:
That is the row matrix is converted to a two dimensional matrix by copying the
elements of the first row to all other rows. Here the number of rows would be
equal to the number of elements in the column matrix. Likewise the column
matrix is also converted into a two dimensional matrix by copying the elements
of the column to all other columns. Here, the number of columns would be equal
to the number of elements in the row matrix. Likewise the results of subtraction,
multiplication, and division can be evaluated. The program follows:
C=B[:,np.newaxis]
C
array([[7],
[8],
[9]])
Sum=A+C
Diff=A-C
Prod=A*C
Div=A/C
print("Sum\t:\n",Sum,"\nDifference\t:\n",Diff,"\nProduct\t:\
n",Prod,"\nDiv\t:\n",Div)
Output
Sum :
[[ 8 9 10]
[ 9 10 11]
[10 11 12]]
Difference :
[[-6 -5 -4]
[-7 -6 -5]
[-8 -7 -6]]
Product :
[[ 7 14 21]
[ 8 16 24]
[ 9 18 27]]
Div :
[[ 0.14285714 0.28571429 0.42857143]
[ 0.125 0.25 0.375 ]
[ 0.11111111 0.22222222 0.33333333]]
If a row array is added to a two dimensional array, the addition is carried out by
converting the first array into a two dimensional array by copying the elements
of the row to all other rows, the number of rows being the same as that in the
second array. That is,
Likewise the subtraction, multiplication, and division can be carried out. The
following snippet shows the results of these operations:
D=[[1,2,3],[4,5,6],[7,8,9]]
Sum=D+A
Diff=D-A
Prod=D*A
Div=D/A
print("Sum\t:\n",Sum,"\nDifference\t:\n",Diff,"\nProduct\t:\
n",Prod,"Div\t:\n",Div)
Output
Sum :
[[ 2 4 6]
[ 5 7 9]
[ 8 10 12]]
Difference :
[[0 0 0]
[3 3 3]
[6 6 6]]
Product :
[[ 1 4 9]
[ 4 10 18]
[ 7 16 27]]
Div :
[[ 1. 1. 1. ]
[ 4. 2.5 2. ]
[ 7. 4. 3. ]]
If a column array is added to a two dimensional array, the addition is carried out
by converting the first array into a two dimensional array by copying the
elements of the columns to all other columns, the number of columns being the
same as that in the second array. The results of addition, subtraction,
multiplication, and division of B and D are as follows (B and D above).
D=[[1,2,3],[4,5,6],[7,8,9]]
Sum=D+B
Diff=D-B
Prod=D*B
Div=D/B
print("Sum\t:\n",Sum,"\nDifference\t:\n",Diff,"\nProduct\
t:\n",Prod,"Div\t:\n",Div)
Output
Sum :
[[ 8 10 12]
[11 13 15]
[14 16 18]]
Difference :
[[-6 -6 -6]
[-3 -3 -3]
[ 0 0 0]]
Product :
[[ 7 16 27]
[28 40 54]
[49 64 81]] Div :
[[ 0.14285714 0.25 0.33333333]
[ 0.57142857 0.625 0.66666667]
[ 1. 1. 1. ]]
If two arrays have different dimensions, the one with lesser dimensions is
padded with the one on the leading side.
If one of the arrays is either row (or column matrix) the elements of the row
(or column) are copied to all other rows (or columns) and then the operation
is applied.
If the dimensions do not match, an error is raised.
Output
[('Harsh', 100, 75500.0) ('Naved', 70, 65500.0) ('Aman', 24,
55500.0)
('Lovish', 18, 45500.0)]
Once a structured array is created, the data can be accessed in the usual way. For
example, to display the value of a particular attribute, we can simply mention the
name of the attribute in single quotes inside the square brackets.
data['name']
Output
array(['Harsh', 'Naved', 'Aman', 'Lovish'], dtype='<U10')
data['age']
array([100, 70, 24, 18])
data['salary']
array([ 75500., 65500., 55500., 45500.])
data[1]
('Naved', 70, 65500.0)
Output
'Lovish'
18.7 CONCLUSION
The NumPy package helps a programmer to deal with the multidimensional arrays
in the most sophisticated way. The package allows us to create arrays of all
types. The package provides a wide range of aggregate functions to deal with the
elements and analyze the data. Here it may be noted that unlike conventional
matrices, the elements of an array can also be operated upon in a unique fashion,
discussed in the last but one section of this chapter. The chapter also sheds light
onto the importance and usage of multidimensional arrays. The next chapter uses
the matplotlib package to visualize the data and analyze the results. The reader
is expected to go through the next chapter and deal with the problems given in
the appendix of this book.
POINTS TO REMEMBER
NumPy is a Python package, which stands for Numerical Python.
NumPy contains multidimensional array objects and the routines which
process these arrays.
The ndarray helps in creating an array. These arrays are zero based
indexed.
The elements of an array are assigned consecutive memory locations.
The elements of an array can be arranged in the row major style (as in the
case of “C”) or column major style (as in the case of Fortran).
A basic array can be created using the numpy.array function.
The linspace(), logspace() and arange() functions help to create arrays
which have specific sequences.
The structured arrays help us to create an array having a structure as its
element.
Broadcasting helps in applying arithmetic operations to arrays that have
different dimensions
Broadcasting does not always work
EXERCISES
MULTIPLE CHOICE QUESTIONS
2. NumPy is
(a) Numeric Python
(b) Numeric
(c) Number Python
(d) None of the above
7. In the above question, if diff = A–C, which of the following options is diff?
(a) [[1, –1, 2], [–5, –7, –8], [–23, –25, –26]]
(b) The arrays cannot be added
(c) [1, –7, –26]
(d) [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
10. In Python an array can have tuple as its element. Which of the following is
true with respect to this statement?
(a) Such arrays are called structured arrays
(b) An array must have a single data type
(c) This is possible in the case of lists not arrays
(d) None of the above
(b) linspace
(c) logspace
(b) Median
(c) Maximum
(d) Minimum
(b) Matplotlib
(c) Both
(d) None of the above
THEORY
1. Explain the importance of the NumPy module.
4. Explain how an array can be generated in NumPy. Explain the syntax and
usage of the following functions:
Linspace
Logspace
Arange
APPLICATIONS/ NUMERICAL
1. Ask the user to enter the value of n. Now create an array, a, containing
integers from 0 to (n-1).
2. Create another array, b, from the above array containing all the even
numbers of the original array.
3. Create an array, c, from an array containing all the odd numbers of the
original array.
4. Now add b and c and divide each element of the resultant array by 2. Check
if the result is same as a.
6. Find the mean, standard deviation, median, 25th percentile, 75th percentile of
the numbers.
8. Implement linear search. Also use the requisite method of NumPy and
compare the running time of both.
9. Sort the elements of the array. Also use the requisite method of NumPy and
compare the running time of both.
10. Create an array of 500 random numbers. Find the product of the numbers
using loops and by using the functions of numpy and compare the running
time by the two methods.
11. From the above array find the maximum element by the following methods:
(a) Using the maximum function of NumPy
(b) Using loops in O(n) time
(c) Using divide and conquer in O(log n) time
12. Create a two-dimensional array having n rows and m columns containing:
(a) All ones
(b) All zeros
(c) 1’s at the diagonal
(d) 0-(m-1) at the diagonal
(e) Random numbers
13. Create a two-dimensional array having 7 rows and 7 columns such that an
element aij (element at the ith row and the jth column) is (i+j)2.
19. From this array create an array having elements of alternate rows and
alternate columns.
(Refer to Q. 13)
20. Create another array, from the original array, having elements from the 4th
row onwards.
(Refer to Q. 13)
21. Create three arrays having the names, age, and roll numbers of students of
an institute.
22. Create a structured array having a tuple as its element, containing name, age
and roll number. Now carry out the following tasks vis-à-vis the structured
array:
(a) Display the names of all the students
(b) Display the ages of all the students
(c) Display the roll numbers of all the students
(d) Display the name of the last student
(e) Display the name of the eldest student
(f) Display the name of the youngest student
(g) Display the names and roll numbers of all the students having an age
entered by the user.
CHAPTER
19
INTRODUCTION TO MATPLOTLIB
After reading this chapter, the reader will be able to
• Understand the importance of MATPLOTLIB
• Create the plots for lines, curves, etc.
• Understand subplotting
• Create three dimensional plots using MATPLOTLIB
19.1 INTRODUCTION
In the previous chapter, the methods and procedures used to deal with the data
were discussed. The chapter introduced numpy which helps to accomplish
numerous tasks. It is important to be able to visualize the data as well.
Visualization gives an insight of the results and may help to uncover the
underlying patterns. Matplotlib is a package that helps to plot various types of
graphs and visualize the data. This chapter primarily discusses the pyplot
package of matplotlib.
The pyplot collection of the matplotlib provides a set of functions which help
programmers to perform various tasks associated with plotting. These functions
provide MATLAB like capabilities to Python programmers. pyplot provides
functions to plot a figure, create a plotting area, assign labels, etc. The pyplot
keeps an account of the current figure and the area and hence can direct the
functions to the requisite axes. The following sections discuss some of the most
important functions in pyplot and present some interesting examples.
The chapter has been organized as follows. Section 19.2 introduces basic
plotting, Section 19.3 discusses sub-plotting and Section 19.4 presents 3D plots.
The last section concludes the chapter.
19.2 THE PLOT FUNCTION
We start by plotting the values of a list. In order to generate a basic plot, a list L,
having n values (index: 0 to (n-1)), can be passed to the plot function. In the
generated plot, the x-axis will have values from 0 to (n-1) and the Y-axis will
have the values in the given list. The xlabel function associates a label with the
X-axis. The argument of the xlabel function is a string. The ylabel function
associates a label with the Y-axis. The show function displays the figure. One can
also save the figure using the savefig function. The savefig function takes two
arguments: the figure to be plotted and the dpi. In the following example, the list
L =[1, 4, 8, 10] is passed to the plot function. The string "X Axis" is passed to
the xlabel function and "Y Axis" is passed to the ylabel function. Note that in
the figure, the X axis has values from 0 to 3 (the indices of the values of the list)
and the Y axis ranges from 0 to 10 (from 0 to the maximum value of the list).
This can be changed using the axis function, which takes a list as an argument.
The function has the following arguments:
xmin
ymin
xmax
ymax
The figure is saved as a png file using the savefig function. The function takes
two arguments: the name of the figure and the dpi. Figure 19.1 shows the output
of the program.
plt.plot([1,4,8,10])
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.show()
plt.savefig("line.png",dpi=80)
FIGURE 19.1 If a list is passed to the plot function, the values are plotted against the indices of
the list
In the above example, the plot function takes one argument. However, it can also
take two arguments indicating the values of X and Y. The following example
plots y = 2x2 – 3 (Figure 19.2).
for x in [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5].
X=[-5,-4,-3,-2,-1,0,1,2,3,4,5]
Y= [2*x*x-3 for x in X]
plt.plot(X,Y)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.show()
plt.savefig("line.png",dpi=80)
FIGURE 19.2 The plot function can also take two arguments; the second argument’s values can
be generated using generators or comprehensions
One can even pass a two dimensional array (or list of lists) in plot, in which case
the first element of each row (or list) would be plotted as a separate plot and the
second as a separate plot. Figure 19.3 shows the output of the plot.
X=[[2,3,1],[4,6,3],[6,9,7],[8,10,5],[9,11,7],[10,18,12],
[11,23,14]]
X
plt.plot(X)
plt.show()
FIGURE 19.3 The plot function can take a two-dimensional array as arguments for plotting
multiple lines
The plot function can have an additional argument stating the color of the plot.
The default color is blue and it can be changed as follows. The color argument
of the plot function can be set to a particular value, say 'red' (color = 'red')in
order to generate a plot of the desired color. In the following example, the x-axis
would now span from 0 to 6 and y-axis would span from 0 to 15, owing to the
arguments of the axis function. The output of the following code would be same
as that of the first one, except for the color of the plot and the axis (Figure 19.4).
plt.plot([1,4,8,10], color='red')
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.axis([0,6,0,15])
plt.show()
plt.savefig("line.png",dpi=80)
FIGURE 19.4 The plot function can also have an argument to set the color of the plot
If one wants to plot only the points and not the lines, an additional argument “o”
can be passed to the plot function, shown as follows. Likewise, the plots
indicated by a square and a triangle can be plotted by giving “s” and “^.” The
code follows and the output of the program has been shown in Figures 19.5 and
19.6.
plt.plot([1,3,4],[7,8,3],'o')
plt.show()
FIGURE 19.5 The plot function can also plot circles using an additional “o” argument
plt.plot([1,3,4],[7,8,3],'o')
plt.plot([1,2,3,4],[2,1,3,5],'s')
plt.plot([1,5,6],[9,10,11],'^')
plt.show()
FIGURE 19.6 The plot function can also plot squares and triangles using additional “s” or “^” as
argument
The following example shows the procedure for plotting the sine and cosine
functions using Matplotlib. The plot, show, and savefig functions have
already been explained in the above examples. In the following code, the X-axis
is divided into 256 parts (from -22/7 to 22/7). The linespace function helps to
accomplish this task. The sine of the X values can be calculated using the sin
function of numpy. Likewise, the cosine can be calculated using the cosine
function. Both the plots are plotted in the same area. The output has been shown
in Figure 19.7.
from matplotlib import pyplot as plt
import numpy as np
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.sin(X), np.cos(X)
plt.plot(X,C)
plt.plot(X,S)
plt.show()
plt.savefig("SinCos.png", dpi=72)
The color of the plots can be changed by setting the color attribute to the
requisite value. The linestyle can also be set. The pyplot also provides the xlim
and ylim functions for setting the limits of the X- and the Y-axis. The ticks on
the X- and the Y-axis can be set by using the xticks and yticks functions.
These functions take a list containing the values to be displayed on the axes.
plt.figure(figsize=(8, 6), dpi=80)
plt.subplot(1, 1, 1)
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linestyle="-")
plt.plot(X, S, color="red", linestyle="-")
plt.xlim(-4.0, 4.0)
plt.xticks(np.linspace(-4, 4, 9, endpoint=True))
plt.ylim(-1.0, 1.0)
plt.yticks(np.linspace(-1, 1, 5, endpoint=True))
plt.savefig("SinCos.png", dpi=180)
plt.show()
FIGURE 19.7 The sine and cosine function in the same plot
The following code prints the plot for the log function of numpy. The only
difference in the previous and the following example is the use of the log
function of numpy in place of the sin of the cosine function. The output of the
code has been shown in Figure 19.8.
plt.figure(figsize=(8, 6), dpi=80)
plt.subplot(1, 1, 1)
X = np.linspace(0.1,2, 100, endpoint=True)
L = np.log(X)
plt.plot(X, L, color="blue", linestyle="-")
plt.xlim(0, 2)
plt.xticks(np.linspace(0, 2, 100, endpoint=True))
plt.ylim(-1.0, 1.0)
plt.yticks(np.linspace(-1, 1, 21, endpoint=True))
# Save figure using 80 dots per inch
plt.savefig("Log.png", dpi=180)
# Show result on screen
plt.show()
FIGURE 19.8 The log function
The imshow function of the matplotlib shows the image. The following
example plots the magnitude and the phase of complex number between –2π to
2π. The output of the code has been shown in Figure 19.9.
import matplotlib.pyplot as plt
x = np.linspace(-2*np.pi, 2*np.pi, 100)
xx = x + 1j * x[:, np.newaxis]
out = np.exp(xx)
plt.subplot(121)
plt.imshow(np.abs(out),extent=[-2*np.pi, 2*np.pi, -2*np. pi,
2*np.pi])
plt.title('Magnitude of exp(x)')
plt.subplot(122)
plt.imshow(np.angle(out),extent=[-2*np.pi, 2*np.pi, -2*np.
pi, 2*np.pi])
plt.title('Phase (angle) of exp(x)')
plt.show()
FIGURE 19.9 The use of implot to generate the magnitude and phase of a complex number
The plots described above are an excellent way of comparing the functions (say
x2, x3 and x4) by using the power function of numpy. The plot function has a
label argument stating the type of curve. The limits of the x-axis are set from 1
to 20 and that of y-axis is from 0 to 800. The output of the code is shown in
Figure 19.10.
x = np.linspace (0, 10, 50)
y1 = np.power(x, 2)
y2=np.power(x,3)
y3 = np.power(x, 4)
plt.plot(x, y1, label='$x^2$')
plt.plot(x, y2, label='$x^3$')
plt.plot(x, y3, label='$x^4$')
plt.xlim((1, 20))
plt.ylim((0, 800))
plt.xlabel('X Axis')
plt.ylabel('Y : Powers')
plt.title('First :$x^2$ Second:$x^3$ Third:$x^4$')
#plt.legend()
plt.savefig("powers.png",dpi=80)
plt.show()
FIGURE 19.10 The plots of x2, x3, and x4
The pyplot function can also be used to plot a histogram. The hist function can
be used to accomplish the task. The hist function has data as an argument. The
color argument of the function associates the color to the histogram. The
optional commutative argument, if True, plots a commutative histogram. The
number of bins indicates the segregations on the x-axis. The following code
exemplifies the function. The output has been shown in Figure 19.11.
data = np.random.randn(100)
f, (ax1, ax2) = plt.subplots(1,2,figsize=(6,3))
ax1.hist(data,bins=10,normed=True,color='blue')
ax2.hist(data,bins=10,normed=True,color='red',cumulative=True)
plt.savefig('histogram.png')
plt.show()
FIGURE 19.11 A histogram can be plotted using the hist function of pyplot
The imshow function plots the data passed as the argument. The matrix generated
by the random function (10 rows and 10 columns) is passed as the argument in
the imgshow function. The colorbar function of the matlpotlib is then invoked
and is finally shown. The following code exemplifies the function and the output
follows (Figure 19.12).
Img = np.random.random((10, 10))
plt.imshow(Img)
plt.colorbar()
plt.savefig('imageplot.png')
plt.show()
FIGURE 19.12 The colorbar function can be used to plot the required plots
19.3 SUBPLOTS
Suppose you want to compare the results of two different experiments. Having
two figures side by side would greatly ease the task of comparing the results. In
such situations the subplots come to our rescue. The idea is to have smaller
axes in a single figure; in fact any sort of layouts in a given figure. This task can
be accomplished in a number of ways. One of the simplest ways to use the
matplotlib.axes function in matplotlib; -this is taking advantage of the
fact that standard axes can be created using the matplotlib. axes() function.
This function can also take a list of four numbers depicting the left, bottom,
width, and height respectively. The mechanism of creating a subplot is as
follows. The first two coordinates specify the origin of the new axes, considering
the original axes to be of a unit’s length. For example in the following figure
(Figure 19.14), the origin of the subplot is (0.5, 0.5) and the axes are 40% of the
length of the original axes. The arguments of the axes function in this case would
be, therefore, (0.5, 0.5, 0.4, 0.4).
FIGURE 19.14 The axis (original) range from 0.0 to 1.0 (for both X and Y axes). The origin of the
subplot is (0.5, 0.5). The length of the axes of the subplot are 40% of that of the original axes.
The subplots can be generated manually by using the axes function as shown in
the following code. The output of the program follows (Figure 19.15).
import matplotlib.pyplot as plt
import numpy as np
axis1=plt.axes()
axis2=plt.axes([0.5,0.5,0.4,0.4])
plt.show()
FIGURE 19.15 Creating a new subplot manually, using the axes function
To divide the given plot into two plots by creating another horizontal axis (that is
dividing the graph, vertically, into two subplots), the add_axes function can be
used. The function takes four arguments in a list as shown in the following
example. The two subplots are plotted on two axes. Both the axes are created
using the add_axis function. The sin function of numpy is used to plot a sin
curve on the first axis and a cosine curve on the second axis. The values of X
(50 in number, from 0 to 10) are obtained using the linspace function. The
output of the code has been shown in Figure 19.16.
FIGURE 19.16 The first subplot has a sine curve and the second subplot shows a cosine curve
fig=plt.figure()
axis1=fig.add_axes([0.0,0.5,0.8,0.4])
axis2=fig.add_axes([0.0,0.1,0.8,0.4])
X=np.linspace(0,10,50)
axis1.plot(np.sin(X))
axis2.plot(np.cos(X))
plt.show()
The index of the subplot has been displayed in the subplot. Figures 19.17 and
19.18 show the output of the following codes.
Note that the distances between various axes of the subplots are not too much
and hence the plot is not that clean. In order to handle such saturations, the
add_subplot function can be used in the pyplot.figure to create axes. The
horizontal and vertical spaces between the various subplots can be specified
using the subplots_adjust function. The following code exemplifies the above
functions and the output follows (Figure 19.19).
fig=plt.figure()
fig.subplots_adjust(hspace=0.4, wspace=0.4)
for i in range(1,10):
axis=fig.add_subplot(3,3,i)
Y=np.sin(X+i*(np.pi/2))
axis.plot(X,Y)
plt.show()
FIGURE 19.19 Using hspace and wspace in plotting subplots
As a matter of fact, matplotlib provides functions to plot the whole grid in one
go too. The pyplot.GridSpec allows more complicated arguments for
sophisticated options. However, both these are beyond the scope of this book.
The toolkit helps the programmer to plot sophisticated figures by passing the
values of X, Y, and Z to the scatter 3D function of the pyploy.axes. The
function has two more arguments: a and cmap. The cmap argument can be set to,
say, ‘Greens’ or ‘binary’ or any other value (see the following tip). In the
following example, the Z has 200 values from 0 to 20. The sine of these values
constitute X and the square of the values of Z constitute Y. The code that follows
exemplifies the function and the output follows (Figure 19.21).
Tip
axis=plt.axes(projection='3d')
Z=np.linspace(0,20,200)
X=np.sin(Z)
Y=[z*z for z in Z]
axis.scatter3D(X, Y, Z, c=Z,cmap='Greens');
plt.show()
In the illustration that follows, the X and the Y have 20 values from -5 to 5. That
is,
Y is the same as X. Z contains the square root of the sum of squares of X and Y,
that is,
The label of the X axis can be set using the set_xlable function. Likewise, the
set_ylabel and set_zlabel function sets the labels for the Y and the Z axis.
The output of the plot has been shown in Figure 19.22.
X=np.linspace(-5,5,20)
Y=np.linspace(-5,5,20)
X,Y = np.meshgrid(X,Y)
Z=np.sqrt(X*X + Y*Y)
fig =plt.figure()
axis=plt.axes(projection='3d')
axis.contour3D(X,Y,Z,50,cmap='Greens')
axis.set_xlabel('X axis')
axis.set_ylabel('Y axis')
axis.set_zlabel('Z axis')
plt.show()
Note that the whole figure can be rotated by any angle along the XY plane and
any angle counter clockwise about the Z axis. The view_init function of the
pyplot. axes helps to accomplish this task. The function takes two arguments:
the angle about the XY plane and that (counterclockwise) about the Z axis. The
following code is same as the above except for the last but one line, which
rotates the figure. Figure 19.23 shows the output.
X=np.linspace(-5,5,20)
Y=np.linspace(-5,5,20)
X,Y = np.meshgrid(X,Y)
Z=np.sqrt(X*X + Y*Y)
fig =plt.figure()
axis=plt.axes(projection='3d')
axis.contour3D(X,Y,Z,50,cmap='Greens')
axis.set_xlabel('X axis')
axis.set_ylabel('Y axis')
axis.set_zlabel('Z axis')
axis.view_init(60,30)
plt.show()
The wireframe function helps with easy visualization of the plot. The following
illustration plots a wireframe plot of the above example. Likewise the surface
plot of the function can also be plotted using the plot_surface function. On the
basis of the above discussion, the reader is expected to decode the output of the
variants that follow (Figures 19.24 and 19.25).
FIGURE 19.24 The use of wireframe function
FIGURE 19.25 The axis.contour 3D (X,Y,Z,50,cmap=‘Greens’) function plots the above graph
Code
X=np.linspace(-5,5,20)
Y=np.linspace(-8,8,20)
X,Y = np.meshgrid(X,Y)
Z=np.sqrt(X*X + Y*Y)
fig =plt.figure()
axis=plt.axes(projection='3d')
axis.contour3D(X,Y,Z,50,cmap='Greens')
axis.set_xlabel('X axis')
axis.set_ylabel('Y axis')
axis.set_zlabel('Z axis')
axis.plot_wireframe(X, Y, Z, color='red')
#axis.view_init(60,30)
plt.show()
Code
X=np.linspace(-5,5,20)
Y=np.linspace(-8,8,20)
X,Y = np.meshgrid(X,Y)
Z=np.sqrt(X*X + Y*Y)
fig =plt.figure()
axis=plt.axes(projection='3d')
axis.contour3D(X,Y,Z,50,cmap='Greens')
axis.set_xlabel('X axis')
axis.set_ylabel('Y axis')
axis.set_zlabel('Z axis')
axis.plot_surface(X, Y, Z, rstride=1, cstride=1,
cmap='viridis', edgecolor='none')
#axis.view_init(60,30)
plt.show()
19.5 CONCLUSION
Plotting is important. It is important to be able to visualize the data to analyze
the results and discover patterns. The popularity of MATLAB is partially
attributed to its ability to present mesmerizing graphs. The same can be achieved
in Python using Matplotlib. This chapter introduces plotting using Matplotlib.
The chapter begins with the explanation of basic plots. The lines, sine curve,
cosine curves and so on can be plotted easily using the Matplotlib package.
Matplotlib allows the subplots also. This can be done manually by using the
Matplotlib.axes function. The subplot function can also be used to create
subplots. As stated earlier Matplotlib used to support only 2-D graphics. The
package now supports 3D graphics as well. This has helped the package share
the stage with MATLAB. In order to plot a 3D graph, an additional argument
'projection' is set to '3d'.
GLOSSARY
Pyplot: The pyplot collection of the matplotlib provides a set of functions
which help the programmers to perform various tasks associated with plotting.
POINTS TO REMEMBER
Visualization gives an insight of the results and may help to uncover the
underlying patterns.
A plot created using pyplot can be saved as a png file using the savefig
function.
If one wants to plot only the points and not the lines, then an additional
argument “o” can be passed to the plot function. Likewise, the plots
indicated by a square and a triangle can be plotted by giving “s” and “^”.
The color of the plots can be changed by setting the color attribute to the
requisite value.
The imshow function of the matplotlib shows the image.
The hist function can be used to accomplish the task.
In order to plot a 3 dimensional plot, the projection attribute of the subplot
function is set to "3D."
To divide the given plot into two plots by creating another horizontal axis
(that is dividing the graph, vertically, into two subplots), the add_axes
function can be used.
The horizontal and vertical spaces between the various subplots can be
specified using the subplots_adjust function.
The label of the x-axis can be set using the set_xlable function.
The wireframe function helps with easy visualization of the plot.
EXERCISES
4. X=[-5,-4,-3,-2,-1,0,1,2,3,4,5]
Y= [2*x*x-3 for x in X]
plt.plot(X,Y)
The above code would plot a
(a) Parabola
(b) Ellipse
(c) Hyperbola
(d) None of the above
8. The plot function can plot circles using which of the following arguments?
(a) o
(b) s
(c) delta
(d) None of the above
5. How is subplotting carried out in Python? Explain the splitting of axes and
the subplot function.
7. How can you change the color of the graph in Pyplot? Also explain the
importance of cmap.
8. Which package, other than pyplot, can be used to plot graphs in Python?
PROGRAMMING EXERCISE
1. Create a list having numbers in arithmetic progression. Ask the user to enter
the first term, the common difference and the number of terms of the
arithmetic progression. Plot the values using the plot function.
2. Create a list having numbers in geometric progression. Ask the user to enter
the first term, the common ratio and the number of terms of the geometric
progression. Plot the values using the plot function.
3. Create a list having numbers in harmonic progression. Ask the user to enter
the values of “a,” “d,” and the number of terms and plot the curve.
5. Now, plot the above curves in the same plot and compare them.
6. Create subplots showing the curves of questions 1, 2, and 3.
7. In the above question, adjust the horizontal and the vertical distance
between the subplots.
8. There are four types of parabolas: upward, downward, left facing, and right
facing. The equations of the parabolas having vertex at the origin are as
follows:
Upward: x2 = 4ay
Downward: x2 = – 4ay
Right facing: y2 = 4ax
Left facing: y2 = – 4ax
If the values of x range from [10, 10] and the values of y are calculated
using the appropriate equation, (you can use comprehensions to calculate
the values of y), plot the above parabolas on a single plot.
11. Plot the curve of tan θ and identify the points of discontinuity.
12. Plot an ellipse having the length of major axis = 10 and the length of minor
axis = 5.
14. Now plot 10 circles having radius 10 and center’s x coordinate varying from
0 to 10. The y coordinate of the center should be 8.
15. Plot a hyperbola. Ask the user to enter a coordinate and display the
coordinate on the plot. The program should display whether the point is
inside the curve or outside it.
20
CHAPTER
INTRODUCTION TO IMAGE
PROCESSING
After reading this chapter, the reader will be able to
• Understand the importance of image processing
• Open an image, read it into an object, and write the object in a file
• Understand the concept of clipping
• Extract statistical information from an image
• Perform rotation, translation, and scaling
20.1 INTRODUCTION
The processing of an image and its manipulation has become more important
with time. Image processing is important in not just identifying people and
objects but is used in numerous fields like medicine, mining, networks, etc. The
importance of image processing can be gauged from the fact that it is used in
magnetic resonance imaging (MRI), X-rays, ultrasound, CT (Computer
Tomography) scans, etc. In addition to the above, image processing is used in
industries for surveillance, fingerprint recognition, face recognition,
authentication, signature verification, etc. Image processing techniques are also
used in areas like weather forecasting, remote sensing and in astronomical
studies. Image processing is an involved and intricate task. Interestingly, humans
are better at recognizing faces and objects. The marvelous network of neurons
helps to recognize objects in a fraction of a second. The recognition of objects
and their classification has always fascinated the computing fraternity. As a
matter of fact the fraternity has lately been mimicking the human beings to
develop such classifiers and recognizers.
The past few decades witnessed marked growth in both hardware and software.
This was coupled with the advances in machine learning techniques. The
combination played a pivotal role in the evolution of the field. The image
processing field has since emerged as one of the most important and independent
fields.
In digital image processing images are manipulated. To begin with, one needs to
remove noise from a given image. The anti-aliasing, sharpening, and removing
blurriness are some of the important tasks that are needed to make a given image
better from our perspective (assuming we all are human beings). From the
machine’s point of view, converting the given image to binary, removing
redundant information, and reducing the sampling rate, etc., are important. So
there are two major goals of image processing: improving human perception and
improving machine perception.
In addition to the above, the machine learning techniques have been successfully
applied to identify diseases from various modalities like MRI (magnetic
resonance imaging) and PET (positron emission tomography). Scientists have
also been successful in making predictive models for the above. However, this
requires some serious image processing. The images need to be segmented and
subjected to various feature extraction techniques, etc., to carry out the above
tasks.
This chapter discusses image processing using standard functions in SciPy and
NumPy, though image processing can also be done in other ways.
The chapter has been organized as follows. Section 20.2 introduces the basics of
image manipulation in Python. The next section discusses the contour function.
Section 20.4 introduces clipping and Section 20.5 discusses basic
transformations like translation, rotation, and scaling. The last section concludes
the chapter.
20.2.2 Reading
In order to read the above image, the imread function can be used. The imread
function takes a png file as an argument and creates a two dimensional array. The
shape and the dtype of the array can be displayed. The output is, as expected,
(512, 512) and the data type is unit 8.
fromscipy import misc
ascent_array = misc.imread('ascent.png')
type(ascent_array)
print(ascent_array.shape)
print(ascent_array.dtype)
Output
(512, 512)
uint8
Summary
importnumpy as np
ascent_array.tofile('ascent.raw')
ascent_raw = np.fromfile('ascent.raw', dtype=np.uint8)
ascent_raw.shape
(262144,)
plt.imshow(a, cmap=plt.cm.jet)
plt.show()
plt.imshow(a, cmap=plt.cm.grey, vmin=30, vmax=200)
plt.show()
The axis can be removed by passing 'off' to the axis function of pyplot.
plt.axis('off')
plt.show()
As a matter of fact, the reader can see the output at various arguments of
contour and observe the differences. The following code passes (10, 20) in the
first iteration, 20, 30 in the second iteration and so on. The output is shown in
Fig. 20.5.
for i in range (1,21):
plt.subplot(5,4,i)
plt.contour(a,[10*i,10*i+10])
plt.show()
FIGURE 20.5 The plots for different values of contour
20.4 CLIPPING
A part of the image can be extracted by creating a mask and putting the values in
the region as 0. For example if one wants to extract a circular area from a given
image, the following steps must be followed. First of all a two-dimensional array
corresponding to the image is created. This is followed by creation of the mask.
Note that in the two examples that follow, the first excludes the area above the
circle (Figure 20.6) and the second excludes the area inside the circle (Figure
20.7).
FIGURE 20.6 The region outside the circular region has been excluded
Code 1
ascent1 = misc.ascent()
ascent1[100:120] = 255
lx, ly = ascent1.shape
X, Y = np.ogrid[0:lx, 0:ly]
mask = ((X - lx / 2) ** 2) + ((Y - ly / 2) ** 2) > lx * ly /
4
ascent1[mask] = 0
ascent1[range(400), range(400)] = 255
plt.imshow(ascent1)
plt.show()
Code 2
ascent1 = misc.ascent()
ascent1[100:120] = 255
lx, ly = ascent1.shape
X, Y = np.ogrid[0:lx, 0:ly]
mask = ((X - lx / 2) ** 2) +((Y - ly / 2) ** 2) < lx * ly /
4
ascent1[mask] = 0
ascent1[range(400), range(400)] = 255
plt.imshow(ascent1)
plt.show()
FIGURE 20.7 The region inside the circular region has been excluded
Output
87.4798736572
255 0
48.7744598771
Translation
Rotation
Scaling
20.6.1 Translation
Translation is the movement of a point or a curve. The operation can be
accomplished by changing the x and the y co-ordinates by a fixed amount. Here,
it may be stated that it is not necessary to change the x and the y co-ordinate by
the same value. The translation of a point is easy to comprehend. The translation
of a line has been shown in the following figure (Figure 20.8).
FIGURE 20.8 The line L is translated along a given direction. The translated line is L’
The movement of the line is shown in the above figure. Note that the shape and
size of the line remains the same and only its x and y co-ordinates would change.
That is, for each (x, y)
In the case of more than one translation, the corresponding matrices are added to
get the translation matrix. That is,
20.6.2 Rotation
Rotation is the movement of a line or a curve from a fixed point in a circular
direction by a certain angle. The fixed point is known as the pivot point and
through this pivot point, a line perpendicular to X-Y axis (in this case) is known
as axis about which the line rotates. Note that the x coordinate and the y
coordinate can be perceived as the projection of a given line along the x and the
y coordinates. That is,
x = r cos a
y = r sin a
After rotation by the angle b, the angle becomes (a + b) and hence the
projections of the final coordinates become:
y′ = r sin (a + b)
= r sin a cos b + r cos a sin b = x cos b + y sin b
x′ = r cos (a + b)
= r cos a cos b – r sin a sin b = x cos b – y sin b
To apply translation and rotation at the same time, the following transformation
is used:
The rotate function, which takes the angle as an argument, can be used to rotate
the figure. The following figures (Figure 20.9 and Figure 20.10) show the
original image and that after rotation.
When you have to rotate the same figure twice, the task can be accomplished by
rotating the figure by an angle α + β where α is the first angle and β is the
second. The premise can be proved as follows:
20.6.3 Scaling
Scaling is changing the size of the curve or a figure by changing its X and Y axis
by some factor. It’s not necessary for the factor to be the same for both the X and
the Y axis. In the formulas that follow, the scale along the X axis is sx and that
along the Y axis is sy.
In the case where translation is followed by scaling, the resultant matrix can be
crafted using the following mathematical formulation.
20.7 CONCLUSION
The chapter introduces image processing in Python. To start with image
processing, it is important to appreciate that an image can be stored as a multi-
dimensional array. It is important to be able to store an image, to create an image
from an array and to be able to save the image in a file. Also the reader must
understand the concept of transformations before applying transformations to a
given image. The underlying mathematics helps to untangle the intricacies and
helps the programmer to devise a solution in the case of challenging situations. It
is equally important to be able to clip an image and extract statistical information
from it. The chapter discusses all the above and paves the way of the application
of Python in diverse areas requiring image processing. The reader is expected to
have a look at the references given at the end of this chapter for a clearer
understanding.
GLOSSARY
Translation: Translation is the movement of a point or a curve.
Scaling: Scaling is changing the size of the curve or a figure by changing its X-
and Y- axis by a factor.
POINTS TO REMEMBER
In order to read an image from an object, the imread function can be used.
The tofile() function of the array converts the array into a raw file.
The edges of the polygon can be seen using the contour function.
A part of the image can be extracted by creating a mask and putting the
values in the region as 0.
The statistical information corresponding to a given image can be extracted
using Numpy. The max() function returns the maximum value; the min()
function returns the minimum value; the mean function returns the mean and
finally the std function returns the standard deviation.
The rotate function, which takes the angle as an argument, can be used to
rotate the figure.
When you have to rotate the same figure twice then the task can be
accomplished by rotating the figure by an angle α + β, where α is the first
angle and is the second angle.
EXERCISES
10. Which of the following can be used for plotting graphs (both 2D and 3D) in
Python?
(a) MATPLOTLIB
(b) NumPy
(c) Scipy
(d) All of the above
THEORY
1. Explain some of the applications of image processing.
4. Prove that if two translation matrices are added, the resultant matrix would
produce the same effect as individual translations.
PROGRAMMING
Write a program to read an image and carry out the following tasks.
1. Store the image in an array and extract statistical information out of it.
4. Scale the image by a factor of 2 along the x-axis and 3 along the y-axis.
USEFUL LINKS
1. http://www.scipy-lectures.org/advanced/image_processing/
MULTITHREADING IN PYTHON
A1.1 INTRODUCTION
Modern systems can run many processes simultaneously. In the case of a
multiprocessing system, various processes are allocated different memory space.
However, these processes can share some memory space for purposes like
communication. If a system has a single CPU (central processing unit), it can
distribute the CPU time between these processes. The CPU hops between these
processes and gives a slice of processing time to each process. There are many
ways to carry out this scheduling like First Come First Serve, Shortest Job First,
Round Robin, etc. Multiprocessing helps with achieving efficiency and results in
better utilization of resources. At times a single process may have some portions
that can run independently, provided that the problems like synchronization have
been handled. This gives rise to the idea of multithreading. As per the literature
“Multithreading is the ability of a computer’s operating system to run several
programs or apps at what seems to be the ‘same time’ by a single processing unit
or CPU.”
Threads can be segregated into two classes. The threads can be created by the
user or even created by a kernel. The latter are the part of the operating system.
In any case different tasks are being done by different threads, resulting in better
CPU utilization. That is, multi-threading is advantageous vis-a-vis resource
utilization. The computers with many processors can use multi-threading to full
advantage. Moreover, as explained in the above discussion, the time during
which input, etc., is processed can be judiciously used. Figure A1.2 shows the
advantages of multi-threading.
In Java, a thread is created using the thread class or the runnable interface. A
new thread is born when it begins its life cycle. This state is referred to as
“New.” When a thread is born, it becomes “Running.” That is, it becomes ready
to accomplish the task for which it was created. During the execution, there
might be a condition where it waits for some signals, perhaps IO. This state is
referred to as the “waiting state.” It may be stated here that this waiting can also
be timed. Finally, a thread is “terminated.” The states of a thread have been
presented in the following diagram (Figure A1.3).
A thread can be assigned some priority, based on which the operating system
decides which thread to execute. In Java, the minimum priority that can be
associated with a thread is 1 (MIN_PRIORITY) and the maximum can be 10
(MAX_PRIORITY). As a matter of fact we assign a higher priority to a thread
when it is more important. However, the final decision in this regards is at the
operating system’s discretion.
The following listing shows the usage of the start_new_thread function. The
function, first of all, needs to be imported from the _thread module. Then a
function, say funl is defined. This is followed by any number of invocations of
the threads, as shown. Note that the exception is caught in the function and
hence when a particular thread is invoked, the requisite exception is caught (or
the invocation leads to a normal execution).
def fun(num):
print(‘Hi there\n Number\t:’ + num)
from _thread import start_new_thread try:
start_new_thread(fun,(1,))
start_new_thread(fun,(2,))
except Exception:
print(‘Caught exception’)
The threads can be monitored using counters. A global counter can be created,
which can be incremented on each call to the start_new_thread function and
decremented when the thread exits. As stated earlier, the thread module has
been deprecated so the threading module provides various interfaces for
accomplishing different tasks. The important points regarding the creation of
threads are as follows:
The number of thread objects that are currently active are displayed by the
active_count() function.
The current thread object is returned by the current_thread() function of
the caller’s thread.
The thread identifier can be seen using the get_ident() function. As per
Python.org
“This is a nonzero integer. Its value has no direct meaning; it is intended as
a magic cookie to be used e.g. to index a dictionary of thread-specific data.
Thread identifiers may be recycled when a thread exits and another thread
is created.”
The complete list of all threads running can be viewed by the enumerate()
function. The list contains the main thread and all other threads.
The main thread can be seen using the main_thread(). In order to set the
trace for all threads settrace() can be used.
The size of the stack can be set using the stack_size function.
A thread can have its local data as well. The data specific to a thread can be
stored in an instance of the local class. An instance of the Threading.local can
be created as follows:
data = threading.local
data.x = 1
A thread in Python can be created by instantiating the Thread class. The activity
that a thread would initiate can be represented in two ways. The first is to pass
the object to the init(), that is the constructor of the thread class, in which case
other methods of the thread class should not be overridden. The other way to
initiate the activity is to override the run() method.
After creating a thread the requisite activity can be started by calling the start
method. The calling of the start() invokes the separate thread of execution.
The thread initiated would be in the live state. The is_alive() method checks
whether the thread is alive.
join()
If the join() method of another thread is invoked by a thread, the calling thread
is blacked until the thread whose call has been invoked is terminated.
name Attribute
The name attribute of a thread is used to see or change the name of a thread.
If a thread is a “daemon thread”, then the program exits if it is left with only
daemon threads. The flag can set through the daemon property. That is they can
be abruptly shunted. The main thread corresponds to the initial thread of control
in Python program. The main thread cannot be a daemon thread.
Then there are dummy threads. These threads are daemonic and are always alive.
These threads cannot be joined with any other thread.
A1.6 CONCLUSION
This appendix introduces multi-threading. The importance of threading and the
difference between a thread and a process was explained in the first section. It
has been argued that multi-threading is good, both in terms of resource
utilization and efficiency. The Python threading model is largely based on the
Java threading model. The appendix, therefore, gives a brief introduction of the
Java threading model as well. The threading class and its important methods
have been discussed so as to give an idea of how threading is implemented in
Python. The reader is requested to visit the references at the end of the book for
a detailed insight into the topic. It may also be stated here that the purpose of the
appendix is not to discuss each and every aspect of threading but to briefly
introduce it.
EXERCISES
1. What is multitasking?
2. State some conditions where multi-threading cannot be used.
3. Differentiate between a thread and a process.
4. What are the advantages of multi-threading?
5. In case of a uni processing system, what is the use of multi-threading?
6. Name three languages which support multi-threading.
7. Explain the Java threading model.
8. Explain how threads are implemented in Python.
9. Name the libraries which help to implement multi-threading in Python.
10. Name a technique via which thread safely can be implemented.
11. Which exception must be handled for a multi-threading code?
12. What is the function of the join() method?
13. All the threads are waiting for a signal. Which method would notify all of
them?
14. How is a thread stopped in Python (name the method)?
15. What are the various types of threads?
APPENDIX
B
REGULAR EXPRESSIONS
The functions studied in strings and the procedures studied in the third section of
this book helped us to search a pattern from a given text or extract it. However,
searching, finding patterns, and extracting a text are common tasks—so common
that a whole module of Python is dedicated to these tasks. The re module helps
the user to extract or search a pattern from a given text. It is a bit complex and
therefore has not been included in the main text. However, it is important and
has therefore been introduced in this appendix. The aim of this appendix is not to
cover the topic comprehensively and analyze every aspect of the topic. However,
a brief introduction paves the way of the use of the module for simple tasks.
Regular expressions are powerful and can be used to search patterns like e-mail
IDs, phone numbers etc., from a given text. Also, their use in parsing and the
development of compilers is well known.
B1.1 INTRODUCTION
Python provides the users with the re module to deal with the regular
expressions and search requisite texts. Writing a complex regular expression is
an intricate task which requires practice. However, simple expressions can be
written right away. In fact, just by reading this section!
First of all, let us consider the characters in a regular expression. The types of
characters in a regular expression are as follows:
Literal characters
Character class
Modifiers
The literals represent the class that has a single character: upper and lower case,
digits and special characters. The special characters require a backslash (/) to be
placed before the character itself.
Character class has one or more characters in square brackets. The expression
will be matched by the occurrence of any character from the class. As a matter of
fact, one can even mention a range in the class. The following symbols depict
some of the standard matches:
sitename= re.compile(r'[\w.]+@[\w.]+')
Each function takes the pos and endpos arguments indicating the beginning and
the end position to be searched in the expression. If the expression is found in
the given text, a match object(s) is returned. If the match is not found then None
is returned. Let us consider the following example:
import re
mailid=re.compile(r'[\w.]+@[\w.]+')
Having seen the basics, let us now dwell into the regular expressions with a
newer and easier perspective.
f=open ('Text1.txt')
i= 1
str=”
for line in f:
The above tasks could also be accomplished by using the existing string
functions. Now, if a little difficult task, say, that of finding all the words that
begin with a “h” followed by 4 symbols followed by a “h” are to be searched
using the re module, first of all the module needs to be imported.
Harsh
Haaah
H123h
H@12h
and so on.
Moreover, we can also specify if the character can repeat. The symbols “*” and
“+” in regular expressions indicate that in place of matching a single instance of
the given character, zero or more instances for a “*” and one or more instances
for a “+.”
Note that there is a “+” after “.” indicating that any number of symbols may be
there between a From and a @
If one wants to extract all the strings that match a regular expression, the
findall() function can be used.
If we want to extract data from a string in Python we can use the findall(). For
example to find all the email IDs from a given string the expression
'\S+@\S+.com' can be used.
list = findall('\S+@\S+.com',str)
list
would generate a list containing all the email IDs that end with a .com.
Note that \S is a non-whitespace character and \S+ indicates any number of non-
whitespace characters. The @ must follow. After the @ symbol, there can be any
number of non-whitespace characters followed by a .com.
Likewise one can craft a regular expression for finding all .edu emails and so on.
[a-zA-Z0-9]\S*@\S*[a-zA-Z]
The regular expressions can also be used to find all the expressions that follow a
particular pattern. For example, if we want to extract patterns that begin with a H
followed by a _ and then a colon followed by any number of digits, then a dot
and then any number of digits, the following re would suffice.
Sample O/P
H-ABCD-lefthanddrive: 0.1234
H-XYZT-righthanddrive: 0.1111
H-NMOP-lefthand: 0.0101
H-KLMN-righthand: 0.0001
H-AAAA-leftdrive: 0.01010
H-C DCD-rightdrive: 1010.90990
We say that we want lines that start with “H-,” followed by zero or more
characters (“.*”), followed by a colon (“:”) and then a space. After the space we
are looking for one or more characters that are either a digit (0-9) or a period
“[0-9.]+”. Note that inside the square brackets, the period matches an actual
period (i.e., it is not a wildcard between the square brackets).
Code
import re
f = open('File1.txt')
for line in f:
line = line.strip()
if re.search('ˆH-\S*: [0-9.]+', line) :
print line
The execution of the above code would throw up the string we are exactly
looking for. Actually the reason for splitting a given text into lines was to spare
the need for parsing and searching at the same time. Parentheses are special
characters in regular expressions. Adding parentheses to a regular expression
helps us to ignore while matching the string.
However, when we use findall() parentheses to indicate that we want the whole
expression to match, we are only interested in extracting a portion of the
substring that matches the regular expression.
import re
f = open('File.txt')
for line in f:
line = line.strip()
pattern = re.findall('ˆH-\S*: ([0-9.]+)', line)
if len(pattern) > 0 :
print(pattern)
['0.8475']
['0.0000']
['0.6178']
['0.0000']
['0.6961']
['0.0000']
At times we need to search the characters which are actually special symbols in a
regular expression. In such cases it must be indicated that the characters are
normal and not that with a special meaning. We can indicate that we want to
simply match a character by prefixing that character with a backslash. The
examples follow.
As stated earlier, the purpose of the appendix was to give an introduction of the
topic. Actually, using the regular expressions we can construct strings that are to
be searched/matched with some of the string in the given text.
B1.3 CONCLUSION
At times, big text needs to be searched for a particular pattern. The strings to be
searched can be of various types. For searching for a given pattern, Python
provides us with regular expressions via the re module. For example, in
searching the email IDs from a given document or in finding the names that end
with “a,” regular expressions can be used. Regular expressions, as a matter of
fact, are not just used to find patterns but can also be used to define or modify a
pattern. For example, if you are required to find “all the TV series whose names
begin with a K followed by a k” the task can be accomplished by defining the
requisite re, compiling it and then using it to find the pattern. This appendix
introduces the package and explains its use.
SYMBOLS TO REMEMBER
Some of those special characters and character sequences are as follows:
[abcde]: The example would match “a”, “b”, “c”, “d”, or “e”, but no
other characters.
\B: Matches the empty string, but not at the start or end of a
word.
EXERCISES
THEORY
1. What are regular expressions? How are they useful?
2. Are regular expressions better then string functions?
3. What is the difference between a compiled and a non-compiled regular
expression?
4. Can we use regular expressions to find patterns from a web page?
5. Name three functions used for finding a string from a given text.
PROGRAMMING
1. Take a text of around 2000 words from a news web site. From this text find
(i) The email IDs of all the people who have their mail at the Yahoo server
(ii) The phone number of people living in Jordan (the phone number starts
from 011-)
(iii) The code that begins with an “H,” has two digits after “H” and any
number of characters after the digits.
(iv) All the occurrences of the names that begin with an “H” and ends with an
“h.”
(v) “Ashish” followed by three digits from the given text.
APPENDIX
C
1. Ask the user to enter a four digit number and check whether the second digit
is one more than the third digit.
2. In the above question if the given condition is false, swap the digits at the
third and the second places and increment the digit at the units’ place by one,
if it is not 9. If the digit at the units place is 9, then do not change the digit.
3. Ask the user to enter a three digit number and find the characters
corresponding to the digits. Create a string out of these characters and find
whether any letter of this string is a capital letter.
4. Ask the user to enter his monthly salary, his house rent (or home loan), his
car, newspaper subscription, the amount he spends on food in a month. Now
find if the amount left is sufficient enough to start a 401K. Note that a 401K
can be started with even $500.
5. Ask the user to enter his total savings. If the savings are above $1,000,000,
then the person need not to pay any tax. Also this person is entitled to get a
subsidy from the Government. If the savings are above $1,000,000 but below
the above specified amount, he is liable to pay 30% of his savings as tax,
plus a surcharge of 2% on the tax. Calculate the total amount paid by the
person as this tax.
6. Ask the user to enter a three digit number and find the largest digit of the
number. Also find the sum of the digits and find if the sum of the digits is the
same as twice the largest digit.
7. Ask the user to enter the marks obtained by a student in 5 subjects. If the
person scores more than 90% in a subject he gets an A+. If the score is less
than 90% but greater than 85%, he gets an A. If the score is greater than
80%, he gets an “A-.” Likewise if the score is greater than 75%, he gets a B+
and B is awarded to a person scoring more than 70%. A person getting more
than 65% but less than 70% gets a “B-” and the one getting more than 60%
but less than 65% gets “C+.” A person getting more than 55% (and less than
60%) gets a “C” and the one getting more than 50% (and less than 55%) gets
a “C-.” Furthermore, for each grade the corresponding CGPA is as follows.
Grade cgPA
A+ 9
A 8
A– 7
B+ 6
B 5
B– 4
C+ 3
C 2
C– 1
Looping
11. Ask the user to enter a number and find the number obtained by reversing the
order of the digits.
12. Ask the user to enter a decimal number and find its binary equivalent.
13. Ask the user to enter a decimal number and find its octal equivalent.
14. Ask the user to enter a decimal number and find its hexadecimal equivalent.
15. Ask the user to enter an n-digit number and find the digit which is the
maximum amongst them.
16. Ask the user to enter any number of numbers (he must enter 0 to quit) and
find the maximum number.
17. In the above question find the minimum number.
18. Ask the user to enter n numbers and find their standard deviation and mean.
19. In the above question, find the mean deviation.
20. Write a program to generate the following pattern. (Refer to the link of
cellular automata at the end of this appendix).
Functions
A piece of data is given to you. The data has many features (columns) and the
last column states the class to which it belongs (0 or 1). Each feature’s data can
be segregated into X and Y, where X is the data that belongs to class 0 and Y is
the data that belongs to class 1. The relevance of a particular feature can be
calculated by numerous methods, one of which is the Fisher Discriminate Ratio.
The Fisher Discriminate Ratio of a feature (a column vector) is calculated
using the following formula
Where μx is the mean of the data X, μy is the mean of the data Y. The
standard deviation of X is σx and that of the Y data is σy.
Ask the user to enter the elements of two lists - feature and label.
21. Create a function, segregate, which takes the feature and label as input and
find the vectors X and Y.
22. The calculate_mean function should calculate the mean of the input vector.
23. The calculate standard_deviation function should calculate the standard
deviation of the input vector.
24. The FDR function should calculate the FDR of a feature.
25. Finally write a program that takes 2D data as input and calculate the FDR of
each feature.
The relevance of a particular feature can also be calculated by the
coefficient of correlation.
The coefficient of correlation of a feature (a column vector) is calculated
using the following formula.
26. Create a function, “segregate” which takes the feature and label as input and
find the vectors X and Y.
27. The calculate_mod function should calculate the |X| for the input vector, X.
28. The calculate_dot function should calculate X.Y.
29. The CORR function should calculate the correlation coefficient of a feature.
30. Finally write a program that takes 2D data as input and calculate the
coefficient of correlation of each feature.
31. Create a file called data and insert data from a text file containing 5 news
articles from a news site.
32. Now open the file and find the words beginning with vowels. Make 5 lists of
words beginning with each vowel.
33. Draw a histogram of the above data.
34. Make the first letter of each word capital and write the words in 5 separate
files.
35. Now, from each file find the words that end with a vowel and place the
words in 5 separate files.
36. Check which of these words begin and end with a vowel.
37. From the original file find the word which is repeated the maximum number
of times.
38. Do the above task for all the words and plot the frequency of each word in a
graph.
39. From the original file find which alphabetic character is used the maximum
number of times.
40. The reader is expected to read about Huffman code from the following link
and encode the file using Huffman code.
https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node210.html
41. From the original file, find the string that has the maximum length.
42. From the original file find the string that has “cat” as the substring.
43. From the original file find the strings which are substrings of some other
strings in the file.
44. From the original file find the strings which begin with a capital letter.
45. From the original file, find all the email IDs.
46. Find the email IDs which are on the Yahoo server.
47. Create a regular expression for the land line number in India and find all the
landline numbers from the file.
48. From the above list find the phone numbers which belong to a particular
area.
49. Find the words which are in all five articles.
50. Find the words which end with a consonant and contain a vowel.
You are required to develop software for a car wash company. The company
wants software that can store the details of a car and generate invoices. After due
deliberation, it was decided that a class called car with the following members
would be created.
Data members
(a) Registration Number
(b) Model
(c) Make
(d) Year
(e) Name of the owner
Methods
(f) getdata() : Takes data from the users
(g) putdata() : Displays data
(h) ___init() : Initializes members
(i) del : Destructor
(j) capacity :
1. Create a class called car to facilitate the development of the said software.
2. Make two instances of the class and display the data. The first instance
should display the data entered using the putdata() function and the second
should display the data assigned using the init () method.
3. Create an array of cars. Ask the user to enter the data of n cars and display
the data.
4. Find the cars whose registration numbers contain “HR51.”
5. Find the cars which are manufactured by “Maruti.”
6. Find the cars which were manufactured before 2007.
7. Find the car whose owners are named “Harsh.”
8. Find the cars whose owners names begin with “A” and are manufactured
after 2014.
9. Find the cars which have a certain type of engine (entered by the user).
10. Find the car with the maximum engine capacity.
Operator Overloading
11. Create a class called vector, which has three data members
(a) x1: The x component of the vector
(b) y1: The y component of the vector
(c) z1: The z component of the vector
The class should have a method called getdata(), which takes data from
the user; putdata(), which displays the data; init, the constructor.
12. Create a class called vectors and make two instances of vector: v1 and v2.
Display the data of the two objects.
13. The mod of a vector can be defined as follows. If then
Create an array of vectors. Ask the user to enter the data of
n vector and find the vector that has the maximum mod.
14. From the above vectors (Question 13) find the vectors which have the y
component 0.
15. Two vectors v1 and v2 can be subtracted by subtracting the corresponding
components of the two vectors. That is if and
then
Using the above concept, overload the + operator for the class.
16. Two vectors, v1 and v2, can be added by adding the corresponding
components of the two vectors. That is if and
then
Using the above concept, overload the + operator for the class.
17. The dot product of two vectors can be obtained by adding the products
obtained by multiplying the corresponding components of the two vectors.
That is, if and then
Using the above concept, overload the . operator for the class.
18. A hypothetical operation can increment can be defined as follows. If
then
Using the above concept, overload the ++ operator for the class.
19. A hypothetical operation can increment can be defined as follows. If
then
Using the above concept, overload the – – operator for the class.
20. For the vector class, overload the unary (–) operator.
Inheritance
21. Create a class called Book that has the following members.
(a) Name of the book : String
(b) Author(s) : List
(c) Year : Year of publication
(d) ISSN : String
(e) Publisher : Name of the publisher
The class should have getdata(), putdata() and init() as its methods.
22. Create two subclasses: TextBook and ReferenceBook having requisite data
members. Demonstrate the use of overriding in the above hierarchy.
23. Now create three subclasses of the TextBook class, namely SocialScience,
Engineering and Management. Each class should define its version of
getdata() and putdata(). Make instances of these subclasses and call the
method of the derived classes.
24. Create a class called XBook, which is a subclass of both TextBook and
Reference Book and demonstrate how this can lead to ambiguity.
25. Create a class called ABC and craft a class method and an instance method
of the class.
Exception Handling
26. Create a class called array which contains an array and max which is the
maximum number of elements the array can have and methods getdata()
and putdata(), which perform the requisite tasks.
27. Now create a class to raise customized exceptions. The exception should be
raised if the user enters more elopements than the max allowed.
28. If the user enters anything except for integer, an exception should be raised
and the requisite message should be displayed.
29. Now ask the user to enter two indices and divide the numbers at those
positions. If the number at the second position is 0, an exception should be
raised.
30. Ask the user to enter three indices. These three indices contain the values of
“a,” “b,” and “c” of the quadratic equation ax2 + bx + c = 0. Find the
discriminant and the roots of the equation. If the value of b2 – 4ac < 0, an
exception should be raised.
1. Implement linear search and binary search. Compare the time for searching
an element from a list of 500 random numbers.
2. Repeat the experiment for a list of 5000 integers and compare the time for
searching for an element with the two algorithms. Does increasing the
number of elements 10 times increase the running time 10 fold?
3. Implement counting sort. (Reference at the end of this appendix)
4. Implement bucket sort. (Refer to the links at the end of this appendix)
5. Implement selection sort which takes O(n log n) time.
6. Now take a list of 500 integers and compare the time for selection sort and
bucket sort.
7. Which of the two - bucket sort or counting sort - takes less time? Are they
really comparable?
8. Implement quick sort and merge sort using lists.
9. Take an array of 5000 random integers and compare the time of running of
quick sort and merge sort.
10. Can the average case complexity of quick sort be bettered?
11. Refer to the chapter on stacks and queues and implement a dynamic stack in
which a single placeholder is added when overflow occurs.
12. Refer to the chapter on stacks and queues and implement a dynamic stack in
which the number of placeholders is doubled when overflow occurs.
13. Implement a dynamic stack in which the number of placeholders is randomly
increased when overflow occurs.
14. Using a stack convert an infix expression into a postfix expression.
15. Using stacks convert an infix expression into a prefix expression.
16. Using stacks find the nth Fibonacci term.
17. Using stacks find the number obtained by reversing the order of digits for a
given number.
18. Using queues implement priority scheduling.
19. Using queues implement First Come First Serve scheduling.
20. Using queues implement First Come First Serve with time slice.
Linked List
21. Write a program to find whether a given linked list has a cycle.
22. Write a program to join two linked lists.
23. Write a program to merge two linked lists.
24. Write a program to remove duplicate elements from a given linked list.
25. Write a program to find the second maximum element from a given linked
list.
26. Write a program to find the element greater than the mean (assume that the
linked list has only integers in the data part).
27. Write a program to find the common elements from two given linked lists.
28. Write a program to find the union of elements of two linked lists.
29. Write a program to arrange the elements of a linked list in descending order.
30. Write a program to partition a linked list as per the algorithm in the following
reference.
3. An ADT consists of
(a) Declaration of data
(b) Declaration of operations
(c) Definition of data
(d) Definition of operations
4. The time complexity of inserting an element at a given position, in an array,
is
(a) O(n)
(b) O(n2)
(c) O(log n)
(d) None of the above
11. Which one of the following is the most essential attribute of an algorithm?
(a) Correctness
(b) Finiteness
(c) Definiteness
(d) All of the above
15. On which of the following data structures does NumPy rely on?
(a) Array
(b) Trees
(c) Stacks
(d) Queues
19. Given an expression: (a/(b + c)) – d. The prefix form of the expression is
____________.
21. Given an expression: a + ((b/c) × (d / f)). The prefix form of the expression
is.
22. In dynamic stacks if one of the elements is added at the time of overflow,
what would the time complexity of copy operations be?
(a) O(n)
(b) O(n2)
(c) O(log n)
(d) None of the above
23. In the dynamic stacks if the number of the elements are doubled at the time
of overflow, what would the time complexity of copy operations be?
(a) O(n) time
(b) O(n2) time
(c) O(log n) time
(d) O(n log n) time
24. When reversing a string which one of the following data structures can be
used?
(a) Array
(b) Trees
(c) Stacks
(d) Queues
25. In case of linear queue what is the initial value of FRONT and REAR?
(a) FRONT = 0, REAR = 0
(b) FRONT = 0, REAR = – 1
(c) FRONT = – 1, REAR = Not Defined
(d) FRONT = –1, REAR = –1
27. In which of the following cases value of FRONT and REAR are same?
(a) Empty queue
(b) A single element
(c) Both
(d) None of the above
28. In FIFO algorithm for scheduling in operating system which data structure is
used?
(a) Array
(b) Trees
(c) Stacks
(d) Queues
Linked List
31. In implementing stacks using linked lists which of the following operations
are used?
(a) Insertion at beginning
(b) Insertion at end
(c) Deletion from beginning
(d) Deletion from end
32. In implementing queues using linked lists which of the following operations
are used?
(a) Insertion at beginning
(b) Insertion at end
(c) Deletion at beginning
(d) Deletion at end
34. Using the above representation what would be the complexity of addition of
polynomials?
(a) O(n)
(b) O(n2)
(c) O(log n)
(d) O(n log n)
37. Which of the following strategies is the most efficient for reversing a linked
list?
(a) Recursion
(b) Creating a new linked list in the order of the elements is reverse of that
of the original linked list
(c) Creating two pointers
(d) Using a temporary array
38. What is the complexity (best case) in reversing a linked list using above
strategy?
(a) O(n)
(b) O(n2)
(c) O(log n)
(d) O(n log n)
Trees
41. What is the height of a complete binary tree which has n nodes?
(a) n
(b) n log n
(c) log n
(d)
42. What is the number of nodes of a complete binary tree which has n levels?
(a) 2n
(b) n log n
(c) n2
(d) 2n
43. What is the complexity of searching in a complete binary tree which has n
nodes?
(a) O(n)
(b) O(n2)
(c) O(log n)
(d) O(n log n)
44. What is the worst case time complexity for searching in a skewed binary
tree?
(a) O(1)
(b) O(n)
(c) O(log n)
(d) O(n log n)
45. What is the best case complexity for searching an element in a skewed tree?
(a) O(n)
(b) O(n2)
(c) O(log n)
(d) O(1)
47. The maximum number of comparisons when deleting an element from the
given tree (Figure _) is
(a) 1
(b) 2
(c) 3
(d) 4
48. Number of comparisons when inserting “36” in the given tree (Figure #) is
(a) 3
(b) 4
(c) 2
(d) None of the above
49. What is the index of “23” in the array representation of the given tree?
(a) 4
(b) 3
(c) 6
(d) 8
50. What is the maximum difference in the height of the left and the right
subtree in a balanced tree?
(a) 1
(b) 0
(c) 2
(d) None of the above
Chapter 2
1. (a)
2. (b)
3. (b)
4. (d)
5. (a)
6. (b)
7. (b)
8. (b)
9. (d)
10. (b)
11. (d)
12. (d)
13. (a)
14. (a)
15. (a)
Chapter 3
1. (a)
2. (a)
3. (b)
4. (a)
5. (b)
6. (a)
7. (a)
8. (b)
9. (b)
10. (b)
Chapter 4
1. (b)
2. (d)
3. (c)
4. (a)
5. (d)
6. (d)
7. (d)
8. (a)
9. (a)
10. (b)
Chapter 5
1. (d)
2. (d)
3. (d)
4. (c)
5. (d)
6. (a)
7. (a)
8. (a)
9. (a)
10. (d)
Chapter 6
1. (a)
2. (a)
3. (a)
4. (a)
5. (b)
6. (a)
7. (d)
8. (d)
9. (d)
10. (a)
Chapter 7
1. (c)
2. (a)
3. (d)
4. (a)
5. (b)
6. (b)
7. (b)
8. (a)
9. (a)
10. (b)
11. (c)
12. (a)
13. (b)
14. (a)
15. (b)
16. (a)
17. (a)
18. (b)
19. (c)
20. (a)
21. (b)
22. (c)
23. (b)
24. (d)
25. (d)
Chapter 8
1. (a)
2. (a)
3. (c)
4. (a)
5. (b)
6. (a)
7. (b)
8. (a)
9. (b)
10. (b)
11. (b)
12. (c)
13. (a)
14. (c)
15. (d)
16. (d)
17. (d)
18. (b)
19. (b)
20. (b)
21. (a)
22. (a)
23. (a)
24. (b)
25. (b, c)
Chapter 9
1. (b, c, d)
2. (d)
3. (a)
4. (a)
5. (a)
6. (a)
7. (a)
8. (b)
9. (a)
10. (a)
11. (b)
12. (a)
13. (d)
14. (d)
15. (a)
16. (d)
17. (b)
18. (b)
19. (b)
20. (d)
Chapter 10
1. (a)
2. (d)
3. (a)
4. (c)
5. (a)
6. (c)
7. (b)
8. (a)
9. (a)
10. (a)
11. (a)
12. (a)
13. (a)
14. (c)
15. (b)
16. (a)
17. (a)
18. (a)
19. (a)
20. (b)
Chapter 11
1. (a)
2. (c)
3. (b)
4. (b)
5. (a)
6. (b)
7. (a)
8. (c)
9. (a)
10. (b)
11. (a)
12. (a)
13. (c)
14. (b)
15. (a)
Chapter 12
1. (a)
2. (a)
3. (d)
4. (b)
5. (b)
6. (a)
7. (b)
8. (b)
9. (c)
10. (b)
11. (a)
12. (a)
Chapter 13
1. (c)
2. (b)
3. (c)
4. (d)
5. (d)
6. (d)
7. (c)
8. (c)
9. (a)
10. (a)
Chapter 14
1. (d)
2. (d)
3. (a, b)
4. (c)
5. (a)
6. (b)
7. (d)
8. (d)
9. (b)
10. (a)
11. (d)
12. (d)
Chapter 15
1. (a)
2. (a)
3. (a)
4. (a)
5. (c)
6. (b)
7. (a)
8. (a)
9. (b)
10. (a)
11. (b)
12. (b)
13. (a)
14. (c)
15. (d)
Chapter 16
1. (b)
2. (c)
3. (a)
4. (c)
5. (d)
6. (b)
7. (a)
8. (a)
9. (b)
10. (b)
11. (a)
12. (b)
13. (b)
14. (a)
15. (a)
Chapter 17
1. (a, c, d)
2. (b, c, d)
3. (b)
4. (a)
5. (d)
6. (a)
7. (b)
8. (c)
9. (b)
10. (c)
Chapter 18
1. (a)
2. (a)
3. (a)
4. (a)
5. (a)
6. (c)
7. (c)
8. (c)
9. (a)
10. (a)
11. (c)
12. (d)
13. (a, b, c, d)
14. (d)
15. (b)
Chapter 19
1. (d)
2. (a)
3. (a)
4. (a)
5. (a)
6. (a)
7. (c)
8. (b)
9. (d)
10. (a)
Chapter 20
1. (b)
2. (c)
3. (a)
4. (d)
5. (a)
6. (d)
7. (d)
8. (a)
9. (a)
10. (a)
BIBLIOGRAPHY
Python
Web resources
11. http://www.python.org
12. http://www.cheeseshop.python.org/
13. http://www.wiki.python.org
A
Abstract classes, 228–229
Abstract data types (ADT), 284, 285
active_count, 442
_add_, 242, 243
add_axes, 406
add_subplot, 409
Aggregate functions, 377–381
Algorithms, 286–287
Anaconda, 7–11
Append mode, 126
Arange, 375
Arguments, 81
Arithmetic operators, 20
Arithmetic progression, 63, 110
Array, 282, 287–292
Assertion error, 266
Assignment operator, 20
Attribute error, 266
Attributes, 164–165
B
Base class, 200, 211
Behavior, 82, 164–165
Binary search tree, 354–364
_bool_, 250, 252
Bound methods, 220–221
Branches, 47
Break, 60, 61
Broadcasting, 381–385
Bubble sort, 293
C
Callable objects, 223–224
Ceil, 21
Character class, 448
Chronology, 5–6
Class, 5, 168–169, 180–181
Class diagram, 164, 165, 208
Clipping, 427–428
close(), 125, 129
cmap, 410, 424
color, 398
colorbar, 403
Command line arguments, 131–132
Complete binary tree, 350
Complex, 19
Composition, 204–208
Comprehension, 103, 115–118
Constructor, 168, 186–187
Continue, 60
Contour function, 426
Copy sign, 21
Cosine, 400, 401
Counters, 442
Cross product, 117, 118
Curdir, 129
Current_thread, 442
D
Daemon, 444
Data hiding, 170
Data structures, 281
Datatype, 373, 375
Decimal, 21
Decision making, 35, 36
Default constructor, 168, 186
Degree of a node, 351
Degree of a tree, 351
Deletion from the beginning, 329–330
Deletion of a node after a particular node, 330–331
Deletion of a node from the end, 331–336
Derived classes, 171, 200
Destructor, 168, 190–192, 253–254
Dictionary, 103, 104, 106, 107, 115
Digital image processing, 422
Django, 2
Dummy, 270
Dynamic typing, 4, 371, 372
E
Edge, 351
Efficiency, 287
Encapsulation, 169–170
EOFError, 266
Evaluation of postfix, 314
Except, 268
Exception, 262
Expect, 263
Explicit overriding, 202
F
Fabs, 22
Factorial, 22, 61
Fibonacci series, 91, 92
File access modes, 126–127
File.closed, 130
File handling mechanism, 124–125
File.mode, 130
File.name, 130
Fileno(), 129
Finally, 273–275
Findall(), 451, 452
First In First Out (FIFO), 283, 316
Floating point error, 266
Floating point numbers, 21, 374
Floor, 22
Flush(), 130
For, 144–147
Fractions, 22
Fromfile, 424
Functional, 5
Function overloading, 172, 188
Functions, 79, 165–168
G
Garbage collection, 253
Generator, 110–114
Geometric progression, 64
get construct, 46–47
get_ident(), 442
Global data, 170
Graph, 284, 349
Graphical User Interface (GUI), 6
_gt_, 249
H
Hierarchical inheritance, 213–216
Hybrid inheritance, 219
I
_idd_, 248
Identity, 19
If, 36, 37, 42
if-elif, 41
If-elif-else ladder, 42–43
if-else, 36
Image processing, 421–422
Imgshow, 403
Immutability, 26
Implicit, 231
Implicit inheritance, 231
ImportError, 266
Imread, 423
imshow(), 423
Indentation, 37, 41, 61
IndexError, 266
Indexing, 24
Infix, 313–315
Inheritance, 171, 200–204, 208–220
Inheritance tree, 226–228
__Init__, 187
In-order, 353, 359
In-order traversal, 353, 359
Insertion after a particular no, 328
Insertion at beginning, 327
Insertion at the end, 329
Instance variable, 183
Instantiation, 181
Integer, 19, 21, 163
IntendationError, 266
Interpreted language, 17
IOERROR, 126
Isalive, 443
Isatty(), 130
__Iter__, 109
Iterable object, 109–110
Iterative, 292
Iterative algorithm, 292–296
Iterators, 107–109
J
Join, 153, 443
K
KeyError, 266
Keywords, 20
Kivy, 2
L
Last in first out, 282, 283, 285, 325
_Len_, 239, 250, 252
Level of a tree, 351
Linear search, 88
Linesep, 129
Linked list, 325
Linspace, 376
List, 27
List of lists, 71–73
Literal characters, 447
Log, 401
Logical operators, 20
Logspace, 377
Looping, 59
M
Manageability, 80
Match, 448–453
Matplotlib, 395, 401, 404, 409
Matplotlib.axes, 405
Matrices, 430
Max, 428
Maximum element, 362–364
MAX_PRIORITY, 441
Mean, 428
Merge sort, 297–298
Method overriding, 179
Methods, 220–226
Min, 428
Minimum element, 362–364
Min_priority, 441
Misc.imread, 424
Misc.imsave, 424
Mixing, 3–4
Modifiers, 447
Modular Programming, 80, 162, 172
_mul_, 242–244
Multilevel inheritance, 216–219
Multiple Inheritance, 208, 219
Multiprocessing, 439
Multi-threading, 439–440
N
Ndarray, 373
Nesting, 70, 185
New, 441
_Next_, 109
No garbage collection, 253–254
None, 19
Non linear data structures, 284, 326
Normal one, 444
NotImplementedError, 267
Numarray, 372
Numbers, 20, 21
Numeric, 372
Numerical Python, 372
NumPy, 372–374
Numpy.all, 378
Numpy.any, 378
Numpy.argmax, 377
Numpy.argmin, 377
Numpy.array, 377
Numpy.max, 377
Numpy.mean, 377
Numpy.median, 377
Numpy.min, 377
Numpy.percentile, 377
Numpy.prod, 377
Numpy.std, 377
Numpy.sum, 377
Numpy.var, 377
O
Object, 169
Object oriented, 5
Object oriented paradigm, 163, 169
Objects, 30
Open, 283
Operator overloading, 237–254
Operators, 20
Object Oriented programming, 168–172, 200
Overflow, 296, 308
OverflowError, 266
Overloading, 81
Overloading binary operators, 242–246
Overriding, 201
P
Parameter, 82
Parameterized constructor, 168, 187
Pardir, 129
Parent, 351
Pathsep, 129
Patterns, 65–70
PEP (Python Enhancement Project), 6
Plot, 396
Plot_surface, 413
Polymorphism, 171–172
Portable, 4
Postfix, 313–314
Post-order, 354
Post-order traversal, 354
Power, 62, 94
Prefix, 313
Prefix to Postfix, 315
Prefix to Prefix, 315
Pre-order, 353
Pre-order traversal, 353
Primary, 282
Primary data structures, 282
Private, 170
Procedural, 4–5
Procedural language, 4–5, 161
Procedural programming, 161, 172
Protected, 170
PSF (Python Software Foundation), 6
Public, 170, 180
Pyplot, 395, 400, 403
Pyplot.figure, 409
Pyplot.GridSpec, 409
Python, 1–2
Q
QTConsole, 11
Queue, 283
Queue using linked list, 339
R
Rabbit problem, 91–94
Raise, 263, 270
Assert, 263
Random, 202
Range (m, n), 75
Range (n), 75
Rational, 21
Readline(), 128
Readlines(), 128
Read mode, 126, 130, 134
Recursion, 91–95
RecursionError, 266
Recursive algorithms, 296–298
Relational operators, 20
Reliability, 210
Re module, 447
Retstep, 376
Reusability, 172
Reversing a String, 312–313
Robustness, 2
Root, 351
Rotation, 430–432
Run, 3
Running, 441
RuntimeError, 266
S
Savefig, 396, 399
Scaling, 432–433
Scions, 2
SciPy, 2
SciPy.misc, 423
Scope, 89–91
Script mode, 18
Search, 226–228
Secondary data structures, 282
Seek(), 128
Selection sort, 294–295
Self, 187, 224
sep, 129
Sequences, 19
Sets, 19
Set_xlable, 412
Set_ylabel, 412
Set_zlabel, 412
Show, 200–202
Simple inheritance, 211–213
Sin, 400
Slicing, 25
Sort, 132
Stack, 283
Stack using a linked list, 336–339
start(), 443
Start_new_thread, 442
Std, 428
StopIteration, 266
Strings, 23–27, 143
Structured Arrays, 386–387
_sub_, 242, 243
Subplot, 407
Subplots, 405–409
Subplots_adjust, 409
Super, 224, 225
Swapping, 29
SyntaxError, 266
SystemError, 267
T
TabError, 266
tell(), 128
Ternary operator, 44–45
Threading, 441–443
Threading.local, 443
Threads, 440, 442
tofile(), 424
Translation, 429–430
Translation rotation scaling, 422
Tree, 284, 299, 349–350
Tree traversal, 353
Truediv_, 244
Try, 264, 268
Tuple, 28–30
Type, 3
Type and run, 3
Type casting, 371
Type error, 267
Types of function, 85–88
U
Unbound local error, 267
Unbound method, 220–223
Underflow, 316
UnicodeError, 267
V
Value, 19
ValueError, 267
Variables, 19
View_init, 413
Virtual, 180
W
Waiting, 441
While, 61–64
Wildcard, 454
Wireframe, 413, 414
Write(), 128
writelines(), 128, 133
Write mode, 126
X
Xlabel, 396
Xticks, 400
Y
Yield, 110, 113
Ylabel, 396
Yticks, 400
Z
Zero division error, 267