0% found this document useful (0 votes)
16 views66 pages

CS 33

Uploaded by

tarak.college10
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views66 pages

CS 33

Uploaded by

tarak.college10
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

CS-33 Programing in Python

BCA Semester - 6

H & H B Kotak Institute of Science, Rajkot


By: Prof. Malay B. Dave
CS-33: Programming in Python

CS- 33 Programing in Python

Unit-1
Introduction to Python

Page 1 of 65
Unit – 3 Plotting using PyLab
Overview of Python
Python is a high-level, interpreted, interactive and object-oriented scripting language. Python is designed to
be highly readable. It uses English keywords frequently where as other languages use punctuation, and it has
fewer syntactical constructions than other languages.
 Python is Interpreted − Python is processed at run me by the interpreter. You do not need to
compile your program before executing it. This is similar to PERL and PHP.
 Python is Interactive − You can actually sit at a Python prompt and interact with the interpreter
directly to write your programs.
 Python is Object-Oriented − Python supports Object-Oriented style or technique of programming
that encapsulates code within objects.
 Python is a Beginner's Language − Python is a great language for the beginner-level programmers
and supports the development of a wide range of applications from simple text processing to WWW
browsers to games.

History of Python
Python was developed by Guido van Rossum in the late eighties and early nineties at the National Research
Institute for Mathematics and Computer Science in the Netherlands.

Python is derived from many other languages, including ABC, Modula-3, C, C++, Algol-68, SmallTalk, and Unix
shell and other scripting languages. Python is copyrighted. Like Perl, Python source code is now available
under the GNU General Public License (GPL). Python is now maintained by a core development team at the
institute, although Guido van Rossum still holds a vital role in directing its progress.

Release Dates of Different Versions


Version Release Data

Python 1.0 (first standard release) January 1994


Python 1.6 (Last minor version) September 5, 2000

Python 2.0 (Introduced list comprehensions) October 16, 2000


Python 2.7 (Last minor version) July 3, 2010

Python 3.0 (Emphasis on removing duplicative constructs and module) December 3, 2008
Python 3.5 (Last updated version) September 13, 2015

Python Features
A simple language which is easier to learn

Python has a very simple and elegant syntax. It's much easier to read and write Python programs compared
to other languages like: C++, Java, C#. Python makes programming fun and allows you to focus on the
solution rather than syntax. If you are a newbie, it's a great choice to start your journey with Python.

Free and open-source: You can freely use and distribute Python, even for commercial use. Not only can you
use and distribute software written in it, you can even make changes to the Python's source code. Python
has a large community constantly improving it in each iteration.

Portability: You can move Python programs from one platform to another, and run it without any changes. It
runs seamlessly on almost all platforms including Windows, Mac OS X and Linux.

Extensible and Embeddable: Suppose an application requires high performance. You can easily combine
pieces of C/C++ or other languages with Python code. This will give your application high performance as
well as scripting capabilities which other languages may not provide out of the box.

Page 2 of 65
CS-33: Programming in Python
A high-level, interpreted language: Unlike C/C++, you don't have to worry about daunting tasks like memory
management, garbage collection and so on. Likewise, when you run Python code, it automatically converts
your code to the language your computer understands. You don't need to worry about any lower-level
operations.

Large standard libraries to solve common tasks: Python has a number of standard libraries which makes life
of a programmer much easier since you don't have to write all the code yourself. For example: Need to
connect MySQL database on a Web server? You can use MySQLdb library using import MySQLdb . Standard
libraries in Python are well tested and used by hundreds of people. So you can be sure that it won't break
your application.

Object-oriented: Everything in Python is an object. Object oriented programming (OOP) helps you solve a
complex problem intuitively. With OOP, you are able to divide these complex problems into smaller sets by
creating objects.

Python Environment Setup: Python is available on a wide variety of platforms including Linux and Mac OS X.
Let's understand how to set up our Python environment.

Applications of Python

Web Applications: You can create scalable Web Apps using frameworks and CMS (Content Management
System) that are built on Python. Some of the popular platforms for creating Web Apps are: Django, Flask,
Pyramid, Plone, Django CMS. Sites like Mozilla, Reddit, Instagram and PBS are written in Python.

Scientific and Numeric Computing: There are numerous libraries available in Python for scientific and
numeric computing. There are libraries like: SciPy and NumPy that are used in general purpose computing.
And, there are specific libraries like: EarthPy for earth science, AstroPy for Astronomy and so on. Also, the
language is heavily used in machine learning, data mining and deep learning.

Creating software Prototypes: Python is slow compared to compiled languages like C++ and Java. It might
not be a good choice if resources are limited and efficiency is a must. However, Python is a great language
for creating prototypes. For example: You can use Pygame (library for creating games) to create your game's
prototype first. If you like the prototype, you can use language like C++ to create the actual game.

Good Language to Teach Programming: Python is used by many companies to teach programming to kids
and newbie. It is a good language with a lot of features and capabilities. Yet, it's one of the easiest languages
to learn because of its simple easy-to-use syntax.

Getting Python
The most up-to-date and current source code, binaries, documentation, news, etc., is available on the official
website of Python https://www.python.org/. You can download Python documentation from
https://www.python.org/doc/. The documentation is available in HTML, PDF, and PostScript formats.

Setting up PATH
Programs and other executable files can be in many directories, so operating systems provide a search path
that lists the directories that the OS searches for executables. The path is stored in an environment variable,
which is a named string maintained by the operating system. This variable contains information available to
the command shell and other programs.

The path variable is named as PATH in Unix or Path in Windows (Unix is case sensitive; Windows is not). In
Mac OS, the installer handles the path details. To invoke the Python interpreter from any particular
directory, you must add the Python directory to your path.

Python Environment Variables


Page 3 of 65
Unit – 3 Plotting using PyLab
Here are important environment variables, which can be recognized by Python –
Sr.No. Variable & Description

1 PYTHONPATH
It has a role similar to PATH. This variable tells the Python interpreter where to locate the module files imported
into a program. It should include the Python source library directory and the directories containing Python
source code. PYTHONPATH is sometimes preset by the Python installer.

2 PYTHONSTARTUP
It contains the path of an initialization file containing Python source code. It is executed every time you start the
interpreter. It is named as .pythonrc.py in Unix and it contains commands that load utilities or modify
PYTHONPATH.

3 PYTHONCASEOK
It is used in Windows to instruct Python to find the first case-insensitive match in an import statement. Set this
variable to any value to activate it.

4 PYTHONHOME
It is an alternative module search path. It is usually embedded in the PYTHONSTARTUP or PYTHONPATH
directories to make switching module libraries easy.

Integrated Development Environment


You can run Python from a Graphical User Interface (GUI) environment as well, if you have a GUI application
on your system that supports Python.
 Unix − IDLE is the very first Unix IDE for Python.
 Windows − PythonWin is the first Windows interface for Python and is an IDE with a GUI.
 Macintosh − The Macintosh version of Python along with the IDLE IDE is available from the main
website, downloadable as either MacBinary or BinHex'd files.
If you are not able to set up the environment properly, then you can take help from your system admin.
Make sure the Python environment is properly set up and working perfectly fine. Note − All the examples
given in subsequent chapters are executed with Python 2.4.3 version available on CentOS flavor of Linux. We
already have set up Python Programming environment online, so that you can execute all the available
examples online at the same time when you are learning theory. Feel free to modify any example and
execute it online.

Starting The Interpreter


After installation, the python interpreter lives in the installed directory. By default it is
/usr/local/bin/pythonX.X in Linux/Unix and C:\PythonXX in Windows, where the 'X' denotes the version
number. To invoke it from the shell or the command prompt we need to add this location in the search path.
Search path is a list of directories (locations) where the operating system searches for executables. For
example, in Windows command prompt, we can type set path=%path%;c:\python33 (python33 means
version 3.3, it might be different in your case) to add the location to path for that particular session. In Mac
OS we need not worry about this as the installer takes care about the search path.

Now there are various ways to start Python.

1. Immediate mode: Typing python in the command line will invoke the interpreter in immediate mode.
We can directly type in Python expressions and press enter to get the output. >>> is the Python prompt.
It tells us that the interpreter is ready for our input. Try typing in 1 + 1 and press enter. We get 2 as the
output. This prompt can be used as a calculator. To exit this mode type exit() or quit() and press enter.
2. Script mode: This mode is used to execute Python program written in a file. Such a file is called a script.
Scripts can be saved to disk for future use. Python scripts have the extension .py, meaning that the
Page 4 of 65
CS-33: Programming in Python
filename ends with .py. To execute this file in script mode we simply write python helloWorld.py at the
command prompt. We can use any text editing software to write a Python script file.

We just need to save it with the .py extension. But using an IDE can make our life a lot easier. IDE is a piece
of software that provides useful features like code hinting, syntax highlighting and checking, file explorers
etc. to the programmer for application development. Using an IDE can get rid of redundant tasks and
significantly decrease the time required for application development. IDLE is a graphical user interface (GUI)
that can be installed along with the Python programming language and is available from the official website.

Python Keywords
Keywords are the reserved words in Python. We cannot use a keyword as variable name, function name or
any other identifier. They are used to define the syntax and structure of the Python language. In Python,
keywords are case sensitive. There are 33 keywords in Python 3.3. This number can vary slightly in course of
time. All the keywords except True, False and None are in lowercase and they must be written as it is. The
list of all the keywords are given below.
Keywords in Python programming language

False class finally is return

None continue for lambda try

True def from nonlocal while

and del global not with

as elif if or yield

assert else import pass

break except in raise

Looking at all the keywords at once and trying to figure out what they mean might be overwhelming. If you
want to have an overview, here is the complete list of all the keywords with examples.

Python Identifiers
Identifier is the name given to entities like class, functions, variables etc. in Python. It helps differentiating
one entity from another.

Rules for writing identifiers


1. Identifiers can be a combination of letters in lowercase (a to z) or uppercase (A to Z) or digits (0 to 9)
or an underscore (_). Names like myClass, var_1 and print_this_to_screen, all are valid example.
2. An identifier cannot start with a digit. 1variable is invalid, but variable1 is perfectly fine.
3. Keywords cannot be used as identifiers.
4. We cannot use special symbols like !, @, #, $, % etc. in our identifier.
5. Identifier can be of any length.

Things to care about


Python is a case-sensitive language. This means, Variable and variable are not the same. Always name
identifiers that make sense. While, c = 10 is valid. Writing count = 10 would make more sense and it would
be easier to figure out what it does even when you look at your code after a long gap. Multiple words can be
separated using an underscore, this_is_a_long_variable. We can also use camel-case style of writing, i.e.,
capitalize every first letter of the word except the initial word without any spaces. For example:
camelCaseExample

Page 5 of 65
Unit – 3 Plotting using PyLab
Python Indentation
Most of the programming languages like C, C++, Java use braces { } to define a block of code. Python uses
indentation. A code block (body of a function, loop etc.) starts with indentation and ends with the first
unindebted line. The amount of indentation is up to you, but it must be consistent throughout that block.
Generally four whitespaces are used for indentation and is preferred over tabs. Here is an example.

for i in range(1,11):
print(i)
if i == 5:
break

The enforcement of indentation in Python makes the code look neat and clean. This results into Python
programs that look similar and consistent. Indentation can be ignored in line continuation. But it's a good
idea to always indent. It makes the code more readable.

