0% found this document useful (0 votes)
32 views

Python

Uploaded by

mohitkulhary30
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views

Python

Uploaded by

mohitkulhary30
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 144

Python

Core and Advance

[email protected]
HIMANSHU RASTOGI
INTRODUCTION TO PYTHON
Python Introduction
Python is a widely used general-purpose, high level programming language. It was created by Guido
van Rossum in 1991 and further developed by the Python Software Foundation. It was designed with
an emphasis on code readability, and its syntax allows programmers to express their concepts in fewer
lines of code.
Python is an easy to learn, powerful programming language. It has efficient high-level data structures
and a simple but effective approach to object-oriented programming. It is optiized for softwaare
quality, developer productivity, program protability and component integration. Python is used by
atleast hundreds of thousands of developers around the world in areas such as Internet Scripting,
System programming, user interface, product customization, numeric programming and more.
As a popular language focused on shrinking development time, Python is deployed in a wide variety
of products and roles. Counted among its current user base are Google, YouTubem Industrial Light &
magic, ESRI, the BitTorrent file sharing system etc.
Getting Python
The Python interpreter and the extensive standard library are freely available in source or binary form
for all major platforms from the Python Web site, https://www.python.org/, and may be freely
distributed. The same site also contains distributions of and pointers to many free third party Python
modules, programs and tools, and additional documentation.

Running Python
Two different way to start Python:
1. Python Command Line Interpreter (Python Shell)
2. Python IDLE (Integrated Development and Learning Environment)

PYTHON COMMAND LINE INTERPRETER


Python command line interpreter is a simple command line window. Any command in command line
interpreter is done by commands. Python command line interpreter is a bit less user friendly.

PYTHON IDLE (Integrated DEVELOPMENT AND LEARNING ENVIRONMENT)


Python IDLE is a GUI interface.
The menus and options are provided in the IDLE to perform various tasks.
It’s like a normal editor and it’s very easy to work with. This is more user friendly than the python
command line interpreter.
However, you can run python code by writing it in another editor and saving it with .py extension. But
in IDLE you have provided all the options available from the time you write to run the program.
Using Comments
The comments (documentation) section help in keeping track of what a particular line of code or a
block code is performing.

1
Python have two type of documentation –
Example:
Single Line Comment
# This is a python single line comment.
Multi Line Comment
“““
Program compiled at Nai Sadak
Meerut” ” ”

Keyword’s
Keyword’s are the reserved word in python. A keyword can not be used as a variable name, function
name or any other indentifier. In Python keyword are case sensitive. Keywords are used to define the
syntax and structure of the language. There are 33 keyword in python.
and False nonlocal as finally
not assert for or break
from pass class global raise
continue if return def import
True del in try elif
is while else lambda with
excet None yield
Constants
A constant (or literal) is a quantity that does not change. A variable is a representation for a quantity
which can vary. The constant (literal) and variables (identifiers) are combined to form an instruction.
Example: - Constant.py
a=3
b = 5.7

Variables and Identifiers


Variables is a data name that may be used to store a data value. it are the named memory location
which can store value and there value can change at run time.
Rules for Constructing Identifier Name
➢ The first character in the identifier name must be a letter. (The underscore _counts as a letter).

➢ An identifier name is any combination of 1 to 8 alphabets, digits or underscores.


➢ Commas or blanks are not allowed within an identifier name.
➢ No special symbol other than an underscore can be used in an identifier name.
➢ Keywords are not allowed as an identifier name.
➢ Identifier name is case sensitive.

2
What’s typle() function
The type of data value that can be stored in an identifier such as variable is known as its data type
type() function
The function type() can be used to determine which class a variable or a value belongs to.
Syntax type(dataValue)

isinstance() function
The function isinstance() is used to check if an obect belongs to a particular class.
Syntax isinstance(dataValue, dataType)
>>> a=23
>>> b=43.32
>>> c= 'Hello Python'
>>> type(a)
<class 'int'>
>>> type(b)
<class 'float'>
>>> type(c)
<class 'str'>
>>> isinstance(a, int)
True
>>> isinstance(c, float)
False
Literals
The data that is provided in the variable are known as literals in Python. Python supports the following
literals: -
Python support the following literals: -
1) String Literals
2) Numeric Literals
3) Boolean Literals
4) None Literal
5) Literal Collections such as List, Tuples, Dictionary
String Literal
Single quotes or double quotes are used to defined by String literals. There are two kinds of strings
supported in Python, single line and multiline string literals.
Example: -
name = 'Python' #Single line string
#Multiline string
name2 = ''' This is
multiline
string '''

3
Numeric Literals
A number can be directly assigned to variables in Python. They are immutable. Numeric literals can
belong to following four different numerical types.
Int: numbers can be both positive and negative) with no fractional part. e.g. 432
Long: Integers of unlimited size followed by lowercase or uppercase L. e.g. 1422L
Float: Real numbers with both integer and fractional part. e.g. -26.2
Complex: In the form of a + bj where a forms the real part and b forms the imaginary part of a complex
number.
e.g. 1 + 2j

Boolean Literals
A Boolean Literal can have True or False value.
None Literal
Python contains a special type of literal known as None. It specifies the field that is not created. and
also can indicate the end of lists in Python.
Literal Collections
There are 4 different literal collections: List Literals, Tuple Literals, Dict Literals, and Set Literals.

List
List is an ordered sequence of items all the items in a list do not need to be of the same type.
Examples: -
>>> colors = ["red", "green", "yellow"] #list
>>> type(colors)
<class ‘list’>
>>> colors[0]
'red'
>>> colors[1]
'green'
>>> colors[-1]
'yellow'
>>> l = [32,57,57,54,86,4,57,5,34,6,57,6,86,6756,4,5]
>>> l[3:7]
[54, 86, 4, 57]
>>> l[4:]
[86, 4, 57, 5, 34, 6, 57, 6, 86, 6756, 4, 5]
>>> l[:7]
[32, 57, 57, 54, 86, 4, 57]
>>> l[1:8:2]
[57, 54, 4, 5]
>>> l[::]
[32, 57, 57, 54, 86, 4, 57, 5, 34, 6, 57, 6, 86, 6756, 4, 5]
>>> l[::-1]