Python Comments
Comments are very important while writing a program. It describes what's going on inside a program so that
a person looking at the source code does not have a hard time figuring it out. You might forget the key
details of the program you just wrote in a month's time. So taking time to explain these concepts in form of
comments is always fruitful. In Python, we use the hash (#) symbol to start writing a comment. It extends up
to the newline character. Comments are for programmers for better understanding of a program. Python
Interpreter ignores comment.

Multi-line comments
If we have comments that extend multiple lines, one way of doing it is to use hash (#) in the beginning of
each line. Another way of doing this is to use triple quotes, either ''' or """. These triple quotes are generally
used for multi-line strings. But they can be used as multi-line comment as well. Unless they are not
docstrings, they do not generate any extra code.

Docstring in Python
Docstring is short for documentation string. It is a string that occurs as the first statement in a module,
function, class, or method definition. We must write what a function/class does in the docstring. Triple
quotes are used while writing docstrings. For example:
def double(num):
"""Function to double the value"""
return 2*num

Docstring is available to us as the attribute __doc__ of the function. Issue the following code in shell once
you run the above program.
print(double.__doc__)
Variable
In most of the programming languages a variable is a named location used to store data in the memory. Each
variable must have a unique name called identifier. It is helpful to think of variables as container that hold
data which can be changed later throughout programming. None technically, you can suppose variable as a
bag to store books in it and those books can be replaced at any time. Note: In Python we don't assign values
to the variables, whereas Python gives the reference of the object (value) to the variable.

Constants
A constant is a type of variable whose value cannot be changed. It is helpful to think of constants as
containers that hold information which cannot be changed later. Non technically, you can think of constant
as a bag to store some books and those books cannot be replaced once placed inside the bag.

Literals
Literal is a raw data given in a variable or constant. In Python, there are various types of literals they are as
follows:

Page 6 of 65
CS-33: Programming in Python

Numeric Literals
Numeric Literals are immutable (unchangeable). Numeric literals can belong to 3 different numerical types
Integer, Float and Complex.

String literals
A string literal is a sequence of characters surrounded by quotes. We can use both single, double or triple
quotes for a string. And, a character literal is a single character surrounded by single or double quotes.

Boolean literals
A Boolean literal can have any of the two values: True or False.

Special literals
Python contains one special literal i.e. None. We use it to specify to that field that is not created.

Data types in Python


Every value in Python has a datatype. Since everything is an object in Python programming, data types are
actually classes and variables are instance (object) of these classes. There are various data types in Python.
Some of the important types are listed below.

Python List
List is an ordered sequence of items. It is one of the most used datatype in Python and is very flexible. All the
items in a list do not need to be of the same type. Declaring a list is pretty straight forward. Items separated
by commas are enclosed within brackets [ ].
a = [1, 2.2, 'python']

>>> a = [1,2,3]
>>> a[2]=4
>>> a
[1, 2, 4]

Python Tuple
Tuple is an ordered sequence of items same as list. The only difference is that tuples are immutable. Tuples
once created cannot be modified. Tuples are used to write-protect data and are usually faster than list as it
cannot change dynamically. It is defined within parentheses () where items are separated by commas.
t = (5,'program', 1+3j)

Python Strings
String is sequence of Unicode characters. We can use single quotes or double quotes to represent strings.
Multi-line strings can be denoted using triple quotes, ''' or """. Like list and tuple, slicing operator [ ] can be
used with string. Strings are immutable.

Python Set
Set is an unordered collection of unique items. Set is defined by values separated by comma inside braces { }.
Items in a set are not ordered. We can perform set operations like union, intersection on two sets. Set have
unique values. They eliminate duplicates.
>>> a = {1,2,2,3,3,3}
>>> a
{1, 2, 3}

Python Dictionary
Dictionary is an unordered collection of key-value pairs. It is generally used when we have a huge amount of
data. Dictionaries are optimized for retrieving data. We must know the key to retrieve the value. In Python,
dictionaries are defined within braces {} with each item being a pair in the form key:value. Key and value can
be of any type.
>>> d = {1:'value','key':2}
Page 7 of 65
Unit – 3 Plotting using PyLab
>>> type(d)
<class 'dict'>
We use key to retrieve the respective value. But not the other way around.

Conversion between data types


We can convert between different data types by using different type conversion functions like int(), float(),
str() etc.

Python Output Using print() function


We use the print() function to output data to the standard output device (screen). We can also output data
to a file, but this will be discussed later.

Output formatting
Sometimes we would like to format our output to make it look attractive. This can be done by using the
str.format() method. This method is visible to any string object.

Python Input
Up till now, our programs were static. The value of variables were defined or hard coded into the source
code. To allow flexibility we might want to take the input from the user. In Python, we have the input()
function to allow this. The syntax for input() is
input([prompt])

Python Import
When our program grows bigger, it is a good idea to break it into different modules.
A module is a file containing Python definitions and statements. Python modules have a filename and end
with the extension .py. Definitions inside a module can be imported to another module or the interactive
interpreter in Python. We use the import keyword to do this. For example, we can import the math module
by typing in import math.
import math
print(math.pi)
Now all the definitions inside math module are available in our scope. We can also import some specific
attributes and functions only, using the from keyword.

What are operators in python?


Operators are special symbols in Python that carry out arithmetic or logical computation. The value that the
operator operates on is called the operand.

Arithmetic operators
Arithmetic operators are used to perform mathematical operations like addition, subtraction, multiplication
etc.

Operator Meaning Example

+ Add two operands or unary plus x+y

- Subtract right operand from the left or unary minus x-y

* Multiply two operands x*y

/ Divide left operand by the right one (always results into float) x/y

x % y (remainder of
% Modulus - remainder of the division of left operand by the right
x/y)

// Floor division - division that results into whole number adjusted to the x // y

Page 8 of 65
CS-33: Programming in Python
left in the number line

** Exponent - left operand raised to the power of right x**y (x to the power y)

Comparison operators
Comparison operators are used to compare values. It either returns True or False according to the condition.

Operator Meaning Example

> Greater that - True if left operand is greater than the right x>y

< Less that - True if left operand is less than the right x<y

== Equal to - True if both operands are equal x == y

!= Not equal to - True if operands are not equal x != y

>= Greater than or equal to - True if left operand is greater than or equal to the right x >= y

<= Less than or equal to - True if left operand is less than or equal to the right x <= y

Logical operators
Logical operators are the and, or, not operators.

Operator Meaning Example

and True if both the operands are true x and y

or True if either of the operands is true x or y

not True if operand is false (complements the operand) not x

Bitwise operators
Bitwise operators act on operands as if they were string of binary digits. It operates bit by bit, hence the
name. For example, 2 is 10 in binary and 7 is 111. In the table below: Let x = 10 (0000 1010 in binary) and y =
4 (0000 0100 in binary)

Operator Meaning Example

& Bitwise AND x& y = 0 (0000 0000)

| Bitwise OR x | y = 14 (0000 1110)

~ Bitwise NOT ~x = -11 (1111 0101)

^ Bitwise XOR x ^ y = 14 (0000 1110)

>> Bitwise right shift x>> 2 = 2 (0000 0010)

<< Bitwise left shift x<< 2 = 40 (0010 1000)

Page 9 of 65
Unit – 3 Plotting using PyLab

Assignment operators
Assignment operators are used in Python to assign values to variables. a = 5 is a simple assignment operator
that assigns the value 5 on the right to the variable a on the left. There are various compound operators in
Python like a += 5 that adds to the variable and later assigns the same. It is equivalent to a = a + 5.

Operator Example Equivatent to

= x=5 x=5

+= x += 5 x=x+5

-= x -= 5 x=x-5

*= x *= 5 x=x*5

/= x /= 5 x=x/5

%= x %= 5 x=x%5

//= x //= 5 x = x // 5

**= x **= 5 x = x ** 5

&= x &= 5 x=x&5

|= x |= 5 x=x|5

^= x ^= 5 x=x^5

>>= x >>= 5 x = x >> 5

<<= x <<= 5 x = x << 5


Special operators
Python language offers some special type of operators like the identity operator or the membership
operator. They are described below with examples.

Identity operators
is and is not are the identity operators in Python. They are used to check if two values (or variables) are
located on the same part of the memory. Two variables that are equal does not imply that they are identical.

Operator Meaning Example

is True if the operands are identical (refer to the same object) x is True

is not True if the operands are not identical (do not refer to the same object) x is not True

Membership operators
in and not in are the membership operators in Python. They are used to test whether a value or variable is
found in a sequence (string, list, tuple, set and dictionary). In a dictionary we can only test for presence of
key, not the value.

Page 10 of 65
CS-33: Programming in Python

Operator Meaning Example

In True if value/variable is found in the sequence 5 in x

not in True if value/variable is not found in the sequence 5 not in x

What is a Namespace in Python?


So now that we understand what names are, we can move on to the concept of namespaces. To simply put
it, namespace is a collection of names. In Python, you can imagine a namespace as a mapping of every name,
you have defined, to corresponding objects. Different namespaces can co-exist at a given time but are
completely isolated. A namespace containing all the built-in names is created when we start the Python
interpreter and exists as long we don't exit. This is the reason that built-in functions like id(), print() etc. are
always available to us from any part of the program. Each module creates its own global namespace.

These different namespaces are isolated. Hence, the same name that may exist in different modules do not
collide. Modules can have various functions and classes. A local namespace is created when a function is
called, which has all the names defined in it. Similar, is the case with class. Following diagram may help to
clarify this concept.

Python Variable Scope


Although there are various unique namespaces defined, we may not be able to access all of them from every
part of the program. The concept of scope comes into play. Scope is the portion of the program from where
a namespace can be accessed directly without any prefix. At any given moment, there are at least three
nested scopes.

1. Scope of the current function which has local names


2. Scope of the module which has global names
3. Outermost scope which has built-in names
When a reference is made inside a function, the name is searched in the local namespace, then in the global
namespace and finally in the built-in namespace. If there is a function inside another function, a new scope is
nested inside the local scope.

Here, the variable a is in the global namespace. Variable b is in the local namespace of outer_function() and c
is in the nested local namespace of inner_function(). When we are in inner_function(), c is local to us, b is
nonlocal and a is global. We can read as well as assign new values to c but can only read b and a from
inner_function(). If we try to assign as a value to b, a new variable b is created in the local namespace which
is different than the nonlocal b. Same thing happens when we assign a value to a. However, if we declare a
as global, all the reference and assignment go to the global a. Similarly, if we want to rebind the variable b, it
must be declared as nonlocal.

What are if...else statement in Python?


Decision making is required when we want to execute a code only if a certain condition is satisfied. The
if…elif…else statement is used in Python for decision making.
if test expression:
statement(s)
Here, the program evaluates the test expression and will execute statement(s) only if the text expression is
True. If the text expression is False, the statement(s) is not executed. In Python, the body of the if statement
is indicated by the indentation. Body starts with an indentation and the first unindebted line marks the end.
Python interprets non-zero values as True. None and 0 are interpreted as False.

Python if...else Statement

if test expression:

Page 11 of 65
Unit – 3 Plotting using PyLab
Body of if
else:
Body of else

Python if...elif...else Statement


if test expression:
Body of if
elif test expression:
Body of elif
else:
Body of else
The elif is short for else if. It allows us to check for multiple expressions. If the condition for if is False, it
checks the condition of the next elif block and so on. If all the conditions are False, body of else is executed.
Only one block among the several if...elif...else blocks is executed according to the condition. The if block can
have only one else block. But it can have multiple elif blocks.

What is for loop in Python?


The for loop in Python is used to iterate over a sequence (list, tuple, string) or other iterable objects.
Iterating over a sequence is called traversal. Syntax of for Loop

for val in sequence:


Body of for

Here, val is the variable that takes the value of the item inside the sequence on each iteration. Loop
continues until we reach the last item in the sequence. The body of for loop is separated from the rest of the
code using indentation.

The range() function


We can generate a sequence of numbers using range() function. range(10) will generate numbers from 0 to 9
(10 numbers). We can also define the start, stop and step size as range(start,stop,step size). step size
defaults to 1 if not provided. This function does not store all the values in memory, it would be inefficient. So
it remembers the start, stop, step size and generates the next number on the go. To force this function to
output all the items, we can use the function list().We can use the range() function in for loops to iterate
through a sequence of numbers. It can be combined with the len() function to iterate though a sequence
using indexing.

for loop with else


A for loop can have an optional else block as well. The else part is executed if the items in the sequence used
in for loop exhausts. break statement can be used to stop a for loop. In such case, the else part is ignored.
Hence, a for loop's else part runs if no break occurs. Here is an example to illustrate this.

What is while loop in Python?


The while loop in Python is used to iterate over a block of code as long as the test expression (condition) is
true. We generally use this loop when we don't know beforehand, the number of times to iterate. Syntax of
while Loop in Python
while test_expression:
Body of while
In while loop, test expression is checked first. The body of the loop is entered only if the test_expression
evaluates to True. After one iteration, the test expression is checked again. This process continues until the
test_expression evaluates to False. In Python, the body of the while loop is determined through indentation.
Body starts with indentation and the first unindented line marks the end. Python interprets any non-zero
value as True. None and 0 are interpreted as False.

What is the use of break and continue in Python?

Page 12 of 65
CS-33: Programming in Python
In Python, break and continue statements can alter the flow of a normal loop. Loops iterate over a block of
code until test expression is false, but sometimes we wish to terminate the current iteration or even the
whole loop without checking test expression. The break and continue statements are used in these cases.

Python break statement


The break statement terminates the loop containing it. Control of the program flows to the statement
immediately after the body of the loop. If break statement is inside a nested loop (loop inside another loop),
break will terminate the innermost loop. Syntax of break
break

Python continue statement


The continue statement is used to skip the rest of the code inside a loop for the current iteration only. Loop
does not terminate but continues on with the next iteration. Syntax of Continue
continue

What is pass statement in Python?


In Python programming, pass is a null statement. The difference between a comment and pass statement in
Python is that, while the interpreter ignores a comment entirely, pass is not ignored. However, nothing
happens when pass is executed. It results into no operation (NOP). Syntax of pass
pass
We generally use it as a placeholder. Suppose we have a loop or a function that is not implemented yet, but
we want to implement it in the future. They cannot have an empty body. The interpreter would complain.
So, we use the pass statement to construct a body that does nothing.

What is a function in Python?


In Python, function is a group of related statements that perform a specific task. Functions help break our
program into smaller and modular chunks. As our program grows larger and larger, functions make it more
organized and manageable. Furthermore, it avoids repetition and makes code reusable. Syntax of Function:

def function_name(parameters):
"""docstring"""
statement(s)
Above shown is a function definition which consists of following components.

1. Keyword def marks the start of function header.


2. A function name to uniquely identify it. Function naming follows the same rules of writing identifiers
in Python.
3. Parameters (arguments) through which we pass values to a function. They are optional.
4. A colon (:) to mark the end of function header.
5. Optional documentation string (docstring) to describe what the function does.
6. One or more valid python statements that make up the function body. Statements must have same
indentation level (usually 4 spaces).
7. An optional return statement to return a value from the function.

For example:

def greet(name):
"""This function greets to
the person passed in as
parameter"""
print("Hello, " + name + ". Good morning!")

How to call a function in python?


Once we have defined a function, we can call it from another function, program or even the Python prompt.
To call a function we simply type the function name with appropriate parameters.
Page 13 of 65
Unit – 3 Plotting using PyLab
>>> greet('Paul')
Hello, Paul. Good morning!
Docstring
The first string after the function header is called the docstring and is short for documentation string. It is
used to explain in brief, what a function does. Although optional, documentation is a good programming
practice. Unless you can remember what you had for dinner last week, always document your code. In the
above example, we have a docstring immediately below the function header. We generally use triple quotes
so that docstring can extend up to multiple lines. This string is available to us as __doc__ attribute of the
function.

The return statement


The return statement is used to exit a function and go back to the place from where it was called. Syntax of
return:
return [expression_list]
This statement can contain expression which gets evaluated and the value is returned. If there is no
expression in the statement or the return statement itself is not present inside a function, then the function
will return the None object.

Scope and Lifetime of variables


Scope of a variable is the portion of a program where the variable is recognized. Parameters and variables
defined inside a function is not visible from outside. Hence, they have a local scope. Lifetime of a variable is
the period throughout which the variable exits in the memory. The lifetime of variables inside a function is as
long as the function executes. They are destroyed once we return from the function. Hence, a function does
not remember the value of a variable from its previous calls. Here is an example to illustrate the scope of a
variable inside a function.
def my_func():
x = 10
print("Value inside function:",x)

x = 20
my_func()
print("Value outside function:",x)

Output:
Value inside function: 10
Value outside function: 20
Here, we can see that the value of x is 20 initially. Even though the function my_func() changed the value of
x to 10, it did not effect the value outside the function. This is because the variable x inside the function is
different (local to the function) from the one outside. Although they have same names, they are two
different variables with different scope. On the other hand, variables outside of the function are visible from
inside. They have a global scope. We can read these values from inside the function but cannot change
(write) them. In order to modify the value of variables outside the function, they must be declared as global
variables using the keyword global.

Types of Functions
Basically, we can divide functions into the following two types:
 Built-in functions - Functions that are built into Python.
 User-defined functions - Functions defined by the users themselves.

What is recursion in Python?


Recursion is the process of defining something in terms of itself. A physical world example would be to place
two parallel mirrors facing each other. Any object in between them would be reflected recursively.

Python Recursive Function


We know that in Python, a function can call other functions. It is even possible for the function to call itself.
These type of construct are termed as recursive functions. Following is an example of recursive function to
Page 14 of 65
CS-33: Programming in Python
find the factorial of an integer. Factorial of a number is the product of all the integers from 1 to that number.
For example, the factorial of 6 (denoted as 6!) is 1*2*3*4*5*6 = 720.

Example of recursive function


# An example of a recursive function to
# find the factorial of a number
def calc_factorial(x):
"""This is a recursive function
to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * calc_factorial(x-1))
num = 4
print("The factorial of", num, "is", calc_factorial(num))

In the above example, calc_factorial() is a recursive functions as it calls itself. When we call this function with
a positive integer, it will recursively call itself by decreasing the number. Each function call multiples the
number with the factorial of number 1 until the number is equal to one. This recursive call can be explained
in the following steps.

Advantages of Recursion
1. Recursive functions make the code look clean and elegant.
2. A complex task can be broken down into simpler sub-problems using recursion.
3. Sequence generation is easier with recursion than using some nested iteration.
Disadvantages of Recursion
1. Sometimes the logic behind recursion is hard to follow through.
2. Recursive calls are expensive (inefficient) as they take up a lot of memory and time.
3. Recursive functions are hard to debug.

What are lambda functions in Python?


In Python, anonymous function is a function that is defined without a name. While normal functions are
defined using the def keyword, in Python anonymous functions are defined using the lambda keyword.
Hence, anonymous functions are also called lambda functions.A lambda function in python has the following
syntax:
lambda arguments: expression
Lambda functions can have any number of arguments but only one expression. The expression is evaluated
and returned. Lambda functions can be used wherever function objects are required.

Use of Lambda Function in python


We use lambda functions when we require a nameless function for a short period of time. In Python, we
generally use it as an argument to a higher-order function (a function that takes in other functions as
arguments). Lambda functions are used along with built-in functions like filter(), map() etc.

What are modules in Python?


Modules refer to a file containing Python statements and definitions. A file containing Python code, for e.g.:
example.py, is called a module and its module name would be example. We use modules to break down
large programs into small manageable and organized files. Furthermore, modules provide reusability of
code. We can define our most used functions in a module and import it, instead of copying their definitions
into different programs.

How to import modules in Python?


We can import the definitions inside a module to another module or the interactive interpreter in Python.
We use the import keyword to do this. To import our previously defined module example we type the
following in the Python prompt.
Page 15 of 65
Unit – 3 Plotting using PyLab
>>> import example

Import with renaming


We can import a module by renaming it as follows.
# import module by renaming it
import math as m
print("The value of pi is", m.pi)

Python from...import statement


We can import specific names from a module without importing the module as a whole. Here is an example.
# import only pi from math module
from math import pi
print("The value of pi is", pi)

Python Module Search Path


While importing a module, Python looks at several places. Interpreter first looks for a built-in module then (if
not found) into a list of directories defined in sys.path. The search is in this order. The current directory.
PYTHONPATH (an environment variable with a list of directory). The installation-dependent default directory

What are packages?


We don't usually store all of our files in our computer in the same location. We use a well-organized
hierarchy of directories for easier access. Similar files are kept in the same directory, for example, we may
keep all the songs in the "music" directory. Analogous to this, Python has packages for directories and
modules for files.

As our application program grows larger in size with a lot of


modules, we place similar modules in one package and
different modules in different packages. This makes a project
(program) easy to manage and conceptually clear. Similar, as
a directory can contain sub-directories and files, a Python
package can have sub-packages and modules.

A directory must contain a file named __init__.py in order for


Python to consider it as a package. This file can be left empty
but we generally place the initialization code for that package
in this file. Here is an example. Suppose we are developing a
game, one possible organization of packages and modules
could be as shown in the figure.

What is a file?
File is a named location on disk to store related information. It is used to permanently store data in a non-
volatile memory (e.g. hard disk). Since, random access memory (RAM) is volatile which loses its data when
computer is turned off, we use files for future use of the data. When we want to read from or write to a file
we need to open it first. When we are done, it needs to be closed, so that resources that are tied with the
file are freed. Hence, in Python, a file operation takes place in the following order.
1. Open a file
2. Read or write (perform operation)
3. Close the file

How to open a file?


Python has a built-in function open() to open a file. This function returns a file object, also called a handle, as
it is used to read or modify the file accordingly.
>>> f = open("test.txt") # open file in current directory
>>> f = open("C:/Python33/README.txt") # specifying full path

Page 16 of 65
CS-33: Programming in Python
We can specify the mode while opening a file. In mode, we specify whether we want to read 'r', write 'w' or
append 'a' to the file. We also specify if we want to open the file in text mode or binary mode. The default is
reading in text mode. In this mode, we get strings when reading from the file. On the other hand, binary
mode returns bytes and this is the mode to be used when dealing with non-text files like image or exe files.

Python File Modes

Mode Description

'r' Open a file for reading. (default)

'w' Open a file for writing. Creates a new file if it does not exist or truncates the file if it exists.

'x' Open a file for exclusive creation. If the file already exists, the operation fails.

'a' Open for appending at the end of the file without truncating it. Creates a new file if it does not exist.

't' Open in text mode. (default)

'b' Open in binary mode.

'+' Open a file for updating (reading and writing)

f = open("test.txt") # equivalent to 'r' or 'rt'


f = open("test.txt",'w') # write in text mode
f = open("img.bmp",'r+b') # read and write in binary mode

How to close a file Using Python?


When we are done with operations to the file, we need to properly close the file. Closing a file will free up
the resources that were tied with the file and is done using Python close() method. Python has a garbage
collector to clean up unreferenced objects but, we must not rely on it to close the file.

f = open("test.txt",encoding = 'utf-8')
# perform file operations
f.close()

How to write to File Using Python?


In order to write into a file in Python, we need to open it in write 'w', append 'a' or exclusive creation 'x'
mode. We need to be careful with the 'w' mode as it will overwrite into the file if it already exists. All
previous data are erased. Writing a string or sequence of bytes (for binary files) is done using write()
method. This method returns the number of characters written to the file.

with open("test.txt",'w',encoding = 'utf-8') as f:


f.write("my first file\n")
f.write("This file\n\n")
f.write("contains three lines\n")

How to read files in Python?


To read a file in Python, we must open the file in reading mode. There are various methods available for this
purpose. We can use the read(size) method to read in size number of data. If size parameter is not specified,
it reads and returns up to the end of the file.

>>> f = open("test.txt",'r',encoding = 'utf-8')


>>> f.read(4) # read the first 4 data
'This'

Page 17 of 65
Unit – 3 Plotting using PyLab
>>> f.read(4) # read the next 4 data
' is '
>>> f.read() # read in the rest till end of file
'my first file\nThis file\ncontains three lines\n'
>>> f.read() # further reading returns empty sting
''
Python File Methods
There are various methods available with the file object. Some of them have been used in above examples.
Here is the complete list of methods in text mode with a brief description.
Python File Methods

Method Description

close() Close an open file. It has no effect if the file is already closed.

detach() Separate the underlying binary buffer from the TextIOBaseand return it.

fileno() Return an integer number (file descriptor) of the file.

flush() Flush the write buffer of the file stream.

isatty() Return True if the file stream is interactive.

Read atmost n characters form the file. Reads till end of file if it is
read(n)
negative or None.

readable() Returns True if the file stream can be read from.

Read and return one line from the file. Reads in at most nbytes if
readline(n=-1)
specified.

Read and return a list of lines from the file. Reads in at


readlines(n=-1)
most n bytes/characters if specified.

Change the file position to offset bytes, in reference to from (start,


seek(offset,from=SEEK_SET)
current, end).

seekable() Returns True if the file stream supports random access.

tell() Returns the current file location.

Resize the file stream to size bytes. If size is not specified, resize to
truncate(size=None)
current location.

writable() Returns True if the file stream can be written to.

write(s) Write string s to the file and return the number of characters written.

writelines(lines) Write a list of lines to the file.

What is Directory in Python?


If there are a large number of files to handle in your Python program, you can arrange your code within
different directories to make things more manageable. A directory or folder is a collection of files and sub

Page 18 of 65
CS-33: Programming in Python
directories. Python has the os module, which provides us with many useful methods to work with directories
(and files as well).

Get Current Directory


We can get the present working directory using the getcwd() method. This method returns the current
working directory in the form of a string. We can also use the getcwdb() method to get it as bytes object.
>>> import os
>>> os.getcwd()
'C:\\Program Files\\PyScripter'
>>> os.getcwdb()
b'C:\\Program Files\\PyScripter'

What are iterators in Python?


Iterators are everywhere in Python. They are elegantly implemented within for loops, comprehensions,
generators etc. but hidden in plain sight. Iterator in Python is simply an object that can be iterated upon. An
object which will return data, one element at a time. Technically speaking, Python iterator object must
implement two special methods, __iter__() and __next__(), collectively called the iterator protocol. An
object is called iterable if we can get an iterator from it. Most of built-in containers in Python like: list, tuple,
string etc. are iterables. The iter() function (which in turn calls the __iter__() method) returns an iterator
from them.

Iterating Through an Iterator in Python


We use the next() function to manually iterate through all the items of an iterator. When we reach the end
and there is no more data to be returned, it will raise StopIteration. Following is an example.
# define a list
my_list = [4, 7, 0, 3]
# get an iterator using iter()
my_iter = iter(my_list)
## iterate through it using next()
#prints 4
print(next(my_iter))

#prints 7
print(next(my_iter))
## next(obj) is same as obj.__next__()
#prints 0
print(my_iter.__next__())
#prints 3
print(my_iter.__next__())
## This will raise error, no items left
next(my_iter)

What are generators in Python?


There is a lot of overhead in building an iterator in Python; we have to implement a class with __iter__() and
__next__() method, keep track of internal states, raise StopIteration when there was no values to be
returned etc. This is both lengthy and counter intuitive. Generator comes into rescue in such situations.
Python generators are a simple way of creating iterators. All the overhead we mentioned above are
automatically handled by generators in Python. Simply speaking, a generator is a function that returns an
object (iterator) which we can iterate over (one value at a time).

How to create a generator in Python?


It is fairly simple to create a generator in Python. It is as easy as defining a normal function with yield
statement instead of a return statement. If a function contains at least one yield statement (it may contain
other yield or return statements), it becomes a generator function. Both yield and return will return some
value from a function. The difference is that, while a return statement terminates a function entirely, yield
statement pauses the function saving all its states and later continues from there on successive calls.

Page 19 of 65
Unit – 3 Plotting using PyLab

Differences between Generator function and a Normal function


Here is how a generator function differs from a normal function.
 Generator function contains one or more yield statement.
 When called, it returns an object (iterator) but does not start execution immediately.
 Methods like __iter__() and __next__() are implemented automatically. So we can iterate through
the items using next().
 Once the function yields, the function is paused and the control is transferred to the caller.
 Local variables and their states are remembered between successive calls.
 Finally, when the function terminates, StopIteration is raised automatically on further calls.
Here is an example to illustrate all of the points stated above. We have a generator function named
my_gen() with several yield statements.
# A simple generator function
def my_gen():
n = 1
print('This is printed first')
# Generator function contains yield statements
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n

Page 20 of 65
CS- 33 Programing in Python

Unit-2
OOP Using Python
CS-33: Programming in Python

Python Errors and Built-in Exceptions


When writing a program, we, more often than not, will encounter errors. Error caused by not following the
proper structure (syntax) of the language is called syntax error or parsing error.
>>> if a < 3
File "<interactive input>", line 1
if a < 3
^
SyntaxError: invalid syntax
We can notice here that a colon is missing in the if statement. Errors can also occur at runtime and these are
called exceptions. They occur, for example, when a file we try to open does not exist (FileNotFoundError),
dividing a number by zero (ZeroDivisionError), module we try to import is not found (ImportError) etc.
Whenever these type of runtime error occur, Python creates an exception object. If not handled properly, it
prints a traceback to that error along with some details about why that error occurred.

Illegal operations can raise exceptions. There are plenty of built-in exceptions in Python that are raised when
corresponding errors occur. This will return us a dictionary of built-in exceptions, functions and attributes.
Some of the common built-in exceptions in Python programming along with the error that cause then are
tabulated below.

Python Built-in Exceptions

Exception Cause of Error

AssertionError Raised when assert statement fails.

AttributeError Raised when attribute assignment or reference fails.

EOFError Raised when the input() functions hits end-of-file condition.

FloatingPointError Raised when a floating point operation fails.

GeneratorExit Raise when a generator's close() method is called.

ImportError Raised when the imported module is not found.

IndexError Raised when index of a sequence is out of range.

KeyError Raised when a key is not found in a dictionary.

KeyboardInterrupt Raised when the user hits interrupt key (Ctrl+c or delete).

MemoryError Raised when an operation runs out of memory.

NameError Raised when a variable is not found in local or global scope.

NotImplementedError Raised by abstract methods.

OSError Raised when system operation causes system related error.

Raised when result of an arithmetic operation is too large to be


OverflowError
represented.

ReferenceError Raised when a weak reference proxy is used to access a garbage


Page 1 of 65
collected referent.

RuntimeError Raised when an error does not fall under any other category.

Raised by next() function to indicate that there is no further item to be


StopIteration
returned by iterator.

SyntaxError Raised by parser when syntax error is encountered.

IndentationError Raised when there is incorrect indentation.

TabError Raised when indentation consists of inconsistent tabs and spaces.

SystemError Raised when interpreter detects internal error.

SystemExit Raised by sys.exit() function.

Raised when a function or operation is applied to an object of incorrect


TypeError
type.

Raised when a reference is made to a local variable in a function or


UnboundLocalError
method, but no value has been bound to that variable.

UnicodeError Raised when a Unicode-related encoding or decoding error occurs.

UnicodeEncodeError Raised when a Unicode-related error occurs during encoding.

UnicodeDecodeError Raised when a Unicode-related error occurs during decoding.

UnicodeTranslateError Raised when a Unicode-related error occurs during translating.

ValueError Raised when a function gets argument of correct type but improper value.

ZeroDivisionError Raised when second operand of division or modulo operation is zero.

We can also define our own exception in Python (if required). Visit this page to learn more about user-
defined exceptions. We can handle these built-in and user-defined exceptions in Python using try, except
and finally statements.

What are exceptions in Python?


Python has many built-in exceptions which forces your program to output an error when something in it
goes wrong. When these exceptions occur, it causes the current process to stop and passes it to the calling
process until it is handled. If not handled, our program will crash. For example, if function A calls function B
which in turn calls function C and an exception occurs in function C. If it is not handled in C, the exception
passes to B and then to A. If never handled, an error message is spit out and our program come to a sudden,
unexpected halt.

Catching Exceptions in Python


In Python, exceptions can be handled using a try statement. A critical operation which can raise exception is
placed inside the try clause and the code that handles exception is written in except clause. It is up to us,
what operations we perform once we have caught the exception. Here is a simple example.

Page 2 of 65
CS-33: Programming in Python
# import module sys to get the type of exception
import sys

randomList = ['a', 0, 2]

for entry in randomList:


try:
print("The entry is", entry)
r = 1/int(entry)
break
except:
print("Oops!",sys.exc_info()[0],"occured.")
print("Next entry.")
print()
print("The reciprocal of",entry,"is",r)

In this program, we loop until the user enters an integer that has a valid reciprocal. The portion that can
cause exception is placed inside try block. If no exception occurs, except block is skipped and normal flow
continues. But if any exception occurs, it is caught by the except block. Here, we print the name of the
exception using ex_info() function inside sys module and ask the user to try again. We can see that the
values 'a' and '1.3' causes ValueError and '0' causes ZeroDivisionError.

Catching Specific Exceptions in Python


In the above example, we did not mention any exception in the except clause. This is not a good
programming practice as it will catch all exceptions and handle every case in the same way. We can specify
which exceptions an except clause will catch. A try clause can have any number of except clause to handle
them differently but only one will be executed in case an exception occurs. We can use a tuple of values to
specify multiple exceptions in an except clause. Here is an example pseudo code.
try:
# do something
pass
except ValueError:
# handle ValueError exception
pass
except (TypeError, ZeroDivisionError):
# handle multiple exceptions
# TypeError and ZeroDivisionError
pass
except:
# handle all other exceptions
pass
Raising Exceptions
In Python programming, exceptions are raised when corresponding errors occur at run time, but we can
forcefully raise it using the keyword raise. We can also optionally pass in value to the exception to clarify
why that exception was raised.

try...finally
The try statement in Python can have an optional finally clause. This clause is executed no matter what, and
is generally used to release external resources. For example, we may be connected to a remote data center
through the network or working with a file or working with a Graphical User Interface (GUI). In all these
circumstances, we must clean up the resource once used, whether it was successful or not. These actions
(closing a file, GUI or disconnecting from network) are performed in the finally clause to guarantee
execution. Here is an example of file operations to illustrate this.
try:
f = open("test.txt",encoding = 'utf-8')
# perform file operations
finally:

Page 3 of 65
f.close()
This type of construct makes sure the file is closed even if an exception occurs.

Python Custom Exceptions


Python has many built-in exceptions which forces your program to output an error when something in it
goes wrong. However, sometimes you may need to create custom exceptions that serves your purpose.

In Python, users can define such exceptions by creating a new class. This exception class has to be derived,
either directly or indirectly, from Exception class. Most of the built-in exceptions are also derived form this
class. When we are developing a large Python program, it is a good practice to place all the user-defined
exceptions that our program raises in a separate file. Many standard modules do this. They define their
exceptions separately as exceptions.py or errors.py (generally but not always).

User-defined exception class can implement everything a normal class can do, but we generally make them
simple and concise. Most implementations declare a custom base class and derive others exception classes
from this base class. This concept is made clearer in the following example.

Example: User-Defined Exception in Python


In this example, we will illustrate how user-defined exceptions can be used in a program to raise and catch
errors. This program will ask the user to enter a number until they guess a stored number correctly. To help
them figure it out, hint is provided whether their guess is greater than or less than the stored number.
# define Python user-defined exceptions
class Error(Exception):
"""Base class for other exceptions"""
pass
class ValueTooSmallError(Error):
"""Raised when the input value is too small"""
pass
class ValueTooLargeError(Error):
"""Raised when the input value is too large"""
pass
# our main program
# user guesses a number until he/she gets it right
# you need to guess this number
number = 10
while True:
try:
i_num = int(input("Enter a number: "))
if i_num < number:
raise ValueTooSmallError
elif i_num > number:
raise ValueTooLargeError
break
except ValueTooSmallError:
print("This value is too small, try again!")
print()
except ValueTooLargeError:
print("This value is too large, try again!")
print()
print("Congratulations! You guessed it correctly.")
What is Assertion?
Assertions are statements that assert or state a fact confidently in your program. For example, while writing
a division function, you're confident the divisor shouldn't be zero, you assert divisor is not equal to zero.
Assertions are simply boolean expressions that checks if the conditions return true or not. If it is true, the
program does nothing and move to the next line of code. However, if it's false, the program stops and
throws an error.

Page 4 of 65
CS-33: Programming in Python
It is also a debugging tool as it brings the program on halt as soon as any error is occurred and shows on
which point of the program error has occurred. You can learn more about assertions in the article: The
benefits of programming with Assertions. We can be clear by looking at the flowchart below:

Python assert Statement


Python has built-in assert statement to use assertion condition in the program. assert statement has a
condition or expression which is supposed to be always true. If the condition is false assert halts the program
and gives an AssertionError. Syntax for using Assert in Pyhton:
assert <condition>
assert <condition>,<error message>
In Python we can use assert statement in two ways as mentioned above.
1. assert statement has a condition and if the condition is not satisfied the program will stop and give
AssertionError.
2. assert statement can also have a condition and a optional error message. If the condition is not satisfied
assert stops the program and gives AssertionError along with the error message.
Let's take an example, where we have a function which will calculate the average of the values passed by the
user and the value should not be an empty list. We will use assert statement to check the parameter and if
the length is of the passed list is zero, program halts.
Example 1: Using assert without Error Message
def avg(marks):
assert len(marks) != 0
return sum(marks)/len(marks)
mark1 = []
print("Average of mark1:",avg(mark1))
When we run the above program, the output will be:
AssertionError
We got an error as we passed an empty list mark1 to assert statement, the condition became false and
assert stops the program and give AssertionError. Now let's pass another list which will satisfy the assert
condition and see what will be our output.
def avg(marks):
assert len(marks) != 0,"List is empty."
return sum(marks)/len(marks)
mark2 = [55,88,78,90,79]
print("Average of mark2:",avg(mark2))
mark1 = []
print("Average of mark1:",avg(mark1))
We passed a non-empty list mark2 and also an empty list mark1 to the avg() function and we got output for
mark2 list but after that we got an error AssertionError: List is empty. The assert condition was satisfied by
the mark2 list and program to continue to run. However, mark1 doesn't satisfy the condition and gives an
AssertionError.
Page 5 of 65
Key Points to Remember
 Assertions are the condition or boolean expression which are always supposed to be true in the
code.
 assert statement takes an expression and optional message.
 assert statement is used to check types, values of argument and the output of the function.
 assert statement is used as debugging tool as it halts the program at the point where an error
occurs.

Introduction to OOPs in Python


Python is a multi-paradigm programming language. Meaning, it supports different programming approach.
One of the popular approach to solve a programming problem is by creating objects. This is known as
Object-Oriented Programming (OOP). An object has two characteristics:
 attributes
 behavior
Let's take an example:
Parrot is an object,
 name, age, color are attributes
 singing, dancing are behavior
The concept of OOP in Python focuses on creating reusable code. This concept is also known as DRY (Don't
Repeat Yourself). In Python, the concept of OOP follows some basic principles:
Inheritance A process of using details from a new class without modifying existing class.

Encapsulation Hiding the private details of a class from other objects.

Polymorphism A concept of using common operation in different ways for different data input.
Class
A class is a blueprint for the object. We can think of class as an sketch of a parrot with labels. It contains all
the details about the name, colors, size etc. Based on these descriptions, we can study about the parrot.
Here, parrot is an object. The example for class of parrot can be :
class Parrot:
pass
Here, we use class keyword to define an empty class Parrot. From class, we construct instances. An instance
is a specific object created from a particular class.

Object
An object (instance) is an instantiation of a class. When class is defined, only the description for the object is
defined. Therefore, no memory or storage is allocated. The example for object of parrot class can be:
obj = Parrot()
Here, obj is object of class Parrot. Suppose we have details of parrot. Now, we are going to show how to
build the class and objects of parrot. Example to Creating Class and Object in Python:
class Parrot:
# class attribute
species = "bird"
# instance attribute
def __init__(self, name, age):
self.name = name
self.age = age
# instantiate the Parrot class
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)
# access the class attributes
print("Blu is a {}".format(blu.__class__.species))
print("Woo is also a {}".format(woo.__class__.species))

Page 6 of 65
CS-33: Programming in Python
# access the instance attributes
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))
When we run the program, the output will be:
Blu is a bird
Woo is also a bird
Blu is 10 years old
Woo is 15 years old
In the above program, we create a class with name Parrot. Then, we define attributes. The attributes are a
characteristic of an object. Then, we create instances of the Parrot class. Here, blu and woo are references
(value) to our new objects.

Then, we access the class attribute using __class __.species. Class attributes are same for all instances of a
class. Similarly, we access the instance attributes using blu.name and blu.age. However, instance attributes
are different for every instance of a class. To learn more about classes and objects, go to Python Classes and
Objects

Methods
Methods are functions defined inside the body of a class. They are used to define the behaviors of an object.
Example to Creating Methods in Python:
class Parrot:
# instance attributes
def __init__(self, name, age):
self.name = name
self.age = age
# instance method
def sing(self, song):
return "{} sings {}".format(self.name, song)
def dance(self):
return "{} is now dancing".format(self.name)
# instantiate the object
blu = Parrot("Blu", 10)
# call our instance methods
print(blu.sing("'Happy'"))
print(blu.dance())
When we run program, the output will be:
Blu sings 'Happy'
Blu is now dancing
In the above program, we define two methods i.e sing() and dance(). These are called instance method
because they are called on an instance object i.e blu.