4
[5, 4, 6756, 86, 6, 57, 6, 34, 5, 57, 4, 86, 54, 57, 57, 32]
>>> l.append(5)
>>> l
[32, 57, 57, 54, 86, 4, 57, 5, 34, 6, 57, 6, 86, 6756, 4, 5, 5]
>>> l.insert(5,333)
>>> l
[32, 57, 57, 54, 86, 333, 4, 57, 5, 34, 6, 57, 6, 86, 6756, 4, 5, 5]
>>> del l[4]
>>> l
[32, 57, 57, 54, 333, 4, 57, 5, 34, 6, 57, 6, 86, 6756, 4, 5, 5]
>>> l.remove(57)
>>> l
[32, 57, 54, 333, 4, 57, 5, 34, 6, 57, 6, 86, 6756, 4, 5, 5]
>>> l.pop()
5
>>> colors[1]
'green'
>>> colors[1][2]
'e'
>>>
Tuple
Tuple is an ordered sequence of items same as list. The only difference between list and tuple is that
typles are immutable, i.e., tuple once created cannot be modified.
Example: -
>>> numbers = (101, 202, 304) #tuple
>>> type(numbers)
<class 'tuple'>
Set
Set is an unordered collection of unique items.
>>> s = {32,5,34,6,57,56,34,34,6,44,34,534,32,57,6} #set
>>> s
{32, 34, 5, 6, 44, 534, 56, 57}
>>> type(s)
<class 'set'>
>>> s[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable
>>>
Dictionary
Dictionaries is an unordered collection of key value pairs. It is generally used to operate on huge
amount of data.
Example -
>>> person = {'name':'Himsnshu', 'address':' Shastri
Nagar'} #dictionary

5
>>> person['name']
'Himsnshu'
>>> person['address']
' Shastri Nagar'
>>> person['mobno']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'mobno'
>>> person['mobno'] = 7251838064
>>> person
{'name': 'Himsnshu', 'address': ' Shastri Nagar', 'mobno': 7251838064}
>>> del person['mobno']
>>> person
{'name': 'Himsnshu', 'address': ' Shastri Nagar'}
>>>
Files
Represents data that can be stored permanently as a document in a computer.

6
Input/Output
Accepting input from Console
Input in Python
To receive information through the keyboard, Python uses either the input([prompt]) function.
These functions have an optional parameter, commonly known as prompt, which is a string that will
be printed on the screen whenever the function is called.
Example: -
>>> n=input('Enter any number: ')
Enter any number: 67
>>> type(n)
<class 'str'>
Python have two functions, int() to convert string to int and float() function convert string to float.
>>> n=int(n)
>>> type(n)
<class 'int'>
>>>n=input('Enter a number: '))
Enter a number: 56.332
>>> n=float(n)
>>> type(n)
<class float>
eval(expression) function
The python eval() is a built-in function that allows us to evaluate the Python expression as a string and
return the value as a number.
>>>p=eval(input('Enter any number: ')
Enter any number: 67
>>>type(p)
<class 'int'>
>>>print(n, p)
'67' 67
>>> e = eval('78+90+8-5')
>>> e
171
>>>name=input('Enter your name: ')
Enter your name: Himanshu
>>>name
'Himanshu'
>>>
Output in Python
The function print() is used to output data to the standard output device, i.e, on monitor screen.
The arguments of the print function are the following ones:

print(*args, sep =' ', end='\n', file=sys.stdout, flush=False)

7
The print function can print an arbitrary number of values ("value1, value2, ..."), which are separated
by commas. These values are separated by blanks.

>>>a=6
>>>b=2
>>>c=a+b
>>>d=a-b
>>>print('c=', c)
c=8
>>>print('d=', d)
d=4
>>> print("a","b")
a b
>>> print("a","b",sep="")
ab
>>> print(192,168,178,42,sep=".")
192.168.178.42
>>> print("a","b",sep="@")
a@b
String.format(…) function
>>>print('Value of a is {} b is {} and c is {}'.format(a,b,c))
Value of a is 6 b is 2 and c is 8
>>>print('Value of a is {a} b is {b} and c is {c}'.format(a=a,c=c,b=b))
Value of a is 6 b is 2 and c is 8
Use data specifier
>>>print('Value of a is %d b is %d and c is %d'%(a,b,c))
Value of a is 6 b is 2 and c is 8
>>>print('Hello %s, %s'%('World','Good Morning!'))
Hello World, Good Morning!

8
Simple ‘Python’ programs
#add two number using
a = 7; b = 6
c=a+b
print('c=',c)
Output: -
c=13

#Hello program
name=input('Enter your name: ')
print('Hello,'+ name +'from Nav Bharat')
Output: -
Enter your name: Himanshu
Hello, Himanshu from Nav Bharat

#Swap number using third variable


a=input("Enter first number:")
b=input("Enter second number:")
t=a
a=b
b=t
print("a = %d\nb = %d"%(a,b))
Output: -
Enter first number:56
Enter second number:67
a=67
b=56

# Compute Avaerage
number1, number2, number3 = eval(input("Enter three numbers separated by commas: "))
# Compute average
average = (number1 + number2 + number3) / 3
# Display result
print("The average of", number1, number2, number3,"is", average)
Output: -
Enter three numbers separated by commas: 7, 8, 6
The average of 7 8 6 is 7.0

Exercise: -
1. Calculate simple interest (Amount, Rate and Time entered by user.).
2. Write a program to read the values of a, b and c and display the value of x, where
x=a/b-e
Test your program for the following values:
(a) a = 250, b = 85, e = 25
9
(b) a = 300, b = 70, c = 70 2.5
3. Write a Python program that will ask for a temperature in Fahrenheit and display in Celsius.
[Hint: c = 5/9 *(F-32)]
4. Write a Python program to calculate the area of Triangle. [Hint: a=1/2(b × h)]
5. (Convert Celsius to Fahrenheit) Write a program that reads a Celsius degree from the console and
converts it to Fahrenheit and displays the result. The formula for the conversion is as follows:
fahrenheit = (9 / 5) * celsius + 32
Here is a sample run of the program:
Enter a degree in Celsius: 43
43 Celsius is 109.4 Fahrenheit
6. (Convert feet into meters) Write a program that reads a number in feet, converts it to meters, and
displays the result. One foot is 0.305 meters. Here is a sample run:
Enter a value for feet: 16.5
16.5 feet is 5.0325 meters
7. (Convert pounds into kilograms) Write a program that converts pounds into kilograms. The
program prompts the user to enter a value in pounds, converts it to kilograms, and displays the
result. One pound is 0.454 kilograms. Here is a sample run:
Enter a value in pounds: 55.5
55.5 pounds is 25.197 kilograms
8. (Print a table) Write a program that displays the following table:
a b a ** b
1 2 1
2 3 8
3 4 81
4 5 1024
5 6 15625

9. (Split digits) Write a program that prompts the user to enter a four-digit integer and displays the
number in reverse order. Here is a sample run:
Enter an integer: 3125
3
1
2
5

10
Operators, Expressions and Python Statements
Operators
Operators are special symbols which represents computation. They are applied on operand(s), which
can be values or variables. Same operator can behave differently on different data types. Operators
when applied on operands form an expression. Operators are categorized as Arithmetic, Relational,
Logical and Assignment. Value and variables when used with operator are known as operands.

Expressions
In Python, operators are special symbols that designate that some sort of computation should be
performed. The values that an operator acts on are called operands. A sequence of operands and
operators, like a + b - 5, is called an expression. Python supports many operators for combining data
objects into expressions.

Arithmetic operators
Arithmetic Operators perform various arithmetic calculations like addition, subtraction,
multiplication, division, %modulus, exponent, etc. There are various methods for arithmetic
calculation in Python like you can use the eval function, declare variable & calculate, or call functions.

Mathematical/Arithmetic Operators
Symbol Description Example 1 Example 2
+ Addition >>>67+78 >>> ‘Himanshu’ + ‘Rastogi’
140 Himanshu Rastogi
- Subtraction >>>56-26 >>>30-40
30 -10
* Multiplication >>>4*5 >>> ‘PCC’*3
20 PCCPCCPCC
/ Division >>>34/3 >>>45/5
11.33333334 9.0
% Remainder/Modulo >>>22%5 >>>27%2
2 1
** Exponentiation >>>16**2 >>>12.5**3
256 156.25
// Integer Division >>7.3//2 >>>15//2
3.0 7
Relational operators
Relational operators are symbols that perform operations on data and return a result as true or false
depending on the comparison conditions. Thus, they are certain functionalities that do something
with your variables. Relational operators can be used to compare numbers as well as strings.

11
operators:
RELATIONAL OPERATOR DESCRIPTION EXAMPLE
> Greater than >>>44>7
True
>>>34>78
False
< Less than >>>67<78
True
>>>56<4
False
>= Greater than or equal to >>>67>=55
True
>>>56>=77
False
<= Less than or equal to >>>56<=78
True
>>>34<=12
False
== Equals >>>56==88
False
>>>45==45
True
!= Not equal to >>>67!=54
True
>>>55!=55
False
Logical operators
A boolean expression (or logical expression) evaluates to one of two states true or false. Python
provides the boolean type that can be either set to False or True. Many functions and operations
returns boolean objects.
SYMBOL DESCRIPTION
or If any one of the operand is true, then the condition becomes true.
23>12 or 12>9
True
56>9 or 59>90
True
67>98 or 4>8
False
and If both the operands are true, then the condition becomes true.
23>12 and 12>9
True
56>9 and 59>90
12
False
67>98 or 4>8
False
not Reverses the state of operand/condition.
not(78>23)
False
not(73>98)
True
Bitwise operators and their precedence
Python Bitwise operators help perform bit operations. All the decimal values will convert into binary
values (bits sequence i.e., 0100, 1100, 1000, 1001, etc.). Next, Python bitwise operators work on these
bits, such as shifting left to right or transforming bit value from 0 to 1, etc.
The below table shows the different Python Bitwise operators and their meaning. For example,
consider x = 6 and y = 8 and their values in binary form are
X=0110
Y=1000
PYTHON MEANING OF EXAMPLES ANSWER EXPLAIN
BITWISE OPERATORS
OPERATORS
& Bitwise AND X&Y 00 X = 0110
Y= 1000
0000
| Bitwise OR X|Y 1110 X = 0110
Y = 1000
1110
^ Bitwise exclusive X^Y 1110 X = 0110
OR Y = 1000
1110
~ Bitwise ~X 00001001 Bitwise Not operator will
complement convert all 0 into 1.
<< Shift Left X << 1 00001100 Bits will move 1 step left. If
we use 2 or 3 then they
shift.
>> Shift Right Y >> 1 00000100 Bits will move 1 step right. If
we use 2 or 3 then they
shift.

Assignment statement
An assignment statement associates a variable name on the left of the equal sign with the value of an
expression calculated from the right of the equal sign.
OPERATOR EXAMPLE

13
= width = 67 a = 7; b = 9
+= a += b a=a+b
a = 16
-= a -= b a=a-b
a -= 2
*= a *= b a=a*b
a = 63
/= a /= b a=a/b
a = 0.77777778
//= a //= b a = 11; b = 2
a = a // b
a=5
%= a %= b a = 11; b = 2
a=a%b
a=1
Example: - # Variable width and assigned value 67
Once a variable is assigned a value, the variable can be used in place of that value. The response to
the expression width is the same as if its value had been entered.

Membership Operator
In python, there are two types of membership operators: ‘in’ and ‘not in’. These operators are used
to test whether a value or variable is a member of a sequence, such as a string, list or tuple.

OPERATOR DESCRIPTION

in 45 in [67,98,45,88,22]
True
67 in [56,87,66,45,78,5]
False
not in 45 not in [67,98,45,88,22]
False
67 not in [56,87,66,45,78,5]
True

Identity Operators
Identity operators are used to compare the objects, not if they are equal, but if the are actually the
same object, with the same memory loaction:

OPERATOR EXAMPLE

is x=[10,11]
y=[10,11]
x=z

14
x is y
False
return false because x is not the same object as y, even if they
have the same content.
x is z
True
return true because z is the same object as x
is not X=[10,11]
y=[10,11]
x=z
x is y
True
return True because x is not the same object as y, even if they
have the same content.
x is z
False
return False because z is the same object as x

15
Conditional statements
Programming often involves examing a set of conditions and deciding which action to take based on
those conditions.
if statement
The if statement will execute a single statement, or a group of statements, when the condition
following if is true. It does nothing when it is false. The general syntax is
if (conditions):
Statement(s)
To execute an if statement, we first determine whether the Condition is true or false.
In Python, the body of the if statement is indicated by the indentation. Body starts with an indentation
and the first unindented line marks the end.

Example: Even.py
n = int(input('Enter any number '))
if n%2 == 0:
print(n, 'is even')
print('Out of if block')

Output
Enter any number 42
42 is even
Out of if block
if-else Statement
The else statement can be used with ‘if’ statement, if ‘if’ condition become false than ‘else’ condition
will be executed.

Syntax:
if (condition):
Statement(s) #Action block 1: Execute when condition is true
else:
Statement(s) #Action block 2 : Execute when condition is false
Example: evenOdd.py
n = int(input('Enter any number '))
if n%2 == 0:
print(n, 'is even')
else:
print(n, 'is odd')
Output
Enter any number 62
62 is even

Enter any number 55

16
55 is even
If…elif […elif…]else
The elif statement allows you to check multiple expressions for true and execute a block of code as
soon as one of the conditions evaluates to true. It is similar to if… else if … else consturct fo C, C++
and Java.
Syntax of if...elif...else: -
if test expression:
#Body of if
elif test expression:
#Body of elif


else:
#Body of else
The elif is short for else if.

Example – Find Division


p = int(input('Enter percentage '))
if p>=60:
print('First Division')
elif p>=45:
print('Second Division')
elif p>=33:
print('Third Division')
else:
print('Fail')
Output
Enter percentage 78
First

Enter percentage 34
Third

Enter percentage 30
Fail

Nested if Statement
It is the condtion when we use ‘if’ condition within another ‘if’. In nested if, we can check multiple
condition but the next condition will be tested if first is true.
Syntax:
if condition:
#statement(s)
if condtion:
17
#statement(s)
else:
#statement(s)
else:
#statement(s)

Example: Find Result


n1 = int(input('Enter first subject marks '))
n2 = int(input('Enter second subject marks '))
n3 = int(input('Enter third subject marks '))
if n1>=33 and n2>=33 and n3>=33:
if n1>=75 or n2>=75 or n3>=75:
print('Pass with Distinction')
else:
print('Pass')
else:
print('Fail')

Python match-case statement


It is used to check multiple condition like 'else if', but the condition of equality can check. The control
statement that allows us to make a decision from the number of choices is called a match.
Syntax
match expression:
case label:
#statement(s)
case label:
#statement(s)


case _:
#statement(s)

Example – match simple calculator


a = int(input('Enter a number '))
b = int(input('Enter a number '))
print('Press 1 to Add')
print('Press 2 to Sub')
print('Press 3 to Mult')
print('Press 4 to Div')
c = int(input('Enter choice '))
match c:
case 1:
print('Addition is', a+b)
case 2:
print('Subtraction is', a-b)

18
case 3:
print('Product is', a*b)
case 4:
print('Div is', a/b)
case _:
print('Invalid choice')
Ternary Operator (if … else)
Syntax
Variable_name = <true block> if <condition> else <false block>
Example
>>> a = 72 if 72 > 64 else 64
>>> a
72
Operator Precedence and Associativity
Operator precedence and associativity determine the order in which operators are evaluated.
Operator precedence and operator associativity determine the order in which Python evaluates
operators. Suppose that you have this expression:
3 + 4 * 4 > 5 * (4 + 3) – 1
What is its value? What is the execution order of the operators?
Arithmetically, the expression in the parentheses is evaluated first. (Parentheses can be nested, in
which case the expression in the inner parentheses is executed first.) When evaluating an expression
without parentheses, the operators are applied according to the precedence rule and the associativity
rule.
Operator Precedence Chart
PRECEDENCE OPERATOR
+, - (Unary plus and minus)
** (Exponentiation)
not
*, /, //, % (Multiplication, division, integer division, and remainder)
+, - (Binary addition and subtraction)
<=, >, >= (Comparison)
==, != (Equality)
and
or
=, +=, -=, *=, /=, //=, %= (Assignment operators)

Exercise
1. (Check a number) Write a program that prompts the user to enter an integer and checks
whether the number is divisible by both 5 and 6, divisible by 5 or 6, or just one of them (but not
both). Here is a sample run:
Enter an integer: 10
Is 10 divisible by 5 and 6? False

19
Is 10 divisible by 5 or 6? True
Is 10 divisible by 5 or 6, but not both? True
2. (Palindrome number) Write a program that prompts the user to enter a three-digit integer and
determines whether it is a palindrome number. A number is a palindrome if it reads the same
from right to left and from left to right.

20
Loops
The computer is capable to perform a set of instructions repeatedly. This involves repeating some
portion of the program either a specified number of times or until a particular condition is being
satisfied. This repetitive operation is done through a loop control structure.
There are three methods by which we can repeat a part of a program. They are:
1. Using a while statement.
2. Using a for statement.
while Statement
The while loop is ideally suited for doing something a fixed number of time. The general form of while
is as shown below:
initialize loop counter
while (test loop counter using a condition):
# statement(s)
# increment loop counter
else:
# statement(s)
# Print 1 to 10 numbers
i = 1
while i<=10:
print(i, end=' ')
i+=1
Output
1 2 3 4 5 6 7 8 9 10

# Print 10 to 1 numbers
Try yourself

# Print 1 to 10 even numbers


i = 1
while i<=10:
if i%2 == 0:
print(i, end=' ')
i+=1
Output
2 4 6 8 10

# Print 10 to 1 odd numbers


Try yourself

#Print sum 1 to 10 numbers


i = 1; sum = 0
while i<=10:
sum+=i
21
i+=1
print('Sum is', sum)
Output
Sum is 55

# Print factorial of any number


n = int(input('Enter a number '))
i = 1; factorial = 1
while i<=5:
factorial*=i
i+=1
print('Factorial is', factorial)
Output
Enter a number 5
Factorial is 120

else statement with while loop


If the else statement is used with a while loop, the else statement is executed when the test expression
evaluates to false.
n=5
while(n>0):
print(n, end=' ')
n-=1
else:
print('\nThe value of n is zero')
Output
54321
The value of n is zero

Infinite Loop
A loop becomes infinite loop if a condition never becomes false.
while True:
print("Type ctrl + c to stop me!")

Break Statement
The break statement causes an immediate exit from a loop. Because the code following it in the loop
is not executed if the break is reached. You can also sometime avoid nesting by including a break.
# Check number is prime or not
n = int(input('Enter a number '))
divisior = 2
while divisior <= n//2:
if n%divisior == 0:
print('Not Prime number')

22
break
divisior+=1
else:
print('Prime number')
Continue Statement
The continue statement causes an immediate jump to the top of a loop. It also sometime lets you
avoid statement nesting.
Example:
x = 10
while x:
x -= 1
if x%2 != 0:
continue
print(x, end=' ')
Output
86420
Pass Statement
Simple things first: the pass statement is a no-operation placeholder that is used when the syntax
requires a statement, but you have nothing useful to say. It is used to code an empty body for a
compound statement.
Example:
while True:
pass
# Write a program to check number is prefect or not [Hint: 6 = 1+2+3, 28 = 1+2+4+7+14]
# Program to Print Fabonnic Series
n1, n2 = 0, 1
i=3
print(n1, n2, end=' ')
while i<=10:
n3 = n1+n2
print(n3, end=' ')
n1, n2 = n2, n3
i+=1

Output
0 1 1 2 3 5 8 13 21 34

# Print table of any number


n = int(input('Enter a number '))
i=1
while i<=10:
print(n*i, end=' ')
i+=1
Output

23
Enter a number 4
4 8 12 16 20 24 28 32 36 40

for loop
The for loop is a generic sequence iterator in Python: it can step through the items in any ordered
sequence object. The for statement work on strings , list, tuple and any built-in iterables.
Iteration over a sequence is also called traversing.

The general form of for statement is as under:


for val in sequence:
# statement (s)
else:
# statement(s)
Here, val is the variable that takes the value of the item inside the sequence on each iteration.
# Example 1
for x in ['Delhi', 'Mumbai', 'Chennai', 'Kolkata']:
print (x, end=' ')
Output
Delhi Mumbai Chennai Kolkata
# Example 2
sum = 0
for x in [1,2,3,4,5]:
sum+=x
print('Sum is', sum)
Output
Sum is 15
# Example 3
t = [(1, 2), (3, 4), (5, 6)]
for (a, b) in t:
print(a, b)
Output
12
34
56
# Example 4
d = {'a': 1,'b': 2,'c': 3}
for k in d:
print(k, end=' ')
Output
abc
# Example 5
24
d = {'a': 1,'b': 2,'c': 3}
print(d.items())
for (k, v) in d.items():
print(k, '->', v)
Output
dict_items([('a', 1), ('b', 2), ('c', 3)])
a -> 1
b -> 2
c -> 3

range() function
The range() function is quite useful in Python language. It is used to generate a sequence of numbers.
It is used with for loop and it generate list of arithmetic progression.
Syntax
range([start], stop, [step])
start: (Optional) By default value 0.
Stop: Required.
Step: (Optional) By default step size is 1.
Example:
>>> range(12)
range(0, 12)
>>> list(range(12))
[0,1,2,3,4,5,6,7,8,9,10,11]
>>> list(range(2, 12))
[2,3,4,5,6,7,8,9,10,11]
>>> list(range(2,12,2))
[2,4,6,8,10]
>>> list(range(5, -5, -1))
[5,4,3,2,1,0,-1,-2,-3,-4]
Iteration using for and while loop
# for loop iteration # while loop iteration
x = 'abcde' x = 'abcde'
for c in x: i=0
print(c, end=' ') while i<len(x):
print(x[i], end=' ')
i+=1
Output
abcde
Traversals: range and slices
# range traversals # slices traversals
x = 'abcdefghijk' x = 'abcdefghijk'
for i in range(0, len(x), 2): for i in x[::2]:
25
print(x[i], end=' ') print(i, end=' ')
Output
acegik
Parallel Traversals: zip
The built-in zip() function allows us to use for loops to visit multiple sequences in parallel. In basic
operation, zip takes one or more sequence as arguments and returns a series of tuples that pair up
parallel item taken from those sequence.

>>> l1 = [1,2,3,4]
>>> l2 = [5,6,7,8]
>>> zip(l1, l2)
<zip object as 0x0265233534f3>
>>> list(zip(l1, l2))
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>> t1, t2, t3 = (1,2,3) , (4,5,6), (7,8,9)
>>> t3
(7,8,9)
>>> list(zip(t1, t2, t3))
[(1,4,7), (2,5,8), (3,6,9)]
Moreover, zip truncates result tuples at the length of the shortest swquence when the argument
lengths differ.

>>> s1 = 'abc'
>>> s2 = 'xyz123'
>>> list(zip(s1, s2))
[('a', 'x'), ('b', 'y'), ('c', 'z')]
With for loop
l1 = [1,2,3,4]
l2 = [5,6,7,8]
for i,j in zip(l1, l2):
print(i, '->', j)
Output
1 -> 5
2 -> 6
3 -> 7
4 -> 8

# Print Table
n = int(input('Enter a number '))
for i in range(1,11):
print(n*i, end=' ')
Output
3 6 9 12 15 18 21 24 27 30
# Check number is Armstrong or not
n = input('Enter a number ')

26
sum = 0
for i in n:
sum = sum + int(i)**3
if sum == int(n):
print('Armstrong number')
else:
print('Not armstrong number')

#Check number is palindrom or not


n = input('Enter a number ')
rev = 0
for i in range(len(n)-1,-1,-1):
rev = rev *10 + int(n[i])
if rev == int(n):
print('Palindrom number')
else:
print('Not Palindrom number')

# Conversion binary to decimal


# Converison decimal to binary

Nesting of Loops
Loops can be nested one within another.

# Print 1 to n prime number


number = int(input('Enter a number '))
for n in range(1,number+1):
for divisior in range(2,n//2):
if n%divisior == 0:
break
else:
print(n, end=' ')
Output
Enter a number 100
1 2 3 4 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
# Print 1 to n Prefect number
number = int(input('Enter a number '))
for n in range(1,number+1):
sum = 0
for divisior in range(1,n//2+1):
if n%divisior == 0:
sum = sum + divisior
if sum == n:
print(n, end=' ')
Output
27
Enter a number 10000
6 28 496 8128
# Print 1 to n factorial number
# Patterns
# Pattern 1 # Pattern 2
n = int(input('Enter number of lines ')) n = int(input('Enter number of lines '))
for i in range(1, n+1): for i in range(n, 0, -1):
print('*'*i) print('*'*i)
Output Output
Enter number of lines 5 Enter number of lines 5
* *****
** ****
*** ***
**** **
***** *
# Pattern 3 # Pattern 4
n = int(input('Enter number of lines ')) n = int(input('Enter number of lines '))
for i in range(n*2-1, 0, -2): for i in range(1, n*2, 2):
print('*'*i) print('*'*i)
Output Output
Enter number of lines 5 Enter number of lines 5
********* *
******* ***
***** *****
*** *******
* *********
# Pattern 5 # Pattern 6
n = int(input('Enter number of lines ')) n = int(input('Enter number of lines '))
s = (n*2)//2 s = 0
for i in range(1, n*2, 2): for i in range(n*2-1,0,-2):
print(' ' * s, end='') print(' ' * s, end='')
print('*'*i) print('*'*i)
s -= 1 s += 1
Output Output
Enter number of lines 5 Enter number of lines 5
* *********
*** *******
***** *****
******* ***
********* *

28
Exercise
1. (Count positive and negative numbers and compute the average of numbers) Write a program
that reads an unspecified number of integers, determines how many positive and negative values
have been read, and computes the total and average of the input values (not counting zeros). Your
program ends with the input 0. Display the average as a floating-point number. Here is a sample run:
Sample run 1:
Enter an integer, the input ends if it is 0: 1
Enter an integer, the input ends if it is 0: 2
Enter an integer, the input ends if it is 0: -1
Enter an integer, the input ends if it is 0: 3
Enter an integer, the input ends if it is 0: 0
The number of positives is 3
The number of negatives is 1
The total is 5
The average is 1.25
Sample run 2:
Enter an integer, the input ends if it is 0: 0
You didn't enter any number

2. (Financial application: compute future tuition) Suppose that the tuition for a university is
$10,000 this year and increases 5% every year. Write a program that computes the tuition in ten
years and the total cost of four years’ worth of tuition starting ten years from now.

3. (Find numbers divisible by 5 and 6) Write a program that displays, ten numbers per line, all the
numbers from 100 to 1,000 that are divisible by 5 and 6. The numbers are separated by exactly one
space.

4. (Find the factors of an integer) Write a program that reads an integer and displays all its smallest
factors, also known as prime factors. For example, if the input integer is 120, the output should be
as follows:
2, 2, 2, 3, 5

5. (Display prime numbers between 2 and 1,000) Display all the prime numbers between 2 and
1,000, inclusive. Display eight prime numbers per line.

6. (Perfect number) A positive integer is called a perfect number if it is equal to the sum of all of its
positive divisors, excluding itself. For example, 6 is the first perfect number, because 6 = 3 + 2 + 1. 28
= 14 + 7 + 4 + 2 + 1
The next is There are four perfect numbers less than 10,000. Write a program to find these four
numbers.

7. (Display prime numbers between 2 and 1,000) Modify Listing 5.13 to display all the prime
numbers between 2 and 1,000, inclusive. Display eight prime numbers per line.

8. (Display numbers in a pyramid pattern) Write a nested for loop that displays the

29
following output:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1

30
Sequence Data Types
Lists
A list can store a collection of data of any size.
Python provides a type called a list that stores a sequential collection of elements.
In Python, square brackets ([]) indicate a list, and individual elements in the list are separated by
commas.

Example: -
>>> courses = ['MS Office', 'Tally', 'DTP', 'CCC', 'O Level']
>>> print(courses)
['MS Office', 'Tally', 'DTP', 'CCC', 'O Level']
Example: - Accessing Elements in a List
>>> courses = ['MS Office, 'Tally', 'DTP', 'CCC', 'O Level']
>>> print(courses[0])
'MS Office'
You can also use the string methods on any element in a list. For example, you can format the element
'trek' more neatly by using the title() method:

>>> courses = ['ms office', 'tally', 'dtp', 'ccc', 'o level']


>>> print(courses[0].title())
This example produces the same output as the preceding example except 'Ms Office' is capitalized.
Note: Python considers the first item in a list to be at position 0, not position 1. The second item in a
list has an index of 1.
Changing, Adding, and Removing Elements
Example: - Modifying Elements in a List
>>> list = [2, 3, 6, 8, 10, 12, 14]
>>> list[1] = 4
>>> print(list)
[2, 4, 6, 8, 10, 12, 14]
Adding Elements to a List
Example - Appending Elements to the End of a List
>>> list = [2, 4, 6, 8, 10, 12, 14]
>>> list.append(16)
>>> print(list)
[2, 4, 6, 8, 10, 12, 14, 16]
Example: -
motorcycles = []
motorcycles.append('honda')
motorcycles.append('yamaha')
motorcycles.append('suzuki')
print(motorcycles)
Output: -

31
['honda', 'yamaha', 'suzuki']

Example: - Inserting Elements into a List


>>> l = [2, 4, 6, 8, 10, 12, 14, 16]
>>> l.insert(1,3)
>>> print(l)
[2, 3, 4, 6, 8, 10, 12, 14, 16]
Example: - Removing Elements from a List
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
del motorcycles[0]
print(motorcycles)
Output: -
['honda', 'yamaha', 'suzuki']
['yamaha', 'suzuki']

Example: - Removing an Item by Value


>>> l = [2, 3, 4, 6, 8, 10, 12, 14, 16]
>>> l.remove(3)
>>> print(l)
[2, 4, 6, 8, 10, 12, 14, 16]
Sorting a List Permanently with the sort() Method
cars = ['bmw', 'audi', 'toyota', 'ferrari']
cars.sort()
print(cars)
The sort() method, changes the order of the list permanently. The cars are now in alphabetical order,
and we can never revert to the original order:
['audi', 'bmw', 'ferrari’, 'toyota']

Sorting a List Temporarily with the sorted() Function


To maintain the original order of a list but present it in a sorted order, you can use the sorted()
function. The sorted() function lets you display your list in a particular order but doesn’t affect the
actual order of the list.
Let’s try this function on the list of cars.

cars = ['bmw', 'audi', 'toyota', 'ferrari']


print("Here is the original list:")
print(cars)
print("\n Here is the sorted list:")
print(sorted(cars))
print("\n Here is the original list again:")
print(cars)
Output: -
Here is the original list:
32
['bmw', 'audi', 'toyota', 'ferrari']
Here is the sorted list:
['audi', 'bmw', 'ferrari', 'toyota']
Here is the original list again:
['bmw', 'audi', 'toyota', 'ferrari']

Example: - Printing a List in Reverse Order


cars = ['bmw', 'audi', 'toyota', 'ferrari']
print(cars)
cars.reverse()
print(cars)
Notice that reverse() doesn’t sort backward alphabetically; it simply reverses the order of the list:
['bmw', 'audi', 'toyota', 'ferrari']
['ferrari', 'toyota', 'audi', 'bmw']
The reverse() method changes the order of a list permanently, but you can revert to the original order
anytime by applying reverse() to the same list a second time.

lst = [1,2,7,4,3,9,5]
lst.reverse()
print(lst)
L=[4,3,2,1]
print(list(reversed(L)))
Output

[5,9,3,4,7,2,1]
[1,2,3,4]
Sorting
>>> l = ['abc', 'ABD', 'aBe']
>>> l.sort()
>>> l
['ABD', 'aBe', 'abc']
>>> l = ['abc', 'ABD', 'aBe']
>>> l.sort(key=str.lower)
>>> l
['abc', 'ABD', 'aBe']
>>> l = ['abc', 'ABD', 'aBe']
>>> l.sort(key=str.lower, reverse = True)
>>> l
['abe', 'ABD', 'abc']
Example - Finding the Length of a List
>>> cars = ['bmw', 'audi', 'toyota', 'ferrari']
>>> len(cars)
4

33
Working with Part of a List
You can also work with a specific group of items in a list, which Python calls a slice.

Slicing a List
>>> courses = [3, 7, 9, 5, 8, 5]
>>> print(courses[0:2])
[3, 7, 9]
List Methods – (Methods: searching)
lst = [1,2,3,4]
i =lst.index(3)
print(i)
Output
2
List Methods – (Methods: searching)
lst = [1,2,3,4,7,6,4,3,9,3,8,7,3,5]
c =lst.count(3)
print(c)
Output
4

List Methods – (Methods: shrinking)


lst = [1,2,7,4,3,9,5]
print(lst. pop())
print(lst)
Output
5

List remove(element) method


lst = [1,2,7,4,3,9,5]
lst. remove(7)
print(lst)
Output
[1,2,4,3,9,5]

List Methods – (Methods: shrinking using del)


lst = [1,2,7,4,3,9,5]
del lst[2]
print(lst)
Output
[1,2,4,3,9,5]
List Methods – (Methods: shrinking using del)
lst = [1,2,7,4,3,9,5]
del lst[2:6]
print(lst)
34
Output
[1,2,5]
Basic List Operations
>>> len([1,2,3])
3
>>> [1,2,3]+[4,5,6]
[1,2,3,4,5,6]
>>> ['Ni!']*4
['Ni!', 'Ni!', 'Ni!', 'Ni!']
>>> str([1,2]) + '34'
'[1, 2]34'
>>> [1,2]+list('34')
[1, 2, '3', '4']
List Iteration and Comprehensions
>>> 3 in [1,2,3]
True
>>> for x in [1,2,3]:
… print(x, end=' ')

1 2 3
>>> res = [c*4 for c in 'SPAM']
>>> res
['SSSS', 'PPPP', 'AAAA', 'MMMM']
>>> list(map(abs, [-1,-2,0,1,2]))
[1,2,0,1,2]
Indexing, Slicing and Matrixes
>>> l = ['spam', 'Spam', 'SPAM!']
>>> L[2]
'SPAM!'
>>> L[-2]
'Spam'
>>> L[1:]
['Spam', 'SPAM!']
>>> list2 = [0.0, 0.5, 1.0, 1.5, 2.0]
>>> list3 = [x for x in list2 if x < 1.5]
>>> list3
[0.0, 0.5, 1.0]
>>> matrix = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix[1]
[4, 5, 6]
>>> matrix[1][1]
5

35
in / not in operator
>>> list1 = [2, 3, 5, 2, 33, 21]
>>> 2 in list1
True
>>> 2 not in list1
False

36
Tuples
Tuples are like lists, but their elements are fixed; that is, once a tuple is created, you cannot add new
elements, delete elements, replace elements, or reorder the elements in the tuple. Tuples are:
Ordered collections of arbitrary objects
➢ Accessed by offset
➢ Of the category “immutable sequence”
➢ Fixed-length, heterogeneous, and arbitrarily nestable
➢ Arrays of object references
Tuples in Action
>>> (1, 2) + (3, 4) # Concatenation
(1, 2, 3, 4)
>>> (1, 2) * 4 # Repetition
(1, 2, 1, 2, 1, 2, 1, 2)
>>> T = (1, 2, 3, 4) # Indexing, slicing
>>> T[0], T[1:3]
(1, (2, 3))

Conversions, methods, and immutability


>>> T = ('cc', 'aa', 'dd', 'bb')
>>> tmp = list(T) # Make a list from a tuple's items
>>> tmp.sort() # Sort the list
>>> tmp
['aa', 'bb', 'cc', 'dd']
>>> T = tuple(tmp) # Make a tuple from the list's items
>>>
('aa', 'bb', 'cc', 'dd')
>>> sorted(T) # Or use the sorted built-in
['aa', 'bb', 'cc', 'dd']
>>> T = (1, 2, 3, 4, 5)
>>> L = [x + 20 for x in T]
>>> L
[21, 22, 23, 24, 25]
index and count
>>> T = (1, 2, 3, 2, 4, 2) # Tuple methods in 2.6 and 3.0
>>> T.index(2) # Offset of first appearance of 2
1
>>> T.index(2, 2) # Offset of appearance after offset 2
3
>>> T.count(2) # How many 2s are there?
3

Immutability
>>> T = (1, [2, 3], 4)
>>> T[1] = 'spam’ # This fails: can't change tuple itself
37
TypeError: object doesn't support item assignment
>>> T[1][0] = 'spam' # This works: can change mutables inside
>>> T
(1, ['spam', 3], 4)
>>> tuple2 = tuple([7, 1, 2, 23, 4, 5]) # Create a tuple from a list 5
>>> print(tuple2)
(7, 1, 2, 23, 4, 5)
>>> len(tuple2) # Use function len
6
>>> max(tuple2)) # Use max
23
>>> min(tuple2) # Use min
1
>>> sum(tuple2) # Use sum
42

38
Set
Sets are like lists in that you use them for storing a collection of elements. Unlike lists, however, the
elements in a set are nonduplicates and are not placed in any particular order.
Creating Sets
You can create a set of elements by enclosing the elements inside a pair of curly braces ({}). The
elements are separated by commas. You can create an empty set, or you can create a set from a list
or a tuple, as shown in the following examples:
>>> s1 = set() # Create an empty set
>>> s2 = {1, 3, 5} # Create a set with three elements
>>> s3 = set([1, 3, 5]) # Create a set from a tuple
# Create a set from a list
>>> s4 = set([x * 2 for x in range(1, 10)])
>>> s5 = set("abac") # s5 is {'a', 'b', 'c'}
>>> set([1, 2, 3, 4]) # Built-in call
{1, 2, 3, 4}
>>> set([1, 2, 3, 4]) # Built-in: same as in 2.6
{1, 2, 3, 4}
>>> set('spam’) # Add all items in an iterable
{'a', 'p', 's', 'm'}
>>> {1, 2, 3, 4}
{1, 2, 3, 4}
>>> S = {'s', 'p', 'a', 'm'}
>>> S.add('alot')
>>> S
{'a', 'p', 's', 'm', 'alot'}
Set Operations
Python provides the methods for performing set union, intersection, difference, and symmetric
difference operations.
The union of two sets is a set that contains all the elements from both sets.
>>> s1 = {1, 2, 4}
>>> s2 = {1, 3, 5}
>>> s1.union(s2)
{1, 2, 3, 4, 5}
>>>
>>> s1 | s2
{1, 2, 3, 4, 5}
The intersection of two sets is a set that contains the elements that appear in both sets.
>>> s1 = {1, 2, 4}
>>> s2 = {1, 3, 5}
>>> s1.intersection(s2)
{1}
>>>
>>> s1 & s2
{1, }
The difference between set1 and set2 is a set that contains the elements in set1 but not in set2.
39
>>> s1 = {1, 2, 4}
>>> s2 = {1, 3, 5}
>>> s1.difference(s2)
{2, 4}
>>>
>>> s1 - s2
{2, 4}
>>>
The symmetric difference (or exclusive or) of two sets is a set that contains the elements in either set,
but not in both sets.
>>> s1 = {1, 2, 4}
>>> s2 = {1, 3, 5}
>>> s1.symmetric_difference(s2)
{2, 3, 4, 5}
>>>
>>> s1 ^ s2
{2, 3, 4, 5}
>>>
Set Comprehension
>>> {x ** 2 for x in [1, 2, 3, 4]} # 3.0 set comprehension
{16, 1, 4, 9}
>>> {x for x in 'spam'} # Same as: set('spam')
{'a', 'p', 's', 'm'}
>>> {c * 4 for c in 'spam'} # Set of collected expression results
{'ssss', 'aaaa', 'pppp', 'mmmm'}
>>> {c * 4 for c in 'spamham'}
{'ssss', 'aaaa', 'hhhh', 'pppp', 'mmmm'}
>>> S = {c * 4 for c in 'spam'}
>>> S | {'mmmm', 'xxxx'}
{'ssss', 'aaaa', 'pppp', 'mmmm', 'xxxx'}
>>> S & {'mmmm', 'xxxx'}
{'mmmm'}
Why sets?
Set operations have a variety of common uses, some more practical than mathematical. For example,
because items are stored only once in a set, sets can be used to filter duplicates out of other
collections. Simply convert the collection to a set, and then convert it back again (because sets are
iterable, they work in the list call here):
>>> L = [1, 2, 1, 3, 2, 4, 5]
>>> set(L)
{1, 2, 3, 4, 5}
>>> L = list(set(L)) # Remove duplicates
>>> L
[1, 2, 3, 4, 5]
>>> engineers = {'bob', 'sue', 'ann', 'vic'}
>>> managers = {'tom', 'sue'}
>>> 'bob' in engineers # Is bob an engineer?
40
True
>>> engineers & managers # Who is both engineer and manager?
{'sue'}
>>> engineers | managers # All people in either category
{'vic', 'sue', 'tom', 'bob', 'ann'}
>>> engineers – managers # Engineers who are not managers
{'vic', 'bob', 'ann'}
>>> managers – engineers # Managers who are not engineers
{'tom'}
>>> engineers > managers # Are all managers engineers? (superset)
False
>>> {'bob', 'sue'} < engineers # Are both engineers? (subset)
True
>>> (managers | engineers) > managers # All people is a superset of managers
True
>>> managers ^ engineers # Who is in one but not both?
{'vic', 'bob', 'ann', 'tom'}
>>> (managers | engineers) - (managers ^ engineers) # Intersection!
{'sue'}

41
Dictionary
A Dictionary is a container object that stores a collection of key/value pairs. It enables fast
retrieval, deletion, and updating of the value by using the key.
Python dictionaries are:
✓ Accessed by key, not offset
✓ Unordered collections of arbitrary objects
✓ Variable-length, heterogeneous, and arbitrarily nestable
✓ mutable mapping
✓ Tables of object references (hash tables)
A Simple Dictionary
>>> D = {'spam': 2, 'ham': 1, 'eggs': 3} # Make a dictionary
>>> D['spam'] # Fetch a value by key
2
>>> D # Order is scrambled
{'eggs': 3, 'ham': 1, 'spam': 2}
>>> len(D) # Number of entries in dictionary
3
>>> 'ham' in D
True
>>> list(D.keys()) # Create a new list of my keys
['eggs', 'ham', 'spam']
>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}
>>> D['ham'] = ['grill', 'bake', 'fry'] # Change entry
>>> D
{'eggs': 3, 'ham': ['grill', 'bake', 'fry'], 'spam': 2}
>>> del D['eggs'] # Delete entry
>>> D
{'ham': ['grill', 'bake', 'fry'], 'spam': 2}
>>> D['brunch'] = 'Bacon' # Add new entry
>>> D
{'brunch': 'Bacon', 'ham': ['grill', 'bake', 'fry'], 'spam': 2}
>>> D = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> list(D.values())
[3, 1, 2]
>>> list(D.items())
[('eggs', 3), ('ham', 1), ('spam', 2)]
>>> D.get('spam') # A key that is there
2
>>> print(D.get('toast')) # A key that is missing
None
>>> D.get('toast', 88)
88
42
>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}
>>> D2 = {'toast':4, 'muffin':5}
>>> D.update(D2)
>>> D
{'toast': 4, 'muffin': 5, 'eggs': 3, 'ham': 1, 'spam': 2}
# pop a dictionary by key
>>> D
{'toast': 4, 'muffin': 5, 'eggs': 3, 'ham': 1, 'spam': 2}
>>> D.pop('muffin')
5
>>> D.pop('toast') # Delete and return from a key
4
>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}

# pop a list by position


>>> L = ['aa', 'bb', 'cc', 'dd']
>>> L.pop() # Delete and return from the end
'dd'
>>> L
['aa', 'bb', 'cc']
>>> L.pop(1) # Delete from a specific position
'bb'
>>> L
['aa', 'cc']
>>> table = {'Python': 'Guido van Rossum',
... 'Perl': 'Larry Wall',
... 'Tcl': 'John Ousterhout' }
>>>
>>> language = 'Python'
>>> creator = table[language]
>>> creator
'Guido van Rossum'
>>> for lang in table: # Same as: for lang in table.keys()
... print(lang, '\t', table[lang])
...
Tcl John Ousterhout
Python Guido van Rossum
Perl Larry Wall

Dictionary Usage Notes


• Sequence operations don’t work
• Assigning to new indexes adds entries.
• Keys need not always be strings

43
Using dictionaries as “records”
>>> rec = {}
>>> rec['name'] = 'mel'
>>> rec['age'] = 45
>>> rec['job'] = 'trainer/writer'
>>>
>>> print(rec['name'])
Mel
>>> mel = {'name': 'Mark',
... 'jobs': ['trainer', 'writer'],
... 'web': 'www.rmi.net/˜lutz',
... 'home': {'state': 'CO', 'zip':80513}}
>>> mel['name']
'Mark'
>>> mel['jobs']
['trainer', 'writer']
>>> mel['jobs'][1]
'writer'
>>> mel['home']['zip']
80513
Dictionary comprehensions
>>> list(zip(['a', 'b', 'c'], [1, 2, 3])) # Zip together keys and
values
[('a', 1), ('b', 2), ('c', 3)]
>>> D = dict(zip(['a', 'b', 'c'], [1, 2, 3])) # Make a dict from zip
result
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> D = {k: v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3])}
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> D = {x: x ** 2 for x in [1, 2, 3, 4]} # Or: range(1, 5)
>>> D
{1: 1, 2: 4, 3: 9, 4: 16}
>>> D = {c: c * 4 for c in 'SPAM’} # Loop over any iterable
>>> D
{'A': 'AAAA', 'P': 'PPPP', 'S': 'SSSS', 'M': 'MMMM'}
>>> D = {c.lower(): c + '!' for c in ['SPAM', 'EGGS', 'HAM']}
>>> D
{'eggs': 'EGGS!', 'ham': 'HAM!', 'spam': 'SPAM!'}
>>> D = dict.fromkeys(['a', 'b', 'c'], 0) # Initialize dict from keys
>>> D
{'a': 0, 'c': 0, 'b': 0}
>>> D = {k:0 for k in ['a', 'b', 'c’]} # Same, but with a comprehension
>>> D
{'a': 0, 'c': 0, 'b': 0}
>>> D = dict.fromkeys('spam’) # Other iterators, default value
44
>>> D
{'a': None, 'p': None, 's': None, 'm': None}
>>> D = {k: None for k in 'spam'}
>>> D
{'a': None, 'p': None, 's': None, 'm': None}

45
String
Python string, an ordered collection of characters used to store and represent text-based information.
The ord and chr Functions Python provides the ord(ch) function for returning the ASCII code for the
character ch and the chr(code) function for returning the character represented by the code.
For example,
>>> ch = 'a'
>>> ord(ch)
97
>>> chr(98)
'b'
>>> ord('A')
65
>>>
>>> ord('a') – ord('A')
32
>>> ord('d') – ord('D')
32
>>> offset = ord('a') – ord('A')
>>> lowercaseLetter = 'h'
>>> uppercaseLetter = chr(ord(lowercaseLetter) – offset)
>>> uppercaseLetter
'H'
>>>
The str Function
The str function can be used to convert a number into a string. For example,
>>> s = str(3.4) # Convert a float to string
>>> s
'3.4'
>>> s = str(3) # Convert an integer to string
>>> s
'3'
>>>
The String Concatenation Operator
You can use the + operator to add two numbers. The + operator can be used to concatenate
two strings. Here are some examples:
>>> message = "Welcome " + "to " + "Python"
>>> message
'Welcome to Python'
>>> chapterNo = 3
>>> s = "Chapter " + str(chapterNo)
>>> s
'Chapter 3'
>>>
>>> message = "Welcome to Python"

46
>>> message
'Welcome to Python'
>>> message += " and Python is fun"
>>> message
'Welcome to Python and Python is fun'
>>>
>>> s = "Welcome"
>>> s1 = # Invoke the lower method
>>> s1
'welcome'
>>> s2 = # Invoke the upper method
>>> s2
'WELCOME'
>>>
Functions of strings
>>> s = "Welcome"
>>> len(s)
7
>>> max(s)
'o'
>>> min(s)
'W'
>>>
>>> s = "Welcome"
>>> for i in range(0, len(s), 2):
... print(s[i], end = '')
Wloe
>>>
The Concatenation (+) and Repetition (*) Operators
>>> s1 = "Welcome"
>>> s2 = "Python"
>>> s3 = s1 + " to " + s2
>>> s3
'Welcome to Python'
>>> s4 = 3 * s1
>>> s4
'WelcomeWelcomeWelcome'
>>> s5 = s1 * 3
>>> s5
'WelcomeWelcomeWelcome'
>>>
The in and not in Operators
>>> s1 = "Welcome"
>>> "come" in s1
True
>>> "come" not in s1
47
False
>>>

Testing Strings
>>> s = "welcome to python"
>>> s.isalnum()
False
>>> "Welcome".isalpha()
True
>>> "2012".isdigit()
True
>>> "first Number".isidentifier()
False
>>> s.islower()
True
>>> s.isupper()
False
>>> s.isspace()
False
>>>
Searching for Substrings
>>> s = "welcome to python"
>>> s.endswith("thon")
True
>>> s.startswith("good")
False
>>> s.find("come")
3
>>> s.find("become")
-1
>>> s.rfind("o")
17
>>> s.count("o")
3
>>>
Converting Strings
>>> s = "welcome to python"
>>> s1 = s.capitalize()
>>> s1
'Welcome to python'
>>> s2 = s.title()
>>> s2
'Welcome To Python'
>>> s = "New England"
>>> s3 = s.lower()
>>> s3
48
'new england'
>>> s4 = s.upper()
>>> s4
'NEW ENGLAND'
>>> s5 = s.swapcase()
>>> s5
'nEW eNGLAND'
>>> s6 = s.replace("England", "Haven")
>>> s6
'New Haven'
>>> s
'New England'
>>>
Formatting Strings
>>> s = "Welcome"
>>> s1 = s.center(11)
>>> s1
' Welcome '
>>> s2 = s.ljust(11)
>>> s2
'Welcome '
>>> s3 = s.rjust(11)
>>> s3
' Welcome'
>>>

49
Concept of Mutability
Python: Mutable vs. Immutable
Everything in Python is an object. You have to understand that Python represents all its data as objects.
An object’s mutability is determined by its type. Some of these objects like lists and dictionaries are
mutable, meaning you can change their content without changing their identity. Other objects like
integers, floats, strings and tuples are objects that cannot be changed.

Strings are Immutable


Strings are immutable in Python, which means you cannot change an existing string. The best you can
do is create a new string that is a variation on the original. Example
mess = 'Hello World!'
mess[0] = 'E'
print(mess)
Instead of producing the output "strings immutable", this code produces the runtime error:
TypeError: ‘str' object cannot support item assignment
Tuples are immutable
tpl = (4,7,8,9,5)
tpl[0] = 8
print(tpl)
Output: -
TypeError: ‘tuple' object does not support item assignment

List are mutable


List is immutable in Python, which means you can change an existing list.

lst = [7,6,9,56,4,7,96]
lst[1] = 65
print(lst)
Output: -
[7, 65, 56, 4, 7, 96]

Dictionary is mutable
dict= {'First_name': 'Himanshu', 'Last_name': 'Rastogi', 'city': 'Meerut'}
dict['city'] = 'Muzaffarnagar'
print(dict)
Output: -
{‘First_name': ‘Himanshu', ‘Last_name': ‘Rastogi', ‘city': ‘Muzaffarnagar'}

50
List processing
Examples: -
#Find maximum number in list
n=int(input("Enter list size:"))
lst=[]
for num in range(0, n):
li=int(input("Enter list element "))
lst.append(li)
print(lst)
max =lst[0]
for item in lst:
if(item>max):
max=item
print("Maximum number is", max)

#Find minimum number in list


n=int(input("Enter list size:"))
lst=[]
for num in range(0, n):
li=int(input("Enter list element "))
lst.append(li)
print(lst)
min =lst[0]
for item in lst:
if(item<min):
min=item
print("Minimum number is", min)

# linear search on list of numbers


found=0
n=int(input("Enter list size:"))
lst=[]
for num in range(0, n):
li=int(input("Enter list element : "))
lst.append(li)
e = int(input("Enter any number:"))
for i in range(len(lst)):
if lst[i] == e:
found=1
if(found==1):
print("Element found")
else:
print("Element not found")

# Binary search on list of numbers


51
found=False
n=int(input("Enter list size:"))
lst=[]
for num in range(0, n):
li=int(input("Enter list element : "))
lst.append(li)
e = int(input("Enter any number:"))
start = 0
end = len(lst)

while start <= end:


middle = (start+end)//2
if lst[middle] == e:
found = True
break
elif e > lst[middle]:
start = middle + 1
else:
end = middle-1

if(found==1):
print("Element found")
else:
print("Element not found")

# counting the frequency of elements in a list using a dictionary


list = ['a','b','a',7,'d','c','c', 7, 6, 4, 6, 6]
frequency = {}
for item in list:
if (item in frequency):
frequency[item] += 1
else:
frequency[item] = 1
print(frequency)
for key, value in frequency.items():
print("% s -> % d" % (key, value))

# Bubble Sort Accending Order


lst = [3,23,5,23,-3,0,34,-4,2,-8,2,5]
for i in range(len(lst)):
for j in range(len(lst)-1-i):
if lst[j] > lst[j+1]:
lst[j], lst[j+1] = lst[j+1], lst[j]
print(lst)

52
# Selection Sort Accending Order
lst = [3,23,5,23,-3,0,34,-4,2,-8,2,5]
for i in range(len(lst)):
for j in range(i, len(lst)):
if lst[i] > lst[j]:
lst[i], lst[j] = lst[j], lst[i]
print(lst)

Exercise
1. (Assign grades) Write a program that reads a list of scores and then assigns grades
based on the following scheme:
The grade is A if score is >= best – 10.
The grade is B if score is >= best – 20.
The grade is C if score is >= best – 30.
The grade is D if score is >= best – 40.
The grade is F otherwise.
Here is a sample run:
Enter scores: 40 55 70 58
Student 0 score is 40 and grade is C
Student 1 score is 55 and grade is B
Student 2 score is 70 and grade is A
Student 3 score is 58 and grade is B

2. (Reverse the numbers entered) Write a program that reads a list of integers and displays them in
the reverse order in which they were read.

3. (Analyze scores) Write a program that reads an unspecified number of scores and determines
how many scores are above or equal to the average and how many scores are below the average.

4. (Print distinct numbers) Write a program that reads in numbers separated by a space in one line
and displays distinct numbers (i.e., if a number appears multiple times, it is displayed only once).
(Hint: Read all the numbers and store them in list1. Create a new list list2. Add a number in list1 to
list2. If the number is already in the list, ignore it.) Here is the sample run of the program:
Enter ten numbers:
The distinct numbers are: 1 2 3 2 6 3 4 5 2
123654

5. (Compute GCD) Write a function that returns the greatest common divisor (GCD) of integers in a
list. Use the following function header: def gcd(numbers): Write a test program that prompts the
user to enter five numbers, invokes the function to find the GCD of these numbers, and displays the
GCD.

6. (Pattern recognition: four consecutive equal numbers) Write the following function that tests
whether the list has four consecutive numbers with the same value. Write a test program that

53
prompts the user to enter a series of integers and reports whether the series contains four
consecutive numbers with the same value.

54
Functions
In Python, a function is a self-contained group of statements, which are intended to perform a specific
task. Functions break the program into smaller modules, which perform a particular operation and
are easy to understand.

Advantages of functions
✓ Avoids Repetition
✓ Modularization
✓ Reduce size
✓ Logical Precision
✓ Save Memory Requirement
✓ Protable
Type of functions
Python functions can be divided into the following two types:
1. Built-in function – These function already define in python.
2. User defined function – These function, the programmer can develop their own functions
depending upon their requirement.
def statement
The def statement creates a function object and assigns it to a name.
Syntax:
def function_name([parameters …]):
#statement(s)

[return returnValue]
A first example: Definitions and calls
#Definitions
def times(x,y):
return x*y
#calls
a = times(4,5)
print(a)
Output
20
Function parameters
Parameters are the value(s) provided in the parenthesis when we write function header. These are
the values required by function to work. Let’s understand this with the help of function written for
calculating area of circle. radius is a parameter to function area.
If there is more than one value required by the function to work on, then, all of them will be listed in
parameter list separated by comma.
Arguments are the value(s) provided in function call/invoke statement. List of arguments should be
supplied in same way as parameters are listed.

55
Example: - argument in function call
>>> area (5)
5 is an argument. An argument can be constant, variable, or expression.

The Return statement


A function doesn’t always have to display its output directly. Instead, it can process some data and
then return a value or set of values. The value the function returns is called a return value. The return
statement takes a value from inside a function and sends it back to the line that called the function.
For Example: -
def get_formatted_name(first_name, last_name):
"""Return a full name, neatly formatted."""
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('Kailash', 'Khair')
print(musician)
Example: Intersection sequences
def interset(seq1, seq2):
res = []
for x in seq1:
if x in seq2:
res.append(x)
return res
if __name__ == '__main__':
s1 = 'SPAM'
s2 = 'SCAM'
print(interset(s1,s2))

Output
[‘S’, ‘A’, ‘M’]

Scope of Variables
Scope of variable refers to the part of the program, where it is visible, i.e., area where you can refer
(use) it. We can say that scope holds the current set of variables and their values. We will discuss
two types of scope of variables- global scope or local scope.
Global Scope
A variable, with global scope can be used anywhere in the program. It can be created by defining a
variable outside the scope of any function/block.
Example: -
x=50
def test ():
print ('Inside test x is', x)
print ('Value of x is', x)

56
on execution the above code will produce
Inside test x is 50
Value of x is 50
Local Scope
A variable with local scope can be accessed only within the function/block that it is created in. When
a variable is created inside the function/block, the variable becomes local to it. A local variable only
exists while the function is executing.

Example: -
X=50
def test():
y = 20
print ('Value of x is', X, '; y is ', y)
print ('Value of x is', X, 'y is', y)

On executing the code, we will get


Value of x is 50; y is 20
The next print statement will produce an error, because the variable y is not accessible outside the
function body.

DocStrings
Python documentation strings (or docstrings) provide a convenient way of associating
documentation with Python modules, functions, classes, and methods. It's specified in source code
that is used, like a comment, to document a specific segment of code.

One line DocString


As the name suggests, one line docstrings fit in one line. They are used in obvious cases. The closing
quotes are on the same line as the opening quotes. For Example: -
def my_fun():
"""This is docString of my_fun"""
print("Hello World!")
my_fun()
print (my_fun.__doc__)
Multi-Line docString
Multi-line docstrings consist of a summary line just like a one-line docstring, followed by a blank line,
followed by a more elaborate description. The summary line may be on the same line as the opening
quotes or on the next line.
For Example: -
def my_fun():
"""This is docString
of my_fun()"""
print("Hello World!")
57
my_fun()
print (my_fun.__doc__)
What is Python Namespace?
When you use a name in a program, Python creates, changes or looks up the name in what is known
as a namespace – a place where name live. When we talk about the search for a name’s value in
relation to code, the term scope refers to a namespace: that is the location of a name’s assignment in
your code determines the scope of the name’s visibility to your code.
In other wrods, the place where you assign name in your source code determines the namespace it
will live in, and hence its scope of visibility.
This means that:
1. Names defined inside a def can only be seen by the code within that def
2. Names defined inside a def do not clash with variables outside the def, even if the same name
are used elsewhere.
Variables may be assigned in three different place, corresponding to three different scopes:
1. If a variable is assigned inside a def, it is local to that function.
2. If a variable is assigned in an enclosing def, it is nonlocal to nested functions.
3. If a variable is assigned outside all defs, it is global to the entire file.

LEGB Rule
In Python, the LEGB rule is used to decide the order in which the namespaces are to be searched for
scope resolution.
The scopes are listed below in terms of hierarchy(highest to lowest/narrowest to broadest):
Local(L): Defined inside function/class
Enclosed(E): Defined inside enclosing functions (Nested function concept)
Global(G): Defined at the uppermost level
Built-in(B): Reserved names in Python builtin modules
Built In
Global

Enclosed
Local

When you use an unqualified name inside a function, python searches up to four scopes – the local
(L) scope, then the local scopes of any enclosing (E) defs and lambdas, then the global (G) and then
the built-in (B) scope and stops at the first place the name its found.
• When you assign a name in a function, python always creates or changes the name in the local
scope, unless it’s declared to be global or nonlocal in that function.
• When you assign a name outside any function, the local scope is the same as the global scope –
the module’s namespace.

58
Local Scope:
Local scope refers to variables defined in current function.Always, a function will first look up for a
variable name in its local scope.

def my_function():
n = 5 #Local variable
print(n)
my_function()
Output: -
5

Global Scope
In Python, a variable declared outside of the function or in global scope is known as a global variable.
This means that a global variable can be accessed inside or outside of the function.

n = 5 #global variable
def my_function():
n=7 #nonlocal/enclosed variable
print('n=', n)
my_function()
print(n)
Output:
n=7
n=5
Enclosed Scope
For the enclosed scope, we need to define an outer function enclosing the inner function.

def function_one():
a=5
def function_two():
b=6
print(b)
function_two()
print(a)
function_one()
Output: -
6
5
Built-in Scopes :
The final check can be done by importing pi from math module.

from math import pi


def my_function():
print(pi)
my_function()

59
Output: -
3.141592653589739
Scope Rules
Functions provide nested namespaces (scopes) that localize the names they use, such that names
inside a function won’t clash with those outside it (in a module or another function). Again,
functions define a local scope, and modules define a global scope.
The two scopes are related as follows:
• The enclosing module is a global scope.
• Each call to a function creates a new local scope.
• Assigned names are local unless declared global or nonlocal.
• All other names are enclosing function locals, globals, or built-ins.
The global Statement
The global statement tells Python that a function plans to change one or more global names—i.e.,
names that live in the enclosing module’s scope (namespace). Here’s a summary:

1. Global names are variables assigned at the top level of the enclosing module file.
2. Global names must be declared only if they are assigned within a function.
3. Global names may be referenced within a function without being declared.

X = 88 # Global X
def func():
global X
X = 99 # Global X: outside def
func()
print(X) # Prints 99

Another Example,

y, z = 1, 2 # Global variables in module


def all_global():
global x # Declare globals assigned
x = y + z # No need to declare y, z: LEGB rule

Enclosed Variables (nonlocal)


Unlike global, though, nonlocal applies to a name in an enclosing function’s scope, not the global
module scope outside all defs. Also unlike global, nonlocal names must already exist in the enclosing
function’s scope when declared—they can exist only in enclosing functions and cannot be created by
a first assignment in a nested def.

Example,
def func1():
x=7 # nonlocal variable
def func2():
print(x)

60
func2()
func1()

Output
7
nonlocal Basics
Python 3.0 introduces a new nonlocal statement, which has meaning only inside a function:

def func():
nonlocal name1, name2, ...

This statement allows a nested function to change one or more names defined in a syntactically
enclosing function’s scope.

Example,

x=5 #global variable


def func1():
x=4 #nonlocal variable
def func2():
nonlocal x #Reference: nonlocal variable
x=8
print('func2',x)
print('before func1', x)
func2()
print('after func1', x)
#main
func1()
print('main',x)
Output
before func1 4
func2 8
after func1 8
main 5
Argument-Passing Basics
Python argument passing—the way that objects are sent to functions as inputs.

➢ Arguments are passed by automatically assigning objects to local variable names.


➢ Assigning to argument names inside a function does not affect the caller.
➢ Changing a mutable object argument in a function may impact the caller.

61
Special Argument-Matching Modes
Default argument values
When writing a function, you can define a default value for each parameter. If an argument for a
parameter is provided in the function call, Python uses the argument value. If not, it uses the
parameter’s default value.
Example

def describe_pet(pet_name, animal_type='dog'):


"""Display information about a pet."""
print("\n I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
#main
describe_pet(pet_name=input("Enter pet name:"))

keyword arguments
A keyword argument is a name-value pair that you pass to a function. You directly associate the name
and the value within the argument, so when you pass the argument to the function, there’s no
confusion.
Let’s write pets.py using keyword arguments to call describe_pet():

def describe_pet(animal_type, pet_name):


"""Display information about a pet."""
print("\n I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(animal_type='dog', pet_name='Tom')

VarArgs parameters
Some functions have no arguments, others have multiple. There are times we have functions with
arguments we don't know about beforehand. We may have a variable number of arguments because
we want to offer a flexible API to other developers or we don't know the input size. With Python, we
can create functions to accept any amount of arguments.

*args parameters
Variable-length arguments, varargs for short, are arguments that can take an unspecified amount of
input. When these are used, the programmer does not need to wrap the data in a list or an alternative
sequence.
For Example: -
def addition(*num):
s = 0
for n in num:
s=s+n
return s

62
print('Addition is', addition(4, 5, 6, 7, 2))

Returning Multiple Values


The Python return statement can return multiple values.
def sort(number1, number2):
if number1 < number2:
return number1, number2
else:
return number1, number2

n1, n2 = sort(3, 2)
print("n1 is", n1)
print("n2 is", n2)

Using Many Named Arguments with **kwargs


Python can accept multiple keyword arguments, better known as **kwargs. It behaves similarly to
*args, but stores the arguments in a dictionary instead of tuples:
For Example: -
def kwarg_type_test(*args, **kwargs):
print(kwargs)
kwarg_type_test(a="hi")
kwarg_type_test(roses="red", violets="blue")
Recursion
A recursive function is one that invokes itself.
Recursion is even an alternative for simple loops and iterations, though not necessarily the simplest
or most efficient one.
Example: -
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
num = eval(input("Enter any number: "))
print(factorial(num))

Output: -
Enter any number: 5
120
RecursivePalindromeUsingSubstring.py

63
def isPalindrom(s):
if len(s) <= 1: # Base case
return True
elif s[0] != s[len(s) - 1]: # Base case
return False
else:
return isPalindrom(s[1:len(s)-1])

print("Is moon a palindrome?", isPalindrom("moon"))


print("Is noon a palindrome?", isPalindrom("noon"))
print("Is a a palindrome?", isPalindrom("a"))
print("Is aba a palindrome?", isPalindrom("aba"))
print("Is ab a palindrome?", isPalindrom("ab"))

Output

Is moon a palindrome? False


Is noon a palindrome? True
Is a a palindrome? True
Is aba a palindrome? True
Is ab a palindrome? False
Example: Sum List
def mysum(L):
print(L) # Trace recursive levels
if not L: # L shorter at each level
return 0
else:
return L[0] + mysum(L[1:])
print(mysum([1, 2, 3, 4, 5]))

Output
[1, 2, 3, 4, 5]
[2, 3, 4, 5]
[3, 4, 5]
[4, 5]
[5]
[]
15
Anonymous Functions: lambda
Besides the def statement, Python also provides an expression form that generates function objects.
Like def, this expression creates a function to be called later, but it returns the function instead of
assigning it to a name. This is why lambdas are sometimes known as anonymous (i.e., unnamed)
functions.

64
lambda Basics The lambda’s general form is the keyword lambda, followed by one or more
arguments (exactly like the arguments list you enclose in parentheses in a def header), followed by
an expression after a colon:
lambda argument1, argument2,... argumentN :expression using arguments

f = lambda x, y, z: x + y + z
print(f(2, 3, 4))
Output
9
Defaults work on lambda arguments, just like in a def:

x = (lambda a="fee", b="fie", c="foe": a + b + c)


x("wee") #output 'weefiefoe'
lower = (lambda x, y: x if x < y else y)
lower('bb', 'aa') #output 'aa'
lower('aa', 'bb') #output 'aa'
Mapping Functions over Sequences: map
One of the more common things programs do with lists and other sequences is apply an operation
to each item and collect the results.

counters = [1, 2, 3, 4]
updated = []
for x in counters:
updated.append(x + 10) # Add 10 to each item
print(updated) #output [11, 12, 13, 14]

The map function applies a passed-in function to each item in an iterable object and returns a list
containing all the function call results. For example:

def inc(x):
return x + 10 # Function to be run
counters = [10,11,12,13]
print(list(map(inc, counters))) # Collect results [11, 12, 13, 14]
Because map expects a function to be passed in, it also happens to be one of the places where
lambda commonly appears:

counters = [10,11,12,13]
print(list(map((lambda x: x + 3), counters))) # Function expression
[4, 5, 6, 7]
pow(3, 4) # 3**4
print(map(pow, [1, 2, 3], [2, 3, 4]))
# 1**2, 2**3, 3**4 # [1, 8, 81]

Exercise
1. (Palindrome integer) Write the functions with the following headers:
65
# Return the reversal of an integer, e.g. reverse(456) returns
# 654
def reverse(number):
# Return true if number is a palindrome
def isPalindrome(number):
Use the reverse function to implement isPalindrome. A number is a palindrome if its reversal is the
same as itself. Write a test program that prompts the
user to enter an integer and reports whether the integer is a palindrome.

2. (Use the isPrime Function) PrimeNumberFunction.py, provides the isPrime(number) function for
testing whether a number is prime. Use this function to find the number of prime numbers less than
10,000.

3. (Display characters) Write a function that prints characters using the following header:
def printChars(ch1, ch2, numberPerLine):
This function prints the characters between ch1 and ch2 with the specified numbers per line. Write
a test program that prints ten characters per line from 1 to Z.

4. (Mersenne prime) A prime number is called a Mersenne prime if it can be written in the form for
some positive integer p. Write a program that finds all Mersenne primes with and displays the
output as follows:
p 2^p - 1
2 3
3 7
5 31
...

5. (Twin primes) Twin primes are a pair of prime numbers that differ by 2. For example, 3 and 5, 5
and 7, and 11 and 13 are twin primes. Write a program to find all
twin primes less than 1,000. Display the output as follows:
(3, 5)
(5, 7)
...

6. (Format an integer) Write a function with the following header to format the integer with the
specified width.
def format(number, width):
The function returns a string for the number with prefix 0s. The size of the string is the width. For
example, format(34, 4) returns "0034" and format(34, 5) returns "00034". If the number is longer
than the width, the function returns the string representation for the number. For example,
format(34, 1) returns "34".
Write a test program that prompts the user to enter a number and its width and displays a string
returned from invoking format(number, width). Here is a sample run:
Enter an integer: 453
Enter the width: 6
The formatted number is 000453

66
7. (Game: craps) Craps is a popular dice game played in casinos. Write a program to play a variation
of the game, as follows:
Roll two dice. Each die has six faces representing values 1, 2, ..., and 6, respectively. Check the sum
of the two dice. If the sum is 2, 3, or 12 (called craps), you lose; if the sum is 7 or 11 (called natural),
you win; if the sum is another value (i.e., 4, 5, 6, 8, 9, or 10), a point is established. Continue to roll
the dice until either a 7 or the same point value is rolled. If 7 is rolled, you lose. Otherwise, you win.
Your program acts as a single player. Here are some sample runs.

You rolled 5 + 6 = 11
You win

You rolled 1 + 2 = 3
You lose

You rolled 4 + 4 = 8
point is 8
You rolled 6 + 2 = 8
You win

You rolled 3 + 2 = 5
point is 5
You rolled 2 + 5 = 7
You lose
8. (Display matrix of 0s and 1s) Write a function that displays an n-by-n matrix using the following
header:
def printMatrix(n):
Each element is 0 or 1, which is generated randomly. Write a test program that prompts the user to
enter n and displays an n-by-n matrix. Here is a sample run:
Enter n: 3
010
000
111

67
Maths function-
Python contains a large library of standard functions which can be used for common programming
tasks.

Numeric Functions:
max()
The max() function returns the largest of the input values. An iterable object like string, list, tuple etc.
max(iterable[, default=obj, key=func]) -> value
Example: -
lst = [7,5,8,9,2,1,5]
print(max(lst))
Output: -
9
min()
The min() function returns the item with the lowest value, or the item with the lowest value in an
iterable. If the values are strings, an alphabetically comparison is done.
Syntax: - min(n1, n2, n3, .......)
Example: -
lst = (2,6,8,5,9,6)
print(min(lst))
Output: -
2

pow()
The pow() function returns the value of x to the power of y (xy).
If a third parameter is present, it returns x to the power of y, modulus z.

Syntax: - pow(x, y, [z])

Example:
print(pow(3,3,5))
round()
round() is a built-in function available with python. It will return you a float number that will be
rounded to the decimal places which are given as input. Syntax: - round(float_num,
num_of_decimals)
Example: -
>>> round(678.868,2)
678.87
ceil()

68
The Python ceil function is one of the Python Math function used to return the smallest integer value,
which is greater than or equal to the specified expression or a specific number.
Example: -
>>> import math
>>> math.ceil(678.764)
679
floor()
floor function is one of the Mathematical Function available in Python math library. This python math.
floor function is used to return the closest integer value which is less than or equal to the specified
expression or Value.
Example: -
>>> import math
>>> math.floor(678.755)
678
sqrt()

sqrt() function is an inbuilt function in Python programming language that returns the square root of
any number.
Example: -
>>> import math
>>> math.sqrt(144) 12
random()
Python has a built-in module that you can use to make random numbers.
Example: -
>>> import random
>>> random.random()
0.1366435678

69
Command Line arguments
The arguments that are given after the name of the program in the command line shell of the program
in the command line shell of the operating system are known as Command Line Arguments.

sys.argv
The sys module provides functions and variables used to manipulate different parts of the Python
runtime environment. This module provides access to some variables used or maintained by the
interpreter and to functions that interact strongly with the interpreter.

Example – ‘File name → commandlinearg.py'

import sys
a = int(sys.argv[1])
b = int(sys.argv[2])
c = a + b
print("c = ", c)
Output: -

70
Module Basics
A module is created as a script file, which contains function definitions.
To define a module, simple use your text editor to type some Python code into a text file, and save it
with a ‘.py’ extension; any such file is automatically considered a python module.
Here we will create a module name myModule.py which compute the factorial and even_odd of a
number.
Example: - myModule.py
# this is factorial module
def fact(n):
f=1
while (n>0):
f=f*n
n-=1
return f
def even_odd(n):
if(n%2 == 0):
print('Even Number')
else:
print('Odd Number')

Create another file main.py

import myModule
print('Factorial is', myModule.fact(6))
even_odd(8)
Output
Factorial is 720
Even Number

There is a variant of the import statement that imports names from a module directly into the
importing module’s symbol table.

For example:
>>> from myModule import fact, even_odd
>>> fact(5)
120
>>> even_odd(64)
Even Number
There is even a variant to import all names that a module defines:
>>> from myModule import *
>>> fact(6)
720
>>> even_odd(45)
Odd Number

71
Packages
Python provides packages for managing directories and modules for files. Similar, modules can be
placed in one package, which makes maintenace of the project or program under development
easier. As directory can contain sub-directory, similarly a package can contain sub packages.
The directory containing package must contain a file named __init__.py. This is required as python
identities it as a package due to __init__.py.
Example- creating a package
C:/MainDir/
main.py
myPackage/
__init__.py
Mymath.py

1. Create a folder myPackage in MainDir.


2. Create a file __init__.py in myModule directory.
3. Create a module file Mymath.py and create following functions.
Mymath.py
def addition(*args):
sum = 0
for n in args:
sum = sum + n
return sum

def subtract(a, b):


return a-b

def multiply(*args):
m = 1
for n in args:
m = m * n
return m

def divide(a, b):


return a/b
main.py
from myPackage import Mymath
print(Mymath.addition(8,9,7))
print(Mymath.subtract(7,2))
print(Mymath.multiply(2,3,4))
print(Mymath.divide(8,5))

72
File Handling
You can use a file to store data permanently.
Data used in a program is temporary; unless the data is specifically saved, it is lost when the
program terminates. To permanently store the data created in a program, you need to save it in a
file on a disk or some other permanent storage device. The file can be transported and can be read
later by other programs.
Text Input and Output
To read and write data from or to a file, use the open function to create a file object and use the
object’s read and write methods to read and write data.
A file is placed in a directory in the file system. An absolute filename contains a filename with its
complete path and drive letter. For example, c:\pybook\Scores.txt is the absolute filename for the
file Scores.txt on the Windows operating system.
Opening a File
You need to first create a file object that is associated with a physical file. This is called opening a
file.
The syntax for opening a file is:
fileVariable = open(filename, mode)
The open function returns a file object for filename. The mode parameter is a string that specifies
how the file will be used (for reading or writing).
MODE DESCRIPTION
"r" Opens a file for reading.
Opens a new file for writing. If the file already exists, its old contents are
"w"
destroyed.
"a" Opens a file for appending data from the end of the file.
"rb" Opens a file for reading binary data.
"wb" Opens a file for writing binary data

For example, the following statement opens a file named Scores.txt in the current directory for
reading:
input = open("Scores.txt", "r")
You can also use the absolute filename to open the file in Windows, as follows:
input = open(r"c:\pybook\Scores.txt", "r")
you would have to write the statement using an escape sequence as:
input = open("c:\\pybook\\Scores.txt", "r")
Writing Data
The open function creates a file object, which is an instance of the _io.TextIOWrapper class. This
class contains the methods for reading and writing data and for closing the file.
_io.TextIOWrapper
73
read([number.int): str Returns the specified number of characters from the file. If the
argument is omitted, the entire remaining contents in the file are
read.
readline(): str Returns the next line of the file as a string.
readlines(): list Returns a list of the remaining lines in the file.
write(s: str): None Writes the string to the file.
writelines(list): None Write a list to the file as string.
close(): None Closes the file.

wrtieDemo.py
with open('data.txt', 'w') as fp:
fp.write('This is first line')
fp.write('This is second line')
fp.close()
print('Data saved successfully')
Testing a File’s Existence
To prevent the data in an existing file from being erased by accident, you should test to see if the file
exists before opening it for writing. The isfile function in the os.path module can be used to
determine whether a file exists. For example:
import os.path
if os.path.isfile("data.txt"):
print("data.txt exists")

Here isfile("data.txt") returns True if the file Presidents.txt exists in the current directory.
Reading Data
After a file is opened for reading data, you can use the read method to read a specified number of
characters or all characters from the file and return them as a string, the readline() method to read
the next line, and the readlines() method to read all the lines into a list of strings.
readDemo.py
print('Using read() function')
with open('data.txt', 'r') as fp:
fp.read()
fp.close()
print('\nUsing read(size) function')
with open('data.txt', 'r') as fp:
fp.read(10)
fp.close()
print('\nUsing readline() function')
with open('data.txt', 'r') as fp:
fp.readline()
fp.readline()
fp.close()

74
print('\nUsing readlines() function')
with open('data.txt', 'r') as fp:
fp.readlines()
fp.close()

Output
Using read() function
This is first line.
This is second line.

Using read(size) function


This is fi

Using readline() function


This is first line.
This is second line.

Using readlines() function


[‘This is first line.\n’, ‘This is second line.’]
CopyFile.py
import os.path
import sys
# Prompt the user to enter filenames
f1 = input("Enter a source file: ").strip()
f2 = input("Enter a target file: ").strip()

# Check if target file exists


if os.path.isfile(f2):
print(f2 + " already exists")
sys.exit()
# Open files for input and output
infile = open(f1, "r")
outfile = open(f2, "w")

# Copy from input file to output file


countLines = countChars = 0
for line in infile:
countLines += 1
countChars += len(line)
outfile.write(line)
print(countLines, "lines and", countChars, "chars copied")
infile.close() # Close the input file
outfile.close()

75
Appending Data
You can use the a mode to open a file for appending data to the end of an existing file. Listing 13.4
gives an example of appending two new lines into a file named Info.txt.
import random
outfile = open("Info.txt", "a")
outfile.write("\nPython is interpreted\n")
outfile.close()

outfile = open("Numbers.txt", "w")


for i in range(10):
outfile.write(str(random.randint(0, 9)) + " ")
outfile.close()
infile = open("Numbers.txt", "r")
s = infile.read()
numbers = [eval(x) for x in s.split()]
for number in numbers:
print(number, end = " ")
infile.close()
File Dialogs
The tkinter.filedialog module contains the functions askopenfilename and asksaveasfilename for
displaying the file Open and Save As dialog boxes.
# Display a file dialog box for opening an existing file
filename = askopenfilename()
# Display a file dialog box for specifying a file for saving data
filename = asksaveasfilename()

from tkinter.filedialog import askopenfilename


from tkinter.filedialog import asksaveasfilename

filenameforReading = askopenfilename()
print("You can read from " + filenameforReading)

filenameforWriting = asksaveasfilename()
print("You can write data to " + filenameforWriting)

Binary IO Using Pickling


To perform binary IO using pickling, open a file using the mode rb or wb for reading binary or writing
binary and invoke the pickle module’s dump and load functions to write and read data.
The Python pickle module implements the powerful and efficient algorithms for serializing and
deserializing objects. Serializing is the process of converting an object into a stream of bytes that can
be saved to a file or transmitted on a network. Deserializing is the opposite process that extracts an
object from a stream of bytes. Serializing/deserializing is also known as pickling/unpickling or
dumping/loading objects in Python.

76
Dumping and Loading Objects
As you know, all data in Python are objects. The pickle module enables you to write and read any
data using the dump and load functions.
BinaryIODemo.py
import pickle
outfile = open("pickle.dat", "wb")
pickle.dump(45, outfile)
pickle.dump(56.6, outfile)
pickle.dump("Programming is fun", outfile)
pickle.dump([1, 2, 3, 4], outfile)
outfile.close() # Close the output file

# Open file for reading binary


infile = open("pickle.dat", "rb")
print(pickle.load(infile))
print(pickle.load(infile))
print(pickle.load(infile))
print(pickle.load(infile))
infile.close()
Output
45
56.6
Programming is fun
[1, 2, 3, 4]

Detecting the End of File


If you don’t know how many objects are in the file, how do you read all the objects? You can
repeatedly read an object using the load function until it throws an EOFError (end of file) exception.
When this exception is raised, catch it and process it to end the file-reading process.
DetectEndOfFile.py
import pickle
# Open file for writing binary
outfile = open("numbers.dat", "wb")
data = eval(input("Enter an integer (the input exits if the input is 0): "))
while data != 0:
pickle.dump(data, outfile)
data = eval(input("Enter an integer (the input exits if the input is 0): "))
outfile.close() # Close the output file
# Open file for reading binary
infile = open("numbers.dat", "rb")
end_of_file = False
while not end_of_file:
try:

77
print( pickle.load(infile), end = " ")
except EOFError:
end_of_file = True
infile.close() # Close the input file
print("\nAll objects are read")

tell() method
The tell() method returns current position of the file object. This method takes no parameters and
returns an integer value. Initially, file pointer points to the beginning of the file. (If not opend in
append mode). So, the initial value of tell() is zero.
Syntax
fileObject.tell()
tellDemo.py
with open('data.txt', 'r') as fp:
print('Cursor location is', fp.tell())
print(fp.readline(), end=' ')
print('Now, cursor location is', fp.tell())
fp.close()
Output
Cursor location is 0
This is first line.
Now, cursor loacation is 21
seek() method
In python seek() function is used to change the position of the file handle to a given specific positon.
File handle is like a cursor, which defines from where the data has to be read of written in the file.
Syntax: - fp.seek (offset, from_what)
from_what has three value 0, 1, 2
0: (Default), set the reference point at the beginning of the file.
1: set the reference point at the current file position.
2: set the reference point at the end of the file.

fp = open('data.txt', "rb") data.txt


print("Name of the file:", fp.name) This is first line.
line = fp.readline() This is second line.
print("Read line:", line)
fp.seek(3, 0)
print(fp.tell())
line = fp.readline()
print("Read line:", line)
fp.close()

78
Output
Name of the file: data.txt
Read line: This is first line.
Rea linde: s is first line.

Working with JSON


The json module allows you to dump simple Python data structures into a file and load the data
from that file the next time the program runs. You can also use json to share data between different
Python programs. Even better, the JSON data format is not specific to Python, so you can share data
you store in the JSON format with people who work in many other programming languages. It’s a
useful and portable format, and it’s easy to learn.
WriteData.json
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
json.dump(numbers, f_obj)
f_obj.close()

ReadData.json
import json
filename = 'numbers.json'
with open(filename) as f_obj:
numbers = json.load(f_obj)
f_obj.close()

print(numbers)

79
Decoraters
In Python, a decorator is a function that takes another function as an argument and extends its
behavior without explicitly modifying the original function. It's a powerful way to add functionality to
existing code in a clean and reusable manner.
Key Concepts:
Functions as First-Class Objects:
In Python, functions are first-class objects, meaning they can be treated like any other variable. They
can be passed as arguments to other functions, returned from functions, and assigned to variables.
Higher-Order Functions:
A higher-order function is a function that takes one or more functions as arguments or returns a
function as its result. Decorators are a type of higher-order function.
Wrapper Functions:
A decorator typically defines an inner wrapper function that wraps the original function. This wrapper
function is responsible for executing the additional functionality before or after calling the original
function.
def myDecorator(func):
def wrapper_function():
print('Decorator called')
func()
return wrapper_function

@myDecorator
def function():
print('Function called')

if __name__ == '__main__':
print('Main called')
function()
• The @decorator_function syntax is a syntactic sugar for original_function =
decorator_function(original_function).

• The wrapper_function takes the same arguments as the original function and returns
the result of the original function after executing the additional functionality.
Common Use Cases:
• Logging:
Decorators can be used to add logging functionality to functions, allowing you to track
when a function is called, its arguments, and its return value.
• Timing:
Decorators can be used to measure the execution time of a function.
• Caching:
80
Decorators can be used to cache the results of a function, improving performance for
repeated calls with the same arguments.
• Authentication and Authorization:
Decorators can be used to enforce access control to functions, ensuring only
authorized users can call them.
Decorators with Arguments:
Decorators can also accept arguments. To achieve this, you need another layer of
nesting:
def myDecorator(func):
def wrapper_function(a, b):
print('Decorator called')
try:
quotient = func(a, b)
return quotient
except:
return "Cannot divide by zero"
return wrapper_function

@myDecorator
def Divide(a,b):
return a/b

if __name__ == '__main__':
print('Main called')
print(Divide(76, 10))
print(Divide(76, 0))

81
Objects
Object-oriented programming enables you to develop large-scale software and GUIs effectively.
Defining Classes for Objects
A class defines the properties and behaviors for objects.
Object-oriented programming (OOP) involves the use of objects to create programs. An object
represents an entity in the real world that can be distinctly identified. For example, a student, a
desk, a circle, a button, and even a loan can all be viewed as objects. An object has a unique identity,
state, and behavior.
■ An object’s identity is like a person’s Social Security number. Python automatically assigns each
object a unique id for identifying the object at runtime.
■ An object’s state (also known as its properties or attributes) is represented by variables, called
data fields. A circle object, for example, has a data field radius, which is a property that characterizes
a circle. A rectangle object has the data fields width and height, which are properties that
characterize a rectangle.
■ Python uses methods to define an object’s behavior (also known as its actions). Recall that
methods are defined as functions. You make an object perform an action by invoking a method on
that object.
A Python class uses variables to store data fields and defines methods to perform actions. A class is
a contract—also sometimes called a template or blueprint—that defines what an object’s data fields
and methods will be.
An object is an instance of a class, and you can create many instances of a class. Creating an instance
of a class is referred to as instantiation. The terms object and instance are often used
interchangeably. An object is an instance and an instance is an object.
A class named Circle and its three objects.

82
Defining Classes
In addition to using variables to store data fields and define methods, a class provides a special
method, __init__. This method, known as an initializer, is invoked to initialize a new object’s state
when it is created. An initializer can perform any action, but initializers are designed to perform
initializing actions, such as creating an object’s data fields with initial values.
Python uses the following syntax to define a class:
class ClassName:
initializer
methods

Listing: defines the Circle class.


The class name is preceded by the keyword class and followed by a colon (:). The initializer is always
named __init__, which is a special method. Note that init needs to be preceded and followed by two
underscores.
Circle.py
import math
class Circle:
# Construct a circle object
def __init__(self, radius = 1):
self.radius = radius
def getPerimeter(self):
return 2 * self.radius * math.pi
def getArea(self):
return self.radius * self.radius * math.pi
def setRadius(self, radius):
self.radius = radius

Constructing Objects
Once a class is defined, you can create objects from the class with a constructor. The constructor
does two things:
■ It creates an object in the memory for the class.
■ It invokes the class’s __init__ method to initialize the object.
All methods, including the initializer, have the first parameter self. This parameter refers to the
object that invokes the method. The self parameter in the __init__ method is automatically set to
reference the object that was just created. You can specify any name for this parameter, but by
convention self is usually used.
The syntax for a constructor is:
ClassName(arguments)

83
Accessing Members of Objects
An object’s member refers to its data fields and methods. Data fields are also called instance
variables, because each object (instance) has a specific value for a data field. Methods are also
called instance methods, because a method is invoked by an object (instance) to perform actions on
the object such as changing the values in data fields for the object. In order to access an object’s
data fields and invoke an object’s methods, you need to assign the object to a variable by using the
following syntax:
objectRefVar = ClassName(arguments)
For example,
c1 = Circle(5)
c2 = Circle()
You can access the object’s data fields and invoke its methods by using the dot operator (.), also
known as the object member access operator. The syntax for using the dot operator is:
objectRefVar.datafield
objectRefVar.method(args)

c = Circle(5)
print(c.radius)
print(c.getPerimeter())
print(c.getArea())

The self Parameter


This parameter is used in the implementation of the method, but it is not used when the method is
called. So, what is this parameter self for? Why does Python need it?
self is a parameter that references the object itself. Using self, you can access object’s members in a
class definition. For example, you can use the syntax self.x to access the instance variable x and
syntax self.m1() to invoke the instance method m1 for the object self in a class.

84
Hiding Data Fields
Making data fields private protects data and makes the class easy to maintain.
You can access data fields via instance variables directly from an object. For example, the following
code, which lets you access the circle’s radius from c.radius, is legal:
c = Circle(5)
c.radius = 5.4 # Access instance variable directly
print(c.radius) # Access instance variable directly
Output
5.4
To prevent direct modifications of data fields, don’t let the client directly access data fields. This is
known as data hiding. This can be done by defining private data fields. In Python, the private data
fields are defined with two leading underscores. You can also define a private method named with
two leading underscores.
Private data fields and methods can be accessed within a class, but they cannot be accessed outside
the class. To make a data field accessible for the client, provide a get method to return its value. To
enable a data field to be modified, provide a set method to set a new value.
Colloquially, a get method is referred to as a getter (or accessor), and a set method is referred to as a
setter (or mutator).
A get method has the following header:
def getPropertyName(self):
If the return type is Boolean, the get method is defined as follows by
convention:
def isPropertyName(self):
#A set method has the following header:
def setPropertyName(self, propertyValue):

CircleWithPrivateRadius.py
import math
class Circle:
# Construct a circle object
85
def __init__(self, radius = 1):
self.__radius = radius
def getRadius(self):
return self.__radius
def getPerimeter(self):
return 2 * self.__radius * math.pi
def getArea(self):
return self.__radius * self.__radius * math.pi
if __name__ == '__main__':
c = Circle(5)
print(c.__radius)
print(c.getRadius())

Output
AttributeError: no attribute '_ _radius'
5
Object-Oriented Thinking
The procedural paradigm for programming focuses on designing functions. The object-oriented
paradigm couples data and methods together into objects. Software design using the object-
oriented paradigm focuses on objects and operations on objects.

86
Inheritance
Object-oriented programming (OOP) allows you to define new classes from existing classes. This is
called inheritance.
Inheritance extends the power of the object-oriented paradigm by adding an important and
powerful feature for reusing software.
You use a class to model objects of the same type. Different classes may have some common
properties and behaviors that you can generalize in a class, which can then be shared by other
classes. Inheritance enables you to define a general class and later extend it to define more
specialized classes. The specialized classes inherit the properties and methods from the general
class.
In OOP terminology, a class C1 extended from another class C2 is called a derived class, child class,
or subclass, and C2 is called a base class, parent class, or superclass. For consistency, this book uses
the terms “subclass” and “superclass.”
A subclass inherits accessible data fields and methods from its superclass, but it can also have other
data fields and methods.
GeometricObject.py

class GeometricObject:
def __init__(self, color = 'green', filled = True):
self.__color = color
self.__filled = filled
def getColor(self):
return self.__color
def setColor(self, color):
self.__color = color
def isFilled(self):
return self.__filled
def setFilled(self, filled):
self.__filled = filled
def __str__(self):
return "color: " + self.__color + " and filled: " + str(self.__filled)

CircleFromGeometricObject.py
from GeometricObject import GeometricObject
import math # math.pi is used in the class
class Circle(GeometricObject):
def __init__(self, radius):
self.__radius = radius

def getRadius(self):
return self.__radius
def setRadius(self, radius):

87
self.__radius = radius
def getArea(self):
return self.__radius * self.__radius * math.pi
def getDiameter(self):
return 2 * self.__radius
def getPerimeter(self):
return 2 * self.__radius * math.pi
def printCircle(self):
print(self.__str__() + " radius: " + str(self.__radius))

RectangleFromGeometricObject.py
from GeometricObject import GeometricObject
class Rectangle(GeometricObject):
def __init__(self, width = 1, height = 1):
super().__inti__()
self.__width = width
self.__height = height
def getWidth(self):
return self.__width
def setWidth(self, width):
self.__width = width
def getHeight(self):
return self.__height
def setHeight(self, height):
self.__height = self.__height
def getArea(self):
return self.__width * self.__height
def getPerimeter(self):
return 2 * (self.__width + self.__height)

TestCircleRectangle.py
from CircleFromGeometricObject import Circle
from RectangleFromGeometricObject import Rectangle

if __name__ == '__main__':
circle = Circle(1.5)
print("A circle", circle)
print("The radius is", circle.getRadius())
print("The area is", circle.getArea())
print("The diameter is", circle.getDiameter())

rectangle = Rectangle(2,4)
print("\nA rectangle", rectangle)
print("The area is", rectangle.getArea())
print("The perimeter is", rectangle.getParimeter())
Output
A circle color: green and filled: True
88
The radius is 1.5
The area is 7.06858347058
The diameter is 3.0

A rectangle color: green and filled: True


The area is 8
The perimeter is 12
Overriding Methods
To override a method, the method must be defined in the subclass using the same header as in its
superclass.
A subclass inherits methods from a superclass. Sometimes it is necessary for the subclass to modify
the implementation of a method defined in the superclass. This is referred to as method overriding.

class A:
def __init__(self, i = 0):
self.i = i
def m1(self):
self.i += 1
class B(A):
def __init__(self, j = 0):
super().__init__(3)
self.j = j
def m1(self):
self.i += 1
def main():
b = B()
b.m1()
print(b.i)
print(b.j)
main() # Call the main function
Output
4
0

The object Class


Every class in Python is descended from the object class.
The object class is defined in the Python library. If no inheritance is specified when a class is defined,
its superclass is object by default.

89
Multiple Inheritance

BasicInformation Marks

Student

class BasicInformation:
def __init__(self, name, rollno):
self.name = name
self.rollno = rollno
def displayInfromation(self):
print('Name is', self.name)
print('Roll no is', self.rollno)

class Marks:
def __init__(self, m1,m2):
self.m1 = m1
self.m2 = m2
def displayMarks(self):
print("Marks is " , self.m1, self.m2)

class Student(BasicInformation, Marks):


def __init__(self, name, rollno, m1, m2):
BasicInformation.__init__(self, name, rollno)
Marks.__init__(self, m1, m2)
self.total = self.getTotal()
def getTotal(self):
return self.m1 + self.m2
def displayStudent(self):
self.displayInfromation()
self.displayMarks()
print('Total is', self.total)

if __name__ == '__main__':
student = Student("Himanshu", 111, 78, 97)
student.displayStudent()
Output
Name is Himanshu

90
Roll no is 111
Marks is 78 97
Total is 175

Multilevl Inheritance

BasicInformation

Marks

Student

class BasicInformation:
def __init__(self, name, rollno):
self.name = name
self.rollno = rollno
def displayInfromation(self):
print('Name is', self.name)
print('Roll no is', self.rollno)

class Marks(BasicInformation):
def __init__(self, name, rollno, m1, m2):
BasicInformation.__init__(self, name, rollno)
self.m1 = m1
self.m2 = m2
def displayMarks(self):
print("Marks is " , self.m1, self.m2)

class Student(Marks):
def __init__(self, name, rollno, m1, m2):
Marks.__init__(self, name, rollno, m1, m2)
self.total = self.getTotal()
def getTotal(self):
return self.m1 + self.m2
def displayStudent(self):
self.displayInfromation()
self.displayMarks()

91
print('Total is', self.total)

if __name__ == '__main__':
student = Student("Himanshu", 111, 78, 97)
student.displayStudent()

92
Operator Overloading
Python allows you to define special methods for operators and functions to perform common
operations. These methods are named in a specific way for Python to recognize the association.
You can use the + operator to concatenate two strings, the * operator to concatenate the same
string multiple times, the relational operators (==, !=, <=, >, and >=) to compare two strings, and the
index operator [] to access a character. For example,

s1 = "Washington"
s2 = "California"
print("The first character in s1 is", s1[0])
print("s1 + s2 is", s1 + s2)
print("s1 < s2?", s1 < s2)
output
The first character in s1 is W
s1 + s2 is WashingtonCalifornia
s1 < s2? False
The operators are actually methods defined in the str class. Defining methods for operators is called
operator overloading. Operator overloading allows the programmer to use the built-in operators for
user-defined methods.
You name these methods with two starting and ending underscores so Python will recognize the
association. For example, to use the + operator as a method, you would define a method named
__add__. Note that these methods are not private, because they have two ending underscores in
addition to the two starting underscores. Recall that the initializer in a class is named __init__,
which is a special method for initializing an object.
For example, you can rewrite the preceding code using the methods as follows:

s1 = "Washington"
s2 = "California"
print("The first character in s1 is", s1.__getitem__(0))
print("s1 + s2 is", s1.__add__(s2))
print("s1 < s2?", s1.__lt__(s2))
Output
The first character in s1 is W
s1 + s2 is WashingtonCalifornia
s1 < s2? False
Operator Overloading: Operators and Special Methods
OPERATOR/FUNCTION METHOD DESCRIPTION
+ __add__(self, other) Addition
* __mul__(self, other) Multiplication
- __sub__(self, other) Subtraction

93
/ __truediv__(self, other) Division
% __mod__(self, other) Remainder
< __lt__(self, other) Less than
<= __le__(self, other) Less than or equal to
== __eq__(self, other) Equal to
!= __ne__(self, other) Not equal to
> __gt__(self, other) Greater than
>= __ge__(self, other) Greater than or equal to
[index] __getitem__(self, index) Index operator
In __contains__(self, value) Check membership
len __len__(self) The number of elements
str __str__(self) The string representation

s1.__getitem__(0) is the same as s1[0], s1.__add__(s2) is the same as s1 + s2, and s1.__lt__(s2) is
the same as s1 < s2.
Now you can see the advantages of operator overloading. Using operators greatly simplifies
programs, making them easier to read and maintain.
Python supports the in operator, which can be used to determine whether a character is in a string
or an element is a member of a container. The corresponding method is named __contains__(self,
e). You can use the method __contains__ or the in operator to see if a character is in a string, as
shown in the following code:

s1 = "Washington"
print("Is W in s1?", 'W' in s1)
print("Is W in s1?", s1.__contains__('W'))
Output
True
True
‘W’ in s1 is the same as s1.__contains__('W').

s1 = "Washington"
print("The length of s1 is", len(s1))
print("The length of s1 is", s1.__len__())
Output
The length of s1 is 10
The length of s1 is 10
len(s1) is the same as s1._ _len_ _().
Many of the special operators are defined in Python built-in types such as int and float. For example,
suppose i is 3 and j is 4. i._ _add_ _(j) is the same as i + j and i._ _sub_ _(j) is the same as i – j.
94
You can pass an object to invoke print(x). This is equivalent to invoking print(x._ _str_ _()) or
print(str(x)).
The comparison operators <=, ==, !=, >, and >= can also be implemented using the __cmp__ (self,
other) method. This method returns a negative integer if self < other, zero if self == other, and a
positive integer if self > other. For two objects a and b, a < b calls a.__lt__(b) if the __lt__ is
available. If not, the __cmp__ method is called to determine the order.
The Retional Class

class Rational:
def __init__(self, numerator = 1, denominator = 0):
divisor = gcd(numerator, denominator)
self.__numerator = (1 if denominator > 0 else -1) * int(numerator / divisor)
self.__denominator = int(abs(denominator) / divisor)

# Add a rational number to this rational number


def __add__(self, secondRational):
n = self.__numerator * secondRational[1] + self.__denominator *
secondRational[0]
d = self.__denominator * secondRational[1]
return Rational(n, d)

# Subtract a rational number from this rational number


def __sub__(self, secondRational):
n = self.__numerator * secondRational[1] - self.__denominator *
secondRational[0]
d = self.__denominator * secondRational[1]
return Rational(n, d)

# Multiply a rational number by this rational number


def __mul__(self, secondRational):
n = self.__numerator * secondRational[0]
d = self.__denominator * secondRational[1]
return Rational(n, d)

# Divide a rational number by this rational number


def __truediv__(self, secondRational):
n = self.__numerator * secondRational[1]
d = self.__denominator * secondRational[0]
return Rational(n, d)

# Return a float for the rational number


def __float__(self):
return self.__numerator / self.__denominator

# Return an integer for the rational number


def __int__(self):
return int(self.__float__())
95
# Return a string representation
def __str__(self):
if self.__denominator == 1:
return str(self.__numerator)
else:
return str(self.__numerator) + "/" + str(self.__denominator)

def __lt__(self, secondRational):


return self.__cmp__(secondRational) < 0

def __le__(self, secondRational):


return self.__cmp__(secondRational) <= 0

def __gt__(self, secondRational):


return self.__cmp__(secondRational) > 0

def __ge__(self, secondRational):


return self.__cmp__(secondRational) >= 0

# Compare two numbers


def __cmp__(self, secondRational):
temp = self.__sub__(secondRational)
if temp[0] > 0:
return 1
elif temp[0] < 0:
return -1
else:
return 0

# Return numerator and denominator using an index operator


def __getitem__(self, index):
if index == 0:
return self.__numerator
else:
return self.__denominator

def gcd(n, d):


n1 = abs(n)
n2 = abs(d)
gcd = 1

k = 1
while k <= n1 and k <= n2:
if n1 % k == 0 and n2 % k == 0:
gcd = k
k += 1
return gcd
96
# Create and initialize two rational numbers r1 and r2.
r1 = Rational(4, 2)
r2 = Rational(2, 3)

# Display results
print(r1, "+", r2, "=", r1 + r2)
print(r1, "-", r2, "=", r1 - r2)
print(r1, "*", r2, "=", r1 * r2)
print(r1, "/", r2, "=", r1 / r2)

print(r1, ">", r2, "is", r1 > r2)


print(r1, ">=", r2, "is", r1 >= r2)
print(r1, "<", r2, "is", r1 < r2)
print(r1, "<=", r2, "is", r1 <= r2)
print(r1, "==", r2, "is", r1 == r2)
print(r1, "!=", r2, "is", r1 != r2)

print("int(r2) is", int(r2))


print("float(r2) is", float(r2))

print("r2[0] is", r2[0])


print("r2[1] is", r2[1])

Output
2 + 2/3 = 8/3
2 - 2/3 = 4/3
2 * 2/3 = 4/3
2 / 2/3 = 3
2 > 2/3 is True
2 >= 2/3 is True
2 < 2/3 is False
2 <= 2/3 is False
2 == 2/3 is False
2 != 2/3 is True
int(r2) is 0
float(r2) is 0.6666666666666666
r2[0] is 2
r2[1] is 3

97
Exception Handling
Exception handling enables a program to deal with exceptions and continue its normal execution.
An error that occurs at runtime is also called an exception. This can be done using Python’s
exception handling syntax.
The syntax for exception handling is to wrap the code that might raise (or throw) an exception
in a try clause, as follows:
try:
<body>
except <ExceptionType>:
<handler>

Here, <body> contains the code that may raise an exception. When an exception occurs, the rest of
the code in <body> is skipped. If the exception matches an exception type, the corresponding handler
is executed. <handler> is the code that processes the exception.
Exception Handling
The try/except block works as follows:
■ First, the statements in the body between try and except are executed.
■ If no exception occurs, the except clause is skipped.
■ If an exception occurs during execution of the try clause, the rest of the clause is skipped.
■ When an exception occurs, if the exception type matches the exception name after the except
keyword, the except clause is executed, and then the execution continues after the try statement.
■ If an exception occurs and it does not match the exception name in the except clause, the
exception is passed on to the caller of this function; if no handler is found, it is an unhandled
exception and execution stops with an error message displayed.
A try statement can have more than one except clause to handle different exceptions. The
statement can also have an optional else and/or finally statement, in a syntax like this:

try:
<body>
except <ExceptionType1>:
<handler1>
except <ExceptionTypeN>:
<handlerN>
except:
<handlerExcept>
else:
<process_else>
finally:
<process_finally>
The multiple excepts are similar to elifs. When an exception occurs, it is checked to match an
exception in an except clause after the try clause sequentially. If a match is found, the handler for the
98
matching case is executed and the rest of the except clauses are skipped. Note that the
<ExceptionType> in the last except clause may be omitted. If the exception does not match any of the
exception types before the last except clause, the <handlerExcept> for the last except clause is
executed.
A try statement may have an optional else clause, which is executed if no exception is raised in the
try body.
A try statement may have an optional finally clause, which is intended to define cleanup actions
that must be performed under all circumstances. Listing gives an example of using exception handling.

TestException.py
def main():
try:
number1, number2 = eval (input ("Enter two numbers, separated by a comma:"))
result = number1 / number2
print("Result is", result)
except ZeroDivisionError:
print ("Division by zero!")
except SyntaxError:
print ("A comma may be missing in the input")
except:
print ("Something wrong in the input")
else:
print ("No exceptions")
finally:
print ("The finally clause is executed")

main()
Output
Enter two numbers, separated by a comma: 3, 4
Result is 0.75
No exceptions
The finally clause is executed

Enter two numbers, separated by a comma: 2, 0


Division by zero!
The finally clause is executed

Enter two numbers, separated by a comma: 2 3


A comma may be missing in the input
The finally clause is executed

Enter two numbers, separated by a comma: a, v


Something wrong in the input
The finally clause is executed

99
Raising Exceptions
Exceptions are wrapped in objects, and objects are created from classes. An exception is raised from
a function.
The information pertaining to an exception is wrapped in an object. An exception is raised from a
function. When a function detects an error, it creates an object from an appropriate exception class
and throws the exception to the caller of the function, using the following syntax:
raise ExceptionClass("Something is wrong")
Here’s how this works. Suppose the program detects that an argument passed to a function violates
the function’s contract; for example, the argument must be nonnegative, but a negative argument is
passed. The program can create an instance of RuntimeError and raise the exception, as follows:
ex = RuntimeError("Wrong argument")
raise ex
Or, if you prefer, you can combine the preceding two statements in one like this:
raise RuntimeError("Wrong argument")
CircleWithException.py
def Area(radius):
if radius < 0:
raise RuntimeError("Negative value not allowed")
else:
return (22.0/7.0)*radius*radius

radius = eval(input('Enter radius '))


try:
print('Area is', Area(radius))
except RuntimeError:
print("Invalid radius")
Output
Enter radius 9
Area is 254.57142857142856

Enter radius -9
Invalid radius
Processing Exceptions Using Exception Objects
You can access an exception object in the except clause.
As stated earlier, an exception is wrapped in an object. To throw an exception, you first create an
exception object and then use the raise keyword to throw it. Can this exception object be accessed
from the except clause? Yes. You can use the following syntax to assign the exception object to a
variable:
try

100
<body>
except ExceptionType as ex
<handler>

With this syntax, when the except clause catches the exception, the exception object is assigned to a
variable named ex. You can now use the object in the handler.
Listing gives an example that prompts the user to enter a number and displays the number if the input
is correct. Otherwise, the program displays an error message.

ProcessExceptionObject.py
try:
number = eval(input("Enter a number: "))
print("The number entered is", number)
except NameError as ex:
print("Exception:", ex)

Output:

Enter a number: 34
The number entered is 34

Enter a number: one


Exception: name 'one' is not defined

Defining Custom Exception Classes


You can define a custom exception class by extending BaseException or a subclass Key
The BaseException class is the root of exception classes. All Python exception classes inherit directly
or indirectly from BaseException.
BaseException

Exception

StandardError

ArithmeticError EnvironmentError RuntimeError LookupError SyntaxError

ZeroDivisionError IndentationError

IOError OSError IndexError KeyError

You can also define your own exception classes, derived from BaseException or from a subclass of
BaseException, such as RuntimeError.

InvalidRadiusException.py
101
class InvalidRadiusException(RuntimeError):
def __init__(self, radius):
super().__init__()
self.radius = radius

def __str__(self):
return "radius " + str(self.radius) + " not allowed"

def Area(radius):
if radius < 0:
raise InvalidRadiusException(radius)
else:
return (22.0/7.0)*radius*radius

radius = eval(input('Enter radius '))


try:
print('Area is', Area(radius))
except InvalidRadiusException as ex:
print(ex)

Output:
Enter radius -9
radius -9 not allowed

The order in which exceptions are specified in except blocks is important, because Python finds a
handler in this order. If an except block for a superclass type appears before an except block for a
subclass type, the except block for the subclass type will never be executed. Thus, it would be wrong
to write the code as follows:
try:
....
except Exception:
print("Something is wrong")
except InvalidRadiusException:
print("Invalid radius")

1. What is displayed when the following program is run?

try:
list = 10 * [0]
x = list[10]
print("Done ")
except IndexError:
print("Index out of bound")
2. What is displayed when the following program is run?
def main():

102
try:
f()
print("After the function call")
except ZeroDivisionError:
print("Divided by zero!")
except:
print("Exception")
def f():
print(1 / 0)
main() # Call the main function
3. What is displayed when the following program is run?
def main():
try:
f()
print("After the function call")
except IndexError:
print("Index out of bound")
except:
print("Exception in main")
def f():
try:
s ="abc"
print(s[3])
except ZeroDivisionError:
print("Divided by zero!")
main() # Call the main function
4.
5. Suppose that statement2 causes an exception in the following statement:
try:
statement1 statement2 statement3
except Exception1:
# Handle exception
except Exception2:
# Handle exception
except Exception3:
# Handle exception
finally:
# statement4
# statement5
Answer the following questions:
■ Will statement5 be executed if the exception is not caught?
■ If the exception is of type Exception3, will statement4 be executed, and will statement5 be
executed?

6. How do you raise an exception in a function?


7. What are the benefits of using exception handling?
103
8. What is displayed when the following program is run?

try:
lst = 10 * [0]
x = lst[9]
print("Done")
except IndexError:
print("Index out of bound")
else:
print("Nothing is wrong")
finally:
print("Finally we are here")
print("Continue")

13.26 What is displayed when the following program is run?


try:
lst = 10 * [0]
x = lst[10]
print("Done ")
except IndexError:
print("Index out of bound")
else:
print("Nothing is wrong")
finally:
print("Finally we are here")
print("Continue")

104
Tkinter
Tkinter enables you to develop GUI programs and is an excellent pedagogical tool for learning object-
oriented programming.
Tkinter, which will enable you to develop GUI projects. Tkinter is not only a useful tool for developing
GUI projects, but it is also a valuable pedagogical tool for learning objectoriented programming.
Getting Started with Tkinter
The tkinter module contains the classes for creating GUIs. The Tk class creates a window for holding
GUI widgets (i.e., visual components).
SimpleGUI.py
from tkinter import *
window = Tk()
label = Label(window, text = "Welcome to Python")
button = Button(window, text = "Click Me")
label.pack()
button.pack()
window.mainloop()

Output

Processing Events
A Tkinter widget can be bound to a function, which is called when an event occurs.
ProcessButtonEvent.py
from tkinter import *
def processOK():
print("OK button is clicked")
def processCancel():
print("Cancel button is clicked")
window = Tk()
btOK = Button(window, text = "OK", fg = "red", command = processOK)
btCancel = Button(window, text = "Cancel", bg = "yellow", command = processCancel)
btOK.pack()
btCancel.pack()
window.mainloop()

105
ProcessButtonEventAlternativeCode.py
from tkinter import *
class ProcessButtonEvent:
def __init__(self):
window = Tk()
btOK = Button(window, text = "OK", fg = "red", command = self.processOK)
btCancel = Button(window, text = "Cancel", bg = "yellow", command =
self.processCancel)
btOK.pack()
btCancel.pack()
window.mainloop()
def processOK(self):
print("OK button is clicked")
def processCancel(self):
print("Cancel button is clicked")
ProcessButtonEvent()

The Widget Classes


Tkinter’s GUI classes define common GUI widgets such as buttons, labels, radio buttons, check
buttons, entries, canvases, and others.

There are many options for creating widgets from these classes. The first argument is always the
parent container. You can specify a foreground color, background color, font, and cursor style when
constructing a widget.

106
To specify a color, use either a color name (such as red, yellow, green, blue, white, black, purple) or
explicitly specify the red, green, and blue (RGB) color components by using a string #RRGGBB, where
RR, GG, and BB are hexadecimal representations of the red, green, and blue values, respectively. You
can specify a font in a string that includes the font name, size, and style.
Here are some examples:
Times 10 bold
Helvetica 10 bold italic
CourierNew 20 bold italic
Courier 20 bold italic overstrike underline
By default, the text in a label or a button is centered. You can change its alignment by using the justify
option with the named constants LEFT, CENTER, or RIGHT.
You can specify a particular style of mouse cursor by using the cursor option with string values such
as arrow (the default), circle, cross, plus, or some other shape.
When you construct a widget, you can specify its properties such as fg, bg, font, cursor, text, and
command in the constructor. Later in the program, you can change the widget’s properties by using
the following syntax:
widgetName["propertyName"] = newPropertyValue
For example, the following code creates a button and its text property is changed to Hide, bg property
to red, and fg to #AB84F9. #AB84F9 is a color specified in the form of RRGGBB.
btShowOrHide = Button(window, text = "Show", bg = "white")
btShowOrHide["text"] = "Hide"
btShowOrHide["bg"] = "red"
btShowOrHide["fg"] = "#AB84F9" # Change fg color to #AB84F9
btShowOrHide["cursor"] = "plus" # Change mouse cursor to plus
btShowOrHide["justify"] = LEFT # Set justify to LEFT

WidgetsDemo.py
from tkinter import *
class WidgetsDemo:
def __init__(self):
window = Tk()
window.title("Widgets Demo")
frame1 = Frame(window)
frame1.pack()
self.v1 = IntVar()
cbtBold = Checkbutton(frame1, text = "Bold", variable=self.v1, command =
self.processCheckbutton)
self.v2= IntVar()
rbRed = Radiobutton(frame1, text = "Red", bg = "red", variable=self.v2 ,
value = 1, command = self.processRadiobutton)
rbYellow = Radiobutton(frame1, text = "Yellow", bg = "yellow", variable =
self.v2, value = 2, command = self.processRadiobutton)
cbtBold.grid(row = 1, column = 1)
rbRed.grid(row = 1, column = 2)
rbYellow.grid(row = 1, column = 3)
frame2 = Frame(window) # Create and add a frame to window
107
frame2.pack()
label = Label(frame2, text = "Enter your name: ")
self.name = StringVar()
entryName = Entry(frame2, textvariable=self.name)
btGetName = Button(frame2, text = "Get Name", command = self.processButton)
message = Message(frame2, text = "It is a widgets demo")
label.grid(row = 1, column = 1)
entryName.grid(row = 1, column = 2)
btGetName.grid(row = 1, column = 3)
message.grid(row = 1, column = 4)

# Add text
text = Text(window) # Create and add text to the window
text.pack()
text.insert(END, "Tip\nThe best way to learn Tkinter is to read ")
text.insert(END, "these carefully designed examples and use them ")
text.insert(END, "to create your applications.")

window.mainloop() # Create an event loop


def processCheckbutton(self):
print("check button is " + ("checked " if self.v1.get() == 1 else
"unchecked"))
def processRadiobutton(self):
print(("Red" if self.v2.get() == 1 else "Yellow") + " is selected " )
def processButton(self):
print("Your name is " + self.name.get())

obj = WidgetsDemo()

You use an entry (text field) for entering a value. The value must be an object of IntVar, DoubleVar, or
StringVar representing an integer, a float, or a string, respectively. IntVar, DoubleVar, and StringVar are
defined in the tkinter module.
from tkinter import *

class ChangeLabel:
def __init__(self):
self.window = Tk()
self.window.title('Home')
self.window.geometry('300x300+0+0')
self.e1 = Entry(self.window)
self.e1.pack()
self.btn = Button(self.window, text='ChangeLabel',
command=self.clickToChange)
self.btn.pack()
self.lbl = Label(self.window, text="Greeting")
self.lbl.pack()

108
self.window.mainloop()

def clickToChange(self):
self.lbl['text'] = self.e1.get()

if __name__ == '__main__':
obj = ChangeLabel()

Canvas
You use the Canvas widget for displaying shapes.
You can use the methods create_rectangle, create_oval, create_arc, create_polygon, or create_line
to draw a rectangle, oval, arc, polygon, or line on a canvas.
CanvasDemo.py
from tkinter import * # Import all definitions from tkinter

class CanvasDemo:
def __init__(self):
window = Tk() # Create a window
window.title("Canvas Demo") # Set title

# Place canvas in the window


self.canvas = Canvas(window, width = 200, height = 100, bg='white')
self.canvas.pack()

# Place buttons in frame


frame = Frame(window)
frame.pack()
btRectangle = Button(frame, text = "Rectangle", command = self.displayRect)
btOval = Button(frame, text = "Oval", command = self.displayOval)
btArc = Button(frame, text = "Arc", command = self.displayArc)
btPolygon = Button(frame, text = "Polygon", command = self.displayPolygon)
btLine = Button(frame, text = "Line", command = self.displayLine)

109
btString = Button(frame, text = "String", command = self.displayString)
btClear = Button(frame, text = "Clear", command = self.clearCanvas)
btRectangle.grid(row = 1, column = 1)
btOval.grid(row = 1, column = 2)
btArc.grid(row = 1, column = 3)
btPolygon.grid(row = 1, column = 4)
btLine.grid(row = 1, column = 5)
btString.grid(row = 1, column = 6)
btClear.grid(row = 1, column = 7)
window.mainloop()

# Display a Rectangle
def displayRect(self):
self.canvas.create_rectangle(10, 10, 190, 90, tags = "rect")

# Display an oval
def displayOval(self):
self.canvas.create_oval(10, 10, 190, 90, fill="red", tags="oval")

# Display an arc
def displayArc(self):
self.canvas.create_arc(10, 10, 190, 90, start=0, extent = 90, width = 8,
fill="red", tags = "arc")

# Display a polygon
def displayPolygon(self):
self.canvas.create_polygon(10, 10, 190, 90, 30, 50, tags = "polygon")

# Display a line
def displayLine(self):
self.canvas.create_line(10, 90, 190, 10, width = 9, arrow = "last",
activefill = "blue", tags = "line")

# Display a string
def displayString(self):
self.canvas.create_text(60, 40, text="Hi, i am a string", font="Times 10
bold underline", tags = "string")

# Clear drawings
def clearCanvas(self):
self.canvas.delete("rect", "oval", "arc", "polygon", "line", "string")

CanvasDemo() # Create GUI

110
The Geometry Managers
Tkinter uses a geometry manager to place widgets inside a container.
Tkinter supports three geometry managers: the grid manager, the pack manager, and the place
manager.
The Grid Manager
The grid manager places widgets into the cells of an invisible grid in a container. You can place a widget
in a specified row and column. You can also use the rowspan and columnspan parameters to place a
widget in multiple rows and columns.
GeometryDemo.py
from tkinter import * # Import all definitions from tkinter

class GridManagerDemo:
window = Tk() # Create a window
window.title("Grid Manager Demo") # Set title
message = Message(window, text = "This Message widget occupies three rows and
two columns")

111
message.grid(row = 1, column = 1, rowspan = 3 , columnspan = 2)
Label(window, text = "First Name:").grid(row = 1, column = 3)
Entry(window).grid(row = 1, column = 4, padx=5 , pady = 5)
Label(window, text = "Last Name:").grid(row = 2, column = 3)
Entry(window).grid(row = 2, column = 4)
Button(window, text = "Get Name").grid(row = 3, padx = 5, pady = 5, column = 4,
sticky=E)
window.mainloop() # Create an event loop

GridManagerDemo()

The Pack Manager


The pack manager can place widgets on top of each other or place them side by side. You can also use
the fill option to make a widget fill its entire container.
These three labels are packed on top of each other. The red label uses the option fill with value BOTH
and expand with value 1. The fill option uses named constants X, Y, or BOTH to fill horizontally,
vertically, or both ways. The expand option tells the pack manager to assign additional space to the
widget box. If the parent widget is larger than necessary to hold all the packed widgets, any extra
space is distributed among the widgets whose expand option is set to a nonzero value.
PackManagerDemo.py
from tkinter import * # Import all definitions from tkinter

class PackManagerDemo:
def __init__(self):
window = Tk() # Create a window
window.title("Pack Manager Demo 1") # Set title

Label(window, text = "Blue", bg = "blue").pack(side=LEFT)


Label(window, text = "Red", bg = "red").pack(fill=BOTH, expand=1, side=LEFT)
Label(window, text = "Green", bg = "green").pack(fill=BOTH, side=LEFT)
window.mainloop() # Create an event loop
PackManagerDemo() # Create GUI

112
Use side to LEFT in all widget.

The Place Manager


The place manager places widgets in absolute positions.
PlaceManagerDemo.py
from tkinter import * # Import all definitions from tkinter
class PlaceManagerDemo:
def __init__(self):
window = Tk() # Create a window
window.title("Place Manager Demo") # Set title
Label(window, text = "Blue", bg = "blue").place(x=20, y=20)
Label(window, text = "Red", bg = "red").place(x = 50, y = 50)
Label(window, text = "Green", bg = "green").place(x = 80, y = 80)
window.mainloop() # Create an event loop
PlaceManagerDemo()

113
Displaying Images
You can add an image to a label, button, check button, or radio button. To create an image, use the
PhotoImage class as follows:
photo = PhotoImage(file = imagefilename)
ImageDemo.py
from tkinter import * # Import all definitions from tkinter
class ImageDemo:
def __init__(self):
window = Tk() # Create a window
window.title("Image Demo") # Set title
# Create PhotoImage objects
wallpaper = PhotoImage(file = "wallpaper.gif")

frame1 = Frame(window)
frame1.pack()
Label(frame1, image=wallpaper).pack(side = LEFT)
window.mainloop()

ImageDemo()

Menus
You can use Tkinter to create menus, popup menus, and toolbars.
MenuDemo.py
from tkinter import *

class MenuDemo:
def __init__(self):
window = Tk()
window.title("Menu Demo")

# Create a menu bar


menubar = Menu(window)
114
window.config(menu = menubar)

# Create a pull-down menu, and add it to the menu bar


operationMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "Operation", menu = operationMenu)
operationMenu.add_command(label = "Add", command = self.add)
operationMenu.add_command(label = "Subtract", command = self.subtract)
operationMenu.add_separator()
operationMenu.add_command(label = "Multiply", command = self.multiply)
operationMenu.add_command(label = "Divide", command = self.divide)

exitmenu = Menu(menubar, tearoff = 0)


menubar.add_cascade(label = "Exit", menu = exitmenu)
exitmenu.add_command(label = "Quit", command = window.quit)

frame1 = Frame(window)
frame1.grid(row = 0, column = 0, pady = 10)
Label(frame1, text = "Number 1:").pack(side = LEFT)
self.v1 = StringVar()
Entry(frame1, width = 5, textvariable = self.v1,
justify = RIGHT).pack(side = LEFT)
Label(frame1, text = "Number 2:").pack(side = LEFT)
self.v2 = StringVar()
Entry(frame1, width = 5, textvariable = self.v2,
justify = RIGHT).pack(side = LEFT)
Label(frame1, text = "Result:").pack(side = LEFT)
self.v3 = StringVar()
Entry(frame1, width = 5, textvariable = self.v3,
justify = RIGHT).pack(side = LEFT)
window.mainloop()

def add(self):
self.v3.set(eval(self.v1.get()) + eval(self.v2.get()))

def subtract(self):
self.v3.set(eval(self.v1.get()) - eval(self.v2.get()))

def multiply(self):
self.v3.set(eval(self.v1.get()) * eval(self.v2.get()))

def divide(self):
self.v3.set(eval(self.v1.get()) / eval(self.v2.get()))

MenuDemo() # Create GUI

115
Popup Menu
A popup menu, also known as a context menu, is like a regular menu, but it does not have a menu bar
and it can float anywhere on the screen.
PopupMenu.py
from tkinter import * # Import all definitions from tkinter

class PopupMenuDemo:
def __init__(self):
window = Tk() # Create a window
window.title("Popup Menu Demo")

self.menu = Menu(window, tearoff = 0)


self.menu.add_command(label = "Draw a line")
self.menu.add_command(label = "Draw an oval")
self.menu.add_command(label = "Draw a rectangle")
self.menu.add_command(label = "Clear")
window.bind("<Button-3>", self.popup)
window.mainloop()

def popup(self, event):


self.menu.post(event.x_root, event.y_root)

PopupMenuDemo()

Mouse, Key Events, and Bindings


You can use the bind method to bind mouse and key events to a widget.
The preceding example used the widget’s bind method to bind a mouse event with a callback handler
by using the syntax:
widget.bind(event, handler)
116
If a matching event occurs, the handler is invoked. In the preceding example, the event is and the
handler function is popup. The event is a standard Tkinter object, which is automatically created when
an event occurs. Every handler has an event as its argument. The following example defines the
handler using the event as the argument:
def popup(event):
menu.post(event.x_root, event.y_root)
Events
Event Description
<Bi-Motion> An event occurs when a mouse button is moved while being held
down on the widget.
<Button-i> Button-1, Button-2, and Button-3 identify the left, middle, and right
buttons. When a mouse button is pressed over the widget, Tkinter
automatically grabs the mouse pointer’s location. ButtonPressed-i is
synonymous with Button-i.
<ButtonReleased- An event occurs when a mouse button is released.
i>
<Double-Button-i> An event occurs when a mouse button is double-clicked.
<Enter> An event occurs when a mouse pointer enters the widget.
<Key> An event occurs when a key is pressed.
<Leave> An event occurs when a mouse pointer leaves the widget.
<Return> An event occurs when the Enter key is pressed.
<Shift+A> You can bind any key such as A, B, Up, Down, Left, Right in the
keyboard with an event. An event occurs when the Shift+A keys are
pressed. You can combine Alt, Shift, and Control with other keys.
<Triple-Button-i> An event occurs when a mouse button is triple-clicked.

Event Properties
Event Property Description
char The character entered from the keyboard for key events.
keycode The key code (i.e., Unicode) for the key entered from the
keyboard for key events.
keysym The key symbol (i.e., character) for the key entered from the
keyboard for key events.
num The button number (1, 2, 3) indicates which mouse button was
clicked.
widget The widget object that fires this event.
x and y The current mouse location in the widget in pixels.
x__root and y_root The current mouse position relative to the upper-left corner of
the screen, in pixels.

MouseKeyEventDemo.py
from tkinter import * # Import all definitions from tkinter

117
class MouseKeyEventDemo:
def __init__(self):
window = Tk() # Create a window
window.title("Event Demo") # Set a title
canvas = Canvas(window, bg = "white", width = 200, height = 100)
canvas.pack()

# Bind with <Button-1> event


canvas.bind("<Button-1>", self.processMouseEvent)

# Bind with <Key> event


canvas.bind("<Key>", self.processKeyEvent)
canvas.focus_set()
window.mainloop() # Create an event loop

def processMouseEvent(self, event):


print("clicked at", event.x, event.y)
print("Position in the screen", event.x_root, event.y_root)
print("Which button is clicked? ", event.num)

def processKeyEvent(self, event):


print("keysym? ", event.keysym)
print("char? ", event.char)
print("keycode? ", event.keycode)

MouseKeyEventDemo()

118
Pattern Matching (Regular Expression)
You may be familiar with searching for text by pressing Ctrl + F and typing in the words you’re looking
for. Regular expressions go one step further: They allow you to specify a pattern of text to search for.
A RegEx, or Regular Expression, is a sequence of character that forms a search pattern. RegEx can be
used to check if a string contains the specified search pattern.

RegEx Module
Python has a build-in package called re, which can be used to work with Regular Expressions.

Example: -
import re
RegEx in Python
When you have imported the re module, you can start using regular expressions: Example: -

import re
line = "This is a line"
x = re.search("^This.*line$", line)
if x:
print("Yes! We have a match!")
else:
print("No match")

Output
Yes! We have a match!

RegEx Functions
The re module offers a set of functions that allows us to search a string for a match:
FUNCTION DESCRIPTION
findall Returns a list containing all matches
search Returns a Match object if there is a match anywhere in the string
split Returns a list where the string has been split at each match
sub Replaces one or many matches with a string
Metacharacters
Metacharacters are characters with a special meaning:
CHARACTER DESCRIPTION EXAMPLE
[] A set of characters "[a-m]"
\ Signals a special sequence (can also be used to escape "\d"
special characters)
. Any character (except newline "he..o"
character)
^ Starts with "^hello"
$ Ends with "world$"

119
* Zero or more occurrences "aix*"
+ One or more occurrences "aix+"
{} Exactly the specified number of occurrences "al{2}"
| Either or "falls|stays"
() Capture and group
Special Sequences
A special sequence is a \ followed by one of the characters in the list below, and has a special
meaning:
Character Description Example
\A Returns a match if the specified characters are at the "\AThe"
beginning of the string
\b Returns a match where the specified characters are at r"\bain" r"ain\b"
the beginning or at the end of a word
(the "r" in the beginning is making sure that the string
is being treated as a "raw string")
\B Returns a match where the specified characters are r"\Bain" r"ain\B"
present, but NOT at the beginning (or at the end) of a
word
(the "r" in the beginning is making sure that the string
is being treated as a "raw string")
\d Returns a match where the string contains digits "\d"
(numbers from 0-9)
\D Returns a match where the string DOES NOT contain "\D"
digits
\s Returns a match where the string contains a white "\s"
space character
\S Returns a match where the string DOES NOT contain a "\S"
white space character
\w Returns a match where the string contains any word "\w"
characters (characters from a to Z, digits from 0-9, and
the underscore _ character)
\W Returns a match where the string DOES NOT contain "\W"
any word characters
\Z Returns a match if the specified characters are at the "Spain\Z"
end of the string
Sets
A set is a set of characters inside a pair of square brackets [] with a special meaning:
Set Description
[arn] Returns a match where one of the specified characters (a, r, or n) are
present
[a-n] Returns a match for any lower case character, alphabetically between a
and n

120
[^arn] Returns a match for any character EXCEPT a, r, and n
[0123] Returns a match where any of the specified digits (0, 1, 2, or 3) are present

[0-9] Returns a match for any digit between 0 and 9


[0-5][0-9] Returns a match for any two-digit numbers from 00 and 59
[a-zA-Z] Returns a match for any character alphabetically between a and z, lower
case OR upper case
[+] In sets, +, *, ., |, (), $,{} has no special meaning, so [+] means: return a
match for any + character in the string
The findall() Function
The findall() function returns a list containing all matches.

Example: -
Print a list of all matches:
import re
line = "This is a line."
x = re.findall("is", line)
print(x)
Output: -
[‘is’, ‘is’]
The list contains the matches in the order they are found.
If no matches are found, an empty list is returned:

Example: -
Return an empty list if no match was found:
import re
txt = "This is a line"
x = re.findall("sentence", txt)
print(x)
Output: -
[]
The search() Function
The search() function searches the string for a match, and returns a Match object if there is a match.
If there is more than one match, only the first occurrence of the match will be returned:
Example: -
Search for the first white-space character in the string:
import re
txt = "This is a line."
x = re.search("\s", txt)
print("The first white-space character is located in position:", x.start())

Output: -
The first white-space character is located in position: 4

121
If no matches are found, the value None is returned:
Example: -
Make a search that returns no match:
import re
txt = "This is a line"
x = re.search("sentence", txt)
print(x)
Output: -
None
If matches are found-
import re
txt = "This is a line"
x=re.search("line", txt)
print(x)
Output: -
<re.Match object; span=(10, 14), match='txt'>
The split() Function
The split() function returns a list where the string has been split at each match:
Example: -
Split at each white-space character:
import re
txt = "This is a line"
x = re.split("\s", txt)
print(x)
Output: -
[‘This’, ‘is’, ‘a’, ‘line’]
You can control the number of occurrences by specifying the maxsplit parameter:
Example: -
Split the string only at the first occurrence:
import re
txt = "This is a line."
x = re.split("\s", txt, 1)
print(x)
Output: -
[‘This’, ‘is a line’]
The sub() Function
The sub() function replaces the matches with the text of your choice:
Example: -
Replace every white-space character with the number 9:
import re
txt = "This is a line"
x = re.sub("\s", "9", txt)
print(x)

122
o
his9is9a9line
You can control the number of replacements by specifying the count parameter:
Example: -
Replace the first 2 occurrences:
import re
txt = "This is a line"
x = re.sub("\s", "9", txt, 2)
print(x)
Output: -
This9is9a line
Match Object
A Match Object is an object containing information about the search and the result.
Note: If there is no match, the value None will be returned, instead of the Match Object.
Example: -
Do a search that will return a Match Object:
x = re.search("is", txt)
print(x) #this will print an object

Output: -
<re.Match object; span=(2, 4), match='is'>
The Match object has properties and methods used to retrieve information about the search, and the
result:
.span(): returns a tuple containing the start-, and end positions of the match.
.string: returns the string passed into the function
.group(): returns the part of the string where there was a match
Example: -
Print the position (start- and end-position) of the first match occurrence. The regular expression looks
for any words that starts with an upper case "S":
import re
txt = "This is a line"
x = re.search(r"\bl\w+", txt)
print(x.span())
Output: -
(10, 14)
Example: -
Print the string passed into the function:
import re
txt = "This is a line"
x = re.search(r"\bl\w+", txt)
print(x.string)
Output

123
This is a line
Example: -
Print the part of the string where there was a match.
The regular expression looks for any words that starts with an upper case "S":
import re
txt = "This is is a line"
x = re.search(r"\bl\w+", txt)
print(x.group())
Output: -
line

124
Introduction to MySQL Connector/Python
MySQL Connector/Python enables Python programs to access MySQL databases.
MySQL Connector/Python includes support for:
▪ Almost all features provided by MySQL Server version 8.0 and higher.
▪ Converting parameter values back and forth between Python and MySQL data types, for
example Python datetime and MySQL DATETIME. You can turn automatic conversion on for
convenience, or off for optimal performance.
▪ All MySQL extensions to standard SQL syntax.
▪ Protocol compression, which enables compressing the data stream between the client and
server.
▪ Connections using TCP/IP sockets and on Unix using Unix sockets.
▪ Secure TCP/IP connections using SSL.
▪ Self-contained driver. Connector/Python does not require the MySQL client library or any
Python modules outside the standard library.
Quick Installation Guide: use pip
> pip install mysql-connector-python
Connecting to MySQL Using Connector/Python
The connect() constructor creates a connection to the MySQL server and returns
a MySQLConnection object.
The following example shows how to connect to the MySQL server:

import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="registration"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
mydb.commit()
mydb.close()
Create Database
import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user"
)
print('Connected') if mydb.is_connected() else print('Not Connected')

cursor = mydb.cursor()

125
cursor.execute("""CREATE DATABASE Student""")
mydb.commit()
mydb.close()

Connecting Student Database


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
mydb.commit()
mydb.close()

Create Table information in Student Database


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')

cursor = mydb.cursor()
cursor.execute("""
CREATE TABLE information (
rollno integer primary key,
name varchar(20),
course varchar(10),
mobileno varchar(10)
)
""")
print('Table created')
mydb.commit()
mydb.close()

Check table is exists


import mysql.connector

126
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')

cursor = mydb.cursor()
cursor.execute("show tables")
tables = cursor.fetchall()
if ('information',) in tables:
print('Table already exists')
else:
cursor.execute("""
CREATE TABLE information (
rollno integer primary key,
name varchar(20),
course varchar(10),
mobileno varchar(10)
)
""")
print('Table created')
mydb.commit()
mydb.close()

Insert Data in information table


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()
cursor.execute("""
insert into information(rollno, name, course, mobileno) values (111, 'Himanshu
Rastogi', 'Python', '7251838064')
""")
print('Data saved')
mydb.commit()
mydb.close()

127
Fetch Data from information table
import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()
cursor.execute("""
select * from information
""")
data = cursor.fetchall()
print(data)
mydb.commit()
mydb.close()
Output
[(111, 'Himanshu Rastogi', 'Python', '7251838064')]

Get Data from User


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()

rollno = input('Enter roll no ')


name = input('Enter name ')
course = input('Enter course ')
mobileno = input('Enter mobile no ')
add_info = "insert into information(rollno, name, course, mobileno) values
(%s,%s,%s,%s)"
info_data = (rollno, name, course, mobileno)
cursor.execute(add_info, info_data)
print('Data saved')
mydb.commit()
mydb.close()
Get Data from Table
import mysql.connector

128
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()

rollno = input('Enter roll no ')

row = "SELECT * FROM information where rollno = %s"

cursor.execute(row, (rollno,))
data = cursor.fetchone()
print(data)

mydb.close()

Update Table Data


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()

rollno = input('Enter roll no ')


name = input('Enter name ')
course = input('Enter course ')
mobileno = input('Enter mobile no ')

update_query = "UPDATE information SET name = %s, course = %s, mobileno = %s where
rollno = %s"

cursor.execute(update_query, (name, course, mobileno, rollno))


print('Update successfully')
mydb.commit()
mydb.close()

129
Delete Information
import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()

rollno = input('Enter roll no ')

update_query = "DELETE from information where rollno = %s"

cursor.execute(update_query, (rollno,))
print('Delete successfully')
mydb.commit()
mydb.close()

Create another Table fee


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')

cursor = mydb.cursor()
cursor.execute("show tables")
tables = cursor.fetchall()
if ('fee',) in tables:
print('Table already exists')
else:
cursor.execute("""
CREATE TABLE fee (
receiptno integer primary key,
rollno integer,
course varchar(10),
fee float
)
""")
130
print('Table created')
mydb.commit()
mydb.close()

Add data into Fee Table


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()

receiptno = input('Enter receipt no ')


rollno = input('Enter rollno ')
course = input('Enter course ')
fee = input('Enter fee ')
add_fee = "insert into fee(receiptno, rollno, course, fee) values (%s,%s,%s,%s)"
fee_data = (receiptno, rollno, course, fee)
cursor.execute(add_fee, fee_data)
print('Data saved')
mydb.commit()
mydb.close()

Joining infromation and fee Table


import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()
query = "SELECT information.name,fee.receiptno, information.course, fee.fee from
information inner join fee on information.rollno = fee.rollno"
cursor.execute(query)
data = cursor.fetchall()
print(data)
mydb.close()

131
Error Handling
errors.Error Exception
This exception is the base class for all other exceptions in the errors module. It can be used to catch
all errors in a single except statement
mysql.connector.errors.IntegrityError

This exception is raised when the relational integrity of the data is affected. For example, a
duplicate key was inserted or a foreign key constraint would fail.

The following example shows a duplicate key error raised as IntegrityError:

import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')
cursor = mydb.cursor()

receiptno = input('Enter receipt no ')


rollno = input('Enter rollno ')
course = input('Enter course ')
fee = input('Enter fee ')
try:
add_fee = "insert into fee(receiptno, rollno, course, fee) values (%s,%s,%s,%s)"
fee_data = (receiptno, rollno, course, fee)
cursor.execute(add_fee, fee_data)
print('Data saved')
except mysql.connector.errors.IntegrityError:
print("Duplicate receipt number")
finally:
mydb.commit()
mydb.close()

errors.IntegrityError is a subclass of errors.DatabaseError.

errors.DataError Exception
This exception is raised when there were problems with the data. Examples are a column set
to NULL that cannot be NULL, out-of-range values for a column, division by zero, column count does
not match value count, and so on.
errors.DataError is a subclass of errors.DatabaseError.
errors.DatabaseError Exception
This exception is the default for any MySQL error which does not fit the other exceptions.
132
errors.DatabaseError is a subclass of errors.Error.
errors.InterfaceError Exception
This exception is raised for errors originating from Connector/Python itself, not related to the
MySQL server.

errors.InterfaceError is a subclass of errors.Error.


errors.InternalError Exception
This exception is raised when the MySQL server encounters an internal error, for example, when a
deadlock occurred.

errors.InternalError is a subclass of errors.DatabaseError.


errors.NotSupportedError Exception
This exception is raised when some feature was used that is not supported by the version of MySQL
that returned the error. It is also raised when using functions or statements that are not supported
by stored routines.

errors.NotSupportedError is a subclass of errors.DatabaseError.


errors.OperationalError Exception
This exception is raised for errors which are related to MySQL's operations. For example: too many
connections; a host name could not be resolved; bad handshake; server is shutting down,
communication errors.

errors.OperationalError is a subclass of errors.DatabaseError.


errors.ProgrammingError Exception
This exception is raised on programming errors, for example when you have a syntax
error in your SQL or a table was not found.

Calling MySQL Functions


Function (In MySql)

delimiter //
create function studentFound(name varchar(20), course varchar(20))
returns int
begin
declare result int;
select count(*) into result from information where information.name = name
and information.course = course;
return result;
end;
//
delimiter ;

Note: The log_bin_trust_function_creators system variable is used to control whether stored


functions and triggers can be created and executed with elevated privileges. When
133
log_bin_trust_function_creators is set to 1, it allows stored functions and triggers to be created
and executed with the privileges of the invoker, rather than the privileages of the definer,

set global log_bin_trust_function_creators = 1;

CallingFunction.py
import mysql.connector

mydb = mysql.connector.connect(
host="localhost",
user="root",
password="user",
database="Student"
)
print('Connected') if mydb.is_connected() else print('Not Connected')

cursor = mydb.cursor()
cursor.execute("select studentFound(%s, %s)", ('Himanshu', 'Django'))
answer = cursor.fetchone()[0]
print(answer)
cursor.close()

134
Multithread Programming
Most computers spend a lot of time doing nothing. If you start a system monitor tool and watch the
CPU utilization, you’ll see what I mean—it’s rare to see one hit 100 percent, even when you are
running multiple programs. There are just too many delays built into software: disk accesses,
network traffic, database queries, waiting for users to click a button, and so on.
Early on in computing, programmers realized that they could tap into such unused processing power
by running more than one program at the same time. By dividing the CPU’s attention among a set of
tasks, its capacity need not go to waste while any given task is waiting for an external event to occur.
The technique is usually called parallel processing (and sometimes “multiprocessing” or even
“multitasking”) because many tasks seem to be performed at once, overlapping and parallel in time.
It’s at the heart of modern operating systems, and it gave rise to the notion of multiple-active-
window computer interfaces we’ve all come to take for granted. Even within a single program,
dividing processing into tasks that run in parallel can make the overall system faster, at least as
measured by the clock on your wall.

Threads
Threads are another way to start activities running at the same time. In short, they run a call to a
function (or any other type of callable object) in parallel with the rest of the program. Threads are
sometimes called “lightweight processes,” but all of them run within the same single process. While
processes are commonly used to start independent programs, threads are commonly used for tasks
such as nonblocking input calls and long-running tasks in a GUI. They also provide a natural model
for algorithms that can be expressed as independently running tasks. For applications that can
benefit from parallel processing, some developers consider threads to offer a number of
advantages:
1) Performance, 2) Simplicity, 3) Shared global memory, 4) Portability, 5) Thread synchronization and
queues, 6) The global interpreter lock (GIL)
The _thread Module
Python scripts that use the Python _thread module work on all of these platforms without changing
their source code.
Example: spawns threads until you reply with a q at the console
import _thread
def child(tid):
print('Hello from thread', tid)
def parent():
i = 0
while True:
i += 1
_thread.start_new_thread(child, (i,))
if input() == 'q':
break
parent()
135
Output
Hello from thread 1

Hello from thread 2

Hello from thread 3

Hello from thread 4


q

Other ways to code threads with _thread


import _thread, time # all 3 print 4294967296
def action(i): # function run in threads
print(i ** 32)
class Power:
def __init__(self, i):
self.i = i
def action(self): # bound method run in threads
print(self.i ** 32)

_thread.start_new_thread(action, (2,)) # simple function


_thread.start_new_thread((lambda: action(2)), ()) # lambda function to defer
obj = Power(2)
_thread.start_new_thread(obj.action, ()) # bound method object
time.sleep(1)
print('End main thread')
Output
42949672964294967296
4294967296

End main thread


thread basics: start 5 copies of a function running in parallel
import _thread as thread, time
def counter(myId, count): # function run in threads
for i in range(count):
time.sleep(1) # simulate real work
print('[%s] => %s' % (myId, i))
for i in range(5): # spawn 5 threads
thread.start_new_thread(counter, (i, 5)) # each thread loops 5 times
time.sleep(6)
print('Main thread exiting.') # don't exit too early
Output
[2] => 0[1] => 0
[0] => 0
136
[3] => 0
[4] => 0
[1] => 1[0] => 1

[2] => 1[3] => 1

[4] => 1
[0] => 2[1] => 2

[3] => 2
[2] => 2[4] => 2

[1] => 3[3] => 3[0] => 3


[2] => 3

[4] => 3
[2] => 4
[3] => 4[0] => 4
[1] => 4[4] => 4

Main thread exiting.


Synchronizing access to shared objects and names
Python’s _thread module comes with its own easy-to-use tools for synchronizing access to objects
shared among threads. These tools are based on the concept of a lock—to change a shared object,
threads acquire a lock, make their changes, and then release the lock for other threads to grab.
Python ensures that only one thread can hold a lock at any point in time; if others request it while
it’s held, they are blocked until the lock becomes available. Lock objects are allocated and processed
with simple and portable calls in the _thread module that are automatically mapped to thread
locking mechanisms on the underlying platform.
A lock object created by _thread.allocate_lock is acquired and released by each thread around the
print call that writes to the shared standard output stream.
Example
import _thread as thread, time
def counter(myId, count): # function run in threads
for i in range(count):
time.sleep(1) # simulate real work
mutex.acquire()
print('[%s] => %s' % (myId, i)) # print isn't interrupted now
137
mutex.release()
mutex = thread.allocate_lock() # make a global lock object
for i in range(5): # spawn 5 threads
thread.start_new_thread(counter, (i, 5)) # each thread loops 5 times
time.sleep(6)
print('Main thread exiting.')
[4] => 0
[1] => 0
[3] => 0
[2] => 0
[0] => 0
[1] => 1
[4] => 1
[3] => 1
[2] => 1
[0] => 1
[1] => 2
[3] => 2
[4] => 2
[2] => 2
[0] => 2
[1] => 3
[3] => 3
[4] => 3
[0] => 3
[2] => 3
[1] => 4
[3] => 4
[0] => 4
[4] => 4
[2] => 4
Main thread exiting.

The threading Module


The Python standard library comes with two thread modules: _thread, the basic lowerlevel interface
illustrated thus far, and threading, a higher-level interface based on objects and classes. The
threading module internally uses the _thread module to implement objects that represent threads
and common synchronization tools. It is loosely based on a subset of the Java language’s threading
model, but it differs in ways that only Java programmers would notice.

import threading

138
class Mythread(threading.Thread): # subclass Thread object
def __init__(self, myId, count, mutex):
self.myId = myId
self.count = count # per-thread state information
self.mutex = mutex # shared objects, not globals
threading.Thread.__init__(self)
def run(self): # run provides thread logic
for i in range(self.count): # still sync stdout access
with self.mutex:
print('[%s] => %s' % (self.myId, i))
stdoutmutex = threading.Lock() # same as thread.allocate_lock()
threads = []
for i in range(10):
thread = Mythread(i, 100, stdoutmutex) # make/start 10 threads
thread.start() # starts run method in a thread
threads.append(thread)
for thread in threads:
thread.join() # wait for thread exits
print('Main thread exiting.')

139
Networking
Computer networking is used to send and receive messages among computers on the Internet.
To browse the Web or send an email, your computer must be connected to the Internet. The
Internet is the global network of millions of computers. Your computer can connect to the Internet
through an Internet Service Provider (ISP) using a dialup, DSL, or cable modem, or through a local
area network (LAN).
When a computer needs to communicate with another computer, it needs to know the other
computer’s address. An Internet Protocol (IP) address uniquely identifies the computer on the
Internet. An IP address consists of four dotted decimal numbers between 0 and 255, such as
130.254.204.33. Since it is not easy to remember so many numbers, they are often mapped to
meaningful names called domain names, such as liang.armstrong.edu. Special servers called Domain
Name Servers (DNS) on the Internet translate host names into IP addresses. When a computer
contacts liang.armstrong.edu, it first asks the DNS to translate this domain name into a numeric IP
address then sends the request using the IP address.
The Internet Protocol is a low-level protocol for delivering data from one computer to another
across the Internet in packets. Two higher-level protocols used in conjunction with the IP are the
Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP). TCP enables two hosts
to establish a connection and exchange streams of data. TCP guarantees delivery of data and also
guarantees that packets will be delivered in the same order in which they were sent. UDP is a
standard, low-overhead, connectionless, host-to-host protocol that is used over the IP. UDP allows
an application program on one computer to send a datagram to an application program on another
computer.
Client/Server Computing
Python provides the Socket module for creating a server socket, and the Socket class for creating a
client socket. Two programs on the Internet communicate through a server socket and a client
socket using I/O streams.
Note:
socket.AF_INET specifies the address family (IPv4)
socket.SOCK_STREAM specifies the socket type (TCP)
bind() binds the socket to a address and port
listen() listens for incoming connections
accept() accepts an incoming connection
recv() receives data from the client
sendall() send data to the client
close() close the connection

Server.py
import socket

#create socket object


140
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#bind the socket to a address and port


server_socket.bind(('localhost', 12345))

# listen for incoming connections


server_socket.listen(1)
print('Server socket listing...')

#accept incoming connection


client_socket, address = server_socket.accept()
print('Connected by', address)

#print data form client


data = client_socket.recv(1024)
print('Received:', data.decode())

#send back data to client


client_socket.sendall(b'Hello from server!')

#close the connection


client_socket.close()

Client.py
import socket

#crate socket object


client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#connect to the server


client_socket.connect(('localhost', 12345))

#send data to server


client_socket.sendall(b'Hello from client')

#Receive data from server


data = client_socket.recv(1024)
print('Received:', data.decode())

#close the connection


client_socket.close()

Run the server script first, then the client script. The client will send a message to the server, and the
server will respond with a message

141
Multithread Server
A multithreaded server in Python is a server that can handle multiple client connections
simultaneously using multiple threads.
import socket
import threading

class Server:
def __init__(self, host='localhost', port=12345):
self.host = host
self.port = port
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(5)
print(f'Server listening on {self.host}:{self.port}...')

def handle_client(self, client_socket, address):


print(f'Connected by {address}')
while True:
data = client_socket.recv(1024)
if not data:
break
print(f'Received: {data.decode()}')
client_socket.sendall(b'Hello from server!')
client_socket.close()

def start(self):
while True:
client_socket, address = self.server_socket.accept()
client_thread = threading.Thread(target=self.handle_client,
args=(client_socket, address))
client_thread.start()

if __name__ == '__main__':
server = Server()
server.start()

Get IP Address
You can find an IP address using a domain name by using the `socket` library in Python.
import socket

def get_ip_address(domain_name):
try:
ip_address = socket.gethostbyname(domain_name)
return ip_address
except socket.gaierror:
return "Unable to get IP address"
142
domain_name = input("Enter domain name: ")
ip_address = get_ip_address(domain_name)

print(f"The IP address of {domain_name} is: {ip_address}")

143

You might also like