Inheritance
Inheritance is a way of creating new class for using details of existing class without modifying it. The newly
formed class is a derived class (or child class). Similarly, the existing class is a base class (or parent class).
Example to Use of Inheritance in Python:
# parent class
class Bird:
def __init__(self):
print("Bird is ready")
def whoisThis(self):
print("Bird")
def swim(self):
print("Swim faster")
# child class
class Penguin(Bird):
def __init__(self):
# call super() function
super().__init__()
Page 7 of 65
print("Penguin is ready")
def whoisThis(self):
print("Penguin")
def run(self):
print("Run faster")
peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()
When we run this program, the output will be:
Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster
In the above program, we created two classes i.e. Bird (parent class) and Penguin (child class). The child class
inherits the functions of parent class. We can see this from swim() method. Again, the child class modified
the behavior of parent class. We can see this from whoisThis() method. Furthermore, we extend the
functions of parent class, by creating a new run() method. Additionally, we use super() function before
__init__() method. This is because we want to pull the content of __init__() method from the parent class
into the child class.

Encapsulation
Using OOP in Python, we can restrict access to methods and variables. This prevent data from direct
modification which is called encapsulation. In Python, we denote private attribute using underscore as prefix
i.e single “ _ “ or double “ __“. Example for Data Encapsulation in Python:
class Computer:
def __init__(self):
self.__maxprice = 900
def sell(self):
print("Selling Price: {}".format(self.__maxprice))
def setMaxPrice(self, price):
self.__maxprice = price
c = Computer()
c.sell()
# change the price
c.__maxprice = 1000
c.sell()
# using setter function
c.setMaxPrice(1000)
c.sell()
When we run this program, the output will be:
Selling Price: 900
Selling Price: 900
Selling Price: 1000
In the above program, we defined a class Computer. We use __init__() method to store the maximum selling
price of computer. We tried to modify the price. However, we can’t change it because Python treats the
__maxprice as private attributes. To change the value, we used a setter function i.e setMaxPrice() which
takes price as parameter.

Polymorphism
Polymorphism is an ability (in OOP) to use common interface for multiple form (data types). Suppose, we
need to color a shape, there are multiple shape option (rectangle, square, circle). However we could use
same method to color any shape. This concept is called Polymorphism. Example for Using Polymorphism in
Python:

Page 8 of 65
CS-33: Programming in Python
class Parrot:
def fly(self):
print("Parrot can fly")
def swim(self):
print("Parrot can't swim")
class Penguin:
def fly(self):
print("Penguin can't fly")
def swim(self):
print("Penguin can swim")
# common interface
def flying_test(bird):
bird.fly()
#instantiate objects
blu = Parrot()
peggy = Penguin()
# passing the object
flying_test(blu)
flying_test(peggy)
When we run above program, the output will be:
Parrot can fly
Penguin can't fly
In the above program, we defined two classes Parrot and Penguin. Each of them have common method fly()
method. However, their functions are different. To allow polymorphism, we created common interface i.e
flying_test() function that can take any object. Then, we passed the objects blu and peggy in the flying_test()
function, it ran effectively.

Key Points to Remember:


 The programming gets easy and efficient.
 The class is sharable, so codes can be reused.
 The productivity of programmars increases
 Data is safe and secure with data abstraction.

What are classes and objects in Python?


Python is an object oriented programming language. Unlike procedure oriented programming, where the
main emphasis is on functions, object oriented programming stress on objects. Object is simply a collection
of data (variables) and methods (functions) that act on those data. And, class is a blueprint for the object.
We can think of class as a sketch (prototype) of a house. It contains all the details about the floors, doors,
windows etc. Based on these descriptions we build the house. House is the object. As, many houses can be
made from a description, we can create many objects from a class. An object is also called an instance of a
class and the process of creating this object is called instantiation.

Defining a Class in Python


Like function definitions begin with the keyword def, in Python, we define a class using the keyword class.
The first string is called docstring and has a brief description about the class. Although not mandatory, this is
recommended. Here is a simple class definition.
class MyNewClass:
'''This is a docstring. I have created a new class'''
pass
A class creates a new local namespace where all its attributes are defined. Attributes may be data or
functions. There are also special attributes in it that begins with double underscores (__). For example,
__doc__ gives us the docstring of that class. As soon as we define a class, a new class object is created with
the same name. This class object allows us to access the different attributes as well as to instantiate new
objects of that class.

class MyClass:
"This is my second class"
Page 9 of 65
a = 10
def func(self):
print('Hello')
# Output: 10
print(MyClass.a)
# Output: <function MyClass.func at 0x0000000003079BF8>
print(MyClass.func)
# Output: 'This is my second class'
print(MyClass.__doc__)
When you run the program, the output will be:
10
<function 0x7feaa932eae8="" at="" myclass.func="">
This is my second class
Creating an Object in Python
We saw that the class object could be used to access different attributes. It can also be used to create new
object instances (instantiation) of that class. The procedure to create an object is similar to a function call.
>>> ob = MyClass()
This will create a new instance object named ob. We can access attributes of objects using the object name
prefix. Attributes may be data or method. Method of an object are corresponding functions of that class. Any
function object that is a class attribute defines a method for objects of that class. This means to say, since
MyClass.func is a function object (attribute of class), ob.func will be a method object.
class MyClass:
"This is my second class"
a = 10
def func(self):
print('Hello')
# create a new MyClass
ob = MyClass()
# Output: <function MyClass.func at 0x000000000335B0D0>
print(MyClass.func)
# Output: <bound method MyClass.func of <__main__.MyClass object at
0x000000000332DEF0>>
print(ob.func)
# Calling function func()
# Output: Hello
ob.func()
You may have noticed the self parameter in function definition inside the class but, we called the method
simply as ob.func() without any arguments. It still worked. This is because, whenever an object calls its
method, the object itself is passed as the first argument. So, ob.func() translates into MyClass.func(ob). In
general, calling a method with a list of n arguments is equivalent to calling the corresponding function with
an argument list that is created by inserting the method's object before the first argument.

For these reasons, the first argument of the function in class must be the object itself. This is conventionally
called self. It can be named otherwise but we highly recommend to follow the convention. Now you must be
familiar with class object, instance object, function object, method object and their differences.

Constructors in Python
Class functions that begins with double underscore (__) are called special functions as they have special
meaning. Of one particular interest is the __init__() function. This special function gets called whenever a
new object of that class is instantiated. This type of function is also called constructors in Object Oriented
Programming (OOP). We normally use it to initialize all the variables.
class ComplexNumber:
def __init__(self,r = 0,i = 0):
self.real = r
self.imag = i
def getData(self):
print("{0}+{1}j".format(self.real,self.imag))

Page 10 of 65
CS-33: Programming in Python
# Create a new ComplexNumber object
c1 = ComplexNumber(2,3)
# Call getData() function
# Output: 2+3j
c1.getData()
# Create another ComplexNumber object
# and create a new attribute 'attr'
c2 = ComplexNumber(5)
c2.attr = 10
# Output: (5, 0, 10)
print((c2.real, c2.imag, c2.attr))
# but c1 object doesn't have attribute 'attr'
# AttributeError: 'ComplexNumber' object has no attribute 'attr'
c1.attr
In the above example, we define a new class to represent complex numbers. It has two functions, __init__()
to initialize the variables (defaults to zero) and getData() to display the number properly. An interesting thing
to note in the above step is that attributes of an object can be created on the fly. We created a new attribute
attr for object c2 and we read it as well. But this did not create that attribute for object c1.

What is Inheritance?
Inheritance is a powerful feature in object oriented programming. It refers to defining a new class with little
or no modification to an existing class. The new class is called derived (or child) class and the one from which
it inherits is called the base (or parent) class. Python Inheritance Syntax:
class BaseClass:
Body of base class
class DerivedClass(BaseClass):
Body of derived class
Derived class inherits features from the base class, adding new features to it. This results into re-usability of
code.

Example of Inheritance in Python


To demonstrate the use of inheritance, let us take an example. A polygon is a closed figure with 3 or more
sides. Say, we have a class called Polygon defined as follows.
class Polygon:
def __init__(self, no_of_sides):
self.n = no_of_sides
self.sides = [0 for i in range(no_of_sides)]
def inputSides(self):
self.sides = [float(input("Enter side "+str(i+1)+" : ")) for
i in range(self.n)]
def dispSides(self):
for i in range(self.n):
print("Side",i+1,"is",self.sides[i])
This class has data attributes to store the number of sides, n and magnitude of each side as a list, sides.
Method inputSides() takes in magnitude of each side and similarly, dispSides() will display these properly. A
triangle is a polygon with 3 sides. So, we can created a class called Triangle which inherits from Polygon. This
makes all the attributes available in class Polygon readily available in Triangle. We don't need to define them
again (code re-usability).

Method Overriding in Python


In the above example, notice that __init__() method was defined in both classes, Triangle as well Polygon.
When this happens, the method in the derived class overrides that in the base class. This is to say, __init__()
in Triangle gets preference over the same in Polygon.

Generally when overriding a base method, we tend to extend the definition rather than simply replace it.
The same is being done by calling the method in base class from the one in derived class (calling
Polygon.__init__() from __init__() in Triangle). A better option would be to use the built-in function super().
Page 11 of 65
So, super().__init__(3) is equivalent to Polygon.__init__(self,3) and is preferred. You can learn more about
the super() function in Python.

Two built-in functions isinstance() and issubclass() are used to check inheritances. Function isinstance()
returns True if the object is an instance of the class or other classes derived from it. Each and every class in
Python inherits from the base class object.

What is operator overloading in Python?


Python operators work for built-in classes. But same operator behaves differently with different types. For
example, the + operator will, perform arithmetic addition on two numbers, merge two lists and concatenate
two strings. This feature in Python, that allows same operator to have different meaning according to the
context is called operator overloading. So what happens when we use them with objects of a user-defined
class? Let us consider the following class, which tries to simulate a point in 2-D coordinate system.
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
Now, run the code and try to add two points in Python shell.
>>> p1 = Point(2,3)
>>> p2 = Point(-1,2)
>>> p1 + p2
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
Overloading the + Operator in Python
To overload the + sign, we will need to implement __add__() function in the class. With great power comes
great responsibility. We can do whatever we like, inside this function. But it is sensible to return a Point
object of the coordinate sum.
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __str__(self):
return "({0},{1})".format(self.x,self.y)
def __add__(self,other):
x = self.x + other.x
y = self.y + other.y
return Point(x,y)
Now let's try that addition again.
>>> p1 = Point(2,3)
>>> p2 = Point(-1,2)
>>> print(p1 + p2)
(1,5)

Search Algorithms
A search algorithm is a method for finding an item or group of items with specific properties within a
collection of items. We refer to the collection of items as a search space. The search space might be
something concrete, such as a set of electronic medical records, or something abstract, such as the set of all
integers. A large number of problems that occur in practice can be formulated as search problems.

Many of the algorithms presented earlier in this book can be viewed as search algorithms. We formulated
finding an approximation to the roots of a polynomial as a search problem, and looked at three algorithms—
exhaustive enumeration, bisection search, and Newton-Raphson—for searching the space of possible
answers. In this section, we will examine two algorithms for searching a list. Each meets the specification:

Page 12 of 65
CS-33: Programming in Python
def search(L, e):
"""Assumes L is a list.
Returns True if e is in L and False otherwise"""

The astute reader might wonder if this is not semantically equivalent to the Python expression e in L. The
answer is yes, it is. And if one is unconcerned about the efficiency of discovering whether e is in L, one
should simply write that expression.

Linear Search and Using Indirection to Access Elements


Python uses the following algorithm to determine if an element is in a list:
def search(L, e):
for i in range(len(L)):
if L[i] == e:
return True
return False

Binary Search and Exploiting Assumptions


Getting back to the problem of implementing search(L, e), is O(len(L)) the best we can do? Yes, if we know
nothing about the relationship of the values of the elements in the list and the order in which they are
stored. In the worst case, we have to look at each element in L to determine whether L contains e. But
suppose we know something about the order in which elements are stored, e.g., suppose we know that we
have a list of integers stored in ascending order. We could change the implementation so that the search
stops when it reaches a number larger than the number for which it is searching:

def search(L, e):


"""Assumes L is a list, the elements of which are in
ascending order.
Returns True if e is in L and False otherwise"""
for i in range(len(L)):
if L[i] == e:
return True
if L[i] > e:
return False
return False
This would improve the average running time. However, it would not change the worst-case complexity of
the algorithm, since in the worst case each element of L is examined.

Sorting Algorithms
We have just seen that if we happen to know that a list is sorted, we can exploit that information to greatly
reduce the time needed to search a list. Does this mean that when asked to search a list one should first sort
it and then perform the search?

Let O(sortComplexity(L)) be the complexity of sorting a list. Since we know that we can always search a list in
O(len(L)) time, the question of whether we should first sort and then search boils down to the question, is
(sortComplexity(L) + log(len(L))) < len(L)? The answer, sadly, is no. One cannot sort a list without looking at
each element in the list at least once, so it is not possible to sort a list in sub-linear time.

Does this mean that binary search is an intellectual curiosity of no practical import? Happily, no. Suppose
that one expects to search the same list many times. It might well make sense to pay the overhead of sorting
the list once, and then amortize the cost of the sort over many searches. If we expect to search the list k
times, the relevant question becomes, is (sortComplexity(L) + k*log(len(L))) less than k*len(L)? As k becomes
large, the time required to sort the list becomes increasingly irrelevant.

How big k needs to be depends upon how long it takes to sort a list. If, for example, sorting were exponential
in the size of the list, k would have to be quite large.

Page 13 of 65
Hash Tables
If we put merge sort together with binary search, we have a nice way to search lists. We use merge sort to
preprocess the list in O(n*log(n)) time, and then we use binary search to test whether elements are in the
list in O(log(n)) time. If we search the list k times, the overall time complexity is O(n*log(n) + k*log(n)). This is
good, but we can still ask, is logarithmic the best that we can do for search when we are willing to do some
preprocessing?

When we introduced the type dict we said that dictionaries use a technique called hashing to do the lookup
in time that is nearly independent of the size of the dictionary. The basic idea behind a hash table is simple.
We convert the key to an integer, and then use that integer to index into a list, which can be done in
constant time. In principle, values of any immutable type can be easily converted to an integer. After all, we
know that the internal representation of each object is a sequence of bits, and any sequence of bits can be
viewed as representing an integer. For example, the internal representation of 'abc' is the string of bits
011000010110001001100011, which can be viewed as a representation of the decimal integer 6,382,179. Of
course, if we want to use the internal representation of strings as indices into a list, the list is going to have
to be pretty darn long.

Page 14 of 65
CS- 33 Programing in Python

Unit-3
Plotting using PyLab
CS-33: Programming in Python

Often text is the best way to communicate information, but sometimes there is a lot of truth to the Chinese
proverb, “A picture's meaning can express ten thousand words”. Yet most programs rely on textual output
to communicate with their users. Why? Because in many programming languages presenting visual data is
too hard. Fortunately, it is simple to do in Python.

Plotting Using PyLab


PyLab is a Python standard library module that provides many of the facilities of MATLAB, “a high-level
technical computing language and interactive environment for algorithm development, data visualization,
data analysis, and numeric computation.”57 Later in the book, we will look at some of the more advanced
features of PyLab, but in this chapter we focus on some of its facilities for plotting data. A complete user’s
guide for PyLab is at the Web site matplotlib.sourceforge.net/users/index.html. There are also a number of
Web sites that provide excellent tutorials. We will not try to provide a user’s guide or a complete tutorial
here. Instead, in this chapter we will merely provide a few example plots and explain the code that
generated them. Other examples appear in later chapters.

Pylab is a programming environment, built on a set of unofficial python tools and libraries that turns Python
into a high-performance scientific computing platform. The name pylab comes in part from the resemblance
of the resulting environment to MATLAB. The components of pylab have developed largely independently,
so there's no unique or "official" distribution. Nonetheless, there are at least four core components (in
addition the standard python distribution) required to have an environment that can reasonably be
considered a pylab environment. These are:

NumPy: this is a set of high-performance libraries (implemented in Fortran and C) that implement
contiguous-memory multidimensional arrays, BLAS and LAPACK linear algebra routines and many other
useful numerical tools. This is listed first because all other components depend on it.

Matplotlib: this is pylab's plotting library. It is set up to seem familiar to users accustomed to Matlab's
plotting utilities, but it is in many ways much more powerful and flexible (It lets you choose between many
different backend renderers, for example, and allows you to build plots in an object-oriented manner).
Matplotlib is an excellent 2D and 3D graphics library for generating scientific figures. Some of the many
advantages of this library include:
 Easy to get started
 Support for LATEX formatted labels and texts
 Great control of every element in a figure, including figure size and DPI.
 High-quality output in many formats, including PNG, PDF, SVG, EPS.
 GUI for interactively exploring figures and support for headless generation of figure files (useful for
batch jobs).
One of the key features of matplotlib is that all aspects of the figure can be controlled programmatically (i.e.,
without needing to muck around with the GUI). This is important for reproducibility and convenient when
one needs to regenerate the figure with updated data or change its appearance. More information at the
Matplotlib web page: http://matplotlib.org/

Matplotlib is automatically included as part of the interactive pylab namespace, but if you need to import it
in its own namespace (e.g., in a non-interactive script or module).

SciPy: this is a set of mostly distinct modules implementing a variety of really useful scientific computing
tasks, including signal processing, FFTs, optimization, statistics, interpolation, numerical integration, etc. It
contains a lot of stuff that you would expect to see in any good scientific programming environment. Though
it depends strongly on Numpy, it is not as completely integrated into the pylab environment as are the other
components. As a result, you'll need to explicitly import most modules from scipy even if you've already
imported the pylab namespace.

Page 1 of 65
Let’s start with a simple example that uses pylab.plot to produce two plots.

import pylab
pylab.figure(1) #create figure 1
pylab.plot([1,2,3,4], [1,7,3,5]) #draw on figure 1
pylab.show() #show figure on screen

will cause a window to appear on your computer monitor. Its exact appearance may depend on the
operating system on your machine, but it will look similar to the following:

Parts of a Chart:

Page 2 of 65
CS-33: Programming in Python
Functions used for plotting:

Plot():
The two parameters of pylab.plot must be sequences of the same length. The first specifies the x-
coordinates of the points to be plotted, and the second specifies the y-coordinates. Together, they provide a
sequence of four <x, y> coordinate pairs, [(1,1), (2,7), (3,3), (4,5)]. These are plotted in order. As each point is
plotted, a line is drawn connecting it to the previous point. plot() is a versatile command, and will take an
arbitrary number of arguments. For example, to plot x versus y. For every x, y pair of arguments, there is an
optional third argument which is the format string that indicates the color and line type of the plot. The
letters and symbols of the format string are from MATLAB, and you concatenate a color string with a line
style string. The default format string is ‘b-‘, which is a solid blue line.

Show():
pylab.show(), causes the window to appear on the computer screen. If that line were not present, the figure
would still have been produced, but it would not have been displayed. pylab.show() causes the process
running Python to be suspended until the figure is closed. The usual workaround is to ensure that
pylab.show() is the last line of code to be executed.

Xlabel():
Pylab.xlabel(), causes to set title of x-axis. One should pass the string value with the method that shows the
values on x-axis.

Ylabel():
Pylab.ylabel(), causes to set title of y-axis. One should pass the string value with the method that shows the
values on x-axis.

Title():
Pylab.title(), causes to display title on the entire plot. One should pass the string value with the method, and
it should be relevant with the entire plot area.

Hist():
Plot a histogram. Compute and draw the histogram of x. The return value is a tuple (n, bins, patches) or ([n0,
n1, ...], bins, [patches0, patches1,...]) if the input contains multiple data. Multiple data can be provided via x
as a list of datasets of potentially different length ([x0, x1, ...]), or as a 2-D ndarray in which each column is a
dataset. Note that the ndarray form is transposed relative to the list form.

Legend():
Places a legend on the axes. To make a legend for lines which already exist on the axes (via plot for instance),
simply call this function with an iterable of strings, one for each legend item. For example:
pylab.plot([1, 2, 3])
pylab.legend(['A simple line'])

Plotting Mortgages, an Extended Example


A collapse in U.S. housing prices helped trigger a severe economic meltdown in the fall of 2008. One of the
contributing factors was that many homeowners had taken on mortgages that ended up having unexpected
consequences. In the beginning, mortgages were relatively simple beasts. One borrowed money from a bank
and made a fixed-size payment each month for the life of the mortgage, which typically ranged from fifteen
to thirty years. At the end of that period, the bank had been paid back the initial loan (the principal) plus
interest, and the homeowner owned the house “free and clear.”

Towards the end of the twentieth century, mortgages started getting a lot more complicated. People could
get lower interest rates by paying “points” at the time they took on the mortgage. A point is a cash payment
of 1% of the value of the loan. People could take mortgages that were “interest-only” for a period of time.
That is to say, for some number of months at the start of the loan the borrower paid only the accrued
interest and none of the principal. Other loans involved multiple rates. Typically the initial rate (called a
Page 3 of 65
“teaser rate”) was low, and then it went up over time. Many of these loans were variable-rate—the rate to
be paid after the initial period would vary depending upon some index intended to reflect the cost to the
lender of borrowing on the wholesale credit market. We worked our way through a hierarchy of mortgages
as way of illustrating the use of subclassing.

We concluded that chapter by observing that “our program should be producing plots designed to show how
the mortgage behaves over time.” enhances class Mortgage by adding methods that make it convenient to
produce such plots. (The function findPayment, which is used in Mortgage) The methods plotPayments and
plotBalance are simple one-liners, but they do use a form of pylab.plot that we have not yet seen.
def findPayment(loan, r, m):
"""Assumes: loan and r are floats, m an int
Returns the monthly payment for a mortgage of size
loan at a monthly rate of r for m months"""
return loan*((r*(1+r)**m)/((1+r)**m - 1))
class Mortgage(object):
"""Abstract class for building different kinds of mortgages"""
def __init__(self, loan, annRate, months):
"""Create a new mortgage"""
self.loan = loan
self.rate = annRate/12.0
self.months = months
self.paid = [0.0]
self.owed = [loan]
self.payment = findPayment(loan, self.rate, months)
self.legend = None #description of mortgage
def makePayment(self):
"""Make a payment"""
self.paid.append(self.payment)
reduction = self.payment - self.owed[-1]*self.rate
self.owed.append(self.owed[-1] - reduction)
def getTotalPaid(self):
"""Return the total amount paid so far"""
return sum(self.paid)
def __str__(self):
return self.legend

Fibonacci Sequences, Revisited


While this implementation of the recurrence is obviously correct, it is terribly inefficient. Try, for example,
running fib(120), but don’t wait for it to complete. The complexity of the implementation is a bit hard to
derive, but it is roughly O(fib(n)). That is, its growth is proportional to the growth in the value of the result,
and the growth rate of the Fibonacci sequence is substantial. For example, fib(120) is
8,670,007,398,507,948,658,051,921. If each recursive call took a nanosecond, fib(120) would take about
250,000 years to finish. Let’s try and figure out why this implementation takes so long. Given the tiny
amount of code in the body of fib, it’s clear that the problem must be the number of times that fib calls
itself. As an example, look at the tree of calls associated with the invocation fib(6).

Page 4 of 65
CS-33: Programming in Python
Notice that we are computing the same values over and over again. For example fib gets called with 3 three
times, and each of these calls provokes four additional calls of fib. It doesn’t require a genius to think that it
might be a good idea to record the value returned by the first call, and then look it up rather than compute it
each time it is needed. This is called memoization, and is the key idea behind dynamic programming.
def fastFib(n, memo = {}):
"""Assumes n is an int >= 0, memo used only by recursive calls
Returns Fibonacci of n"""
if n == 0 or n == 1:
return 1
try:
return memo[n]
except KeyError:
result = fastFib(n-1, memo) + fastFib(n-2, memo)
memo[n] = result
return result

If you try running fastFib, you will see that it is indeed quite fast: fib(120) returns almost instantly. What is
the complexity of fastFib? It calls fib exactly once for each value from 0 to n. Therefore, under the
assumption that dictionary lookup can be done in constant time, the time complexity of fastFib(n) is O(n).

Dynamic programming and the 0/1 Knapsack algorithm


One of the optimization problems we looked at in Chapter 17 was the 0/1 knapsack problem. Recall that we
looked at a greedy algorithm that ran in n log n time, but was not guaranteed to find an optimal solution. We
also looked at a brute-force algorithm that was guaranteed to find an optimal solution, but ran in
exponential time. Finally, we discussed the fact that the problem is inherently exponential in the size of the
input. In the worst case, one cannot find an optimal solution without looking at all possible answers.

Fortunately, the situation is not as bad as it seems. Dynamic programming provides a practical method for
solving most 0/1 knapsack problems in a reasonable amount of time. As a first step in deriving such a
solution, we begin with an exponential solution based on exhaustive enumeration. The key idea is to think
about exploring the space of possible solutions by constructing a rooted binary tree that enumerates all
states that satisfy the weight constraint. A rooted binary tree is an acyclic directed graph in which
• There is exactly one node with no parents. This is called the root.
• Each non-root node has exactly one parent.
• Each node has at most two children. A childless node is called a leaf.
Each node in the search tree for the 0/1 knapsack problem is labeled with a quadruple that denotes a partial
solution to the knapsack problem

Dynamic programming and divide and conquer


Like divide-and-conquer algorithms, dynamic programming is based upon solving independent subproblems
and then combining those solutions. There are, however, some important differences. Divide-and-conquer
algorithms are based upon finding subproblems that are substantially smaller than the original problem. For
example, merge sort works by dividing the problem size in half at each step. In contrast, dynamic
programming involves solving problems that are only slightly smaller than the original problem.

For example, computing the 19th Fibonacci number is not a substantially smaller problem than computing
the 20th Fibonacci number. Another important distinction is that the efficiency of divide-and-conquer
algorithms does not depend upon structuring the algorithm so that the same problems are solved
repeatedly. In contrast, dynamic programming is efficient only when the number of distinct subproblems is
significantly smaller than the total number of subproblems.

Page 5 of 65
CS- 33 Programing in Python

Unit-4
Network Programming and GUI using Python
Network Programming
Python provides two levels of access to network services. At a low level, you can access the basic socket
support in the underlying operating system, which allows you to implement clients and servers for both
connection-oriented and connectionless protocols. Python also has libraries that provide higher-level access
to specific application-level network protocols, such as FTP, HTTP, and so on.

Protocol: In networking, a protocol is a set of rules for formatting and processing data. Network protocols
are like a common language for computers. The computers within a network may use vastly different
software and hardware; however, the use of protocols enables them to communicate with each other
regardless. Standardized protocols are like a common language that computers can use, similar to how two
people from different parts of the world may not understand each other's native languages, but they can
communicate using a shared third language. If one computer uses the Internet Protocol (IP) and a second
computer does as well, they will be able to communicate — just as the United Nations relies on its 6 official
languages to communicate amongst representatives from all over the globe. But if one computer uses IP and
the other does not know this protocol, they will be unable to communicate. On the Internet, there are
different protocols for different types of processes. Protocols are often discussed in terms of which OSI
model layer they belong to.

Sockets: Sockets are the endpoints of a bidirectional communications channel. Sockets may communicate
within a process, between processes on the same machine, or between processes on different continents.
Sockets may be implemented over a number of different channel types: Unix domain sockets, TCP, UDP, and
so on. The socket library provides specific classes for handling the common transports as well as a generic
interface for handling the rest.

To create a socket, you must use the socket.socket() function available in socket module, which has the
general syntax:
s = socket.socket (socket_family, socket_type, protocol=0)

Here is the description of the parameters:


 socket_family − This is either AF_UNIX or AF_INET, as explained earlier.
 socket_type − This is either SOCK_STREAM or SOCK_DGRAM.
 protocol − This is usually le out, defaul ng to 0.

Once you have socket object, then you can use required functions to create your client or server program.
Following is the list of functions required:
Server Socket Methods

Sr. Method & Description

1 s.bind()
This method binds address (hostname, port number pair) to socket.

2 s.listen()
This method sets up and start TCP listener.

3 s.accept()
This passively accept TCP client connection, waiting until connection
arrives (blocking).

Page 1 of 65
Unit – 4 Regular Expressions
Client Socket Methods

Sr. Method & Description

1 s.connect()
This method actively initiates TCP server connection.

General Socket Methods

Sr. Method & Description

1 s.recv()
This method receives TCP message

2 s.send()
This method transmits TCP message

3 s.recvfrom()
This method receives UDP message

4 s.sendto()
This method transmits UDP message

5 s.close()
This method closes socket

6 socket.gethostname()
Returns the hostname.

Python Internet modules: A list of some important modules in Python Network/Internet programming.

Protocol Common function Port No Python module

HTTP Web pages 80 httplib, urllib, xmlrpclib

NNTP Usenet news 119 nntplib

FTP File transfers 20 ftplib, urllib

SMTP Sending email 25 smtplib

POP3 Fetching email 110 poplib

IMAP4 Fetching email 143 imaplib

Telnet Command lines 23 telnetlib

Gopher Document transfers 70 gopherlib, urllib

o Knowing IP Address
o URL, Reading the Source Code of a Web Page
o Downloading a Web Page from Internet

Page 2 of 65
o Downloading an Image from Internet
o A TCP/IP Server, A TCP/IP Client
o A UDP Server, A UDP Client
o File Server, File Client

Two-Way Communication between Server and Client


A Simple Server: To write Internet servers, we use the socket function available in socket module to create a
socket object. A socket object is then used to call other functions to setup a socket server. Now call
bind(hostname, port) function to specify a port for your service on the given host. Next, call the accept
method of the returned object. This method waits until a client connects to the port you specified, and then
returns a connection object that represents the connection to that client.
import socket # Import socket module

s = socket.socket() # Create a socket object


host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port

s.listen(5) # Now wait for client connection.


while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close()

A Simple Client: Let us write a very simple client program which opens a connection to a given port 12345
and given host. This is very simple to create a socket client using Python's socket module function. The
socket.connect(hosname, port ) opens a TCP connection to hostname on the port. Once you have a socket
open, you can read from it like any IO object. When done, remember to close it, as you would close a file.
The following code is a very simple client that connects to a given host and port, reads any available data
from the socket, and then exits:
import socket # Import socket module

s = socket.socket() # Create a socket object


host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.

s.connect((host, port))
print s.recv(1024)
s.close()

Sending a Simple Mail: Simple Mail Transfer Protocol (SMTP) is a protocol, which handles sending e-mail and
routing e-mail between mail servers. Python provides smtplib module, which defines an SMTP client session
object that can be used to send mail to any Internet machine with an SMTP or ESMTP listener daemon. Here
is a simple syntax to create one SMTP object, which can later be used to send an e-mail:
import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

Here is the detail of the parameters:


Page 3 of 65
Unit – 4 Regular Expressions
 host − This is the host running your SMTP server. You can specify IP address of the host or a domain
name like tutorialspoint.com. This is optional argument.
 port − If you are providing host argument, then you need to specify a port, where SMTP server is
listening. Usually this port would be 25.
 local_hostname − If your SMTP server is running on your local machine, then you can specify just
localhost as of this option.

An SMTP object has an instance method called sendmail, which is typically used to do the work of mailing a
message. It takes three parameters:
 The sender − A string with the address of the sender.
 The receivers − A list of strings, one for each recipient.
 The message − A message as a string forma ed as specified in the various RFCs.

Example…
import smtplib

sender = '[email protected]'
receivers = ['[email protected]']

message = """From: From Person <[email protected]>


To: To Person <[email protected]>
Subject: SMTP e-mail test

This is a test e-mail message.


"""

try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message)
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"

Here, you have placed a basic e-mail in message, using a triple quote, taking care to format the headers
correctly. An e-mail requires a From, To, and Subject header, separated from the body of the e-mail with a
blank line. To send the mail you use smtpObj to connect to the SMTP server on the local machine and then
use the sendmail method along with the message, the from address, and the destination address as
parameters (even though the from and to addresses are within the e-mail itself, these aren't always used to
route mail). If you are not running an SMTP server on your local machine, you can use smtplib client to
communicate with a remote SMTP server.

GUI Programming
Event-driven programming paradigm: Eventually, the flow of a program depends upon the events, and
programming which focuses on events is called Event-Driven programming. We were only dealing with
either parallel or sequential models, but now we will discuss the asynchronous model. The programming
model following the concept of Event-Driven programming is called the Asynchronous model. The working of
Event-Driven programming depends upon the events happening in a program. Other than this, it depends

Page 4 of 65
upon the program's event loops that always listen to a new incoming event in the program. Once an event
loop starts in the program, then only the events will decide what will execute and in which order.

Creating simple GUI


Tkinter is the standard GUI library for Python. Python when combined with Tkinter provides a fast and easy
way to create GUI applications. Tkinter provides a powerful object-oriented interface to the Tk GUI toolkit.
Creating a GUI application using Tkinter is an easy task. All you need to do is perform the following steps −
 Import the Tkinter module.
 Create the GUI application main window.
 Add one or more of the above-mentioned widgets to the GUI application.
 Enter the main event loop to take action against each event triggered by the user.

Example:
import Tkinter
top = Tkinter.Tk()
# Code to add widgets will go here...
top.mainloop()

Tkinter Widgets: Tkinter provides various controls, such as buttons, labels and text boxes used in a GUI
application. These controls are commonly called widgets. There are currently different types of widgets in
Tkinter. We present these widgets as well as a brief description in the following sections:

Buttons: The Button widget is used to add buttons in a Python application. These buttons can display text or
images that convey the purpose of the buttons. You can attach a function or a method to a button which is
called automatically when you click the button. Here is the simple syntax to create this widget:
w = Button (master, option=value, ...)
Parameters
 master − This represents the parent window.
 options − Here is the list of most commonly used op ons for this widget. These op ons can be used
as key-value pairs separated by commas.

Sr. Option & Description

1 activebackground
Background color when the button is under the cursor.

2 activeforeground
Foreground color when the button is under the cursor.

3 bd
Border width in pixels. Default is 2.

4 bg
Normal background color.

5 command
Function or method to be called when the button is clicked.

6 fg
Normal foreground (text) color.

Page 5 of 65
Unit – 4 Regular Expressions
7 font
Text font to be used for the button's label.

8 height
Height of the button in text lines (for textual buttons) or pixels (for
images).

9 highlightcolor
The color of the focus highlight when the widget has focus.

10 image
Image to be displayed on the button (instead of text).

11 justify
How to show multiple text lines: LEFT to left-justify each line; CENTER
to center them; or RIGHT to right-justify.

12 padx
Additional padding left and right of the text.

13 pady
Additional padding above and below the text.

14 relief
Relief specifies the type of the border. Some of the values are
SUNKEN, RAISED, GROOVE, and RIDGE.

15 state
Set this option to DISABLED to gray out the button and make it
unresponsive. Has the value ACTIVE when the mouse is over it.
Default is NORMAL.

16 underline
Default is -1, meaning that no character of the text on the button will
be underlined. If nonnegative, the corresponding text character will
be underlined.

17 width
Width of the button in letters (if displaying text) or pixels (if displaying
an image).

18 wraplength
If this value is set to a positive number, the text lines will be wrapped
to fit within this length.

Following are commonly used methods for this widget:

Sr. Method & Description

1 flash()
Causes the button to flash several times between active and normal colors.
Leaves the button in the state it was in originally. Ignored if the button is
disabled.

Page 6 of 65
2 invoke()
Calls the button's callback, and returns what that function returns. Has no effect
if the button is disabled or there is no callback.
Example:
import Tkinter
import tkMessageBox

top = Tkinter.Tk()

def helloCallBack():
tkMessageBox.showinfo( "Hello Python", "Hello World")

B = Tkinter.Button(top, text ="Hello", command = helloCallBack)


B.pack()
top.mainloop()

Labels: This widget implements a display box where you can place text or images. The text displayed by this
widget can be updated at any time you want. It is also possible to underline part of the text (like to identify a
keyboard shortcut) and span the text across multiple lines. Here is the simple syntax to create this widget:
w = Label ( master, option, ... )

Parameters:
 master − This represents the parent window.
 options − Here is the list of most commonly used op ons for this widget. These op ons can be used
as key-value pairs separated by commas.

Sr. Option & Description

1 anchor
This options controls where the text is positioned if the widget has more space than the text
needs. The default is anchor=CENTER, which centers the text in the available space.

2 bg
The normal background color displayed behind the label and indicator.

3 bitmap
Set this option equal to a bitmap or image object and the label will display that graphic.

4 bd
The size of the border around the indicator. Default is 2 pixels.

5 cursor
If you set this option to a cursor name (arrow, dot etc.), the mouse cursor will change to that
pattern when it is over the checkbutton.

6 font
If you are displaying text in this label (with the text or textvariable option, the font option
specifies in what font that text will be displayed.

7 fg
If you are displaying text or a bitmap in this label, this option specifies the color of the text. If

Page 7 of 65
Unit – 4 Regular Expressions
you are displaying a bitmap, this is the color that will appear at the position of the 1-bits in
the bitmap.

8 height
The vertical dimension of the new frame.

9 image
To display a static image in the label widget, set this option to an image object.

10 justify
Specifies how multiple lines of text will be aligned with respect to each other: LEFT for flush
left, CENTER for centered (the default), or RIGHT for right-justified.

11 padx
Extra space added to the left and right of the text within the widget. Default is 1.

12 pady
Extra space added above and below the text within the widget. Default is 1.

13 relief
Specifies the appearance of a decorative border around the label. The default is FLAT; for
other values.

14 text
To display one or more lines of text in a label widget, set this option to a string containing the
text. Internal newlines ("\n") will force a line break.

15 textvariable
To slave the text displayed in a label widget to a control variable of class StringVar, set this
option to that variable.

16 underline
You can display an underline (_) below the nth letter of the text, counting from 0, by setting
this option to n. The default is underline=-1, which means no underlining.

17 width
Width of the label in characters (not pixels!). If this option is not set, the label will be sized to
fit its contents.

18 wraplength
You can limit the number of characters in each line by setting this option to the desired
number. The default value, 0, means that lines will be broken only at newlines.

Example:
from Tkinter import *

root = Tk()
var = StringVar()
label = Label( root, textvariable=var, relief=RAISED )

var.set("Hey!? How are you doing?")


label.pack()
root.mainloop()

Page 8 of 65
Entry: The Entry widget is used to accept single-line text strings from a user. If you want to display multiple
lines of text that can be edited, then you should use the Text widget. If you want to display one or more lines
of text that cannot be modified by the user, then you should use the Label widget. Here is the simple syntax
to create this widget:
w = Entry( master, option, ... )

Parameters:
 master − This represents the parent window.
 options − Here is the list of most commonly used op ons for this widget. These op ons can be used
as key-value pairs separated by commas.

Sr. Option & Description

1 bg
The normal background color displayed behind the label and indicator.

2 bd
The size of the border around the indicator. Default is 2 pixels.

3 command
A procedure to be called every time the user changes the state of this checkbutton.

4 cursor
If you set this option to a cursor name (arrow, dot etc.), the mouse cursor will change
to that pattern when it is over the checkbutton.

5 font
The font used for the text.

6 exportselection
By default, if you select text within an Entry widget, it is automatically exported to the
clipboard. To avoid this exportation, use exportselection=0.

7 fg
The color used to render the text.

8 highlightcolor
The color of the focus highlight when the checkbutton has the focus.

9 justify
If the text contains multiple lines, this option controls how the text is justified:
CENTER, LEFT, or RIGHT.

10 relief
With the default value, relief=FLAT, the checkbutton does not stand out from its
background. You may set this option to any of the other styles

11 selectbackground
The background color to use displaying selected text.

12 selectborderwidth
The width of the border to use around selected text. The default is one pixel.

Page 9 of 65
Unit – 4 Regular Expressions
13 selectforeground
The foreground (text) color of selected text.

14 show
Normally, the characters that the user types appear in the entry. To make a
.password. entry that echoes each character as an asterisk, set show="*".

15 state
The default is state=NORMAL, but you can use state=DISABLED to gray out the control
and make it unresponsive. If the cursor is currently over the checkbutton, the state is
ACTIVE.

16 textvariable
In order to be able to retrieve the current text from your entry widget, you must set
this option to an instance of the StringVar class.

17 width
The default width of a checkbutton is determined by the size of the displayed image or
text. You can set this option to a number of characters and the checkbutton will
always have room for that many characters.

18 xscrollcommand
If you expect that users will often enter more text than the onscreen size of the
widget, you can link your entry widget to a scrollbar.

Following are commonly used methods for this widget:

Sr. Method & Description

1 delete ( first, last=None )


Deletes characters from the widget, starting with the one at index first, up to but not
including the character at position last. If the second argument is omitted, only the single
character at position first is deleted.

2 get()
Returns the entry's current text as a string.

3 icursor ( index )
Set the insertion cursor just before the character at the given index.

4 index ( index )
Shift the contents of the entry so that the character at the given index is the leftmost visible
character. Has no effect if the text fits entirely within the entry.

5 insert ( index, s )
Inserts string s before the character at the given index.

6 select_adjust ( index )
This method is used to make sure that the selection includes the character at the specified
index.

7 select_clear()
Clears the selection. If there isn't currently a selection, has no effect.

Page 10 of 65
8 select_from ( index )
Sets the ANCHOR index position to the character selected by index, and selects that
character.

9 select_present()
If there is a selection, returns true, else returns false.

10 select_range ( start, end )


Sets the selection under program control. Selects the text starting at the start index, up to
but not including the character at the end index. The start position must be before the end
position.

11 select_to ( index )
Selects all the text from the ANCHOR position up to but not including the character at the
given index.

12 xview ( index )
This method is useful in linking the Entry widget to a horizontal scrollbar.

13 xview_scroll ( number, what )


Used to scroll the entry horizontally. The what argument must be either UNITS, to scroll by
character widths, or PAGES, to scroll by chunks the size of the entry widget. The number is
positive to scroll left to right, negative to scroll right to left.
Example:
from Tkinter import *

top = Tk()
L1 = Label(top, text="User Name")
L1.pack( side = LEFT)
E1 = Entry(top, bd =5)
E1.pack(side = RIGHT)

top.mainloop()

Dialogs

Layouts (What is a layout manager?): When you create graphical interfaces, the widgets in the window
must have a way to be arranged relative to each other. For example, placing widgets can be accomplished
using their relative positions to other widgets or by defining their positions by specifying pixel locations. In
Tkinter there are three types of layout managers -- pack, place, and grid. Each manager uses a different
method to help us arrange widgets.

Pack Layout Manager: The simplest way to think about it is that the pack() method turns each individual
widget into a block. Each widget has its own size and the pack manager fits them all together just like you
would do with real blocks. Each widget already has its own size and parameters. Of course, you can change
these to better fit your needs. Once every widget's size is determined, the manager does its job to arrange
them in the window.

Let's take a moment to learn some of the basics of the pack layout manager. With pack, the manager stacks
widgets on top of each other vertically like blocks. Of course, you can also achieve a horizontal layout by

Page 11 of 65
Unit – 4 Regular Expressions
changing the side parameter to 'left' or 'right'. You can also change the height, width, and locations of the
widgets. Some of the pack manager's more useful parameters are listed below:
 side -- specifies the general location of the widget in the window, arguments are 'top', 'bottom',
'left', 'right' (default is 'top').
 fill -- which directions you want the widget to fill in the parent window, can choose 'x', 'y' directions,
or 'both'.
 padx, pady -- the number of pixels surrounding the widget to create a padding between other
widgets, for horizontal or vertical padding.
 ipadx, ipady -- how many pixels to use for padding inside the widget, also for horizontal or vertical
padding
 expand -- set to True if you want the widget to stretch if the parent window expands. Default is
False.
 anchor -- where the widget is placed in the parent widget, specified by 'n', 's', 'e', 'w', or some
combination of them. Default is 'center'.

Grid Layout Manager: I personally think that using the grid


layout manager is the easiest manager out of the three
managers that Tkinter offers. The reason is because it works
similar to a matrix, with rows and columns. The upper left-most
corner has row value 0 and column value 0. So moving around
the grid and arranging widgets is quite simple. If you want to
place widgets in a horizontal row, then the row value stays the
same and the column value increases by 1 for each widget. It is similar if you want to move down a column,
with the column value staying the same and the row value increasing. Check out the image for a visual
example. Now let's look at some of the main parameters that can help you arrange widgets using the grid
layout manager.
 row, column -- the row and column values for the location of the widget. Both start from 0.
 columnspan, rowspan -- specifies how many columns or rows a widget will be in. This is very useful
to help get the spacing right for your widgets.
 padx, pady -- the number of pixels surrounding the widget to create padding between other
widgets, for horizontal or vertical padding
 ipadx, ipady -- how many pixels to use for padding inside the widget, also for horizontal or vertical
padding
 sticky -- specifies a value of S, N, E, W, or a combination of them, e.g. NW, NE, SW, or SE. The
parameter tells which side of the "cell" the widget will "stick" to. If you use W+E+N+S, then the
widget will fill up the "cell". Default is to center the widget within the "cell".

Place Layout Manager: The place layout manager allows for you to have more absolute control about the
arrangement of your widgets. With place, you can specify the size of the widget, as well as the exact x and y
coordinates to arrange it within the parent window. In many cases, this can prove to be easier when you are
thinking about the layout of your GUI. But it also means that you may have to spend a little more time
playing around with the x and y values. The place manager is most useful for arranging buttons or other
smaller widgets together within a larger dialog window. A few of the parameters you can play around with
are listed below.
 in_ -- specifies the master window for the widget
 x, y -- specifies the specific x and y values of the widget in the parent window

Page 12 of 65
 relx, rely -- horizontal and vertical offset relative to the size of the parent widget, values between 0.0
and 0.1
 relwidth, relheight -- set height and width of widget relative to the size of the parent widget, values
between 0.0 and 0.1
 anchor -- where the widget is placed in the parent widget, specified by 'n', 's', 'e', 'w', or some
combination of them. Default is 'center'

Frames: The Frame widget is very important for the process of grouping and organizing other widgets in a
somehow friendly way. It works like a container, which is responsible for arranging the position of other
widgets. It uses rectangular areas in the screen to organize the layout and to provide padding of these
widgets. A frame can also be used as a foundation class to implement complex widgets. Here is the simple
syntax to create this widget:
w = Frame ( master, option, ... )

Parameters:
 master − This represents the parent window.
 options − Here is the list of most commonly used options for this widget. These options can be used
as key-value pairs separated by commas.

Sr. Option & Description

1 bg
The normal background color displayed behind the label and indicator.

2 bd
The size of the border around the indicator. Default is 2 pixels.

3 cursor
If you set this option to a cursor name (arrow, dot etc.), the mouse cursor will
change to that pattern when it is over the checkbutton.

4 height
The vertical dimension of the new frame.

5 highlightbackground
Color of the focus highlight when the frame does not have focus.

6 highlightcolor
Color shown in the focus highlight when the frame has the focus.

7 highlightthickness
Thickness of the focus highlight.

8 relief
With the default value, relief=FLAT, the checkbutton does not stand out from its
background. You may set this option to any of the other styles

9 width
The default width of a checkbutton is determined by the size of the displayed
image or text. You can set this option to a number of characters and the
checkbutton will always have room for that many characters.

Page 13 of 65
Unit – 4 Regular Expressions
Example:
# Import Module
from tkinter import *

# Create Tkinter Object


root = Tk()

# Set Geometry
root.geometry("400x400")

# Frame 1
frame1 = Frame(root,bg="black",width=500,height=300)
frame1.pack()

# Frame 2
frame2 = Frame(frame1,bg="white",width=100,height=100)
frame2.pack(pady=20,padx=20)

# Execute Tkinter
root.mainloop()

Page 14 of 65
CS- 33 Programing in Python

Unit-5
Connecting with Database
Verifying the MySQLdb Interface Installation
The Python standard for database interfaces is the Python DB-API. Most Python database interfaces adhere
to this standard. You can choose the right database for your application. Python Database API supports a
wide range of database servers like: MySQL, SQLite, Oracle, Sybase, MS SQL Server, and Informix. We must
download a separate DB API module for each database we need to access. For example, if you need to
access an Oracle database as well as a MySQL database, you must download both the Oracle and the MySQL
database modules. The DB API provides a minimal standard for working with databases using Python
structures and syntax wherever possible. This API includes the following:
 Importing the API module.
 Acquiring a connection with the database.
 Issuing SQL statements and stored procedures.
 Closing the connection

MySQLdb is an interface for connecting to a MySQL database server from Python. It implements the Python
Database API v2.0 and is built on top of the MySQL C API. The following Packages need to Install:
 mysql-connector-python
 mysql-python

Import-Package in source code:


import MYSQLdb

The following example verify that python module is installed and connect with MySQL database server:
import MySQLdb

def mysqlconnect():
try:
db_connection= MySQLdb.connect("localhost","root","","db")
except:
print("Can't connect to database")
return 0
print("Connected")
cursor=db_connection.cursor()
cursor.execute("SELECT CURDATE();")
m = cursor.fetchone()
print("Today's Date Is ",m[0])
db_connection.close()
mysqlconnect()

Working with MySQL Database


MySQL is a fast, easy-to-use RDBMS being used for many small and big businesses. MySQL is developed,
marketed and supported by MySQL AB, which is a Swedish company. MySQL is becoming so popular because
of many good reasons:
 MySQL is released under an open-source license. So you have nothing to pay to use it.
 MySQL is a very powerful program in its own right. It handles a large subset of the functionality of
the most expensive and powerful database packages.
 MySQL uses a standard form of the well-known SQL data language.
 MySQL works on many operating systems and with many languages including PHP, PERL, C, C++,
JAVA, etc.
 MySQL works very quickly and works well even with large data sets.
 MySQL is very friendly to PHP, the most appreciated language for web development.
 MySQL supports large databases, up to 50 million rows or more in a table. The default file size limit
for a table is 4GB, but you can increase this (if your operating system can handle it) to a theoretical
limit of 8 million terabytes (TB).

Page 1 of 65
Unit – 5 Python and Data Analytics
 MySQL is customizable. The open-source GPL license allows programmers to modify the MySQL
software to fit their own specific environments.

Example to create Database in MySQL:


import mariadb as MySQLdb
conn = MySQLdb.connect(host="localhost", user="root", password="")
cursor = conn.cursor()
sql = "CREATE database MYDATABASE"
cursor.execute(sql)
print("List of databases: ")
cursor.execute("SHOW DATABASES")
print(cursor.fetchall())
conn.close()

Using MySQL from Python

Retrieving All Rows from a Table: READ Operation on any database means to fetch some useful information
from the database. Once the database connection is established, you are ready to make a query into this
database. You can use either fetchone() method to fetch a single record or fetchall() method to fetch
multiple values from a database table.
 fetchone() − It fetches the next row of a query result set. A result set is an object that is returned
when a cursor object is used to query a table.
 fetchall() − It fetches all the rows in a result set. If some rows have already been extracted from the
result set, then it retrieves the remaining rows from the result set.
 rowcount − This is a read-only attribute and returns the number of rows that were affected by an
execute() method.

Example:
import mariadb as MySQLdb
myconn = MySQLdb.connect(host="localhost", user="root", passwd="",
database="mydatabase")
cur = myconn.cursor()
try:
cur.execute("select * from employee")
result = cur.fetchall()
for x in result:
print(x)
except:
myconn.rollback()
myconn.close()

Inserting Rows into a Table: The INSERT Operation is required when you want to create your records into a
database table. Example:
import mariadb as MySQLdb
db = MySQLdb.connect(host="localhost", user="root", password="",
database="mydatabase" )
cursor = db.cursor()
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, INCOME)
VALUES ('Malay', 'Dave', 42, 5000)"""
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
db.close()

Page 2 of 65
Deleting Rows from a Table: DELETE operation is required when you want to delete some records from your
database. Following is the procedure to delete all the records from EMPLOYEE where AGE is more than 20:

import mariadb as MySQLdb

db = MySQLdb.connect(host = "localhost", user = "root", passwd = "",


database = "mydatabase")
cursor = db.cursor()
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
db.close()

Updating Rows in a Table: UPDATE Operation on any database means to update one or more records, which
are already available in the database. The following procedure updates all the records having SEX as 'M'.
Here, we increase the AGE of all the males by one year.
import mariadb as MySQLdb

db = MySQLdb.connect(host="localhost", user="root", passwd="",


database="mydatabase")
cursor = db.cursor()
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1
WHERE SEX = '%c'" % ('M')
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
db.close()

Creating Database Tables through Python: Once a database connection is established, we are ready to
create tables or records into the database tables using execute method of the created cursor. Example:

import mariadb as MySQLdb


db = MySQLdb.connect( host="localhost", user="root", password="",
database="mydatabase" )
cursor = db.cursor()
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
INCOME FLOAT )"""
cursor.execute(sql)
db.close()

Performing Transactions: Transactions are a mechanism that ensures data consistency. Transactions have
the following four properties:
 Atomicity − Either a transac on completes or nothing happens at all.
 Consistency − A transac on must start in a consistent state and leave the system in a consistent
state.

Page 3 of 65
Unit – 5 Python and Data Analytics
 Isolation − Intermediate results of a transac on are not visible outside the current transac on.
 Durability − Once a transac on was commi ed, the effects are persistent, even a er a system
failure.

The Python DB API 2.0 provides two methods to either commit or rollback a transaction.

COMMIT Operation: Commit is an operation, which gives a green signal to the database to finalize the
changes, and after this operation, no change can be reverted back. Here is a simple example to call the
commit method.
db.commit()

ROLLBACK Operation: If you are not satisfied with one or more of the changes and you want to revert back
those changes completely, then use the rollback() method. Here is a simple example to call the rollback()
method.
db.rollback()

Disconnecting Database: To disconnect the Database connection, use the close() method.
db.close()

If the connection to a database is closed by the user with the close() method, any outstanding transactions
are rolled back by the DB. However, instead of depending on any of the DB lower level implementation
details, your application would be better off calling commit or rollback explicitly.

Handling Errors: There are many sources of errors. A few examples are a syntax error in an executed SQL
statement, a connection failure, or calling the fetch method for an already canceled or finished statement
handle. The DB API defines a number of errors that must exist in each database module. The following table
lists these exceptions.

Sr. Exception & Description

1 Warning
Used for non-fatal issues. Must subclass StandardError.

2 Error
Base class for errors. Must subclass StandardError.

3 InterfaceError
Used for errors in the database module, not the database itself.
Must subclass Error.

4 DatabaseError
Used for errors in the database. Must subclass Error.

5 DataError
Subclass of DatabaseError that refers to errors in the data.

6 OperationalError
Subclass of DatabaseError that refers to errors such as the loss of
a connection to the database. These errors are generally outside
of the control of the Python scripter.

7 IntegrityError
Subclass of DatabaseError for situations that would damage the
Page 4 of 65
relational integrity, such as uniqueness constraints or foreign
keys.

8 InternalError
Subclass of DatabaseError that refers to errors internal to the
database module, such as a cursor no longer being active.

9 ProgrammingError
Subclass of DatabaseError that refers to errors such as a bad table
name and other things that can safely be blamed on you.

10 NotSupportedError
Subclass of DatabaseError that refers to trying to call
unsupported functionality.
Your Python scripts should handle these errors, but before using any of the above exceptions, make sure
your MySQLdb has support for that exception. You can get more information about them by reading the DB
API 2.0 specification.

Page 5 of 65

You might also like