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

Python Material

Python is a high-level, interpreted, and object-oriented programming language known for its readability and simplicity. It supports dynamic typing, strong typing, and is suitable for beginners, making it versatile for various applications such as web development, scientific computing, and artificial intelligence. Python's features include portability, ease of use, and a rich set of libraries, along with an integrated development environment called IDLE for executing scripts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Python Material

Python is a high-level, interpreted, and object-oriented programming language known for its readability and simplicity. It supports dynamic typing, strong typing, and is suitable for beginners, making it versatile for various applications such as web development, scientific computing, and artificial intelligence. Python's features include portability, ease of use, and a rich set of libraries, along with an integrated development environment called IDLE for executing scripts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 159

PYTHON PROGRAMMING

DEFINITION: Python is a high-level, interpreted, interactive and object-oriented scripting


language. Python is designed to be highly readable. It uses English keywords frequently
where as other languages use punctuation and it has fewer syntactical constructions than
other languages
Python is High-level: Python is a high level language that enables a programmer to write
programs that are more (or) less independent of a particular type of computer. Python
language is easier to read, write and maintain because it is closer to human language and
farther from machine language.
Python is Interpreted: High level language must be translated to machine language by a
compiler (or) interpreter. Python is processed at runtime by the interpreter. We do not need
to compile our program before executing it. This is similar to PERL and PHP.
Python is Interactive: We can actually sit at a Python prompt and interact with the
interpreter directly to write our programs.
Python is Object-Oriented: Python supports Object-Oriented style or technique of
programming that encapsulates code within objects.

FEATURES OF PYTHON PROGRAMMING


Python is Dynamically typed: Python is dynamically typed because we don’t declare a type
(eg: integer) for a variable name and assign something of that type and only that type.
Instead we have variable names and we bind them to entities whose type stays with the
entity itself.
For example, a=5 makes the variable name ‘a’ to refer to integer 5, b=’hello’ makes the
variable name ‘b’ to refer to string hello.
Static typed languages are when we declare int a and then a = 5, but assigning a =
"hello" would have been a compile time error.
Python is Strongly typed: Python is strongly typed because every type conversion in python
must be done explicitly. It means that if a = "5" (the string whose value is '5') will remain a
string, and never converted to a number if the context requires so.
Python is a Beginner's Language: Python is a great language for the beginner-level
programmers and supports the development of a wide range of applications from simple text
processing to WWW browsers to games.
Python is object oriented: Python is object oriented, with class-based inheritance. Everything
is an object (including classes, functions, modules, etc), in the sense that they can be passed
around as arguments, have methods and attributes, and so on.
Python enforces correct indentation: Python enforces correct indentation of the code by
making the indentation part of the syntax. There are no control braces in Python. Blocks of
code are identified by the level of indentation
Python is Simple: Python is a simple programming language. When we read a python
program, we feel like reading English Sentences. It means more clarity and less stress on
understanding the syntax of the language. Hence, developing and understanding programs
will become easy.
Easy to learn: Python uses very few keywords. Its programs use very simple structure. So,
developing programs in python become easy. Also Python resembles C language. Most of
the language constructs in C are also available in Python. Hence migrating from C to Python
is easy for programmers.

Easy to use: The code is compiled into byte code and then executed in a virtual machine.
This means that precompiled code is portable between platforms. It supports automatic
garbage collection.
Open Source: There is no need to pay for Python software. Python can be freely downloaded
from www.python.org website. Its source code can be read, modified and can be used in
programs as desired by the programmers.
Platform Independent: Python’s byte code represents a fixed set of instructions that run on
all operating systems and hardware. Using a Python Virtual Machine (PVM) anybody can run
these byte code instructions on any computer system. Hence, python programs are not
dependent on any specific operating system. We can use python on almost all operating
systems like UNIX, Linux, Windows, Macintosh etc. This makes Python an ideal programming
language for any network or internet.
Python is Portable: When a program yields the same result on any computer in the world
then it is called a portable program. Python programs will give the same result since they are
platform independent. Once a python Program is written, it can run on any computer system
using PVM.
Embeddable: We can insert Python programs into a C or C++ or Java Program. Several
applications are already developed in Python which can be integrated into other
programming languages like C, C++, PHP, Java and .NET. It means programmers can use
these applications for their advantage in various software projects.
Support libraries: It provides a vast range of libraries for the various fields such as machine
learning, web developer, and also for the scripting. There are various machine learning
libraries, such as Tensor flow, Pandas, Numpy, Keras, and Pytorch, etc. Django, flask,
pyramids are the popular framework for Python web development.

PYTHON APPLICATIONS
Python is known for its general-purpose nature that makes it applicable in almost every
domain of software development. Python makes its presence in every emerging field. It is the
fastest-growing programming language and can develop any application.
Here, we are specifying application areas where Python can be applied.
Some of the applications are
Web Applications
We can use Python to develop web applications. It provides libraries to handle
internet protocols such as HTML and XML, Email processing, request, One of Python web-
framework named Django is used on Instagram.

Console-based Application
Console-based applications run from the command-line or shell. These applications
are computer program which are used commands to execute. This kind of application
was more popular in the old generation of computers.
Python can develop this kind of application very effectively. It is famous for having REPL,
which means the Read-Eval-Print Loop that makes it the most suitable language for the
command-line applications.
Software Development
Python is useful for the software development process. It works as a support language
and can be used to build control and management, testing, etc.
o SCons is used to build control.
o Buildbot and Apache Gumps are used for automated continuous compilation and
testing.
o Round or Trac for bug tracking and project management. Scientific and Numeric
This is the era of Artificial intelligence where the machine can perform the task the same
as the human. Python language is the most suitable language for Artificial intelligence or
machine learning. It consists of many scientific and mathematical libraries, which makes
easy to solve complex calculations.
Implementing machine learning algorithms require complex mathematical calculation.
Python has many libraries for scientific and numeric such as Numpy, Pandas, Scipy, Scikit-
learn, etc. If you have some basic knowledge of Python, you need to import libraries on the
top of the code. Few popular frameworks of machine libraries are given below.

o SciPy
o Scikit-learn
o NumPy
o Pandas
o Matplotlib

PYTHON IDLE
IDLE (Integrated Development and Learning Environment) is an integrated
development environment (IDE) for Python. The Python installer for Windows contains the
IDLE module by default.
IDLE can be used to execute a single statement just like Python Shell and also to create,
modify, and execute Python scripts.

To start an IDLE interactive shell, search for the IDLE icon in the start menu and double click

on it.

This will open IDLE, where you can write and execute the Python scripts, as shown below.

Steps to Execute
 To execute a Python script, create a new file by selecting File -> New File from the
menu.
 Enter multiple statements and save the file with extension .py using File -> Save.
 Now, press F5 to run the script in the editor window. The IDLE shell will show the
output.
 Thus, it is easy to write, test and run Python scripts in IDLE.
IDLE Startup Details
Most readers should be able to use IDLE immediately, as it is a standard
component on Mac OS X and most Linux installations today, and is installed automatically
with standard Python on Windows.
Technically, IDLE is a Python program that uses the standard library‘s tkinter GUI toolkit
(named Tkinter in Python 2.X) to build its windows. This makes IDLE portable —it works the
same on all major desktop platforms—but it also means that we‘ll need to have tkinter
support in our Python to use IDLE.

DIFFERENCES BETWEEN PYTHON AND C


METRICS PYTHON C
Python is an interpreted, high- C is a general-purpose,
Introduction level,general-purpose programming procedural computer
language. programming language.
Interpreted programs execute Compiled programs execute
Speed slower as compared to compiled faster as compared to
programs. interpreted programs.
It is easier to write a code in Python Program syntax is harder
Usage as the number of lines is less than Python.
comparatively.
There is no need to declare the type In C, the type of a
of variable. Variables are untyped in variable must be declared
Declaration of Python. when it is created, and only
variables A given variable can be stuck on values of that type must be
values of different types at different assigned to it.
times during the program execution

Error debugging is simple. This In C, error debugging is difficult


means it takes only one in as it is a compiler dependent
instruction at a time and compiles language.
Error Debugging and executes simultaneously.
Errors are shown instantly and the This means that it takes the
execution is stopped, at that entire source code, compiles it
instruction. and then shows all the errors.

Supports function renaming C does not support function


Function renaming mechanism i.e, the same function renaming mechanism.
mechanism can be used by two different This means the same function
names. cannot be used by two
different names.

Complexity Syntax of Python programs is The syntax of a C program is


easy to learn, write and read. harder than Python.
Python uses an automatic garbage In C, the Programmer has to do
Memory- collector for memory memory management on their
management management. own.
PYTHON KEYWORDS
Python Keywords are special reserved words that convey a special meaning to the
compiler/interpreter.
Each keyword has a special meaning and a specific operation. These keywords can't be
used as a variable. Following is the List of Python Keywords.

True False None and as

asset def class continue break

else finally elif del except

global for if from import

raise try or return pass

nonlocal in not is lambda

If you want to retrieve all keywords list in interpreter mode, the command used is
>>> help(‘keywords’)

Python Variables
Variable is a name that is used to refer to memory location. Python variable is
also known as an identifier and used to hold value.
In Python, we don't need to specify the type of variable because Python is a
infer language and smart enough to get variable type.
Variable names can be a group of both the letters and digits, but they have to
begin with a letter or an underscore.
It is recommended to use lowercase letters for the variable name.
Identifier Naming
Variables are the example of identifiers. An Identifier is used to identify the literals used
in the program. The rules to name an identifier are given below.

o The first character of the variable must be an alphabet or underscore ( _ ).


o All the characters except the first character may be an alphabet of lower- case(a
-z), upper-case (A-Z), underscore, or digit (0-9).
o Identifier name must not contain any white-space, or special character (!, @, #,
%, ^, &, *).
o Identifier name must not be similar to any keyword defined in the language.
o Identifier names are case sensitive; for example, my name, and MyName is not
the same.
o Examples of valid identifiers: a123, _n, n_9, etc.
o Examples of invalid identifiers: 1a, n%4, n 9, etc.

Declaring Variable and Assigning Values


Python does not bind us to declare a variable before using it in the application.
It allows us to create a variable at the required time.
We don't need to declare explicitly variable in Python. When we assign any value
to the variable, that variable is declared automatically.
The equal (=) operator is used to assign value to a variable.
Object References
It is necessary to understand how the Python interpreter works when we declare a
variable. The process of treating variables is somewhat different from many other
programming languages.
Python is the highly object-oriented programming language; that's why every data item
belongs to a specific type of class. Consider the following example.

>>> a="python"
>>> a
'python'

>>> type(a)

<class 'str'>

>>>
>>> a=10

>>> type(a)

<class 'int'>
>>>

Object Identity
In Python, every created object identifies uniquely in Python. Python provides the guaranteed
that no two objects will have the same identifier.
The built-in id() function, is used to identify the object identifier. Consider the following
example.

>>> a=50
>>> b=50
>>> id(a)
140736484377184

>>> id(b)
140736484377184

>>> a=100
>>> id(a)
140736484378784
>>>
We assigned the b and a values are same, a and b both point to the same object. When
we checked by the id() function it returned the same number. We reassign a to 500; then
it referred to the new object identifier.

Variable Names
We have already discussed how to declare the valid variable. Variable names can be
any length can have uppercase, lowercase (A to Z, a to z), the digit (0-9), and
underscore character(_).
Consider the following example of valid variables names.

name = "Devansh" age


= 20

marks = 80.50
print(name)
print(age)
print(marks)
Multiple Assignment
Python allows us to assign a value to multiple variables in a single statement, which is
also known as multiple assignments.
We can apply multiple assignments in two ways, either by assigning a single value to
multiple variables or assigning multiple values to multiple variables.
Consider the following example.
Assigning single value to multiple variables
Eg:
x=y=z=50
print(x)
print(y)
print(z)
Assigning multiple values to multiple variables:
Eg:
a,b,c=5,10,15
print a
print b
print c
The values will be assigned in the order in which variables appear.

Delete a variable
We can delete the variable using the del keyword. The syntax is given below.
Syntax –
del <variable_name>
In the following example, we create a variable x and assign value to it. We deleted variable x,
and print it, we get the error "variable x is not defined".
The variable x will no longer use in future.
Example -
# Assigning a value to x x =
6
print(x)
# deleting a variable.
del x
print(x)

Printing Multiple Variables


a=5
b=6
# printing multiple variables
print(a,b)

INPUT, PROCESSING, AND OUTPUT


Most useful programs accept inputs from some source, process these inputs, and then
finally output results to some destination. In terminal-based interactive programs, the input
source is the keyboard, and the output destination is the terminal display. The Python shell
itself takes inputs as Python expressions or statements. Its processing evaluates these
items. Its outputs are the results displayed in the shell. Python provides numerous built-in
functions that are readily available to us at the Python prompt. Some of the functions like
input() and print() are widely used for standard input and output operations respectively.
Let us see the output section first. : Python Output Using print () function
We use the print() function to output data to the standard output device (screen).
We can also output data to a file
Syntax of print():
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

objects - object to the printed. * indicates that there may be more than one object

sep - objects are separated by sep. Default value: ' '

end - end is printed at last by default it has \n

file - must be an object with write(string) method. If omitted it, sys.stdout will be
used which prints objects on the screen.

flush - A Boolean, specifying if the output is flushed (True) or buffered (False). Default:
False
Example 1:
print('This sentence is output to the screen')

Output: This sentence is output to the screen


Example 2:
a=5
print('The value of a is', a)

Output: The value of a is 5


Example 3:
print("Python is fun.")
a=5

# Two objects are


passed
print("a =", a)
b=a
# Three objects are
passed
print('a =', a, '= b')

Case 1: print without any arguments


print(‘KCPG College’)
print () # we have not passed any argument by default it takes new line and create one line
blank space
print(‘Master of Computer Applications’)

Output:

KCPG College
Master of Computer Applications
Case 2: print function with string operations (with arguments)
1.Print(‘helloworld’)
Output: helloworld
2.print(‘hello\nworld’)
Output: hello world
3.print(‘hello\tworld’)
Output: hello world

# string concatenation both objects are string only


print(‘course ’ + ‘mca’)
Output: course mca

# repeat string into number of times


print(5*’mca’) Output: mcamcamcamcamca
print(4*'mca\n')
Output:
Mca
mca
mca
mca

Case 3 : print function with any number of arguments


1. (a) print(‘values are :’,10,20,30)
Output: values are : 10 20 30

(b) a,b,c=10,20,30
print(‘values are:’,a,b,c)
Output: values are : 10 20 30

2. print function with “sep” attribute: This is used to separate objects


By default, value of sep is empty space(sep=’’)
>>>print('values are:',10,20,30,sep=":")

Output: values are::10:20:30

>>>print('values are:',10,20,30,sep="--")
Output: values are:--10--20—30
Case 4: print statement with end attribute
The end key of print function will set the string that needs to be appended when
printing is done. By default, the end key is set by newline character (By default, attribute end
=’\n’ in print function). So after finishing printing all the variables, a newline character is
appended.
Hence, we get the output of each print statement in different line. But we will now
overwrite the newline character by any character at the end of the print statement.

Example-1:
print('HAI') # in this statement by default end =’\n’ so it takes new line
print('SRIRAM’) # in this statement by default end =’\n’ so it takes new line
print('KRISHNA') # in this statement by default end =’\n’ so it takes new line

Output:
HAI SRIRAM KRISHNA

Note: when you observe output 1st print statement prints output HAI and immediately takes
new line character and execute 2nd print statement and followed.

Case 5: Print function with sep and end attribute Example


print(19,20,30,sep=':',end='$$$')
print(40,50,sep=':')
print(70,80,sep=':',end='&&&')
print(90,100)
Output: 19:20:30$$$40:50 70:80&&&90 100

Python | Output Formatting


There are several ways to present the output of a program, data can be printed in a
human-readable form, or written to a file for future use. Sometimes user often wants more
control the formatting of output than simply printing space-separated values.
There are several ways to format output.
Formatting output using String modulo operator (%):
Syntax: print („formatted string‟ %( variable list)
Example 1
#print integer and float value
print ("MCA: % 2d, Portal: % 5.2f"%(1, 05.333))

# print integer value


print ("Total students: % 3d, Boys: % 2d"%(240, 120))
# print octal value
print ("% 7.3o"%(25))
# print exponential value
print ("% 10.3E"%(356.08977))

Output :
MCA: 1, Portal: 5.33
Total students: 240, Boys: 120
031
3.561E+02

Example 2
(a) a=6
print(‘a value is =%i’ %a)
Output: a value is =6
(b) a=6;b=7;c=8
print('a value is =%i and b=%f and c=%i' %(a,b,c))
Output: a value is =6 and b=7.000000 and c=8

Print function with replacement operator {}or format function


str.format() is one of the string formatting methods in Python3, which allows multiple
substitutions and value formatting. This method lets us concatenate elements within a
string through positional formatting.
Example:1
Name=‘John’
Salary=’1000’
print(‘hello my name is {} and my salary is {}’.format(Name, Salary))
Output: hello my name is John and my salary is 1000

Example:2
name='Joh
n'
salary=100
0
print('hello my name is "{}" and my salary is "{}"'.format(name, salary))
Output: : hello my name is "John" and my salary is "1000"

*********we can also use index values and print the output*********
Example: 3
name='Joh
n'
salary=10
00
print('hello my name is {0} and my salary is {1} ‘.format(name, salary))
Output: hello my name is John and my salary is 1000

Reading Input from the Keyboard:


In python input() is used to read the input from the keyboard dynamically. By default, the
value of the input function will be stored as a string .
Syntax: Variable name =input(‘prompt’)
Example:
name =input("Enter Student Name ")
salary =input("Enter Branch ")
company =input("Enter College name ")
print("\n")
print("Student Details")
print("Student name is {} ,Branch- {}, College Name is {}"
.format(name,salary,company))

OUTPUT:
Enter Student Name RAMA KRISHNA
Branch MCA
Enter College name KCPG
Student Details
Student name is RAMA KRISHNA- MCA, College Name is KCPG
Accept an numeric input from User:
To accept an integer value from a user in Python. We need to convert an input string value into
an integer using a int() function.
Example:
first_number = int(input("Enter first number "))
We need to convert an input string value into an integer using a float() function.
Example:
first_number = float(input("Enter first number "))

# program to calculate addition of two input numbers


first_number = int(input("Enter first number "))
second_number=int(input("Enter second number "))
print("First Number:",first_number)
print("Second Number:",second_number)
sum1 =first_number+second_number
print("Addition of two number is: ", sum1)
Output:
Enter first number 20 Enter second number 40 First Number: 20
Second Number: 40
Addition of two number is: 60

Get multiple input values from a user in one line:


In Python, we can accept two or three values from the user in one input() call.
Example: In a single execution of the input() function, we can ask the user hi/her name,
age, and phone number and store it in three different variables.
name, age, phone =input("Enter your name, Age, Percentage separated by space ").split()
print("\n")
print("User Details: ", name, age, phone)
Output:
Enter your name, Age, Percentage separated by space
john 15 80%
User Details: john 15 80%

Data types in Python


Every value in Python has a data type. Since everything is an object in Python
programming, data types are actually classes and variables are instance (object) of these
classes.
Variables can hold values, and every value has a data-type. Python is a
dynamically typed language; hence we do not need to define the type of the variable while
declaring it. The interpreter implicitly binds the value with its type.
Python enables us to check the type of the variable used in the program. Python
provides us the type() function, which returns the type of the variable passed.
There are various data types in Python.
Python Numbers

Integers, floating point numbers and complex numbers fall under Python numbers
category. They are defined as int, and classes in Python. We can use the function to know
which class a variable or a value belongs to. Similarly, the function is used to check if an
object belongs to a Particular class.
A floating-point number is accurate up to 15 decimal places. Integer and floating points are
separated by decimal points. 1 is an integer, 1.0 is a floating-point number.
Complex numbers are written in the form, x + yj, where x is the real part and y is the imaginary
part. Here are some examples.

Sequence Type: (List ,Tuple,String)

List
 Python Lists are similar to arrays in C.
 However, the list can contain data of different types. The items stored in
the list are separated with a comma (,) and enclosed within square
brackets [].
 We can use slice [:] operators to access the data of the list.
 The concatenation operator (+) and repetition operator (*) works with
the list in the same way as they were working with the strings.
Consider the following example.

list1 = [1, "hi", "Python", 2] #Checking type of given list print(type(list1))


#Printing the list1
print (list1)
# List slicing
print (list1[3:])
# List slicing
print (list1[0:2])
# List Concatenation using + operator
print (list1 + list1)
# List repetation using * operator
print (list1 * 3)

Tuple
 A tuple is similar to the list in many ways. Like lists, tuples also contain the collection of
the items of different data types.
 The items of the tuple are separated with a comma (,) and enclosed in parentheses ().
 A tuple is a read-only data structure as we can't modify the size and value of the items
of a tuple.

Let's see a simple example of the tuple. tup = ("hi", "Python", 2)

# Checking type of tup


print (type(tup))
#Printing the tuple
print (tup)
# Tuple slicing
print (tup[1:])
print (tup[0:1])
# Tuple concatenation using + operato
print (tup + tup)
# Tuple repatation using * operator
print (tup * 3)
# Adding value to tup. It will throw an
error. tup[2] = "hi"

Dictionary
 Dictionary is an unordered set of a key-value pair of items.
 It is like an associative array or a hash table where each key stores a specific value.
Key can hold any primitive data type, whereas value is an arbitrary Python object.
 The items in the dictionary are separated with the comma (,) and enclosed in the curly
braces {}.

Consider the following example.


d = {1:'A', 2:'B', 3:'C', 4:'D'}
# Printing dictionary
print (d)

# Accesing value using keys


print("1st name is "+d[1])
print("2nd name is "+ d[4])

print (d.keys())
print (d.values())

Boolean
 Boolean type provides two built-in values, True and False.
 These values are used to determine the given statement true or false. It denotes by the
class bool.
 True can be represented by any non-zero value or 'T' whereas false can be represented
by the 0 or 'F'. Consider the following example.

# Python program to check the boolean type


print(type(True)) print(type(False)) print(false)

Sets
 A Python set is the collection of the unordered items. Each element in the set must be
unique, immutable, and the sets remove the duplicate elements.
 Sets are mutable which means we can modify it after its creation.
 Unlike other collections in Python, there is no index attached to the elements of the set,
i.e., we cannot directly access any element of the set by the index. However, we can
print them all together, or we can get the list of elements by looping through the set
 The set is created by using a built-in function set(), or a sequence of elements is
passed in the curly braces and separated by the comma. It can contain various types of
values. Consider the following example.

# Creating Empty set set1 = set()

set2 = {'10', 2.3, 30,'Python'}


#Printing Set value
print(set2)
# Adding element to the set set2.add(10)
print(set2)
#Removing element from the set set2.remove(2.3)
print(set2)

OUTPUT:

{'Python', 2.3, 30, '10'}

{2.3, '10', 10, 'Python', 30}

{'10', 10, 'Python', 30}

Python Strings
String is sequene of Unicode characters. We can use single quotes or double quotes to
represent strings. Multi line can be denoted using triple quotes “ “ “.
Eg:
s = "This is a string"
print(s)
s = '''A multiline string'''
print(s)
Output:
This is a string
A multiline string
Just like a list and tuple, the slicing operator [ ] can be used with strings. Strings, however, are
immutable.

Type Conversion
The process of converting the value of one data type (integer, string, float, etc.) to
another data type is called type conversion. Python has two types of type conversion.
1. Implicit Type Conversion
2. Explicit Type Conversion

Implicit Type Conversion


In Implicit type conversion, Python automatically converts one data type to another
data type. This process doesn't need any user involvement.
datatype of num_new: <class 'float'>
Let's see an example where Python promotes the conversion of the lower data type (integer)
to the higher data type (float) to avoid data loss.

Example 1: Converting integer to float


num_int = 123
num_flo = 1.23
num_new = num_int + num_flo
print("datatype of num_int:",type(num_int))
print("datatype of num_flo:",type(num_flo))
print("Value of num_new:",num_new)
print("datatype of num_new:",type(num_new))

Output:
datatype of num_int: <class 'int'>
datatype of num_flo: <class 'float'>
Value of num_new: 124.23
We add two variables num_int and num_flo, storing the value in num_new.
We will look at the data type of all three objects respectively.
In the output, we can see the data type of num_int is integer whilt the data type of num_flo is
a float

Explicit Type Conversion


In Explicit Type Conversion, users convert the data type of an object to required data type. We
use the predefined functions like int(), float(), str(), etc to perform explicit type conversion.
This type of conversion is also called typecasting because the user casts (changes) the data
type of the objects.

Syntax :

<required_datatype>(expression)
Eg:
num_int = 123
num_str = "456"

print("Data type of num_int:",type(num_int))


print("Data type of num_str before Type Casting:",type(num_str))

num_str = int(num_str)
print("Data type of num_str after Type Casting:",type(num_str))
num_sum = num_int + num_str
print("Sum of num_int and num_str:",num_sum)

print("Data type of the sum:",type(num_sum))

Output:
Data type of num_int: <class 'int'>
Data type of num_str before Type Casting: <class 'str'>
Data type of num_str after Type Casting: <class 'int'>
Sum of num_int and num_str: 579
Data type of the sum: <class 'int'>

 We add num_str and num_int variable.


 We converted num_str from string(higher) to integer(lower) type
using int() function to perform the addition.
 After converting num_str to an integer value, Python is able to add these two
 variables.

PYTHON OPERATORS
The operator can be defined as a symbol which is responsible for a particular operation
between two operands.
For example, 5 + 6 is an expression where + is an operator that performs arithmetic add
operation on numeric left operand 5 and the right side operand 6 and returns a sum of
two operands as a result.
Python includes the operator module that includes underlying methods for each
operator. For example, the + operator calls the operator.add(a,b) method.
Python includes the following categories of operators:
 Arithmetic Operators
 Assignment Operators
 Comparison Operators
 Logical Operators
 Identity Operators
 Membership Test Operators
 Bitwise Operators

Arithmetic Operators
Arithmetic operators perform the common mathematical operation on the numeric
operands. The arithmetic operators return the type of result depends on the type of
operands, as below.
1. If either operand is a complex number, the result is converted to complex;
2. If either operand is a floating point number, the result is converted to
floating point;
3. If both operands are integers, then the result is an integer and no
conversion is needed.

Example in Python
Operation Operator Function Shell
Addition: Sum of two + operator.add(a,b) >>> x = 5; y = 6
operands >>> x + y
11
>>> import operator
>>> operator.add(5,6) 11

Subtraction: Left operand - operator.sub(a,b) >>> x = 10; y = 5


minus right operand >>> x - y
5
>>> import operator
>>> operator.sub(10, 5)
5

Multiplication * operator.mul(a,b) >>> x = 5; y = 6


>>> x * y
30
>>> import operator
>>> operator.mul(5,6)
30

Exponentiation: Left operand ** operator.pow(a,b) >>> x = 2; y = 3


raised to the power of right >>> x ** y 8
>>> import operator
>>> operator.pow(2, 3)
8

Division / operator.truediv(a,b) >>> x = 6; y = 3


>>> x / y 2
>>> import operator
>>> operator.truediv(6,
3)
2

Floor division: equivilant // operator.floordiv(a,b) >>> x = 6; y = 5


to math.floor(a/b) >>> x // y
1
>>> import operator
>>>
operator.floordiv(6,5)
1
Modulus: Reminder of a/b % operator.mod(a, >>> x = 11; y = 3
b) >>> x % y
12
>>> import operator
>>> operator.mod(11, 3)
2

Assignment Operators
The assignment operators are used to assign values to variables. The
following table lists all the Assignment operators in Python:

Operator Function Example in Python Shell

= >>> x = 5;
>>> x
5
+= operator.iadd(a,b) >>> x = 5
>>> x += 5
10
>>> import operator
>>> x = operator.iadd(5, 5) 10

-= operator.isub(a,b) >>> x = 5
>>> x -= 2 3
>>> import operator
>>> x = operator.isub(5,2)

*= operator.imul(a,b) >>> x = 2
>>> x *= 3
6
>>> import operator
>>> x = operator.imul(2, 3)
/= operator.itruediv(a,b) >>> x = 6
>>> x /= 3 2
>>> import operator
>>> x = operator.itruediv(6, 3)

//= operator.ifloordiv(a,b) >>> x = 6


>>> x //= 5
1
>>> import operator
>>> operator.ifloordiv(6,5)
%= operator.imod(a, b) >>> x = 11
>>> x %= 3 2
>>> import operator
>>> operator.imod(11, 3)
2

Comparison Operators
The comparison operators compare two operands and return a boolean
either True or False. The following table lists comparison operators in Python.

Operator Function Description Example in Python Shell

> operator.gt(a,b) True if the left >>> x = 5; y = 6


operand is higher >>> x > y
than the right one False
>>> import operator
>>> operator.gt(5,6) False

< operator.lt(a,b) True if the left >>> x = 5; y = 6


operand is lower >>> x < y True
than right one
>>> import operator
>>> operator.add(5,6) True
== operator.eq(a,b)True if the operands are >>> x = 5; y = 6
equal >>> x == y
False
>>> import operator
>>> operator.eq(5,6)
False

!= operator.ne(a,b) True if the operands are >>> x = 5; y = 6


not equal >>> x != y
True
>>> import operator
>>> operator.ne(5,6) True

>= operator.ge(a,b) True if the left >>> x = 5; y = 6


operand is higher >>> x >= y
than or equal to the False
right one >>> import operator
>>> operator.ge(5,6)
False

<= operator.le(a,b) True if the left >>> x = 5; y = 6


operand is lower >>> x <= y
than or equal to the True
right one >>> import operator
>>> operator.le(5,6) True

Logical Operators
The logical operators are used to combine two boolean expressions. The
logical operations are generally applicable to all objects, and support truth tests,
identity tests, and boolean operations.

Operator Description Example

and True if both are true >>> x = 5; y = 6


>>> x > 1 and y <10
True
or True if at least one is true >>> x = 5; y = 6
>>> x > 6 or y <10
True
not Returns True if an expression evalutes to >>> x = 5
false and vice-versa >>> not x > 1
False
Identity Operators
The identity operators check whether the two objects have the same id
value e.i. both the objects point to the same memory location.

Operator Function Description Example in Python Shell

is operator.is_(a,b) True if both are true >>> x = 5; y = 6


>>> x is y
False
>>> import operator
>>> operator.is_(x,y)
False
is not operator.is_not(a,b) True if at least one is >>> x = 5; y = 6
true >>> x is not y True
>>> import operator
>>> operator.is_not(x, y) True

It compares the memory location of two objects .Memory location can easily be
traced by using id( ) function.

Membership Test Operators


The membership test operators in and not in test whether the sequence
has a given item or not. For the string and bytes types, x in y is True if and only if
x is a substring of y.
OperatorFunction Description Example in Python Shell

in operator.contains(a,b) Returns True if the >>> nums = [1,2,3,4,5]


sequence contains the >>> 1 in nums True
specified item else returns >>> 10 in nums
False. False
>>> 'str' in 'string'
True
>>> import operator
>>>
operator.contains(nums, 2)
True

not in not Returns True if the >>> nums = [1,2,3,4,5]


operator.contains(a,b) sequence does not >>> 1 not in nums
contains the specified False
item, else returns False. >>> 10 not in nums
True
>>> 'str' not in 'string'
False
>>> import operator
>>> not
operator.contains(nums, 2)
False

Bitwise Operators
Bitwise operators perform operations on binary operands. These
operators ae used to perform bit level operations.

bits AND-& OR-| XOR-^ NOT A-~ NOT B


0 0 0 0 0 1 1
0 1 0 1 1 1 0
1 0 0 1 1 0 1
1 1 1 1 0 0 0

Example: perform a & b , where a=5, b= 6


1. Convert a= 5 into binary .( The binary value for 5 is 0101)
2. Convert b=10 into binary ( The binary value for 10 is 1010)
3. Perform a & b using the truth table
values.
A = 0101
B= 1010
A & B= 0 0 0 0( value is 0)

& operator.and_(a,b) Sets each bit to 1 if >>> x=5; y=10


BITWISE both bits are 1. >>> z=x & y
AND >>>
z0
>>> import operator
>>> operator.and_(x, y)
0
| operator.or_(a,b) Sets each bit to 1 if one >>> x=5; y=10
BITWISE of two bits is 1. >>> z=x | y
OR >>>
z 15
>>> import operator
>>> operator.or_(x, y)
15
^ operator.xor(a,b) Sets each bit to 1 if >>> x=5; y=10
BITWISE only one of two bits >>> z=x ^ y
XOR is 1. >>>
z
15
>>> import operator
>>> operator.xor(x, y)
15
~ operator.invert(a) Inverts all the bits. >>> x=5
BITWISE >>> ~x
NOT -6
>>> import operator
>>> operator.invert(x)
-6
<< operator.lshift(a,b) Shift left by pushing >>> x=5
LEFT zeros in from the right >>>
SHIFT and let the leftmost bits x<<2 20
fall off. >>> import operator
>>> operator.lshift(x,2)
20
>> operator.rshift(a,b)Shift right by pushing >>> x=5
RIGHT copies of the leftmost bit >>>
SHIFT in from the left, and let x>>2 1
the rightmost bits fall off. >>> import operator
>>> operator.rshift(x,2)
1

Precedence and Associativity of Operators in Python


Precedence of Python Operators
The combination of values, variables, operators, and function calls is termed as an
expression. The Python interpreter can evaluate a valid expression.

For example:
>>> 5 - 7
-2

Here 5 - 7 is an expression. There can be more than one operator in an expression.


To evaluate these types of expressions there is a rule of precedence in Python. It
guides the order in which these operations are carried out.
For example, multiplication has higher precedence than subtraction.

# Multiplication has higher precedence # than subtraction


>>> 10 - 4 * 2
2
But we can change this order using parentheses () as it has higher precedence than
multiplication.
# Parentheses () has higher precedence
>>> (10 - 4) * 2
12
Operator Precedence
The precedence of the operators is essential to find out since it enables us to know
which operator should be evaluated first. The precedence table of the operators in Python
is given below.

Operator Description
** The exponent operator is given priority over all the others used in the
expression.
~+- The negation, unary plus, and minus.
* / % // The multiplication, divide, modules, reminder, and floor division.
+- Binary plus, and minus
>> << Left shift. and right shift
& Binary and.
^| Binary xor, and or
<= < > >= Comparison operators (less than, less than equal to, greater than, greater then
equal to).
<> == != Equality operators.
= %= /= //= - Assignment operators
=
+=
*= **=
is is not Identity operators
in not in Membership operators
not or and Logical operators

Example:
When you execute the above program, it produces the following result –
a = 20
b = 10
c = 15
d=5
e=0

e = (a + b) * c / d #( 30 * 15 ) / 5
print ("Value of (a + b) * c / d is ", e)

e = ((a + b) * c) / d # (30 * 15 ) / 5
print ("Value of ((a + b) * c) / d is ", e)

e = (a + b) * (c / d); # (30) * (15/5)


print ("Value of (a + b) * (c / d) is ", e)

e = a + (b * c) / d; # 20 + (150/5)
print ("Value of a + (b * c) / d is ", e)
Value of (a + b) * c / d is 90
Value of ((a + b) * c) / d is 90
Value of (a + b) * (c / d) is 90
Value of a + (b * c) / d is 50
Associativity of Python Operators
When two operators have the same precedence, associativity helps to determine the
order of operations. Associativity is the order in which an expression is evaluated that has
multiple operators of the same precedence. Almost all the operators have left-to-right
associativity.

For example, multiplication and floor division have the same precedence. Hence, if both of
them are present in an expression, the left one is evaluated first.
# Left-right associtivity # Output: 3
Print(5 * 2 //3)
# shows left-right associativity # Output: 0
Print( 5 * (2//3))

Wecansee that 2 ** 3 ** 2 is equivalent to 2 ** (3 ** 2).

# Shows the right-left associativity of ** # Output: 512, Since 2**(3**2) =


2**9 print(2 ** 3 ** 2)
# If 2 needs to be exponated fisrt, need to use () # Output: 64
print((2 ** 3) ** 2)

CONTROL STATEMENTS
1, Decision Making Statements
Decision making statements in programming languages decides the direction of flow of
program execution. Decision making statements available in python are:
 if statement
 if..else statements
 nested if statements
 if-elif ladder
 Short Hand if statement
 Short Hand if-else statement

if statement
`if statement is the most simple decision making statement. It is used to decide whether a
certain statement or block of statements will be executed or not i.e if a certain condition is
true then a block of statement is executed otherwise not.
Syntax:

if condition:
# Statements to execute if
# condition is true
Here, condition after evaluation will be either true or false. if statement accepts boolean
values – if the value is true then it will execute the block of statements below it otherwise
not. We can use condition with bracket ‘(‘ ‘)’ also.
As we know, python uses indentation to identify a block. So the block under an if statement
will be identified as shown in the below example:
if condition:
statement1
statement2
Flowchart:-

# python program to illustrate If statement


i = 10
if (i > 15):
print ("10 is less than 15")
print ("I am Not in if")

Output:
I am Not in if
As the condition present in the if statement is false. So, the block below the if statement is
not executed.

if- else
The if statement alone tells us that if a condition is true it will execute a block of
statements and if the condition is false it won’t. But what if we want to do something else if
the condition is false. Here comes the else statement. We can use the else statement
with if statement to execute a block of code when the condition is false.
Syntax:
if (condition):
# Executes this block if
# condition is true
else:
# Executes this block if
# condition is false
Flow Chart:-

# python program to illustrate If else statement


i = 20;
if (i < 15):
print ("i is smaller than 15")
print ("i'm in if Block")
else:
print ("i is greater than 15")
print ("i'm in else Block")
print ("i'm not in if and not in else Block")

Output:
i is greater than 15
i'm in else Block
i'm not in if and not in else Block

The block of code following the else statement is executed as the condition present in the if
statement is false after call the statement which is not in block(without spaces).
nested-if
A nested if is an if statement that is the target of another if statement. Nested if statements
mean an if statement inside another if statement. Yes, Python allows us to nest if
statements within if statements. i.e, we can place an if statement inside another if
statement.
Syntax:
if (condition1):
# Executes when condition1 is true
if (condition2):
# Executes when condition2 is true
# if Block is end here
# if Block is end here
Flow chart:-

# python program to illustrate nested If statement

i = 10
if (i == 10):
# First if statement
if (i < 15):
print ("i is smaller than 15")
# Nested - if statement
# Will only be executed if statement above
# it is true
if (i < 12):
print ("i is smaller than 12 too")
else:
print ("i is greater than 15")
Output:
i is smaller than 15
i is smaller than 12 too

if-elif-else ladder
Here, a user can decide among multiple options. The if statements are executed from
the top down. As soon as one of the conditions controlling the if is true, the statement
associated with that if is executed, and the rest of the ladder is bypassed. If none of the
conditions is true, then the final else statement will be executed.

Syntax:-
if (condition):
statement
elif (condition):
statement
.
.
else:
statement
Flow Chart:-

Example:-
# Python program to illustrate if-elif-else ladder

i = 20
if (i == 10):
print ("i is 10")
elif (i == 15):
print ("i is 15")
elif (i == 20):
print ("i is 20")
else:
print ("i is not present")

Output:
i is 20

Looping Statements

• In general, statements are executed sequentially: The first statement in a function is


executed first, followed by the second, and so on. There may be a situation when you
need to execute a block of code several number of times.
• A loop statement allows us to execute a statement or group of statements multiple
times.

• Looping Statements supported by Python :

– for

– while

• There are two types of loops—

– those that repeat an action a predefined number of times(definite iteration),


and
– those that perform the action until the program determines that it needs to
stop
(indefinite iteration).

1 Definite iteration for Loop

• Executing a Statement a Given Number of Times

– The form of this type of for loop is


for <variable> in range(<an integer expression>):

<statement-1>

<statement-n>

• The first line of code in a loop is sometimes called the loop header,which denotes the
number of iterations that the loop performs.
– The colon (:) ends the loop header.
• The loop body comprises the statements in the remaining lines of code, below
theheader.These statements are executed in sequence on each pass through the
loop.

– The statements in the loop body must be indented and aligned in the
samecolumn.
>>> for i in range(4):
print(i)
0

Count-Controlled Loops:

• Loops that count through a range of numbers are also called count-controlled loops.

• The value of the count on each pass is often used in computations.

• To count from an explicit lower bound, the programmer can supply a second integer
expression in the loop header. When two arguments are supplied to range, the count
rangesfrom the first argument to the second argument minus 1

• The only thing in this version to be careful about is the second argument of range, which
should specify an integer greater by 1 than the desired upper bound of the count.

• Here is the form of this version of the for loop:


for <variable> in range(<lower bound>, <upper bound + 1>):

<loop body>

>>>for i in range(5,10):

print(i)

5
6
7
8
9

Loop Errors: Off-by-One Error:


• The loop fails to perform the expected number of iterations. Because this number
istypically off by one, the error is called an off-by-one error

Traversing the Contents of a Data Sequence:

The values contained in any sequence can be visited by running a for loop , as
follows:

for <variable> in <sequence>:

<do something with variable>

– On each pass through the loop, the variable is bound to or assigned the
next value in the sequence, starting with the first one and ending with the
last one.
>>> name="Surya Lakshmi"

>>> nl=[45,36,644]

>>> nt=(4,22,6,1)

>>> for i in name: #Traversing string


print(i,end=",")
S,u,r,y,a, ,L,a,k,s,h,m,i,

>>>for i in nl: #Traversing list


print(i,end=",")
45,36,644,

>>>for i in nt: #Traversing tuple


print(i,end=",")
4,22,6,1,

Specifying the Steps in the Range :

• A variant of Python’s range function expects a third argument that allows you to nicely
skip some numbers.
• The third argument specifies a step value, or the interval between the numbers used in
therange, as shown in the examples that follow:
>>> list(range(1, 6, 1)) # Same as using two
arguments[1, 2, 3, 4, 5]
>>> list(range(1, 6, 2)) # Use every other number

[1, 3, 5]

>>> list(range(1, 6, 3)) # Use every third


number[1, 4]
Loops That Count Down

• Once in a while, a problem calls for counting in the opposite direction, from the upper
bound down to the lower bound.
• a loop displays the count from 10 down to 1 to show how this would be done:

>>> for count in range(10, 0, -1):


print(count, end = " ")
10 9 8 7 6 5 4 3 2 1

• When the step argument is a negative number, the range function generates a
sequenceof numbers from the first argument down to the second argument plus 1.

2. Conditional Iteration: The while Loop

• A loop continues to repeat as long as a condition remains true.This is called


Conditionaliteration
• The Structure and Behavior of a while Loop :

• Conditional iteration requires that a condition be tested within the loop to determine
whether the loop should continue. Such a condition is called the loop’s continuation
condition.
– If the continuation condition is false, the loop ends.
– If the continuation condition is true, the statements within the loop are
executedagain.
• Syntax:

while <condition>:

<sequence of statements>

• The while loop is also called an entry-control loop, because its condition is tested at
the top of the loop.
• This implies that the statements within the loop can execute zero or more times.

# Summation with a while looptheSum = 0


count = 1

while count <= 10:

theSum += countcount += 1 print(theSum)


• The while loop is also called an entry-control loop, because its condition is tested at
the top of the loop.

– This implies that the statements within the loop can execute zero or more times.

The while True Loop and the break Statement

• If the loop must run at least once, use a while True loop and delay the examination
ofthe termination condition until it becomes available in the body of the loop.
• Ensure that something occurs in the loop to allow the condition to be checked and
abreak statement to be reached eventually.

while True:

number = int(input("Enter the numeric grade: "))


if number >= 0 and number <= 100:
print(number) # Just echo the valid input
break

else:
print("Error: grade must be between 100 and 0")

OUTPUT

A trial run with just this segment shows the following interaction:

Enter the numeric grade: 101

Error: grade must be between 100 and 0


Enter the numeric grade: –1
Error: grade must be between 100 and 0
Enter the numeric grade: 45
45

UNIT-II
Lists in Python
Python offers a range of compound data types often referred to as sequences. List is
one of the most frequently used and very versatile data types used in Python.
In Python programming, a list is created by placing all the items (elements) inside square
brackets [], separated by commas. It can have any number of items and they may be of
different types (integer, float, string etc.).
Eg:
# empty list
my_list = []

# list of integers
my_list = [1, 2, 3]

# list with mixed data types


my_list = [1, "Hello", 3.4]

A list can also have another list as an item. This is called a nested list.
# nested list
my_list = ["mouse", [8, 4, 6], ['a']]
Access List Elements
There are various ways in which we can access the elements of a list.
List Index
We can use the index operator [] to access an item in a list. In Python, indices start at 0. So, a
list having 5 elements will have an index from 0 to 4.
Trying to access indexes other than these will raise an Index Error. he index must be an
integer. We can't use float or other types, this will result in Type Error.
Eg:
my_list = ['p', 'r', 'o', 'b', 'e']
print(my_list[0])
# Output: p

print(my_list[2])
# Output: o

print(my_list[4])
# Output: e

# Nested List
n_list = ["Happy", [2, 0, 1, 5]]

# Nested indexing
print(n_list[0][1])
print(n_list[1][3])

# Error! Only integer can be used for indexing


print(my_list[4.0])
Output:
p
o
e
a
5
Negative indexing
Python allows negative indexing for its sequences. The index of -1 refers to the last item, -2 to
the second last item and so on.

# Negative indexing in lists


my_list = ['p','r','o','b','e']
print(my_list[-1])
print(my_list[-5])
When we run the above program, we will get the following output:
e
p
slice lists in Python
We can access a range of items in a list by using the slicing operator :(colon).
# List slicing in Python

my_list = ['p','r','o','g','r','a','m','i','z']

# elements 3rd to 5th


print(my_list[2:5])
# elements beginning to 4th
print(my_list[:-5])

# elements 6th to end


print(my_list[5:])

# elements beginning to end


print(my_list[:])
Output
['o', 'g', 'r']
['p', 'r', 'o', 'g']
['a', 'm', 'i', 'z']
['p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z']
Slicing can be best visualized by considering the index to be between the elements as shown
below. So if we want to access a range, we need two indices that will slice that portion from
the list.
Add/Change List Elements
Lists are mutable, meaning their elements can be changed unlike string or tuple.
We can use the assignment operator = to change an item or a range of items.
# Correcting mistake values in a list
odd = [2, 4, 6, 8]
# change the 1st item
odd[0] = 1
print(odd)
# change 2nd to 4th items
odd[1:4] = [3, 5, 7]
print(odd)

Output
[1, 4, 6, 8]
[1, 3, 5, 7
We can add one item to a list using the append() method or add several items
using extend() method.
# Appending and Extending lists in Python
odd = [1, 3, 5]
odd.append(7)
print(odd)
odd.extend([9, 11, 13])
print(odd)

Output
[1, 3, 5, 7]
[1, 3, 5, 7, 9, 11, 13]
We can also use + operator to combine two lists. This is also called concatenation.
The * operator repeats a list for the given number of times.
# Concatenating and repeating lists
odd = [1, 3, 5]
print(odd + [9, 7, 5])
print(["re"] * 3)

Output
[1, 3, 5, 9, 7, 5]
['re', 're', 're']
Furthermore, we can insert one item at a desired location by using the method insert() or
insert multiple items by squeezing it into an empty slice of a list.
# Demonstration of list insert() method
odd = [1, 9]
odd.insert(1,3)
print(odd)
odd[2:2] = [5, 7]
print(odd)

Output
[1, 3, 9]
[1, 3, 5, 7, 9]

Delete/Remove List Elements

We can delete one or more items from a list using the keyword del. It can even delete the list
entirely.
# Deleting list items
my_list = ['p', 'r', 'o', 'b', 'l', 'e', 'm']
# delete one item
del my_list[2]
print(my_list)
# delete multiple items
del my_list[1:5]
print(my_list)
# delete entire list
del my_list
# Error: List not defined
print(my_list)

Output
['p', 'r', 'b', 'l', 'e', 'm']
['p', 'm']

We can use remove() method to remove the given item or pop() method to remove an item at
the given index.
The pop() method removes and returns the last item if the index is not provided. This helps us
implement lists as stacks (first in, last out data structure).
We can also use the clear() method to empty a list.

my_list = ['p','r','o','b','l','e','m']
my_list.remove('p')
print(my_list)

# Output: ['r', 'o', 'b', 'l', 'e', 'm']

print(my_list.pop(1))
# Output: 'o'

print(my_list)
# Output: ['r', 'b', 'l', 'e', 'm']
print(my_list.pop())

# Output: 'm'

print(my_list)
# Output: ['r', 'b', 'l', 'e']

my_list.clear()

# Output: []
print(my_list)
Output
['r', 'o', 'b', 'l', 'e', 'm']
o
['r', 'b', 'l', 'e', 'm']
m
['r', 'b', 'l', 'e']
[]
Finally, we can also delete items in a list by assigning an empty list to a slice of elements.

>>> my_list = ['p','r','o','b','l','e','m']


>>> my_list[2:3] = []
>>> my_list
['p', 'r', 'b', 'l', 'e', 'm']
>>> my_list[2:5] = []
>>> my_list
['p', 'r', 'm']

Python List Methods


Methods that are available with list objects in Python programming are tabulated below.
They are accessed as lilst.method().

Python List Methods


append() - Add an element to the end of the list
extend() - Add all elements of a list to the another list
insert() - Insert an item at the defined index
remove() - Removes an item from the list
pop() - Removes and returns an element at the given index
clear() - Removes all items from the list
index() - Returns the index of the first matched item
count() - Returns the count of the number of items passed as an argument
sort() - Sort items in a list in ascending order
reverse() - Reverse the order of items in the list
copy() - Returns a shallow copy of the list

# Python list methods


my_list = [3, 8, 1, 6, 0, 8, 4]

print(my_list.index(8))
print(my_list.count(8))
my_list.sort()

# Output: [0, 1, 3, 4, 6, 8, 8]
print(my_list)
my_list.reverse()

# Output: [8, 8, 6, 4, 3, 1, 0]
print(my_list)
Output
1
2
[0, 1, 3, 4, 6, 8, 8]
[8, 8, 6, 4, 3, 1, 0]

List Comprehension: Elegant way to create Lists


List comprehension is an elegant and concise way to create a new list from an existing list in
Python.
A list comprehension consists of an expression followed by for statement inside square
brackets.
Here is an example to make a list with each item being increasing power of 2.

pow2 = [2 ** x for x in range(10)]


print(pow2)
Output
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
This code is equivalent to:
pow2 = []
for x in range(10):
pow2.append(2 ** x)

A list comprehension can optionally contain more for or if statements. An


optional if statement can filter out items for the new list. Here are some examples.
>>> pow2 = [2 ** x for x in range(10) if x > 5]
>>> pow2
[64, 128, 256, 512]
>>> odd = [x for x in range(20) if x % 2 == 1]
>>> odd
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
>>> [x+y for x in ['Python ','C '] for y in ['Language','Programming']]
['Python Language', 'Python Programming', 'C Language', 'C Programming']

Other List Operations in Python


List Membership Test

We can test if an item exists in a list or not, using the keyword in.
my_list = ['p', 'r', 'o', 'b', 'l', 'e', 'm']

# Output: True
print('p' in my_list)

# Output: False
print('a' in my_list)

# Output: True
print('c' not in my_list)
Output
True
False
True
Iterating Through a List

Using a for loop we can iterate through each item in a list.


for fruit in ['apple','banana','mango']:
print("I like",fruit)
Output
I like apple
I like banana
I like mango

Tuples in Python
A tuple in Python is similar to a list. The difference between the two is that we cannot
change the elements of a tuple once it is assigned whereas we can change the elements of a
list.
Creating a Tuple

A tuple is created by placing all the items (elements) inside parentheses (), separated
by commas. The parentheses are optional, however, it is a good practice to use them.
A tuple can have any number of items and they may be of different types (integer, float,
list, string, etc.).

# Different types of tuples

# Empty tuple
my_tuple = ()
print(my_tuple)

# Tuple having integers


my_tuple = (1, 2, 3)
print(my_tuple)

# tuple with mixed datatypes


my_tuple = (1, "Hello", 3.4)
print(my_tuple)

# nested tuple
my_tuple = ("mouse", [8, 4, 6], (1, 2, 3))
print(my_tuple)

Output
()
(1,2,3)
(1, ‘Hello’,3.4)
(‘mouse’,[8,4,6],(1,2,3))

A tuple can also be created without using parentheses. This is known as tuple packing.
my_tuple = 3, 4.6, "dog"
print(my_tuple)

# tuple unpacking is also possible


a, b, c = my_tuple

print(a) #3
print(b) # 4.6
print(c) # dog
Output:
(3,4.6,’dog’)
3
4.6
Dog
Creating a tuple with one element is a bit tricky.

Having one element within parentheses is not enough. We will need a trailing comma to
indicate that it is, in fact, a tuple.

my_tuple = ("hello")
print(type(my_tuple)) # <class 'str'>

# Creating a tuple having one element


my_tuple = ("hello",)
print(type(my_tuple)) # <class 'tuple'>

# Parentheses is optional
my_tuple = "hello",
print(type(my_tuple)) # <class 'tuple'>

Output:
<class ,’str’>
<class ‘tuple’>
<class ‘tuple’>

Access Tuple Elements


There are various ways in which we can access the elements of a tuple.
1. Indexing
We can use the index operator [] to access an item in a tuple, where the index starts from 0.
So, a tuple having 6 elements will have indices from 0 to 5. Trying to access an index outside
of the tuple index range(6,7,... in this example) will raise an IndexError.
The index must be an integer, so we cannot use float or other types. This will result in TypeError.
Likewise, nested tuples are accessed using nested indexing, as shown in the example below.

# Accessing tuple elements using indexing


my_tuple = ('p','e','r','m','i','t')

print(my_tuple[0]) # 'p'
print(my_tuple[5]) # 't'

# IndexError: list index out of range


# print(my_tuple[6])
# Index must be an integer
# TypeError: list indices must be integers, not float
# my_tuple[2.0]

# nested tuple
n_tuple = ("mouse", [8, 4, 6], (1, 2, 3))

# nested index
print(n_tuple[0][3]) # 's'
print(n_tuple[1][1]) #4

Output:
P
T
S
4
2. Negative Indexing
Python allows negative indexing for its sequences.
The index of -1 refers to the last item, -2 to the second last item and so on.
# Negative indexing for accessing tuple elements
my_tuple = ('p', 'e', 'r', 'm', 'i', 't')

# Output: 't'
print(my_tuple[-1])

# Output:
'p'
print(my_tuple[-6])

Output:
T
P
3. Slicing

We can access a range of items in a tuple by using the slicing operator colon :.
# Accessing tuple elements using slicing
my_tuple = ('p','r','o','g','r','a','m','i','z')

# elements 2nd to 4th


# Output: ('r', 'o', 'g')
print(my_tuple[1:4])

# elements beginning to 2nd


# Output: ('p', 'r')
print(my_tuple[:-7])

# elements 8th to end


# Output: ('i', 'z')
print(my_tuple[7:])

# elements beginning to end


# Output: ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
print(my_tuple[:])

Output:
(‘r’, ‘o’, ‘g’)
(‘p’, ‘r’)
(‘I’, ‘z’)
(‘p’,’r’,’o’,’g’,’r’,’a’,’m’,’I’,’z’)

Slicing can be best visualized by considering the index to be between the elements as shown
below. So if we want to access a range, we need the index that will slice the portion from the
tuple.
Changing a Tuple

Unlike lists, tuples are immutable.

This means that elements of a tuple cannot be changed once they have been assigned. But, if
the element is itself a mutable data type like a list, its nested items can be changed. We can
also assign a tuple to different values (reassignment).

# Changing tuple values


my_tuple = (4, 2, 3, [6, 5])

# TypeError: 'tuple' object does not support item assignment


# my_tuple[1] = 9

# However, item of mutable element can be changed


my_tuple[3][0] = 9 # Output: (4, 2, 3, [9, 5])
print(my_tuple)

# Tuples can be reassigned


my_tuple = ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')

# Output: ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
print(my_tuple)

Output:
(4,2,3, [9,5])
(‘p’,’r’,’o’,’g’,’r’,’a’,’m’,’I’,’z’)
We can use + operator to combine two tuples. This is called concatenation. We can
also repeat the elements in a tuple for a given number of times using the * operator.
Both + and * operations result in a new tuple.
# Concatenation
# Output: (1, 2, 3, 4, 5, 6)
print((1, 2, 3) + (4, 5, 6))

# Repeat
# Output: ('Repeat', 'Repeat', 'Repeat')
print(("Repeat",) * 3)

Output:
(1,2,3,4,5,6)
(‘repeat,’repeat’,’repeat’)
Deleting a Tuple

As discussed above, we cannot change the elements in a tuple. It means that we cannot
delete or remove items from a tuple. Deleting a tuple entirely, however, is possible using the
keyword del.

# Deleting tuples
my_tuple = ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')

# can't delete items


# TypeError: 'tuple' object doesn't support item deletion
# del my_tuple[3]

# Can delete an entire tuple


del my_tuple

# NameError: name 'my_tuple' is not defined


print(my_tuple)
Tuple Methods

Methods that add items or remove items are not available with tuple. Only the following two
methods are available. Some examples of Python tuple methods:

my_tuple = ('a', 'p', 'p', 'l', 'e',)

print(my_tuple.count('p')) # Output: 2
print(my_tuple.index('l')) # Output: 3

Output
2
3

Other Tuple Operations

1. Tuple Membership Test

We can test if an item exists in a tuple or not, using the keyword in.
# Membership test in tuple
my_tuple = ('a', 'p', 'p', 'l', 'e',)

# In operation
print('a' in my_tuple)
print('b' in my_tuple)
# Not in operation
print('g' not in my_tuple)

Output:
True
False
True
2. Iterating Through a Tuple

We can use a for loop to iterate through each item in a tuple.


# Using a for loop to iterate through a tuple
for name in ('John', 'Kate'):
print("Hello", name)

Advantages of Tuple over List


Since tuples are quite similar to lists, both of them are used in similar situations. However,
there are certain advantages of implementing a tuple over a list. Below listed are some of the
main advantages:
 We generally use tuples for heterogeneous (different) data types and lists for homogeneous
(similar) data types.
 Since tuples are immutable, iterating through a tuple is faster than with list. So there is a slight
performance boost.
 Tuples that contain immutable elements can be used as a key for a dictionary. With lists, this
is not possible.
 If you have data that doesn't change, implementing it as tuple will guarantee that it remains
write-protected.

Strings in Python
A string is a sequence of characters. A character is simply a symbol. For example, the English
language has 26 characters. Computers do not deal with characters, they deal with numbers
(binary). Even though you may see characters on your screen, internally it is stored and
manipulated as a combination of 0s and 1s.
This conversion of character to a number is called encoding, and the reverse process is
decoding. ASCII and Unicode are some of the popular encodings used.
In Python, a string is a sequence of Unicode characters. Unicode was introduced to include
every character in all languages and bring uniformity in encoding.

String in Python
Strings can be created by enclosing characters inside a single quote or double-quotes. Even
triple quotes can be used in Python but generally used to represent multiline strings and
docstrings.
# defining strings in Python
# all of the following are equivalent
my_string = 'Hello'
print(my_string)

my_string = "Hello"
print(my_string)

my_string = '''Hello'''
print(my_string)

# triple quotes string can extend multiple lines


my_string = """Hello, welcome to
the world of Python"""
print(my_string)

Output:
Hello

Hello
Hello
Hello, Welcome to the world of python

How to access characters in a string?


We can access individual characters using indexing and a range of characters using slicing.
Index starts from 0. Trying to access a character out of index range will raise an IndexError.
The index must be an integer. We can't use floats or other types, this will result into TypeError.
Python allows negative indexing for its sequences.
The index of -1 refers to the last item, -2 to the second last item and so on. We can access a
range of items in a string by using the slicing operator :(colon).

#Accessing string characters in Python


str = 'programiz'
print('str = ', str)

#first character
print('str[0] = ', str[0])

#last character
print('str[-1] = ', str[-1])

#slicing 2nd to 5th character


print('str[1:5] = ', str[1:5])

#slicing 6th to 2nd last character


print('str[5:-2] = ', str[5:-2])

Output:
str = programiz
str[0] = p
str[-1] = z
str[1:5] = rogr
str[5:-2] = am

If we try to access an index out of the range or use numbers other than an integer, we will get
errors.

# index must be in range


>>> my_string[15]
...
IndexError: string index out of range

# index must be an integer


>>> my_string[1.5]
...
TypeError: string indices must be integers
Strings are immutable. This means that elements of a string cannot be changed once they
have been assigned. We can simply reassign different strings to the same name.

>>> my_string = 'programiz'


>>> my_string[5] = 'a'
...
TypeError: 'str' object does not support item assignment
>>> my_string = 'Python'
>>> my_string
'Python'
We cannot delete or remove characters from a string. But deleting the string entirely is
possible using the del keyword.
>>> del my_string[1]
...
TypeError: 'str' object doesn't support item deletion
>>> del my_string
>>> my_string
...
NameError: name 'my_string' is not defined
Python String Operations
There are many operations that can be performed with strings which makes it one of the most
used data types in Python.
To learn more about the data types available in Python visit: Python Data Types
Concatenation of Two or More Strings
Joining of two or more strings into a single one is called concatenation.
The + operator does this in Python. Simply writing two string literals together also
concatenates them.
The * operator can be used to repeat the string for a given number of times.
# Python String Operations
str1 = 'Hello'
str2 ='World!'

# using +
print('str1 + str2 = ', str1 + str2)

# using *
print('str1 * 3 =', str1 * 3)
When we run the above program, we get the following output:

str1 + str2 = HelloWorld!


str1 * 3 = HelloHelloHello
Writing two string literals together also concatenates them like + operator.
If we want to concatenate strings in different lines, we can use parentheses.

>>> # two string literals together


>>> 'Hello ''World!'
'Hello World!'

>>> # using parentheses


>>> s = ('Hello '
... 'World')
>>> s
'Hello World'
Iterating Through a string

We can iterate through a string using a for loop. Here is an example to count the number of 'l's
in a string.
# Iterating through a string
count = 0
for letter in 'Hello World':
if(letter == 'l'):
count += 1
print(count,'letters found')
When we run the above program, we get the following output:

3 letters found
String Membership Test

We can test if a substring exists within a string or not, using the keyword in.
>>> 'a' in 'program'
True
>>> 'at' not in 'battle'
False
Built-in functions to Work with Python

Various built-in functions that work with sequence work with strings as well. Some of the
commonly used ones are enumerate() and len(). The enumerate() function returns an enumerate
object. It contains the index and value of all the items in the string as pairs. This can be useful
for iteration. Similarly, len() returns the length (number of characters) of the string.

str = 'cold'

# enumerate()
list_enumerate = list(enumerate(str))
print('list(enumerate(str) = ', list_enumerate)

#character count
print('len(str) = ', len(str))
When we run the above program, we get the following output:

list(enumerate(str) = [(0, 'c'), (1, 'o'), (2, 'l'), (3, 'd')]


len(str) = 4
Python String Formatting

Escape Sequence

If we want to print a text like He said, "What's there?", we can neither use single quotes nor
double quotes. This will result in a SyntaxError as the text itself contains both single and double
quotes.
>>> print("He said, "What's there?"")
...
SyntaxError: invalid syntax
>>> print('He said, "What's there?"')
...
SyntaxError: invalid syntax
One way to get around this problem is to use triple quotes. Alternatively, we can use escape
sequences. An escape sequence starts with a backslash and is interpreted differently. If we
use a single quote to represent a string, all the single quotes inside the string must be
escaped. Similar is the case with double quotes. Here is how it can be done to represent the
above text.

# using triple quotes


print('''He said, "What's there?"''')

# escaping single quotes


print('He said, "What\'s there?"')

# escaping double quotes


print("He said, \"What's there?\"")
When we run the above program, we get the following output:

He said, "What's there?"


He said, "What's there?"
He said, "What's there?"
Here is a list of all the escape sequences supported by Python.

Escape Sequence Description


\newline Backslash and newline ignored
\\ Backslash
\' Single quote
\" Double quote
\a ASCII Bell
\b ASCII Backspace
\f ASCII Formfeed
\n ASCII Linefeed
\r ASCII Carriage Return
\t ASCII Horizontal Tab
\v ASCII Vertical Tab
\ooo Character with octal value ooo
\xHH Character with hexadecimal value HH
Here are some examples

>>> print("C:\\Python32\\Lib")
C:\Python32\Lib

>>> print("This is printed\nin two lines")


This is printed
in two lines

>>> print("This is \x48\x45\x58 representation")


This is HEX representation
Raw String to ignore escape sequence

Sometimes we may wish to ignore the escape sequences inside a string. To do this we can
place r or R in front of the string. This will imply that it is a raw string and any escape sequence
inside it will be ignored.
>>> print("This is \x61 \ngood example")
This is a
good example
>>> print(r"This is \x61 \ngood example")
This is \x61 \ngood example
The format() Method for Formatting Strings

The format() method that is available with the string object is very versatile and powerful in
formatting strings. Format strings contain curly braces {} as placeholders or replacement
fields which get replaced.
We can use positional arguments or keyword arguments to specify the order.

# Python string format() method

# default(implicit) order
default_order = "{}, {} and {}".format('John','Bill','Sean')
print('\n--- Default Order ---')
print(default_order)

# order using positional argument


positional_order = "{1}, {0} and {2}".format('John','Bill','Sean')
print('\n--- Positional Order ---')
print(positional_order)
# order using keyword argument
keyword_order = "{s}, {b} and {j}".format(j='John',b='Bill',s='Sean')
print('\n--- Keyword Order ---')
print(keyword_order)
When we run the above program, we get the following output:

--- Default Order ---


John, Bill and Sean
--- Positional Order ---
Bill, John and Sean
--- Keyword Order ---
Sean, Bill and John
The format() method can have optional format specifications. They are separated from the field
name using colon. For example, we can left-justify <, right-justify > or center ^ a string in the
given space.
We can also format integers as binary, hexadecimal, etc. and floats can be rounded or
displayed in the exponent format. There are tons of formatting you can use. Visit here for all
the string formatting available with the format() method.
>>> # formatting integers
>>> "Binary representation of {0} is {0:b}".format(12)
'Binary representation of 12 is 1100'

>>> # formatting floats


>>> "Exponent representation: {0:e}".format(1566.345)
'Exponent representation: 1.566345e+03'

>>> # round off


>>> "One third is: {0:.3f}".format(1/3)
'One third is: 0.333'

>>> # string alignment


>>> "|{:<10}|{:^10}|{:>10}|".format('butter','bread','ham')
'|butter | bread | ham|'
Old style formatting

We can even format strings like the old sprintf() style used in C programming language. We use
the % operator to accomplish this.
>>> x = 12.3456789
>>> print('The value of x is %3.2f' %x)
The value of x is 12.35
>>> print('The value of x is %3.4f' %x)
The value of x is 12.3457
Common Python String Methods

There are numerous methods available with the string object. The format() method that we
mentioned above is one of them. Some of the commonly used methods
are lower(), upper(), join(), split(), find(), replace() etc. Here is a complete list of all the built-in
methods to work with strings in Python.
>>> "PrOgRaMiZ".lower()
'programiz'
>>> "PrOgRaMiZ".upper()
'PROGRAMIZ'
>>> "This will split all words into a list".split()
['This', 'will', 'split', 'all', 'words', 'into', 'a', 'list']
>>> ' '.join(['This', 'will', 'join', 'all', 'words', 'into', 'a', 'string'])
'This will join all words into a string'
>>> 'Happy New Year'.find('ew')
7
>>> 'Happy New Year'.replace('Happy','Brilliant')
'Brilliant New Year'

Method Description Examples

capitalize() Returns a copy of the string with its >>> mystring = "hello python"
first character capitalized and the >>>
rest lowercased. print(mystring.capitalize())
Hello python

Casefold() Returns a casefolded copy of the >>> mystring = "hello


string. Casefolded strings may be PYTHON"
used for caseless matching. >>> print(mystring.casefold())
hello python

Center(width, [fillchar]) Returns the string centered in a string >>> mystring = "Hello"
of length width. Padding can be done >>> x = mystring.center(12,
using the specified fillchar (the "-")
default padding uses an ASCII >>> print(x)
space). The original string is returned ---Hello----
if width is less than or equal to len(s)

Count(sub, [start], [end]) Returns the number of non- >>> mystr = "Hello Python"
overlapping occurrences of substring >>> print(mystr.count("o"))
(sub) in the range [start, end]. 2
Optional arguments startand end are >>> print(mystr.count("th"))
interpreted as in slice notation. 1
>>> print(mystr.count("l"))
2
>>> print(mystr.count("h"))
1
>>> print(mystr.count("H"))
1
>>> print(mystr.count("hH"))
0

Encode(encoding = “utf-g”, Returns an encoded version of the >>> mystr = 'python!'


errors = “strict”) string as a bytes object. The default >>> print('The string is:',
encoding is utf-8. errors may be given mystr)
to set a different error handling The string is: python!
scheme. The possible value for >>> print('The encoded
errors are: version is: ',
mystr.encode("ascii",
 strict (encoding errors raise "ignore"))
The encoded version is:
a UnicodeError)
b'python!'
 ignore >>> print('The encoded
version (with replace) is:',
 replace mystr.encode("ascii",
"replace"))
 xmlcharrefreplace The encoded version (with
 backslashreplace replace) is: b'python!'

 any other name registered via


codecs.register_error()

endswith(suffix, [start], [end]) Returns True if the string ends with >>> mystr = "Python"
the specified suffix, otherwise it >>>
returns False. print(mystr.endswith("y"))
False
>>>
print(mystr.endswith("hon"))
True

Expandtabs(tabsize=8) Returns a copy of the string where all >>> mystr = "1\t2\t3"
tab characters are replaced by one or >>> print(mystr)
more spaces, depending on the 123
current column and the given tab >>>
size. print(mystr.expandtabs())
123
>>>
print(mystr.expandtabs(tabsi
ze=15))
12
3
>>>
print(mystr.expandtabs(tabsi
ze=2))
123

Find(sub, [start], [end]) Returns the lowest index in the string >>> mystring = "Python"
where substring sub is found within >>>
the slice s[start:end]. print(mystring.find("P"))
0
>>>
print(mystring.find("on"))
4

Format(*args, **kwargs) Performs a string formatting >>> print("{} and


operation. The string on which this {}".format("Apple",
method is called can contain literal "Banana"))
text or replacement fields delimited Apple and Banana
by braces {}. >>> print("{1} and
{0}".format("Apple",
"Banana"))
Banana and Apple
>>> print("{lunch} and
{dinner}".format(lunch="Peas
", dinner="Beans"))
Peas and Beans

format_map(mapping) Similar to format(**mapping), except >>> lunch = {"Food":


that mapping is used directly and not "Pizza", "Drink": "Wine"}
copied to a dictionary. >>> print("Lunch: {Food},
{Drink}".format_map(lunch))
Lunch: Pizza, Wine
>>> class Default(dict):
def __missing__(self,
key):
return key
>>> lunch = {"Drink":
"Wine"}
>>> print("Lunch: {Food},
{Drink}".format_map(Default(
lunch)))
Lunch: Food, Wine

Index(sub, [start], [end]) Searches the string for a specified >>> mystr = "HelloPython"
value and returns the position of >>> print(mystr.index("P"))
where it was found 5
>>>
print(mystr.index("hon"))
8
>>> print(mystr.index("o"))
4

isalnum Returns True if all characters in the >>> mystr = "HelloPython"


string are alphanumeric >>> print(mystr.isalnum())
True
>>> a = "123"
>>> print(a.isalnum())
True
>>> a= "$*%!!!"
>>> print(a.isalnum())
False

Isalpha() Returns True if all characters in the >>> mystr = "HelloPython"


string are in the alphabet >>> print(mystr.isalpha())
True
>>> a = "123"
>>> print(a.isalpha())
False
>>> a= "$*%!!!"
>>> print(a.isalpha())
False

Isdecimal() Returns True if all characters in the >>> mystr = "HelloPython"


string are decimals >>> print(mystr.isdecimal())
False
>>> a="1.23"
>>> print(a.isdecimal())
False
>>> c = u"\u00B2"
>>> print(c.isdecimal())
False
>>> c="133"
>>> print(c.isdecimal())
True

Isdigit() Returns True if all characters in the >>> c="133"


string are digits >>> print(c.isdigit())
True
>>> c = u"\u00B2"
>>> print(c.isdigit())
True
>>> a="1.23"
>>> print(a.isdigit())
False

isidentifier() Returns True if the string is an >>> c="133"


identifier >>> print(c.isidentifier())
False
>>> c="_user_123"
>>> print(c.isidentifier())
True
>>> c="Python"
>>> print(c.isidentifier())
True

Islower() Returns True if all characters in the >>> c="Python"


string are lower case >>> print(c.islower())
False
>>> c="_user_123"
>>> print(c.islower())
True
>>> print(c.islower())
False

Isnumeric() Returns True if all characters in the >>> c="133"


string are numeric >>> print(c.isnumeric())
True
>>> c="_user_123"
>>> print(c.isnumeric())
False
>>> c="Python"
>>> print(c.isnumeric())
False

isprintable() Returns True if all characters in the >>> c="133"


string are printable >>> print(c.isprintable())
True
>>> c="_user_123"
>>> print(c.isprintable())
True
>>> c="\t"
>>> print(c.isprintable())
False

isspace() Returns True if all characters in the >>> c="133"


string are whitespaces >>> print(c.isspace())
False
>>> c="Hello Python"
>>> print(c.isspace())
False
73
>>> c="Hello"
>>> print(c.isspace())
False
>>> c="\t"
>>> print(c.isspace())
True

istitle() Returns True if the string follows the >>> c="133"


rules of a title >>> print(c.istitle())
False
>>> c="Python"
>>> print(c.istitle())
True
>>> c="\t"
>>> print(c.istitle())
False

isupper() Returns True if all characters in the >>> c="Python"


string are upper case >>> print(c.isupper())
False
>>> c="PYHTON"
>>> print(c.isupper())
True
>>> c="\t"
>>> print(c.isupper())
False

join(iterable) Joins the elements of an iterable to >>> a ="-"


the end of the string >>> print(a.join("123"))
1-2-3
>>> a="Hello Python"
>>> a="**"
>>> print(a.join("Hello
Python"))
H**e**l**l**o**
**P**y**t**h**o**n

ljust(width[,fillchar]) Returns a left justified version of the >>> a="Hello"


string >>> b = a.ljust(12, "_")
>>> print(b)
Hello_______

lower() Converts a string into lower case >>> a = "Python"


>>> print(a.lower())
Python

lstrip([chars]) Returns a left trim version of the >>> a = " Hello "
string >>> print(a.lstrip(), "!")
Hello

maketrans(x[, y[, z]]) Returns a translation table to be used >>> frm = "SecretCode"
in translations >>> to = "4203040540"
>>> trans_table =
str.maketrans(frm,to)
>>> sec_code = "Secret
Code".translate(trans_table)
>>> print(sec_code)
400304 0540

partition(sep) Returns a tuple where the string is >>> mystr = "Hello-Python"


parted into three parts >>> print(mystr.partition("-
"))
('Hello', '-', 'Python')
74
>>>
print(mystr.partition("."))
('Hello-Python', '', '')

replace(old, new[,count]) Returns a string where a specified >>> mystr = "Hello Python.
value is replaced with a specified Hello Java. Hello C++."
value >>>
print(mystr.replace("Hello",
"Bye"))
Bye Python. Bye Java. Bye
C++.
>>>
print(mystr.replace("Hello",
"Hell", 2))
Hell Python. Hell Java.
Hello C++.

rfind(sub[, start[,end]]) Searches the string for a specified >>> mystr = "Hello-Python"
value and returns the last position of >>> print(mystr.rfind("P"))
where it was found 6
>>> print(mystr.rfind("-"))
5
>>> print(mystr.rfind("z"))
-1

rindex(sub[, start[,end]]) Searches the string for a specified >>> mystr = "Hello-Python"
value and returns the last position of >>> print(mystr.rindex("P"))
where it was found 6
>>> print(mystr.rindex("-"))
5
>>> print(mystr.rindex("z"))
Traceback (most recent call
last):
File "<pyshell#253>", line
1, in <module>
print(mystr.rindex("z"))
ValueError: substring not
found

rjust(width[,fillchar]) Returns the string right justified in a >>> mystr = "Hello Python"
string of length width. >>> mystr1 = mystr.rjust(20,
"-")
>>> print(mystr1)
--------Hello Python

rpartition(sep) Returns a tuple where the string is >>> mystr = "Hello Python"
parted into three parts >>>
print(mystr.rpartition("."))
('', '', 'Hello Python')
>>> print(mystr.rpartition("
"))
('Hello', ' ', 'Python')

rsplit(sep=None, maxsplit=-1) Splits the string at the specified >>> mystr = "Hello Python"
separator, and returns a list >>> print(mystr.rsplit())
['Hello', 'Python']
>>> mystr = "Hello-Python-
Hello"
>>>
print(mystr.rsplit(sep="-",
maxsplit=1))
['Hello-Python', 'Hello']

rstrip([chars]) Returns a right trim version of the >>> mystr = "Hello Python"
string >>> print(mystr.rstrip(),
"!")
Hello Python !
>>> mystr = "------------
Hello Python-----------"
>>> print(mystr.rstrip(), "-
")
------------Hello Python----
------- -
>>> print(mystr.rstrip(),
"_")
------------Hello Python----
------- _

split(sep=None, maxsplit=-1) Splits the string at the specified >>> mystr = "Hello Python"
separator, and returns a list >>> print(mystr.split())
['Hello', 'Python']
>>> mystr1="Hello,,Python"
>>> print(mystr1.split(","))
['Hello', '', 'Python']

splitlines([keepends]) Splits the string at line breaks and >>> mystr = "Hello:\n\n
returns a list Python\r\nJava\nC++\n"
>>>
print(mystr.splitlines())
['Hello:', '', ' Python',
'Java', 'C++']
>>>
print(mystr.splitlines(keepe
nds=True))
['Hello:\n', '\n', '
Python\r\n', 'Java\n',
'C++\n']

startswith(prefix[,start[, end]]) Returns true if the string starts with >>> mystr = "Hello Python"
the specified value >>>
print(mystr.startswith("P"))
False
>>>
print(mystr.startswith("H"))
True
>>>
print(mystr.startswith("Hell
"))
True
strip([chars]) Returns a trimmed version of the >>> mystr = "
string Hello Python
"
>>> print(mystr.strip(),
"!")
Hello Python !
>>> print(mystr.strip(), "
")
Hello Python

swapcase() Swaps cases, lower case becomes >>> mystr = "Hello PYthon"
upper case and vice versa >>> print(mystr.swapcase())
hELLO python

title() Converts the first character of each >>> mystr = "Hello PYthon"
word to upper case >>> print(mystr.title())
Hello Python
>>> mystr = "HELLO JAVA"
>>> print(mystr.title())
Hello Java

translate(table) Returns a translated string >>> frm = "helloPython"


>>> to = "40250666333"
>>> trans_table =
str.maketrans(frm, to)
>>> secret_code = "Secret
Code".translate(trans_table)
>>> print(secret_code)
S0cr06 C3d0

upper() Converts a string into upper case >>> mystr = "hello Python"
>>> print(mystr.upper())
HELLO PYTHON

zfill(width) Fills the string with a specified >>> mystr = "999"


number of 0 values at the beginning >>> print(mystr.zfill(9))
000000999
>>> mystr = "-40"
>>> print(mystr.zfill(5))
-0040

Dictionaries in Python
Python dictionary is an unordered collection of items. Each item of a dictionary has
a key/value pair. Dictionaries are optimized to retrieve values when the key is known.
Creating Python Dictionary

Creating a dictionary is as simple as placing items inside curly braces {} separated by commas.
An item has a key and a corresponding value that is expressed as a pair (key: value). While the
values can be of any data type and can repeat, keys must be of immutable type
(string, number or tuple with immutable elements) and must be unique.

# empty dictionary
my_dict = {}

# dictionary with integer keys


my_dict = {1: 'apple', 2: 'ball'}

# dictionary with mixed keys


my_dict = {'name': 'John', 1: [2, 4, 3]}

# using dict()
my_dict = dict({1:'apple', 2:'ball'})

# from sequence having each item as a pair


my_dict = dict([(1,'apple'), (2,'ball')])
As you can see from above, we can also create a dictionary using the built in dict() function.

Accessing Elements from Dictionary

While indexing is used with other data types to access values, a dictionary uses keys. Keys can
be used either inside square brackets [] or with the get() method. If we use the square
brackets [], KeyError is raised in case a key is not found in the dictionary. On the other hand,
the get() method returns None if the key is not found.
# get vs [] for retrieving elements
my_dict = {'name': 'Jack', 'age': 26}

# Output: Jack
print(my_dict['name'])

# Output: 26
print(my_dict.get('age'))

# Trying to access keys which doesn't exist throws error


# Output None
print(my_dict.get('address'))

# KeyError
print(my_dict['address'])
Output
Jack
26
None
Traceback (most recent call last):
File "<string>", line 15, in <module>
print(my_dict['address'])
KeyError: 'address'

Changing and Adding Dictionary elements


Dictionaries are mutable. We can add new items or change the value of existing items using
an assignment operator.
If the key is already present, then the existing value gets updated. In case the key is not
present, a new (key: value) pair is added to the dictionary.
# Changing and adding Dictionary Elements
my_dict = {'name': 'Jack', 'age': 26}

# update value
my_dict['age'] = 27

#Output: {'age': 27, 'name': 'Jack'}


print(my_dict)

# add item
my_dict['address'] = 'Downtown'

# Output: {'address': 'Downtown', 'age': 27, 'name': 'Jack'}


print(my_dict)
Output
{'name': 'Jack', 'age': 27}
{'name': 'Jack', 'age': 27, 'address': 'Downtown'}

Removing elements from Dictionary

We can remove a particular item in a dictionary by using the pop() method. This method
removes an item with the provided key and returns the value.
The popitem() method can be used to remove and return an arbitrary (key, value) item pair from
the dictionary. All the items can be removed at once, using the clear() method.
We can also use the del keyword to remove individual items or the entire dictionary itself.
# Removing elements from a dictionary

# create a dictionary
squares = {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# remove a particular item, returns its value


# Output: 16
print(squares.pop(4))
# Output: {1: 1, 2: 4, 3: 9, 5: 25}
print(squares)

# remove an arbitrary item, return (key,value)


# Output: (5, 25)
print(squares.popitem())

# Output: {1: 1, 2: 4, 3: 9}
print(squares)

# remove all items


squares.clear()

# Output: {}
print(squares)

# delete the dictionary itself


del squares

# Throws Error
print(squares)
Output
16
{1: 1, 2: 4, 3: 9, 5: 25}
(5, 25)
{1: 1, 2: 4, 3: 9}
{}
Traceback (most recent call last):
File "<string>", line 30, in <module>
print(squares)
NameError: name 'squares' is not defined

Python Dictionary Methods


Methods that are available with a dictionary are tabulated below. Some of them have already
been used in the above examples.
Method Description
clear() Removes all items from the dictionary.
copy() Returns a shallow copy of the dictionary.
fromkeys(seq[, v]) Returns a new dictionary with keys from seq and value equal to v
(defaults to None).
get(key[,d]) Returns the value of the key. If the key does not exist, returns d
(defaults to None).
items() Return a new object of the dictionary's items in (key, value) format.
keys() Returns a new object of the dictionary's keys.
pop(key[,d]) Removes the item with the key and returns its value or d if key is not
found. If d is not provided and the key is not found, it raises KeyError.
popitem() Removes and returns an arbitrary item (key, value). Raises KeyError if
the dictionary is empty.
setdefault(key[,d]) Returns the corresponding value if the key is in the dictionary. If not,
inserts the key with a value of d and returns d (defaults to None).
update([other]) Updates the dictionary with the key/value pairs from other, overwriting
existing keys.
values() Returns a new object of the dictionary's values
Here are a few example use cases of these methods.

# Dictionary Methods
marks = {}.fromkeys(['Math', 'English', 'Science'], 0)

# Output: {'English': 0, 'Math': 0, 'Science': 0}


print(marks)

for item in marks.items():


print(item)

# Output: ['English', 'Math', 'Science']


print(list(sorted(marks.keys())))
Output
{'Math': 0, 'English': 0, 'Science': 0}
('Math', 0)
('English', 0)
('Science', 0)
['English', 'Math', 'Science']

Python Dictionary Comprehension


Dictionary comprehension is an elegant and concise way to create a new dictionary from an
iterable in Python.
Dictionary comprehension consists of an expression pair (key: value) followed by
a for statement inside curly braces {}.
Here is an example to make a dictionary with each item being a pair of a number and its
square.
# Dictionary Comprehension
squares = {x: x*x for x in range(6)}

print(squares)
Output
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
This code is equivalent to
squares = {}
for x in range(6):
squares[x] = x*x
print(squares)
Output
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
A dictionary comprehension can optionally contain more for or if statements.
An optional if statement can filter out items to form the new dictionary.
Here are some examples to make a dictionary with only odd items.

# Dictionary Comprehension with if conditional


odd_squares = {x: x*x for x in range(11) if x % 2 == 1}

print(odd_squares)
Output
{1: 1, 3: 9, 5: 25, 7: 49, 9: 81}

Other Dictionary Operations


Dictionary Membership Test
We can test if a key is in a dictionary or not using the keyword in. Notice that the membership
test is only for the keys and not for the values.
# Membership Test for Dictionary Keys
squares = {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}

# Output: True
print(1 in squares)

# Output: True
print(2 not in squares)

# membership tests for key only not value


# Output: False
print(49 in squares)
Output
True
True
False
Iterating Through a Dictionary
We can iterate through each key in a dictionary using a for loop.
# Iterating through a Dictionary
squares = {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}
for i in squares:
print(squares[i])
Output
1
9
25
49
81

Dictionary Built-in Functions

Built-in functions like all(), any(), len(), cmp(), sorted(), etc. are commonly used with dictionaries to
perform different tasks.

Function Description
all() Return True if all keys of the dictionary are True (or if the dictionary is empty).
any() Return True if any key of the dictionary is true. If the dictionary is empty, return
False.
len() Return the length (the number of items) in the dictionary.
cmp() Compares items of two dictionaries. (Not available in Python 3)
sorted() Return a new sorted list of keys in the dictionary.
Here are some examples that use built-in functions to work with a dictionary.

# Dictionary Built-in Functions


squares = {0: 0, 1: 1, 3: 9, 5: 25, 7: 49, 9: 81}

# Output: False
print(all(squares))

# Output: True
print(any(squares))

# Output: 6
print(len(squares))

# Output: [0, 1, 3, 5, 7, 9]
print(sorted(squares))
Output
False
True
6
[0, 1, 3, 5, 7, 9]

Sets in Python
A set is an unordered collection of items. Every set element is unique (no duplicates) and
must be immutable (cannot be changed). However, a set itself is mutable. We can add or
remove items from it.
Sets can also be used to perform mathematical set operations like union, intersection,
symmetric difference, etc.

Creating Python Sets


A set is created by placing all the items (elements) inside curly braces {}, separated by comma,
or by using the built-in set() function.
It can have any number of items and they may be of different types (integer, float, tuple, string
etc.). But a set cannot have mutable elements like lists, sets or dictionaries as its elements.
# Different types of sets in Python
# set of integers
my_set = {1, 2, 3}
print(my_set)

# set of mixed datatypes


my_set = {1.0, "Hello", (1, 2, 3)}
print(my_set)
Output
{1, 2, 3}
{1.0, (1, 2, 3), 'Hello'}
Try the following examples as well.

# set cannot have duplicates


# Output: {1, 2, 3, 4}
my_set = {1, 2, 3, 4, 3, 2}
print(my_set)

# we can make set from a list


# Output: {1, 2, 3}
my_set = set([1, 2, 3, 2])
print(my_set)

# set cannot have mutable items


# here [3, 4] is a mutable list
# this will cause an error.

my_set = {1, 2, [3, 4]}


Output
{1, 2, 3, 4}
{1, 2, 3}
Traceback (most recent call last):
File "<string>", line 15, in <module>
my_set = {1, 2, [3, 4]}
TypeError: unhashable type: 'list'
Creating an empty set is a bit tricky.

Empty curly braces {} will make an empty dictionary in Python. To make a set without any
elements, we use the set() function without any argument.
# Distinguish set and dictionary while creating empty set

# initialize a with {}
a = {}

# check data type of a


print(type(a))

# initialize a with set()


a = set()

# check data type of a


print(type(a))
Output
<class 'dict'>
<class 'set'>

Modifying a set in Python

Sets are mutable. However, since they are unordered, indexing has no meaning. We cannot
access or change an element of a set using indexing or slicing. Set data type does not support
it.

We can add a single element using the add() method, and multiple elements using
the update() method. The update() method can take tuples, lists, strings or other sets as its
argument. In all cases, duplicates are avoided.
# initialize my_set
my_set = {1, 3}
print(my_set)

# add an element
my_set.add(2)
print(my_set)
# Output: {1, 2, 3}

# add multiple elements


my_set.update([2, 3, 4])
print(my_set)
# Output: {1, 2, 3, 4}

# add list and set


# Output: {1, 2, 3, 4, 5, 6, 8}
my_set.update([4, 5], {1, 6, 8})
print(my_set)
Output
{1, 3}
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4, 5, 6, 8}

Removing elements from a set


A particular item can be removed from a set using the methods discard() and remove().
The only difference between the two is that the discard() function leaves a set unchanged if the
element is not present in the set. On the other hand, the remove() function will raise an error in
such a condition (if element is not present in the set).
The following example will illustrate this.
# Difference between discard() and remove()

# initialize my_set
my_set = {1, 3, 4, 5, 6}
print(my_set)

# discard an element
# Output: {1, 3, 5, 6}
my_set.discard(4)
print(my_set)

# remove an element
# Output: {1, 3, 5}
my_set.remove(6)
print(my_set)

# discard an element
# not present in my_set
# Output: {1, 3, 5}
my_set.discard(2)
print(my_set)

# remove an element
# not present in my_set
# you will get an error.
# Output: KeyError

my_set.remove(2)
Output
{1, 3, 4, 5, 6}
{1, 3, 5, 6}
{1, 3, 5}
{1, 3, 5}
Similarly, we can remove and return an item using the pop() method. Since set is an unordered
data type, there is no way of determining which item will be popped. It is completely arbitrary.
We can also remove all the items from a set using the clear() method.

# Output: set of unique elements


my_set = set("HelloWorld")
print(my_set)

print(my_set.pop())
# Output: random element

my_set.pop()
print(my_set)

my_set.clear()
print(my_set)
# Output: set()

print(my_set)
Output
{'H', 'l', 'r', 'W', 'o', 'd', 'e'}
H
{'r', 'W', 'o', 'd', 'e'}
set()
Python Set Operations
Sets can be used to carry out mathematical set operations like union, intersection, difference
and symmetric difference. We can do this with operators or methods.
Let us consider the following two sets for the following operations.
>>> A = {1, 2, 3, 4, 5}
>>> B = {4, 5, 6, 7, 8}
Set Union

Set Union in Python


Union of A and B is a set of all elements from both sets.
Union is performed using | operator. Same can be accomplished using the union() method.
# Set union method
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use | operator
print(A | B)

Output
{1, 2, 3, 4, 5, 6, 7, 8}
Try the following examples on Python shell.

# use union function


>>> A.union(B)
{1, 2, 3, 4, 5, 6, 7, 8}

# use union function on B


>>> B.union(A)
{1, 2, 3, 4, 5, 6, 7, 8}
Set Intersection

Set Intersection in Python


Intersection of A and B is a set of elements that are common in both the sets. Intersection is
performed using & operator. Same can be accomplished using the intersection() method.
# Intersection of sets
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use & operator


# Output: {4, 5}
print(A & B)

Output
{4, 5}
Try the following examples on Python shell.

# use intersection function on A


>>> A.intersection(B)
{4, 5}

# use intersection function on B


>>> B.intersection(A)
{4, 5}

Set Difference

Set Difference in Python


Difference of the set B from set A(A - B) is a set of elements that are only in A but not in B.
Similarly, B - A is a set of elements in B but not in A.
Difference is performed using - operator. Same can be accomplished using
the difference() method.
# Difference of two sets
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# use - operator on A
print(A - B)
Output
{1, 2, 3}
Try the following examples on Python shell.

# use difference function on A


>>> A.difference(B)
{1, 2, 3}

# use - operator on B
>>> B - A
{8, 6, 7}

# use difference function on B


>>> B.difference(A)
{8, 6, 7}

Set Symmetric Difference

Set Symmetric Difference in Python


Symmetric Difference of A and B is a set of elements in A and B but not in both (excluding the
intersection).
Symmetric difference is performed using ^ operator. Same can be accomplished using the
method symmetric_difference().
# Symmetric difference of two sets
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use ^ operator
print(A ^ B)
Output
{1, 2, 3, 6, 7, 8}
Try the following examples on Python shell.

# use symmetric_difference function on A


>>> A.symmetric_difference(B)
{1, 2, 3, 6, 7, 8}

# use symmetric_difference function on B


>>> B.symmetric_difference(A)
{1, 2, 3, 6, 7, 8}
Other Python Set Methods
There are many set methods, some of which we have already used above. Here is a list of all
the methods that are available with the set objects:

Method Description
add() Adds an element to the set
clear() Removes all elements from the set
copy() Returns a copy of the set
difference() Returns the difference of two or more sets as a new set
difference_update() Removes all elements of another set from this set
discard() Removes an element from the set if it is a member. (Do
nothing if the element is not in set)
intersection() Returns the intersection of two sets as a new set
intersection_update() Updates the set with the intersection of itself and another
isdisjoint() Returns True if two sets have a null intersection
issubset() Returns True if another set contains this set
issuperset() Returns True if this set contains another set
pop() Removes and returns an arbitrary set element. Raises
KeyError if the set is empty
remove() Removes an element from the set. If the element is not a
member, raises a KeyError
symmetric_difference() Returns the symmetric difference of two sets as a new set
symmetric_difference_update() Updates a set with the symmetric difference of itself and
another
union() Returns the union of sets in a new set
update() Updates the set with the union of itself and others

Other Set Operations


Set Membership Test
We can test if an item exists in a set or not, using the in keyword.
# initialize my_set
my_set = set("apple")

# check if 'a' is present


print('a' in my_set)

# check if 'p' is present


print('p' not in my_set)
Output
True
False
Iterating Through a Set
We can iterate through each item in a set using a for loop.
>>> for letter in set("apple"):
... print(letter)
...
a
p
e
l
Built-in Functions with Set
Built-in functions like all(), any(), enumerate(), len(), max(), min(), sorted(), sum() etc. are commonly
used with sets to perform different tasks.

Function Description
all() Returns True if all elements of the set are true (or if the set is empty).
any() Returns True if any element of the set is true. If the set is empty, returns
False.
enumerate() Returns an enumerate object. It contains the index and value for all the items
of the set as a pair.
len() Returns the length (the number of items) in the set.
max() Returns the largest item in the set.
min() Returns the smallest item in the set.
sorted() Returns a new sorted list from elements in the set(does not sort the set
itself).
sum() Returns the sum of all elements in the set.

Python Frozenset
Frozenset is a new class that has the characteristics of a set, but its elements cannot be
changed once assigned. While tuples are immutable lists, frozensets are immutable sets. Sets
being mutable are unhashable, so they can't be used as dictionary keys. On the other hand,
frozensets are hashable and can be used as keys to a dictionary. Frozensets can be created
using the frozenset() function.
This data type supports methods
like copy(), difference(), intersection(), isdisjoint(), issubset(), issuperset(), symmetric_difference() and union().
Being immutable, it does not have methods that add or remove elements.
# Frozensets
# initialize A and B
A = frozenset([1, 2, 3, 4])
B = frozenset([3, 4, 5, 6])
Try these examples on Python shell.

>>> A.isdisjoint(B)
False
>>> A.difference(B)
frozenset({1, 2})
>>> A | B
frozenset({1, 2, 3, 4, 5, 6})
>>> A.add(3)
...
AttributeError: 'frozenset' object has no attribute 'add'

User Defined Functions in Python


A function is a block of organized, reusable code that is used to perform a single, related
action. Functions provide better modularity for your application and a high degree of code
reusing.
As you already know, Python gives you many built-in functions like print(), etc. but you can
also create your own functions. These functions are called user-defined functions.
Defining a Function
You can define functions to provide the required functionality. Here are simple rules to define
a function in Python.
 Function blocks begin with the keyword def followed by the function name and
parentheses ( ( ) ).
 Any input parameters or arguments should be placed within these parentheses. You
can also define parameters inside these parentheses.
 The first statement of a function can be an optional statement - the documentation
string of the function or docstring.
 The code block within every function starts with a colon (:) and is indented.
 The statement return [expression] exits a function, optionally passing back an
expression to the caller. A return statement with no arguments is the same as return
None.
Syntax
def functionname( parameters ):
"function_docstring"
function_suite
return [expression]
By default, parameters have a positional behavior and you need to inform them in the same
order that they were defined.
Example
The following function takes a string as input parameter and prints it on standard screen.
def printme( str ):
"This prints a passed string into this function"
print str
return
Calling a Function
Defining a function only gives it a name, specifies the parameters that are to be included in
the function and structures the blocks of code.
Once the basic structure of a function is finalized, you can execute it by calling it from
another function or directly from the Python prompt. Following is the example to call printme()
function −

# Function definition is here


def printme( str ):
"This prints a passed string into this function"
print str
return;

# Now you can call printme function


printme("I'm first call to user defined function!")
printme("Again second call to the same function")
When the above code is executed, it produces the following result −
I'm first call to user defined function!
Again second call to the same function

Pass by reference vs value


All parameters (arguments) in the Python language are passed by reference. It means if you
change what a parameter refers to within a function, the change also reflects back in the
calling function. For example −
# Function definition is here
def changeme( mylist ):
"This changes a passed list into this function"
mylist.append([1,2,3,4]);
print "Values inside the function: ", mylist
return

# Now you can call changeme function


mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist
Here, we are maintaining reference of the passed object and appending values in the same
object. So, this would produce the following result −
Values inside the function: [10, 20, 30, [1, 2, 3, 4]]
Values outside the function: [10, 20, 30, [1, 2, 3, 4]]
There is one more example where argument is being passed by reference and the reference
is being overwritten inside the called function.
# Function definition is here
def changeme( mylist ):
"This changes a passed list into this function"
mylist = [1,2,3,4]; # This would assig new reference in mylist
print "Values inside the function: ", mylist
return

# Now you can call changeme function


mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist
The parameter mylist is local to the function changeme. Changing mylist within the function
does not affect mylist. The function accomplishes nothing and finally this would produce the
following result −
Values inside the function: [1, 2, 3, 4]
Values outside the function: [10, 20, 30]

Function Arguments
You can call a function by using the following types of formal arguments −

 Required arguments

 Keyword arguments

 Default arguments

 Variable-length arguments

Required arguments
Required arguments are the arguments passed to a function in correct positional order. Here,
the number of arguments in the function call should match exactly with the function
definition.
To call the function printme(), you definitely need to pass one argument, otherwise it gives a
syntax error as follows −
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print str
return;

# Now you can call printme function


printme()
When the above code is executed, it produces the following result −
Traceback (most recent call last):
File "test.py", line 11, in <module>
printme();
TypeError: printme() takes exactly 1 argument (0 given)

Keyword arguments
Keyword arguments are related to the function calls. When you use keyword arguments in a
function call, the caller identifies the arguments by the parameter name.
This allows you to skip arguments or place them out of order because the Python interpreter
is able to use the keywords provided to match the values with parameters. You can also
make keyword calls to the printme() function in the following ways −

# Function definition is here


def printme( str ):
"This prints a passed string into this function"
print str
return;

# Now you can call printme function


printme( str = "My string")
When the above code is executed, it produces the following result −
My string
The following example gives more clear picture. Note that the order of parameters does not
matter.
# Function definition is here
def printinfo( name, age ):
"This prints a passed info into this function"
print "Name: ", name
print "Age ", age
return;

# Now you can call printinfo function


printinfo( age=50, name="miki" )
When the above code is executed, it produces the following result −
Name: miki
Age 50

Default arguments
A default argument is an argument that assumes a default value if a value is not provided in
the function call for that argument. The following example gives an idea on default
arguments, it prints default age if it is not passed −
# Function definition is here
def printinfo( name, age = 35 ):
"This prints a passed info into this function"
print "Name: ", name
print "Age ", age
return;

# Now you can call printinfo function


printinfo( age=50, name="miki" )
printinfo( name="miki" )
When the above code is executed, it produces the following result −
Name: miki
Age 50
Name: miki
Age 35

Variable-length arguments
You may need to process a function for more arguments than you specified while defining
the function. These arguments are called variable-length arguments and are not named in the
function definition, unlike required and default arguments.
Syntax for a function with non-keyword variable arguments is this −
def functionname([formal_args,] *var_args_tuple ):
"function_docstring"
function_suite
return [expression]
An asterisk (*) is placed before the variable name that holds the values of all nonkeyword
variable arguments. This tuple remains empty if no additional arguments are specified during
the function call. Following is a simple example −
# Function definition is here
def printinfo( arg1, *vartuple ):
"This prints a variable passed arguments"
print "Output is: "
print arg1
for var in vartuple:
print var
return;

# Now you can call printinfo function


printinfo( 10 )
printinfo( 70, 60, 50 )
When the above code is executed, it produces the following result −
Output is:
10
Output is:
70
60
50
The Anonymous Functions
These functions are called anonymous because they are not declared in the standard manner
by using the def keyword. You can use the lambda keyword to create small anonymous
functions.
 Lambda forms can take any number of arguments but return just one value in the form
of an expression. They cannot contain commands or multiple expressions.
 An anonymous function cannot be a direct call to print because lambda requires an
expression
 Lambda functions have their own local namespace and cannot access variables other
than those in their parameter list and those in the global namespace.
 Although it appears that lambda's are a one-line version of a function, they are not
equivalent to inline statements in C or C++, whose purpose is by passing function
stack allocation during invocation for performance reasons.
Syntax
The syntax of lambda functions contains only a single statement, which is as follows −
lambda [arg1 [,arg2,.....argn]]:expression
Following is the example to show how lambda form of function works −
# Function definition is here
sum = lambda arg1, arg2: arg1 + arg2;

# Now you can call sum as a function


print "Value of total : ", sum( 10, 20 )
print "Value of total : ", sum( 20, 20 )
When the above code is executed, it produces the following result −
Value of total : 30
Value of total : 40
The return Statement
The statement return [expression] exits a function, optionally passing back an expression to
the caller. A return statement with no arguments is the same as return None.
All the above examples are not returning any value. You can return a value from a function as
follows −
# Function definition is here
def sum( arg1, arg2 ):
# Add both the parameters and return them."
total = arg1 + arg2
print "Inside the function : ", total
return total;

# Now you can call sum function


total = sum( 10, 20 );
print "Outside the function : ", total
When the above code is executed, it produces the following result −
Inside the function : 30
Outside the function : 30
Scope of Variables
All variables in a program may not be accessible at all locations in that program. This
depends on where you have declared a variable.
The scope of a variable determines the portion of the program where you can access a
particular identifier. There are two basic scopes of variables in Python −
 Global variables
 Local variables
Global vs. Local variables
Variables that are defined inside a function body have a local scope, and those defined
outside have a global scope.
This means that local variables can be accessed only inside the function in which they are
declared, whereas global variables can be accessed throughout the program body by all
functions. When you call a function, the variables declared inside it are brought into scope.
Following is a simple example −
total = 0; # This is global variable.
# Function definition is here
def sum( arg1, arg2 ):
# Add both the parameters and return them."
total = arg1 + arg2; # Here total is local variable.
print "Inside the function local total : ", total
return total;

# Now you can call sum function


sum( 10, 20 );
print "Outside the function global total : ", total
When the above code is executed, it produces the following result −
Inside the function local total : 30
Outside the function global total : 0

Python File I/O


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

Opening Files in Python


Python has a built-in open() function to open a file. This function returns a file object, also
called a handle, as it is used to read or modify the file accordingly.
>>> f = open("test.txt") # open file in current directory
>>> f = open("C:/Python38/README.txt") # specifying full path
We can specify the mode while opening a file. In mode, we specify whether we want to read r,
write w or append a to the file. We can also specify if we want to open the file in text mode or
binary mode.
The default is reading in text mode. In this mode, we get strings when reading from the file.

On the other hand, binary mode returns bytes and this is the mode to be used when dealing
with non-text files like images or executable files.

Mode Description
R Opens a file for reading. (default)
W Opens a file for writing. Creates a new file if it does not exist or truncates the file if
it exists.
X Opens a file for exclusive creation. If the file already exists, the operation fails.
A Opens a file for appending at the end of the file without truncating it. Creates a
new file if it does not exist.
T Opens in text mode. (default)
B Opens in binary mode.
+ Opens a file for updating (reading and writing)
f = open("test.txt") # equivalent to 'r' or 'rt'
f = open("test.txt",'w') # write in text mode
f = open("img.bmp",'r+b') # read and write in binary mode
Unlike other languages, the character a does not imply the number 97 until it is encoded
using ASCII (or other equivalent encodings).
Moreover, the default encoding is platform dependent. In windows, it is cp1252 but utf-8 in Linux.
So, we must not also rely on the default encoding or else our code will behave differently in
different platforms.

Hence, when working with files in text mode, it is highly recommended to specify the encoding
type.

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

Closing Files in Python


When we are done with performing operations on the file, we need to properly close the file.
Closing a file will free up the resources that were tied with the file. It is done using
the close() method available in Python.
Python has a garbage collector to clean up unreferenced objects but we must not rely on it to
close the file.
f = open("test.txt", encoding = 'utf-8')
# perform file operations
f.close()
This method is not entirely safe. If an exception occurs when we are performing some
operation with the file, the code exits without closing the file.

A safer way is to use a try...finally block.


try:
f = open("test.txt", encoding = 'utf-8')
# perform file operations
finally:
f.close()
This way, we are guaranteeing that the file is properly closed even if an exception is raised
that causes program flow to stop.
The best way to close a file is by using the with statement. This ensures that the file is closed
when the block inside the with statement is exited.
We don't need to explicitly call the close() method. It is done internally.
with open("test.txt", encoding = 'utf-8') as f:
# perform file operations
Writing to Files in Python
In order to write into a file in Python, we need to open it in write w, append a or exclusive
creation x mode.
We need to be careful with the w mode, as it will overwrite into the file if it already exists. Due
to this, all the previous data are erased.
Writing a string or sequence of bytes (for binary files) is done using the write() method. This
method returns the number of characters written to the file.
with open("test.txt",'w',encoding = 'utf-8') as f:
f.write("my first file\n")
f.write("This file\n\n")
f.write("contains three lines\n")

This program will create a new file named test.txt in the current directory if it does not exist. If it
does exist, it is overwritten.
We must include the newline characters ourselves to distinguish the different lines.
Reading Files in Python
To read a file in Python, we must open the file in reading r mode.
There are various methods available for this purpose. We can use the read(size) method to read
in the size number of data. If the size parameter is not specified, it reads and returns up to the
end of the file.
We can read the text.txt file we wrote in the above section in the following way:
>>> f = open("test.txt",'r',encoding = 'utf-8')
>>> f.read(4) # read the first 4 data
'This'

>>> f.read(4) # read the next 4 data


' is '

>>> f.read() # read in the rest till end of file


'my first file\nThis file\ncontains three lines\n'

>>> f.read() # further reading returns empty sting


''
We can see that the read() method returns a newline as '\n'. Once the end of the file is reached,
we get an empty string on further reading.
We can change our current file cursor (position) using the seek() method. Similarly,
the tell() method returns our current position (in number of bytes).
>>> f.tell() # get the current file position
56

>>> f.seek(0) # bring file cursor to initial position


0

>>> print(f.read()) # read the entire file


This is my first file
This file
contains three lines

We can read a file line-by-line using a for loop. This is both efficient and fast.
>>> for line in f:
... print(line, end = '')
...
This is my first file
This file
contains three lines
In this program, the lines in the file itself include a newline character \n. So, we use the end
parameter of the print() function to avoid two newlines when printing.
Alternatively, we can use the readline() method to read individual lines of a file. This method
reads a file till the newline, including the newline character.
>>> f.readline()
'This is my first file\n'

>>> f.readline()
'This file\n'

>>> f.readline()
'contains three lines\n'

>>> f.readline()
''
Lastly, the readlines() method returns a list of remaining lines of the entire file. All these reading
methods return empty values when the end of file (EOF) is reached.
>>> f.readlines()
['This is my first file\n', 'This file\n', 'contains three lines\n']

UNIT-III
Python OOPs Concepts
Like other general-purpose programming languages, Python is also an object-oriented
language since its beginning. It allows us to develop applications using an Object-Oriented
approach. In Python, we can easily create and use classes and objects.
An object-oriented paradigm is to design the program using classes and objects. The object is
related to real-word entities such as book, house, pencil, etc. The oops concept focuses on
writing the reusable code. It is a widespread technique to solve the problem by creating
objects.
Major principles of object-oriented programming system are given below.
o Class
o Object
o Method
o Inheritance
o Polymorphism
o Data Abstraction
o Encapsulation
Class
The class can be defined as a collection of objects. It is a logical entity that has some specific
attributes and methods. For example: if you have an employee class, then it should contain an
attribute and method, i.e. an email id, name, age, salary, etc.
class ClassName:
<statement-1>
.
.
<statement-N>
Object
The object is an entity that has state and behavior. It may be any real-world object like the
mouse, keyboard, chair, table, pen, etc.
Everything in Python is an object, and almost everything has attributes and methods. All
functions have a built-in attribute __doc__, which returns the docstring defined in the function
source code.
When we define a class, it needs to create an object to allocate the memory. Consider the
following example.
Example:
class car:
def __init__(self,modelname, year):
self.modelname = modelname
self.year = year
def display(self):
print(self.modelname,self.year)

c1 = car("Toyota", 2016)
c1.display()
Output:
Toyota 2016
In the above example, we have created the class named car, and it has two attributes
modelname and year. We have created a c1 object to access the class attribute. The c1 object
will allocate memory for these values. We will learn more about class and object in the next
tutorial.
Method
The method is a function that is associated with an object. In Python, a method is not unique
to class instances. Any object type can have methods.
Inheritance
Inheritance is the most important aspect of object-oriented programming, which simulates the
real-world concept of inheritance. It specifies that the child object acquires all the properties
and behaviors of the parent object.
By using inheritance, we can create a class which uses all the properties and behavior of
another class. The new class is known as a derived class or child class, and the one whose
properties are acquired is known as a base class or parent class.
It provides the re-usability of the code.
Polymorphism
Polymorphism contains two words "poly" and "morphs". Poly means many, and morph means
shape. By polymorphism, we understand that one task can be performed in different ways. For
example - you have a class animal, and all animals speak. But they speak differently. Here, the
"speak" behavior is polymorphic in a sense and depends on the animal. So, the abstract
"animal" concept does not actually "speak", but specific animals (like dogs and cats) have a
concrete implementation of the action "speak".
Encapsulation
Encapsulation is also an essential aspect of object-oriented programming. It is used to restrict
access to methods and variables. In encapsulation, code and data are wrapped together
within a single unit from being modified by accident.
Data Abstraction
Data abstraction and encapsulation both are often used as synonyms. Both are nearly
synonyms because data abstraction is achieved through encapsulation.
Abstraction is used to hide internal details and show only functionalities. Abstracting
something means to give names to things so that the name captures the core of what a
function or a whole program does.
Object-oriented vs. Procedure-oriented Programming languages
The difference between object-oriented and procedure-oriented programming is given below:
Index Object-oriented Programming Procedural Programming

1. Object-oriented programming is the Procedural programming uses a list of


problem-solving approach and used instructions to do computation step by
where computation is done by using step.
objects.

2. It makes the development and In procedural programming, It is not


maintenance easier. easy to maintain the codes when the
project becomes lengthy.

3. It simulates the real world entity. So real- It doesn't simulate the real world. It
world problems can be easily solved works on step by step instructions
through oops. divided into small parts called
functions.

4. It provides data hiding. So it is more Procedural language doesn't provide


secure than procedural languages. You any proper way for data binding, so it is
cannot access private data from less secure.
anywhere.

5. Example of object-oriented programming Example of procedural languages are:


languages is C++, Java, .Net, Python, C#, C, Fortran, Pascal, VB etc.
etc.

Python Class and Objects


We have already discussed in previous tutorial, a class is a virtual entity and can be seen as a
blueprint of an object. The class came into existence when it instantiated. Let's understand it
by an example.
Suppose a class is a prototype of a building. A building contains all the details about the floor,
rooms, doors, windows, etc. we can make as many buildings as we want, based on these
details. Hence, the building can be seen as a class, and we can create as many objects of this
class.
On the other hand, the object is the instance of a class. The process of creating an object can
be called instantiation.
In this section of the tutorial, we will discuss creating classes and objects in Python. We will
also discuss how a class attribute is accessed by using the object.
Creating classes in Python
In Python, a class can be created by using the keyword class, followed by the class name. The
syntax to create a class is given below.
Syntax
class ClassName:
#statement_suite
In Python, we must notice that each class is associated with a documentation string which
can be accessed by using <class-name>.__doc__. A class contains a statement suite
including fields, constructor, function, etc. definition.
Consider the following example to create a class Employee which contains two fields as
Employee id, and name. The class also contains a function display(), which is used to display
the information of the Employee.
Example
class Employee:
id = 10
name = "Devansh"
def display (self):
print(self.id,self.name)
Here, the self is used as a reference variable, which refers to the current class object. It is
always the first argument in the function definition. However, using self is optional in the
function call.
The self-parameter
The self-parameter refers to the current instance of the class and accesses the class
variables. We can use anything instead of self, but it must be the first parameter of any
function which belongs to the class.
Creating an instance of the class
A class needs to be instantiated if we want to use the class attributes in another class or
method. A class can be instantiated by calling the class using the class name.
The syntax to create the instance of the class is given below.
1. <object-name> = <class-name>(<arguments>)
The following example creates the instance of the class Employee defined in the above
example.
Example
class Employee:
id = 10
name = "John"
def display (self):
print("ID: %d \nName: %s"%(self.id,self.name))
# Creating a emp instance of Employee class
emp = Employee()
emp.display()
Output:
ID: 10
Name: John
In the above code, we have created the Employee class which has two attributes named id
and name and assigned value to them. We can observe we have passed the self as parameter
in display function. It is used to refer to the same class attribute.
We have created a new instance object named emp. By using it, we can access the attributes
of the class.
Delete the Object
We can delete the properties of the object or object itself by using the del keyword. Consider
the following example.
Example
class Employee:
id = 10
name = "John"

def display(self):
print("ID: %d \nName: %s" % (self.id, self.name))
# Creating a emp instance of Employee class
emp = Employee()
# Deleting the property of object
del emp.id
# Deleting the object itself
del emp
emp.display()

It will through the Attribute error because we have deleted the object emp.
Python Constructor
A constructor is a special type of method (function) which is used to initialize the instance
members of the class.
In C++ or Java, the constructor has the same name as its class, but it treats constructor
differently in Python. It is used to create an object.
Constructors can be of two types.
1. Parameterized Constructor
2. Non-parameterized Constructor
Constructor definition is executed when we create the object of this class. Constructors also
verify that there are enough resources for the object to perform any start-up task.
Creating the constructor in python
In Python, the method the __init__() simulates the constructor of the class. This method is
called when the class is instantiated. It accepts the self-keyword as a first argument which
allows accessing the attributes or method of the class.
We can pass any number of arguments at the time of creating the class object, depending
upon the __init__() definition. It is mostly used to initialize the class attributes. Every class
must have a constructor, even if it simply relies on the default constructor.
Consider the following example to initialize the Employee class attributes.
Example
class Employee:
def __init__(self, name, id):
self.id = id
self.name = name

def display(self):
print("ID: %d \nName: %s" % (self.id, self.name))

emp1 = Employee("John", 101)


emp2 = Employee("David", 102)
emp1.display()
emp2.display()

Output:

ID: 101
Name: John
ID: 102
Name: David
Counting the number of objects of a class
The constructor is called automatically when we create the object of the class. Consider the
following example.
Example
class Student:
count = 0
def __init__(self):
Student.count = Student.count + 1
s1=Student()
s2=Student()
s3=Student()
print("The number of students:",Student.count)

Output:
The number of students: 3
Python Non-Parameterized Constructor
The non-parameterized constructor uses when we do not want to manipulate the value or the
constructor that has only self as an argument. Consider the following example.
Example
class Student:
# Constructor - non parameterized
def __init__(self):
print("This is non parametrized constructor")
def show(self,name):
print("Hello",name)
student = Student()
student.show("John")

Python Parameterized Constructor


The parameterized constructor has multiple parameters along with the self. Consider the
following example.
Example
class Student:
# Constructor - parameterized
def __init__(self, name):
print("This is parametrized constructor")
self.name = name
def show(self):
print("Hello",self.name)
student = Student("John")
student.show()
Output:
This is parametrized constructor
Hello John
Python Default Constructor
When we do not include the constructor in the class or forget to declare it, then that becomes
the default constructor. It does not perform any task but initializes the objects. Consider the
following example.
Example
class Student:
roll_num = 101
name = "Joseph"

def display(self):
print(self.roll_num,self.name)

st = Student()
st.display()

Output:

101 Joseph
More than One Constructor in Single class
Let's have a look at another scenario, what happen if we declare the two same constructors in
the class.
Example
class Student:
def __init__(self):
print("The First Constructor")
def __init__(self):
print("The second contructor")

st = Student()

Output:

The Second Constructor


In the above code, the object st called the second constructor whereas both have the same
configuration. The first method is not accessible by the st object. Internally, the object of the
class will always call the last constructor if the class has multiple constructors.
Note: The constructor overloading is not allowed in Python.
Python built-in class functions
The built-in functions defined in the class are described in the following table.

SN Function Description

1 getattr(obj,name,default) It is used to access the attribute of the object.

2 setattr(obj, name,value) It is used to set a particular value to the specific attribute


of an object.

3 delattr(obj, name) It is used to delete a specific attribute.

4 hasattr(obj, name) It returns true if the object contains some specific


attribute.

Example
class Student:
def __init__(self, name, id, age):
self.name = name
self.id = id
self.age = age

s = Student("John", 101, 22)


print(getattr(s, 'name'))
setattr(s, "age", 23)
print(getattr(s, 'age'))
print(hasattr(s, 'id'))
delattr(s, 'age')

# this will give an error since the attribute age has been deleted
print(s.age)

Output:

John
23
True
AttributeError: 'Student' object has no attribute 'age'
Built-in class attributes
Along with the other attributes, a Python class also contains some built-in class attributes
which provide information about the class.
The built-in class attributes are given in the below table.

SN Attribute Description

1 __dict__ It provides the dictionary containing the information about the class
namespace.

2 __doc__ It contains a string which has the class documentation

3 __name__ It is used to access the class name.

4 __module__ It is used to access the module in which, this class is defined.

5 __bases__ It contains a tuple including all base classes.

Example
class Student:
def __init__(self,name,id,age):
self.name = name;
self.id = id;
self.age = age
def display_details(self):
print("Name:%s, ID:%d, age:%d"%(self.name,self.id))
s = Student("John",101,22)
print(s.__doc__)
print(s.__dict__)
print(s.__module__)

Output:

None
{'name': 'John', 'id': 101, 'age': 22}
__main__
Python Operator Overloading
Python operators work for built-in classes. But the same operator behaves differently with
different types. For example, the + operator will perform arithmetic addition on two numbers,
merge two lists, or concatenate two strings.
This feature in Python that allows the same operator to have different meaning according to
the context is called operator overloading.
So what happens when we use them with objects of a user-defined class? Let us consider the
following class, which tries to simulate a point in 2-D coordinate system.
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

p1 = Point(1, 2)
p2 = Point(2, 3)
print(p1+p2)
Output
Traceback (most recent call last):
File "<string>", line 9, in <module>
print(p1+p2)
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
Here, we can see that a TypeError was raised, since Python didn't know how to add
two Point objects together.
However, we can achieve this task in Python through operator overloading. But first, let's get a
notion about special functions.

Python Special Functions


Class functions that begin with double underscore __ are called special functions in Python.
These functions are not the typical functions that we define for a class. The __init__() function
we defined above is one of them. It gets called every time we create a new object of that class.
There are numerous other special functions in Python. Visit Python Special Functions to learn
more about them.
Using special functions, we can make our class compatible with built-in functions.
>>> p1 = Point(2,3)
>>> print(p1)
<__main__.Point object at 0x00000000031F8CC0>
Suppose we want the print() function to print the coordinates of the Point object instead of what
we got. We can define a __str__() method in our class that controls how the object gets printed.
Let's look at how we can achieve this:
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y

def __str__(self):
return "({0},{1})".format(self.x,self.y)
Now let's try the print() function again.
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

def __str__(self):
return "({0}, {1})".format(self.x, self.y)

p1 = Point(2, 3)
print(p1)
Output
(2, 3)
That's better. Turns out, that this same method is invoked when we use the built-in
function str() or format().
>>> str(p1)
'(2,3)'

>>> format(p1)
'(2,3)'
So, when you use str(p1) or format(p1), Python internally calls the p1.__str__() method. Hence the
name, special functions.
Now let's go back to operator overloading.
Overloading the + Operator

To overload the + operator, we will need to implement __add__() function in the class. With great
power comes great responsibility. We can do whatever we like, inside this function. But it is
more sensible to return a Point object of the coordinate sum.
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

def __str__(self):
return "({0},{1})".format(self.x, self.y)

def __add__(self, other):


x = self.x + other.x
y = self.y + other.y
return Point(x, y)
Now let's try the addition operation again:

class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

def __str__(self):
return "({0},{1})".format(self.x, self.y)

def __add__(self, other):


x = self.x + other.x
y = self.y + other.y
return Point(x, y)

p1 = Point(1, 2)
p2 = Point(2, 3)

print(p1+p2)
Output
(3,5)
What actually happens is that, when you use p1 + p2, Python calls p1.__add__(p2) which in turn
is Point.__add__(p1,p2). After this, the addition operation is carried out the way we specified.

Inheritance
Inheritance is an important aspect of the object-oriented paradigm. Inheritance provides code
reusability to the program because we can use an existing class to create a new class instead
of creating it from scratch.

In inheritance, the child class acquires the properties and can access all the data members
and functions defined in the parent class. A child class can also provide its specific
implementation to the functions of the parent class. In this section of the tutorial, we will
discuss inheritance in detail.

In python, a derived class can inherit base class by just mentioning the base in the bracket
after the derived class name. Consider the following syntax to inherit a base class into the
derived class.

Syntax
class derived-class(base class):
<class-suite>
A class can inherit multiple classes by mentioning all of them inside the bracket. Consider the
following syntax.
Syntax
class derive-class(<base class 1>, <base class 2>, ..... <base class n>):
<class - suite>
Example 1
class Animal:
def speak(self):
print("Animal Speaking")
#child class Dog inherits the base class Animal
class Dog(Animal):
def bark(self):
print("dog barking")
d = Dog()
d.bark()
d.speak()

Output:

dog barking
Animal Speaking

Python Multi-Level inheritance

Multi-Level inheritance is possible in python like other object-oriented languages. Multi-level


inheritance is archived when a derived class inherits another derived class. There is no limit on
the number of levels up to which, the multi-level inheritance is archived in python.

The syntax of multi-level inheritance is given below.

Syntax
class class1:
<class-suite>
class class2(class1):
<class suite>
class class3(class2):
<class suite>
.
.

Example
class Animal:
def speak(self):
print("Animal Speaking")
#The child class Dog inherits the base class Animal
class Dog(Animal):
def bark(self):
print("dog barking")
#The child class Dogchild inherits another child class Dog
class DogChild(Dog):
def eat(self):
print("Eating bread...")
d = DogChild()
d.bark()
d.speak()
d.eat()

Output:

dog barking
Animal Speaking
Eating bread...

Python Multiple inheritance

Python provides us the flexibility to inherit multiple base classes in the child class.

The syntax to perform multiple inheritance is given below.

Syntax
class Base1:
<class-suite>

class Base2:
<class-suite>
.
.
.
class BaseN:
<class-suite>

class Derived(Base1, Base2, ...... BaseN):


<class-suite>

Example
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(d.Summation(10,20))
print(d.Multiplication(10,20))
print(d.Divide(10,20))

Output:

30
200
0.5

The issubclass(sub,sup) method

The issubclass(sub, sup) method is used to check the relationships between the specified
classes. It returns true if the first class is the subclass of the second class, and false
otherwise.

Consider the following example.

Example
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(issubclass(Derived,Calculation2))
print(issubclass(Calculation1,Calculation2))

Output:

True
False
The isinstance (obj, class) method

The isinstance() method is used to check the relationship between the objects and classes. It
returns true if the first parameter, i.e., obj is the instance of the second parameter, i.e., class.

Consider the following example.

Example
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(isinstance(d,Derived))

Output:

True
Method Overriding
We can provide some specific implementation of the parent class method in our child class.
When the parent class method is defined in the child class with some specific implementation,
then the concept is called method overriding. We may need to perform method overriding in
the scenario where the different definition of a parent class method is needed in the child
class.
Consider the following example to perform method overriding in python.
Example
class Animal:
def speak(self):
print("speaking")
class Dog(Animal):
def speak(self):
print("Barking")
d = Dog()
d.speak()
Output: Barking
Data abstraction in python
Abstraction is an important aspect of object-oriented programming. In python, we can also
perform data hiding by adding the double underscore (___) as a prefix to the attribute which is
to be hidden. After this, the attribute will not be visible outside of the class through the object.
Consider the following example.
Example
class Employee:
__count = 0;
def __init__(self):
Employee.__count = Employee.__count+1
def display(self):
print("The number of employees",Employee.__count)
emp = Employee()
emp2 = Employee()
try:
print(emp.__count)
finally:
emp.display()

Output: The number of employees 2

Errors and Exceptions


Until now error messages haven’t been more than mentioned, but if you have tried out the
examples you have probably seen some. There are (at least) two distinguishable kinds of
errors: syntax errors and exceptions.
Syntax Errors

Syntax errors, also known as parsing errors, are perhaps the most common kind of complaint
you get while you are still learning Python:
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax

The parser repeats the offending line and displays a little ‘arrow’ pointing at the earliest point
in the line where the error was detected. The error is caused by (or at least detected at) the
token preceding the arrow: in the example, the error is detected at the function print(), since a
colon (':') is missing before it. File name and line number are printed so you know where to
look in case the input came from a script.
Exceptions

Even if a statement or expression is syntactically correct, it may cause an error when an


attempt is made to execute it. Errors detected during execution are called exceptions and are
not unconditionally fatal: you will soon learn how to handle them in Python programs. Most
exceptions are not handled by programs, however, and result in error messages as shown
here:
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
The last line of the error message indicates what happened. Exceptions come in different
types, and the type is printed as part of the message: the types in the example
are ZeroDivisionError, NameError and TypeError. The string printed as the exception type is
the name of the built-in exception that occurred. This is true for all built-in exceptions, but
need not be true for user-defined exceptions (although it is a useful convention). Standard
exception names are built-in identifiers (not reserved keywords).
The rest of the line provides detail based on the type of exception and what caused it.
The preceding part of the error message shows the context where the exception occurred, in
the form of a stack traceback. In general it contains a stack traceback listing source lines;
however, it will not display lines read from standard input.
Built-in Exceptions lists the built-in exceptions and their meanings.
Handling Exceptions
It is possible to write programs that handle selected exceptions. Look at the following
example, which asks the user for input until a valid integer has been entered, but allows the
user to interrupt the program (using Control-C or whatever the operating system supports); note
that a user-generated interruption is signalled by raising the KeyboardInterrupt exception.

>>> while True:


... try:
... x = int(input("Please enter a number: "))
... break
... except ValueError:
... print("Oops! That was no valid number. Try again...")
...

The try statement works as follows.

 First, the try clause (the statement(s) between the try and except keywords) is executed.
 If no exception occurs, the except clause is skipped and execution of the try statement
is finished.
 If an exception occurs during execution of the try clause, the rest of the clause is
skipped. Then if its type matches the exception named after the except keyword, the
except clause is executed, and then execution continues after the try statement.
 If an exception occurs which does not match the exception named in the except clause,
it is passed on to outer try statements; if no handler is found, it is an unhandled
exception and execution stops with a message as shown above.

A try statement may have more than one except clause, to specify handlers for different
exceptions. At most one handler will be executed. Handlers only handle exceptions that occur
in the corresponding try clause, not in other handlers of the same try statement. An except
clause may name multiple exceptions as a parenthesized tuple, for example:

... except (RuntimeError, TypeError, NameError):


... pass

A class in an except clause is compatible with an exception if it is the same class or a base
class thereof (but not the other way around — an except clause listing a derived class is not
compatible with a base class). For example, the following code will print B, C, D in that order:

class B(Exception):
pass

class C(B):
pass

class D(C):
pass

for cls in [B, C, D]:


try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
Note that if the except clauses were reversed (with except B first), it would have printed B, B, B
— the first matching except clause is triggered.
The last except clause may omit the exception name(s), to serve as a wildcard. Use this with
extreme caution, since it is easy to mask a real programming error in this way! It can also be
used to print an error message and then re-raise the exception (allowing a caller to handle the
exception as well):
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise

The try … except statement has an optional else clause, which, when present, must follow all
except clauses. It is useful for code that must be executed if the try clause does not raise an
exception. For example:

for arg in sys.argv[1:]:


try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
The use of the else clause is better than adding additional code to the try clause because it
avoids accidentally catching an exception that wasn’t raised by the code being protected by
the try … except statement.
When an exception occurs, it may have an associated value, also known as the
exception’s argument. The presence and type of the argument depend on the exception type.
The except clause may specify a variable after the exception name. The variable is bound to
an exception instance with the arguments stored in instance.args. For convenience, the
exception instance defines __str__() so the arguments can be printed directly without having
to reference .args. One may also instantiate an exception first before raising it and add any
attributes to it as desired.

>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
If an exception has arguments, they are printed as the last part (‘detail’) of the message for
unhandled exceptions.
Exception handlers don’t just handle exceptions if they occur immediately in the try clause, but
also if they occur inside functions that are called (even indirectly) in the try clause. For
example:
>>> def this_fails():
... x = 1/0
...
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print('Handling run-time error:', err)
...
Handling run-time error: division by zero

Raising Exceptions

The raise statement allows the programmer to force a specified exception to occur. For
example:

>>> raise NameError('HiThere')


Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: HiThere
The sole argument to raise indicates the exception to be raised. This must be either an
exception instance or an exception class (a class that derives from Exception). If an exception
class is passed, it will be implicitly instantiated by calling its constructor with no arguments:
raise ValueError # shorthand for 'raise ValueError()'
If you need to determine whether an exception was raised but don’t intend to handle it, a
simpler form of the raise statement allows you to re-raise the exception:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
...
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: HiThere

Exception Chaining

The raise statement allows an optional from which enables chaining exceptions. For example:
# exc must be exception instance or None.
raise RuntimeError from exc

This can be useful when you are transforming exceptions. For example:
>>> def func():
... raise IOError
...
>>> try:
... func()
... except IOError as exc:
... raise RuntimeError('Failed to open database') from exc
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in func
OSError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):


File "<stdin>", line 4, in <module>
RuntimeError: Failed to open database

Exception chaining happens automatically when an exception is raised inside


an except or finally section. Exception chaining can be disabled by using from None idiom:

>>> try:
... open('database.sqlite')
... except OSError:
... raise RuntimeError from None
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError

User-defined Exceptions
Programs may name their own exceptions by creating a new exception class (see Classes for
more about Python classes). Exceptions should typically be derived from the Exception class,
either directly or indirectly.
Exception classes can be defined which do anything any other class can do, but are usually
kept simple, often only offering a number of attributes that allow information about the error
to be extracted by handlers for the exception. When creating a module that can raise several
distinct errors, a common practice is to create a base class for exceptions defined by that
module, and subclass that to create specific exception classes for different error conditions:
class Error(Exception):
"""Base class for exceptions in this module."""
pass

class InputError(Error):
"""Exception raised for errors in the input.

Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""

def __init__(self, expression, message):


self.expression = expression
self.message = message

class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.

Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""

def __init__(self, previous, next, message):


self.previous = previous
self.next = next
self.message = message

Most exceptions are defined with names that end in “Error”, similar to the naming of the
standard exceptions.

Many standard modules define their own exceptions to report errors that may occur in
functions they define. More information on classes is presented in chapter Classes.
Defining Clean-up Actions
The try statement has another optional clause which is intended to define clean-up actions
that must be executed under all circumstances. For example:
>>> try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
File "<stdin>", line 2, in <module>

If a finally clause is present, the finally clause will execute as the last task before
the try statement completes. The finally clause runs whether or not the try statement
produces an exception. The following points discuss more complex cases when an exception
occurs:

 If an exception occurs during execution of the try clause, the exception may be handled
by an except clause. If the exception is not handled by an except clause, the exception
is re-raised after the finally clause has been executed.
 An exception could occur during execution of an except or else clause. Again, the
exception is re-raised after the finally clause has been executed.
 If the finally clause executes a break, continue or return statement, exceptions are not
re-raised.
 If the try statement reaches a break, continue or return statement, the finally clause will
execute just prior to the break, continue or return statement’s execution.
 If a finally clause includes a return statement, the returned value will be the one from
the finally clause’s return statement, not the value from
the try clause’s return statement.

For example:

>>> def bool_return():


... try:
... return True
... finally:
... return False
...
>>> bool_return()
False

A more complicated example:

>>> def divide(x, y):


... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
As you can see, the finally clause is executed in any event. The TypeError raised by dividing
two strings is not handled by the except clause and therefore re-raised after the finally clause
has been executed.
In real world applications, the finally clause is useful for releasing external resources (such as
files or network connections), regardless of whether the use of the resource was successful.
Predefined Clean-up Actions
Some objects define standard clean-up actions to be undertaken when the object is no longer
needed, regardless of whether or not the operation using the object succeeded or failed. Look
at the following example, which tries to open a file and print its contents to the screen.
for line in open("myfile.txt"):
print(line, end="")
The problem with this code is that it leaves the file open for an indeterminate amount of time
after this part of the code has finished executing. This is not an issue in simple scripts, but
can be a problem for larger applications. The with statement allows objects like files to be
used in a way that ensures they are always cleaned up promptly and correctly.
with open("myfile.txt") as f:
for line in f:
print(line, end="")

After the statement is executed, the file f is always closed, even if a problem was encountered
while processing the lines. Objects which, like files, provide predefined clean-up actions will
indicate this in their documentation.

API Packages (6)


Package: Collection of Classes. Class contains methods and attributes.
Stdio.h : collection of functions. Printf(), scanf(), ..

Python Modules
A python module can be defined as a python program file which contains a python code
including python functions, class, or variables. In other words, we can say that our python
code file saved with the extension (.py) is treated as the module. We may have a runnable
code inside the python module.
Modules in Python provides us the flexibility to organize the code in a logical way. To use the
functionality of one module into another, we must have to import the specific module.
Example
In this example, we will create a module named as file.py which contains a function func that
contains a code to print some message on the console. Balcony
Let's create the module named as file.py.
#displayMsg prints a message to the name being passed.
def displayMsg(name)
print("Hi "+name);

Here, we need to include this module into our main module to call the method displayMsg()
defined in the module named file.

Loading the module in our python code


We need to load the module in our python code to use its functionality. Python provides two
types of statements as defined below.
1. The import statement
2. The from-import statement
The import statement
The import statement is used to import all the functionality of one module into another. Here,
we must notice that we can use the functionality of any python source file by importing that
file as the module into another python source file.
We can import multiple modules with a single import statement, but a module is loaded once
regardless of the number of times, it has been imported into our file.
The syntax to use the import statement is given below.
1. import module1,module2,........ module n
Hence, if we need to call the function displayMsg() defined in the file file.py, we have to import
that file as a module into our module as shown in the example below.
Example:
import file;
name = input("Enter the name?")
file.displayMsg(name)
Output:
Enter the name?John
Hi John
The from-import statement
Instead of importing the whole module into the namespace, python provides the flexibility to
import only the specific attributes of a module. This can be done by using from? import
statement. The syntax to use the from-import statement is given below.
1. from < module-name> import <name 1>, <name 2>..,<name n>
Consider the following module named as calculation which contains three functions as
summation, multiplication, and divide.

calculation.py:

#place the code in the calculation.py


def summation(a,b):
return a+b
def multiplication(a,b):
return a*b;
def divide(a,b):
return a/b;

Main.py:

import calculation;
#it will import only the summation() from calculation.py
a = int(input("Enter the first number"))
b = int(input("Enter the second number"))
print("Sum = ",summation(a,b)) #we do not need to specify the module name while accessing su
mmation()

Output:

Enter the first number10


Enter the second number20
Sum = 30
The from...import statement is always better to use if we know the attributes to be imported
from the module in advance. It doesn't let our code to be heavier. We can also import all the
attributes from a module by using *.
Consider the following syntax.
from <module> import *
Renaming a module
Python provides us the flexibility to import some module with a specific name so that we can
use this name to use that module in our python source file.
The syntax to rename a module is given below.
import <module-name> as <specific-name>
Example
#the module calculation of previous example is imported in this example as cal.
import calculation as cal;
a = int(input("Enter a?"));
b = int(input("Enter b?"));
print("Sum = ",cal.summation(a,b))
Output:
Enter a?10
Enter b?20
Sum = 30
Using dir() function
The dir() function returns a sorted list of names defined in the passed module. This list
contains all the sub-modules, variables and functions defined in this module.
Consider the following example.

Example
import json
List = dir(json)
print(List)

Output:
['JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__',
'__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__',
'_default_decoder', '_default_encoder', 'decoder', 'dump', 'dumps', 'encoder', 'load', 'loads',
'scanner']

The reload() function


As we have already stated that, a module is loaded once regardless of the number of times it
is imported into the python source file. However, if you want to reload the already imported
module to re-execute the top-level code, python provides us the reload() function. The syntax
to use the reload() function is given below.
1. reload(<module-name>)
for example, to reload the module calculation defined in the previous example, we must use
the following line of code.
1. reload(calculation)
Scope of variables
In Python, variables are associated with two types of scopes. All the variables defined in a
module contain the global scope unless or until it is defined within a function.
All the variables defined inside a function contain a local scope that is limited to this function
itself. We can not access a local variable globally.
If two variables are defined with the same name with the two different scopes, i.e., local and
global, then the priority will always be given to the local variable.
Consider the following example.
Example
name = "john"
def print_name(name):
print("Hi",name) #prints the name that is local to this function only.
name = input("Enter the name?")
print_name(name)
Output:
Hi David

Python packages
The packages in python facilitate the developer with the application development environment
by providing a hierarchical directory structure where a package contains sub-packages,
modules, and sub-modules. The packages are used to categorize the application level code
efficiently.
Let's create a package named Employees in your home directory. Consider the following steps.
1. Create a directory with name Employees on path /home.
2. Create a python source file with name ITEmployees.py on the path /home/Employees.
ITEmployees.py
def getITNames():
List = ["John", "David", "Nick", "Martin"]
return List;
3. Similarly, create one more python file with name BPOEmployees.py and create a function
getBPONames().
4. Now, the directory Employees which we have created in the first step contains two python
modules. To make this directory a package, we need to include one more file here, that is
__init__.py which contains the import statements of the modules defined in this directory.
__init__.py
from ITEmployees import getITNames
from BPOEmployees import getBPONames
5. Now, the directory Employees has become the package containing two python modules.
Here we must notice that we must have to create __init__.py inside a directory to convert this
directory to a package.
6. To use the modules defined inside the package Employees, we must have to import this in
our python source file. Let's create a simple python source file at our home directory (/home)
which uses the modules defined in this package.

Test.py
import Employees
print(Employees.getNames())
Output:
['John', 'David', 'Nick', 'Martin']

We can have sub-packages inside the packages. We can nest the packages up to any level
depending upon the application requirements.
The following image shows the directory structure of an application Library management
system which contains three sub-packages as Admin, Librarian, and Student. The sub-
packages contain the python modules.

Namespaces in Python
In python we deal with variables, functions, libraries and modules etc. There is a chance the
name of the variable you are going to use is already existing as name of another variable or as
the name of another function or another method. In such scenario, we need to learn about
how all these names are managed by a python program. This is the concept of namespace.
Following are the three categories of namespace
 Local Namespace: All the names of the functions and variables declared by a program
are held in this namespace. This namespace exists as long as the program runs. < /p>
 Global Namespace: This namespace holds all the names of functions and other
variables that are included in the modules being used in the python program. It
encompasses all the names that are part of the Local namespace.
 Built-in Namespace: This is the highest level of namespace which is available with
default names available as part of the python interpreter that is loaded as the
programing environment. It encompasses Global Namespace which in turn
encompasses the local namespace.
Scope in Python
The namespace has a lifetime when it is available. That is also called the scope. Also the
scope will depend on the coding region where the variable or object is located. You can see in
the below program how the variables declared in an inner loop are available to the outer loop
but not vice-versa. Also please note how the name of the outer function also becomes part of
a global variable.
Example
prog_var = 'Hello'
def outer_func():
outer_var = 'x'
def inner_func():
inner_var = 'y'
print(dir(), ' Local Variable in Inner function')

inner_func()
print(dir(), 'Local variables in outer function')

outer_func()
print(dir(), 'Global variables ')
Running the above code gives us the following result –

Output
['inner_var'] Local Variable in Inner function
['inner_func', 'outer_var'] Local variables in outer function
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__',
'__package__'

Recursion in Python
What is recursion?
Recursion is the process of defining something in terms of itself. A physical world example
would be to place two parallel mirrors facing each other. Any object in between them would be
reflected recursively.
Python Recursive Function
In Python, we know that a function can call other functions. It is even possible for the function
to call itself. These types of construct are termed as recursive functions.
The following image shows the working of a recursive function called recurse.

Recursive Function in Python


Following is an example of a recursive function to find the factorial of an integer.
Factorial of a number is the product of all the integers from 1 to that number. For example, the
factorial of 6 (denoted as 6!) is 1*2*3*4*5*6 = 720.

Example of a recursive function


def factorial(x):
if x == 1:
return 1
else:
return (x * factorial(x-1))
num = 3
print("The factorial of", num, "is", factorial(num))
Output: The factorial of 3 is 6
In the above example, factorial() is a recursive function as it calls itself.
When we call this function with a positive integer, it will recursively call itself by decreasing the
number. Each function multiplies the number with the factorial of the number below it until it
is equal to one. This recursive call can be explained in the following steps.

factorial(3) # 1st call with 3


3 * factorial(2) # 2nd call with 2
3 * 2 * factorial(1) # 3rd call with 1
3*2*1 # return from 3rd call as number=1
3*2 # return from 2nd call
6 # return from 1st call
Let's look at an image that shows a step-by-step process of what is going on:

Working of a recursive factorial function


Our recursion ends when the number reduces to 1. This is called the base condition. Every
recursive function must have a base condition that stops the recursion or else the function
calls itself infinitely.
The Python interpreter limits the depths of recursion to help avoid infinite recursions, resulting
in stack overflows. By default, the maximum depth of recursion is 1000. If the limit is crossed,
it results in RecursionError. Let's look at one such condition.
def recursor():
recursor()
recursor()
RecursionError: maximum recursion depth exceeded
Advantages of Recursion
1. Recursive functions make the code look clean and elegant.
2. A complex task can be broken down into simpler sub-problems using recursion.
3. Sequence generation is easier with recursion than using some nested iteration.

Disadvantages of Recursion
1. Sometimes the logic behind recursion is hard to follow through.
2. Recursive calls are expensive (inefficient) as they take up a lot of memory and time.
3. Recursive functions are hard to debug.
4.
Recursion vs Iteration
Since Python does not store anything about previous iteration steps, iteration is quite
faster and memory-efficient than recursion. In practice, almost all iterations can be performed
by recursions and vice-versa. Some tasks can be executed by recursion simpler than iteration
due to repeatedly calling the same function. On the other hand, some tasks can be executed
by iteration in an elegant way rather than recursion. In terms of time complexity and memory
constraints, iteration is preferred over recursion. Both recursion and ‘while’ loops in iteration
may result in the dangerous infinite calls situation. If the limiting criteria are not met, a while
loop or a recursive function will never converge and lead to a break in program execution.
Since recursion is executed by defining a function, this function can be called whenever
required anywhere in the program. Iterative codes must be constructed at the place
requirement. Nevertheless, an iterative code set can be generalized by declaring inside a
typical Python function (not a recursive function).
The following examples will give a better understanding of recursive and iterative
programming approaches.
Factorial of an Integer
Calculating factorial is a popular use case to understand iteration and recursion. For instance,
we wish to calculate the factorial of 10. It can be determined as 1*2*3*4*5*6*7*8*9*10 =
3628800. This can be viewed as 10 subproblems of multiplying an incrementing integer to a
final result.
# using a for loop
n = 10
result = 1
for i in range(1,n+1):
result *= i
print(result)

A range function is implemented in a ‘for’ loop since it requires a sequence to iterate over.
Range function supplies values iteratively from 1 through 10, one at a time. It stops iteration
when the range function stops supplying values(i.e., at 10).

# using a while loop


n = 10
result = 1
i=1
while i <= n:
result *= i
i += 1
print(result)

In a ‘while’ loop, an iterator i is introduced and incremented through every loop. While loop
stops iterating when the value of i exceeds the integer 10.
# using recursion
def Factorial(n):
# declare a base case (a limiting criteria)
if n == 1:
return 1
# continue with general case
else:
return n * Factorial(n-1)

print(Factorial(10))

A recursive function, named Factorial(), is defined with the limiting criteria of n=1. It first
attempts to find the factorial of 10. Factorial(10) is broken down into 10 * Factorial(9). Further,
Factorial(9) is broken down into 9 * Factorial(8), and so on. When Factorial(1) is called, it
stops the recursion.

UNIT-IV
Python Tkinter

Python provides the standard library Tkinter for creating the graphical user interface for
desktop based applications. Developing desktop based applications with python Tkinter is not
a complex task. An empty Tkinter top-level window can be created by using the following
steps.
1. import the Tkinter module.
2. Create the main application window.
3. Add the widgets like labels, buttons, frames, etc. to the window.
4. Call the main event loop so that the actions can take place on the user's computer
screen.

Example:
# !/usr/bin/python3
from tkinter import *
#creating the application main window.
top = Tk()
#Entering the event main loop
top.mainloop()
Output:

Tkinter widgets
There are various widgets like button, canvas, check button, entry, etc. that are used to build
the python GUI applications.
SN Widget Description

1 Button The Button is used to add various kinds of buttons to the python
application.

2 Canvas The canvas widget is used to draw the canvas on the window.

3 Checkbutton The Checkbutton is used to display the CheckButton on the window.

4 Entry The entry widget is used to display the single-line text field to the
user. It is commonly used to accept user values.

5 Frame It can be defined as a container to which, another widget can be


added and organized.
6 Label A label is a text used to display some message or information about
the other widgets.

7 ListBox The ListBox widget is used to display a list of options to the user.

8 Menubutton The Menubutton is used to display the menu items to the user.

9 Menu It is used to add menu items to the user.

10 Message The Message widget is used to display the message-box to the user.

11 Radiobutton The Radiobutton is different from a checkbutton. Here, the user is


provided with various options and the user can select only one option
among them.

12 Scale It is used to provide the slider to the user.

13 Scrollbar It provides the scrollbar to the user so that the user can scroll the
window up and down.

14 Text It is different from Entry because it provides a multi-line text field to


the user so that the user can write the text and edit the text inside it.

14 Toplevel It is used to create a separate window container.

15 Spinbox It is an entry widget used to select from options of values.

16 PanedWindow It is like a container widget that contains horizontal or vertical panes.

17 LabelFrame A LabelFrame is a container widget that acts as the container

18 MessageBox This module is used to display the message-box in the desktop


based applications.
Python Tkinter Geometry
The Tkinter geometry specifies the method by using which, the widgets are represented on
display. The python Tkinter provides the following geometry methods.
1. The pack() method
2. The grid() method
3. The place() method

Python Tkinter pack() method


The pack() widget is used to organize widget in the block. The positions widgets added to the
python application using the pack() method can be controlled by using the various options
specified in the method call.
However, the controls are less and widgets are generally added in the less organized manner.
The syntax to use the pack() is given below.
syntax
1. widget.pack(options)
A list of possible options that can be passed in pack() is given below.
o expand: If the expand is set to true, the widget expands to fill any space.
o Fill: By default, the fill is set to NONE. However, we can set it to X or Y to determine
whether the widget contains any extra space.
o size: it represents the side of the parent to which the widget is to be placed on the
window.
Example
# !/usr/bin/python3
from tkinter import *
parent = Tk()
redbutton = Button(parent, text = "Red", fg = "red")
redbutton.pack( side = LEFT)
greenbutton = Button(parent, text = "Black", fg = "black")
greenbutton.pack( side = RIGHT )
bluebutton = Button(parent, text = "Blue", fg = "blue")
bluebutton.pack( side = TOP )
blackbutton = Button(parent, text = "Green", fg = "red")
blackbutton.pack( side = BOTTOM)
parent.mainloop()

Output:

Python Tkinter grid() method


The grid() geometry manager organizes the widgets in the tabular form. We can specify the
rows and columns as the options in the method call. We can also specify the column span
(width) or rowspan(height) of a widget.
This is a more organized way to place the widgets to the python application. The syntax to use
the grid() is given below.
Syntax
1. widget.grid(options)
A list of possible options that can be passed inside the grid() method is given below.
o Column
The column number in which the widget is to be placed. The leftmost column is
represented by 0.
o Columnspan
The width of the widget. It represents the number of columns up to which, the column
is expanded.
o ipadx, ipady
It represents the number of pixels to pad the widget inside the widget's border.
o padx, pady
It represents the number of pixels to pad the widget outside the widget's border.
o row
The row number in which the widget is to be placed. The topmost row is represented by
0.
o rowspan
The height of the widget, i.e. the number of the row up to which the widget is expanded.
o Sticky
If the cell is larger than a widget, then sticky is used to specify the position of the
widget inside the cell. It may be the concatenation of the sticky letters representing the
position of the widget. It may be N, E, W, S, NE, NW, NS, EW, ES.
Example
# !/usr/bin/python3
from tkinter import *
parent = Tk()
name = Label(parent,text = "Name").grid(row = 0, column = 0)
e1 = Entry(parent).grid(row = 0, column = 1)
password = Label(parent,text = "Password").grid(row = 1, column = 0)
e2 = Entry(parent).grid(row = 1, column = 1)
submit = Button(parent, text = "Submit").grid(row = 4, column = 0)
parent.mainloop()

Output:

Python Tkinter place() method


The place() geometry manager organizes the widgets to the specific x and y coordinates.
Syntax
1. widget.place(options)
A list of possible options is given below.
o Anchor: It represents the exact position of the widget within the container. The default
value (direction) is NW (the upper left corner)
o bordermode: The default value of the border type is INSIDE that refers to ignore the
parent's inside the border. The other option is OUTSIDE.
o height, width: It refers to the height and width in pixels.
o relheight, relwidth: It is represented as the float between 0.0 and 1.0 indicating the
fraction of the parent's height and width.
o relx, rely: It is represented as the float between 0.0 and 1.0 that is the offset in the
horizontal and vertical direction.
o x, y: It refers to the horizontal and vertical offset in the pixels.

Example
# !/usr/bin/python3
from tkinter import *
top = Tk()
top.geometry("400x250")
name = Label(top, text = "Name").place(x = 30,y = 50)
email = Label(top, text = "Email").place(x = 30, y = 90)
password = Label(top, text = "Password").place(x = 30, y = 130)
e1 = Entry(top).place(x = 80, y = 50)
e2 = Entry(top).place(x = 80, y = 90)
e3 = Entry(top).place(x = 95, y = 130)
top.mainloop()
Output:

Python Tkinter event handling


In programming, an event is something that occurs within an application's environment such
as a mouse click, key press or changes in the GUI. In Python, using the Tkinter GUI package,
we can handle these events by binding them to either pre defined or user-defined functions,
this allows us to run pieces of code when a certain event occurs within a widget.
Basic Tkinter event binding syntax
To bind an event with a function, we can make use of the bind() function that is included in all
widgets. The bind() function takes 2 arguments:
event
A representative string that contains details about which event to listen for, this must be given
in the following format:
"<modifier-type-detail>"
The only required part of this string is the "type" section, this represents the type of event to
listen for, if you leave out the other section it can be written as "<type>".
handler
The name of the function to call when the event occurs. This is only the name of the function,
meaning you cannot include a list of your own arguments.
The function included as the event handler will be passed an event object which includes
details about the event that was triggered, meaning you should include a parameter to be
assigned this object in your function.

As an example, let's assign an event handler to a mouse click event on a label that will print a
message when activated:
from tkinter import *

window = Tk()

def mouseClick( event ):


print( "mouse clicked" )

label = Label( window, text="Click me" )


label.pack()

label.bind( "<Button>", mouseClick )

window.mainloop()
The above code will create a window with a single label with the text "click me", when any of
the mouse buttons are clicked (left click, right click or middle mouse button click) the
mouseClick() function will be called and will print "mouse clicked" to the console.

Event types
There are several event types available with Tkinter, including:

KeyPress: Activated when a keyboard button has been pressed, the Key event can also be
used for this.
KeyRelease : Activated when a keyboard button is released.
Button : Activated when a mouse button has been clicked.
ButtonRelease : Activated when a mouse button has been released.
Motion : Activated when the mouse cursor moves across the designated widget.
Enter : Activated when the mouse cursor enters the designated widget.
Leave : Activated when the mouse cursor leaves the designated widget.
MouseWheel : Activated when the mouse wheel is scrolled.
FocusIn : Activated when the designated widget gains focus through user input such as the
mouse clicking on it.
FocusOut : Activated when the designated widget loses focus.
Configure : Activated when the designated widget's configurations have changes such as its
width being adjusted by the user or its border being adjusted.
Event modifiers
An event modifier can alter the circumstances in which an event's handler is activated, for
example, some modifiers will require another button to be depressed while the event occurs.

Control : Requires that the control button is being pressed while the event is occurring.
Alt : Requires that the alt button is being pressed while the event is occurring.
Shift : Requires that the shift button is being pressed while the event is occurring.
Lock : Requires that caps lock is activated when the event occurs.
Double : Requires that the given event happens twice in quick succession (such as a double
click)
Triple : Requires that the given event happens three times in quick succession
Quadruple : Requires that the given event happens four times in quick succession
As an example, let's create an event handler that only activates on a double click:

label.bind( "<Double-Button>", mouseClick )

Event details
The detail section of the event string allows us to specify a more specific event such as only a
certain key on the keyboard being pressed or only a certain mouse being being pressed.
When using Button or ButtonRelease
We can give a numeric detail from 1 to 5
Which represents the specific mouse button you wish to have the handler trigger from.
When using KeyPress or KeyRelease
We can give the ASCII value of the specific key we wish to trigger the event.
As an example, let's create an event handler that only activates on the double click of the left
mouse button.

label.bind( "<Double-Button-1>", mouseClick )

The event object


The event object that is passed to the handler when the event is triggered can be used to
collect and use information about the event that has occurred. The event object has a number
of useful properties such as:
Keysym : Returns the name of the key (space, e, return) that triggered a keyboard based event
such as KeyPress or KeyRelease
Keycode : Returns the code of the key that triggered a keyboard based event.
Button : Returns the mouse button (1-5) that triggered a mouse based event.
X : Returns the x coordinate of where events such as Button occur.
Y : Returns the y coordinate of where events such as Button occur.
Width : Returns the current width of the widget associated with the event.
Height : Returns the current height of the widget associated with the event.

As an example, let's create an event handler that prints the x and y coordinates of a mouse
click event to the console.
def mouseClick( event ):
print( "mouse clicked at x=" + event.x + " y=" + event.y )
label.bind( "<Button>", mouseClick )

output:
"mouse clicked at x=45 y=23"

Python GUI
Python offers multiple options for developing GUI (Graphical User Interface). Out of all the
GUI methods, tkinter is the most commonly used method. It is a standard Python interface
to the Tk GUI toolkit shipped with Python. Python with tkinter is the fastest and easiest way
to create the GUI applications. Creating a GUI using tkinter is an easy task.
To create a tkinter app:
1. Importing the module – tkinter
2. Create the main window (container)
3. Add any number of widgets to the main window
4. Apply the event Trigger on the widgets.
Importing tkinter is same as importing any other module in the Python code. Note that the
name of the module in Python 2.x is ‘Tkinter’ and in Python 3.x it is ‘tkinter’.
import tkinter
There are two main methods used which the user needs to remember while creating the
Python application with GUI.
1. Tk(screenName=None, baseName=None, className=’Tk’, useTk=1): To create a main
window, tkinter offers a method ‘Tk(screenName=None, baseName=None,
className=’Tk’, useTk=1)’. To change the name of the window, you can change the
className to the desired one. The basic code used to create the main window of the
application is:
1. mainloop(): There is a method known by the name mainloop() is used when your
application is ready to run. mainloop() is an infinite loop used to run the application, wait
for an event to occur and process the event as long as the window is not closed.
m.mainloop()
import tkinter
m = tkinter.Tk()
'''
widgets are added here
'''
m.mainloop()
tkinter also offers access to the geometric configuration of the widgets which can organize
the widgets in the parent windows. There are mainly three geometry manager classes class.
1. pack() method:It organizes the widgets in blocks before placing in the parent widget.
2. grid() method:It organizes the widgets in grid (table-like structure) before placing in the
parent widget.
3. place() method:It organizes the widgets by placing them on specific positions directed by
the programmer.
There are a number of widgets which you can put in your tkinter application. Some of the
major widgets are explained below:
Button:To add a button in your application, this widget is used.
The general syntax is:
w=Button(master, option=value)
master is the parameter used to represent the parent window.
There are number of options which are used to change the format of the Buttons. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 activebackground: to set the background color when button is under the cursor.
 activeforeground: to set the foreground color when button is under the cursor.
 bg: to set he normal background color.
 command: to call a function.
 font: to set the font on the button label.
 image: to set the image on the button.
 width: to set the width of the button.
 height: to set the height of the button.

import tkinter as tk
r = tk.Tk()
r.title('Counting Seconds')
button = tk.Button(r, text='Stop', width=25, command=r.destroy)
button.pack()
r.mainloop()

Canvas: It is used to draw pictures and other complex layout like graphics, text and widgets.
The general syntax is:
w = Canvas(master, option=value)
master is the parameter used to represent the parent window.
There are number of options which are used to change the format of the widget. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 bd: to set the border width in pixels.
 bg: to set the normal background color.
 cursor: to set the cursor used in the canvas.
 highlightcolor: to set the color shown in the focus highlight.
 width: to set the width of the widget.
 height: to set the height of the widget.

from tkinter import *


master = Tk()
w = Canvas(master, width=40, height=60)
w.pack()
canvas_height=20
canvas_width=200
y = int(canvas_height / 2)
w.create_line(0, y, canvas_width, y )
mainloop()

CheckButton: To select any number of options by displaying a number of options to a user


as toggle buttons. The general syntax is:
w = CheckButton(master, option=value)
There are number of options which are used to change the format of this widget. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 Title: To set the title of the widget.
 activebackground: to set the background color when widget is under the cursor.
 activeforeground: to set the foreground color when widget is under the cursor.
 bg: to set he normal backgrouSteganography
Break
Secret Code:
Attach a File:nd color.
 command: to call a function.
 font: to set the font on the button label.
 image: to set the image on the widget.

from tkinter import *


master = Tk()
var1 = IntVar()
Checkbutton(master, text='male', variable=var1).grid(row=0, sticky=W)
var2 = IntVar()
Checkbutton(master, text='female', variable=var2).grid(row=1, sticky=W)
mainloop()

Entry:It is used to input the single line text entry from the user.. For multi-line text input, Text
widget is used.
The general syntax is:
w=Entry(master, option=value)
master is the parameter used to represent the parent window.
There are number of options which are used to change the format of the widget. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 bd: to set the border width in pixels.
 bg: to set the normal background color.
 cursor: to set the cursor used.
 command: to call a function.
 highlightcolor: to set the color shown in the focus highlight.
 width: to set the width of the button.
 height: to set the height of the button.

from tkinter import *


master = Tk()
Label(master, text='First Name').grid(row=0)
Label(master, text='Last Name').grid(row=1)
e1 = Entry(master)
e2 = Entry(master)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
mainloop()

Frame: It acts as a container to hold the widgets. It is used for grouping and organizing the
widgets. The general syntax is:
w = Frame(master, option=value)
master is the parameter used to represent the parent window.
There are number of options which are used to change the format of the widget. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 highlightcolor: To set the color of the focus highlight when widget has to be focused.
 bd: to set the border width in pixels.
 bg: to set the normal background color.
 cursor: to set the cursor used.
 width: to set the width of the widget.
 height: to set the height of the widget.

from tkinter import *

root = Tk()
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
redbutton = Button(frame, text = 'Red', fg ='red')
redbutton.pack( side = LEFT)
greenbutton = Button(frame, text = 'Brown', fg='brown')
greenbutton.pack( side = LEFT )
bluebutton = Button(frame, text ='Blue', fg ='blue')
bluebutton.pack( side = LEFT )
blackbutton = Button(bottomframe, text ='Black', fg ='black')
blackbutton.pack( side = BOTTOM)
root.mainloop()
Label: It refers to the display box where you can put any text or image which can be updated
any time as per the code.
The general syntax is:
w=Label(master, option=value)
master is the parameter used to represent the parent window.
There are number of options which are used to change the format of the widget. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 bg: to set he normal background color.
 bg to set he normal background color.
 command: to call a function.
 font: to set the font on the button label.
 image: to set the image on the button.
 width: to set the width of the button.
 height” to set the height of the button.

from tkinter import *


root = Tk()
w = Label(root, text='GeeksForGeeks.org!')
w.pack()
root.mainloop()

Listbox: It offers a list to the user from which the user can accept any number of options.
The general syntax is:
w = Listbox(master, option=value)
master is the parameter used to represent the parent window.
There are number of options which are used to change the format of the widget. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 highlightcolor: To set the color of the focus highlight when widget has to be focused.
 bg: to set he normal background color.
 bd: to set the border width in pixels.
 font: to set the font on the button label.
 image: to set the image on the widget.
 width: to set the width of the widget.
 height: to set the height of the widget.

from tkinter import *

top = Tk()
Lb = Listbox(top)
Lb.insert(1, 'Python')
Lb.insert(2, 'Java')
Lb.insert(3, 'C++')
Lb.insert(4, 'Any other')
Lb.pack()
top.mainloop()

Text: To edit a multi-line text and format the way it has to be displayed.
The general syntax is:
w =Text(master, option=value)
There are number of options which are used to change the format of the text. Number of
options can be passed as parameters separated by commas. Some of them are listed below.
 highlightcolor: To set the color of the focus highlight when widget has to be focused.
 insertbackground: To set the background of the widget.
 bg: to set he normal background color.
 font: to set the font on the button label.
 image: to set the image on the widget.
 width: to set the width of the widget.
 height: to set the height of the widget.

from tkinter import *


root = Tk()
T = Text(root, height=2, width=30)
T.pack()
T.insert(END, 'Python GUI \nBEST Program\n')
mainloop()

Python API
Python API tutorial, we’ll learn how to retrieve data for data science projects. There are
millions of APIs online which provide access to data. Websites like Reddit, Twitter,
and Facebook all offer certain data through their APIs.
To use an API, you make a request to a remote web server, and retrieve the data you need.
But why use an API instead of a static CSV dataset you can download from the web? APIs are
useful in the following cases:

 The data is changing quickly. An example of this is stock price data. It doesn’t really
make sense to regenerate a dataset and download it every minute — this will take a lot
of bandwidth, and be pretty slow.

 You want a small piece of a much larger set of data. Reddit comments are one
example. What if you want to just pull your own comments on Reddit? It doesn’t make
much sense to download the entire Reddit database, then filter just your own comments.

 There is repeated computation involved. Spotify has an API that can tell you the genre
of a piece of music. You could theoretically create your own classifier, and use it to
compute music categories, but you’ll never have as much data as Spotify does.

What is an API?
An API, or Application Programming Interface, is a server that you can use to retrieve and send
data to using code. APIs are most commonly used to retrieve data, and that will be the focus
of this beginner tutorial.
When we want to receive data from an API, we need to make a request. Requests are used all
over the web. For instance, when you visited this blog post, your web browser made a request
to the Dataquest web server, which responded with the content of this web page.

API requests work in exactly the same way – you make a request to an API server for data,
and it responds to your request.
Making API Requests in Python
In order to work with APIs in Python, we need tools that will make those requests. In Python,
the most common library for making requests and working with APIs is the requests library.
The requests library isn’t part of the standard Python library, so you’ll need to install it to get
started.
If you use pip to manage your Python packages, you can install requests using the following
command:
pip install requests
If you use conda, the command you’ll need is:
conda install requests
Once you’ve installed the library, you’ll need to import it. Let’s start with that important step:
import requests
Now that we’ve installed and imported the requests library, let’s start using it.

Making Our First API Request


There are many different types of requests. The most commonly used one, a GET request, is
used to retrieve data. Because we’ll just be working with retrieving data, our focus will be on
making ‘get’ requests.
When we make a request, the response from the API comes with a response code which tells
us whether our request was successful. Response codes are important because they
immediately tell us if something went wrong.

To make a ‘GET’ request, we’ll use the requests.get() function, which requires one argument
— the URL we want to make the request to. We’ll start by making a request to an API endpoint
that doesn’t exist, so we can see what that response code looks like.
response = requests.get("https://api.open-notify.org/this-api-doesnt-exist")
The get() function returns a response object. We can use the response.status_code attribute to
receive the status code for our request:
print(response.status_code)

404

The ‘404’ status code might be familiar to you — it’s the status code that a server returns if it
can’t find the file we requested. In this case, we asked for this-api-doesnt-exist which (surprise,
surprise) didn’t exist!

API Status Codes


Status codes are returned with every request that is made to a web server. Status codes
indicate information about what happened with a request. Here are some codes that are
relevant to GET requests:

 200: Everything went okay, and the result has been returned (if any).

 301: The server is redirecting you to a different endpoint. This can happen when a
company switches domain names, or an endpoint name is changed.

 400: The server thinks you made a bad request. This can happen when you don’t send
along the right data, among other things.

 401: The server thinks you’re not authenticated. Many APIs require login ccredentials, so
this happens when you don’t send the right credentials to access an API.

 403: The resource you’re trying to access is forbidden: you don’t have the right
permissions to see it.

 404: The resource you tried to access wasn’t found on the server.

 503: The server is not ready to handle the request.

Regular Expressions (Pattern Matching)

A Regular Expression (RegEx) is a sequence of characters that defines a search pattern. For
example,
^a...s$
The above code defines a RegEx pattern. The pattern is: any five letter string starting
with a and ending with s.
A pattern defined using RegEx can be used to match against a string.
Expression String Matched?
abs No match
alias Match
^a...s$ abyss Match
Alias No match
An abacus No match
Python has a module named re to work with RegEx. Here's an example:
import re

pattern = '^a...s$'
test_string = 'abyss'
result = re.match(pattern, test_string)

if result:
print("Search successful.")
else:
print("Search unsuccessful.")
Here, we used re.match() function to search pattern within the test_string. The method returns a
match object if the search is successful. If not, it returns None.
There are other several functions defined in the re module to work with RegEx. Before we
explore that, let's learn about regular expressions themselves.

Specify Pattern Using RegEx


To specify regular expressions, meta characters are used. In the above example, ^ and $ are
meta characters.

MetaCharacters
Metacharacters are characters that are interpreted in a special way by a RegEx engine. Here's
a list of metacharacters:
[] . ^ $ * + ? {} () \ |
[] - Square brackets

Square brackets specifies a set of characters you wish to match.

Expression String Matched?


[abc] a 1 match
ac 2 matches
Hey Jude No match
abc de ca 5 matches
Here, [abc] will match if the string you are trying to match contains any of the a, b or c.
You can also specify a range of characters using - inside square brackets.
 [a-e] is the same as [abcde].
 [1-4] is the same as [1234].
 [0-39] is the same as [01239].
You can complement (invert) the character set by using caret ^ symbol at the start of a square
-bracket.
 [^abc] means any character except a or b or c.
 [^0-9] means any non-digit character.

Period
A period matches any single character (except newline '\n').
Expression String Matched?
.. a No match
ac 1 match
acd 1 match
acde 2 matches (contains 4 characters)
^ - Caret

The caret symbol ^ is used to check if a string starts with a certain character.
Expression String Matched?
^a a 1 match
abc 1 match
bac No match
^ab abc 1 match
acb No match (starts with a but not followed by b)
$ - Dollar

The dollar symbol $ is used to check if a string ends with a certain character.
Expression String Matched?
a$ a 1 match
formula 1 match
cab No match
* - Star

The star symbol * matches zero or more occurrences of the pattern left to it.
Expression String Matched?
ma*n mn 1 match
man 1 match
maaan 1 match
main No match (a is not followed by n)
woman 1 match
+ - Plus
The plus symbol + matches one or more occurrences of the pattern left to it.
Expression String Matched?
ma+n mn No match (no a character)
man 1 match
maaan 1 match
main No match (a is not followed by n)
woman 1 match
? - Question Mark

The question mark symbol ? matches zero or one occurrence of the pattern left to it.
Expression String Matched?
ma?n mn 1 match
man 1 match
maaan No match (more than one a character)
main No match (a is not followed by n)
woman 1 match
{} - Braces

Consider this code: {n,m}. This means at least n, and at most m repetitions of the pattern left to
it.
Expression String Matched?
a{2,3} abc dat No match
abc daat 1 match (at daat)
aabc daaat 2 matches (at aabc and daaat)
aabc daaaat 2 matches (at aabc and daaaat)
Let's try one more example. This RegEx [0-9]{2, 4} matches at least 2 digits but not more than 4
digits
Expression String Matched?
[0-9]{2,4} ab123csde 1 match (match at ab123csde)
12 and 345673 3 matches (12, 3456, 73)
1 and 2 No match
| - Alternation

Vertical bar | is used for alternation (or operator).


Expression String Matched?
a|b cde No match
ade 1 match (match at ade)
acdbea 3 matches (at acdbea)
Here, a|b match any string that contains either a or b
() - Group

Parentheses () is used to group sub-patterns. For example, (a|b|c)xz match any string that
matches either a or b or c followed by xz
Expression String Matched?
(a|b|c)xz ab xz No match
abxz 1 match (match at abxz)
axz cabxz 2 matches (at axzbc cabxz)
\ - Backslash
Backlash \ is used to escape various characters including all metacharacters. For example,
\$a match if a string contains $ followed by a. Here, $ is not interpreted by a RegEx engine in a
special way.
If you are unsure if a character has special meaning or not, you can put \ in front of it. This
makes sure the character is not treated in a special way.

Special Sequences
Special sequences make commonly used patterns easier to write. Here's a list of special
sequences:
\A - Matches if the specified characters are at the start of a string.
Expression String Matched?
\Athe the sun Match
In the sun No match
\b - Matches if the specified characters are at the beginning or end of a word.
Expression String Matched?
\bfoo football Match
a football Match
afootball No match
foo\b the foo Match
the afoo test Match
the afootest No match
\B - Opposite of \b. Matches if the specified characters are not at the beginning or end of a

word.
Expression String Matched?
\Bfoo football No match
a football No match
afootball Match
foo\B the foo No match
the afoo test No match
the afootest Match
\d - Matches any decimal digit. Equivalent to [0-9]
Expression String Matched?
\d 12abc3 3 matches (at 12abc3)
Python No match
\D - Matches any non-decimal digit. Equivalent to [^0-9]
Expression String Matched?
\D 1ab34"50 3 matches (at 1ab34"50)
1345 No match
\s - Matches where a string contains any whitespace character. Equivalent to [ \t\n\r\f\v].
Expression String Matched?
\s Python RegEx 1 match
PythonRegEx No match
\S - Matches where a string contains any non-whitespace character. Equivalent to

[^ \t\n\r\f\v].

Expression String Matched?


\S ab 2 matches (at a b)
No match
\w - Matches any alphanumeric character (digits and alphabets). Equivalent to [a-zA-Z0-9_]. By

the way, underscore _ is also considered an alphanumeric character.


Expression String Matched?
\w 12&": ;c 3 matches (at 12&": ;c)
%"> ! No match
\W - Matches any non-alphanumeric character. Equivalent to [^a-zA-Z0-9_]
Expression String Matched?
\W 1a2%c 1 match (at 1a2%c)
Python No match
\Z - Matches if the specified characters are at the end of a string.
Expression String Matched?
Python\Z I like Python 1 match
I like Python Programming No match
Python is fun. No match
Tip: To build and test regular expressions, you can use RegEx tester tools such as regex101.
This tool not only helps you in creating regular expressions, but it also helps you learn it.
Now you understand the basics of RegEx, let's discuss how to use RegEx in your Python code.

Python RegEx
Python has a module named re to work with regular expressions. To use it, we need to import
the module.
import re
The module defines several functions and constants to work with RegEx.

re.findall()
The re.findall() method returns a list of strings containing all matches.
Example 1: re.findall()

# Program to extract numbers from a string


import re
string = 'hello 12 hi 89. Howdy 34'
pattern = '\d+'
result = re.findall(pattern, string)
print(result)
# Output: ['12', '89', '34']

If the pattern is not found, re.findall() returns an empty list.

re.split()
The re.split method splits the string where there is a match and returns a list of strings where
the splits have occurred.
Example 2: re.split()

import re
string = 'Twelve:12 Eighty nine:89.'
pattern = '\d+'
result = re.split(pattern, string)
print(result)

# Output: ['Twelve:', ' Eighty nine:', '.']


If the pattern is not found, re.split() returns a list containing the original string.
You can pass maxsplit argument to the re.split() method. It's the maximum number of splits that
will occur.

import re

string = 'Twelve:12 Eighty nine:89 Nine:9.'


pattern = '\d+'
# maxsplit = 1
# split only at the first occurrence
result = re.split(pattern, string, 1)
print(result)

# Output: ['Twelve:', ' Eighty nine:89 Nine:9.']


By the way, the default value of maxsplit is 0; meaning all possible splits.
re.sub()
The syntax of re.sub() is:
re.sub(pattern, replace, string)
The method returns a string where matched occurrences are replaced with the content
of replace variable.
Example 3: re.sub()
# Program to remove all whitespaces
import re
# multiline string
string = 'abc 12\
de 23 \n f45 6'
# matches all whitespace characters
pattern = '\s+'
# empty string
replace = ''
new_string = re.sub(pattern, replace, string)
print(new_string)

# Output: abc12de23f456
If the pattern is not found, re.sub() returns the original string.
You can pass count as a fourth parameter to the re.sub() method. If omited, it results to 0. This
will replace all occurrences.

import re

# multiline string
string = 'abc 12\
de 23 \n f45 6'
# matches all whitespace characters
pattern = '\s+'
replace = ''
new_string = re.sub(r'\s+', replace, string, 1)
print(new_string)

# Output:
# abc12de 23
# f45 6
re.subn()

The re.subn() is similar to re.sub() except it returns a tuple of 2 items containing the new string
and the number of substitutions made.
Example 4: re.subn()

# Program to remove all whitespaces


import re

# multiline string
string = 'abc 12\
de 23 \n f45 6'
# matches all whitespace characters
pattern = '\s+'
# empty string
replace = ''
new_string = re.subn(pattern, replace, string)
print(new_string)

# Output: ('abc12de23f456', 4)

re.search()
The re.search() method takes two arguments: a pattern and a string. The method looks for the
first location where the RegEx pattern produces a match with the string.
If the search is successful, re.search() returns a match object; if not, it returns None.
match = re.search(pattern, str)
Example 5: re.search()
import re

string = "Python is fun"


# check if 'Python' is at the beginning
match = re.search('\APython', string)
if match:
print("pattern found inside the string")
else:
print("pattern not found")

# Output: pattern found inside the string


Here, match contains a match object.
Match object
You can get methods and attributes of a match object using dir() function. Some of the
commonly used methods and attributes of match objects are:

match.group()

The group() method returns the part of the string where there is a match.
Example 6: Match object
import re

string = '39801 356, 2102 1111'


# Three digit number followed by space followed by two digit number
pattern = '(\d{3}) (\d{2})'
# match variable contains a Match object.
match = re.search(pattern, string)
if match:
print(match.group())
else:
print("pattern not found")

# Output: 801 35
Here, match variable contains a match object.
Our pattern (\d{3}) (\d{2}) has two subgroups (\d{3}) and (\d{2}). You can get the part of the string
of these parenthesized subgroups. Here's how:
>>> match.group(1)
'801'
>>> match.group(2)
'35'
>>> match.group(1, 2)
('801', '35')
>>> match.groups()
('801', '35')
match.start(), match.end() and match.span()
The start() function returns the index of the start of the matched substring.
Similarly, end() returns the end index of the matched substring.
>>> match.start()
2
>>> match.end()
8
The span() function returns a tuple containing start and end index of the matched part.
>>> match.span()
(2, 8)
match.re and match.string

The re attribute of a matched object returns a regular expression object.


Similarly, string attribute returns the passed string.
>>> match.re
re.compile('(\\d{3}) (\\d{2})')

>>> match.string
'39801 356, 2102 1111'
Using r prefix before RegEx
When r or R prefix is used before a regular expression, it means raw string. For example, '\n' is
a new line whereas r'\n' means two characters: a backslash \ followed by n. Backlash \ is used
to escape various characters including all metacharacters. However, using r prefix
makes \ treat as a normal character.
Example 7: Raw string using r prefix

import re

string = '\n and \r are escape sequences.'

result = re.findall(r'[\n\r]', string)


print(result)

# Output: ['\n', '\r']

Python for database programming


The Python programming language has powerful features for database programming. Python
supports various databases like SQLite, MySQL, Oracle, Sybase, PostgreSQL, etc. Python also
supports Data Definition Language (DDL), Data Manipulation Language (DML) and Data Query
Statements.
There are many good reasons to use Python for programming database applications:

 Programming in Python is arguably more efficient and faster compared to other


languages.

 Python is famous for its portability.

 It is platform independent.

 Python supports SQL cursors.

 In many programming languages, the application developer needs to take care of

the open and closed connections of the database, to avoid further exceptions and

errors. In Python, these connections are taken care of.

 Python supports relational database systems.

 Python database APIs are compatible with various databases, so it is very easy to

migrate and port database application interfaces.

DB-API (SQL-API) for Python


Python DB-API is independent of any database engine, which enables you to write
Python scripts to access any database engine. The Python DB API implementation for MySQL
is MySQLdb. For PostgreSQL, it supports psycopg, PyGresQL and pyPgSQL modules. DB-API
implementations for Oracle are dc_oracle2 and cx_oracle. Pydb2 is the DB-API implementation
for DB2. Python’s DB-API consists of connection objects, cursor objects, standard exceptions
and some other module contents, all of which we will discuss.

Connection objects

Connection objects create a connection with the database and these are further used for

different transactions. These connection objects are also used as representatives of the

database session.

A connection is created as follows:


>>>conn = MySQLdb.connect('library', user='suhas', password='python')

You can use a connection object for calling methods like commit(), rollback() and close() as

shown below:
>>>cur = conn.cursor() //creates new cursor object for executing SQL statements
>>>conn.commit() //Commits the transactions
>>>conn.rollback() //Roll back the transactions
>>>conn.close() //closes the connection
>>>conn.callproc(proc,param) //call stored procedure for execution
>>>conn.getsource(proc) //fetches stored procedure code

Python and MySQL


Python and MySQL are a good combination to develop database applications. After
starting the MySQL service on Linux, you need to acquire MySQLdb, a Python DB-API for
MySQL to perform database operations. You can check whether the MySQLdb module is
installed in your system with the following command:
>>>import MySQLdb
If this command runs successfully, you can now start writing scripts for your database.
To write database applications in Python, there are five steps to follow:
1. Import the SQL interface with the following command:
>>> import MySQLdb
2. Establish a connection with the database with the following command:
>>> conn=MySQLdb.connect(host='localhost',user='root',passwd='')
…where host is the name of your host machine, followed by the username and
password. In case of the root, there is no need to provide a password.
3. Create a cursor for the connection with the following command:
>>>cursor = conn.cursor()
4. Execute any SQL query using this cursor as shown below—here the outputs in terms
of 1L or 2L show a number of rows affected by this query:
5. >>> cursor.execute('Create database Library')
6. 1L // 1L Indicates how many rows affected
7. >>> cursor.execute('use Library')
8. >>>table='create table books(book_accno char(30) primary key, book_name
9. char(50),no_of_copies int(5),price int(5))'
10. >>> cursor.execute(table)
0L
11. Finally, fetch the result set and iterate over this result set. In this step, the user can
fetch the result sets as shown below:
12. >>> cursor.execute('select * from books')
13. 2L
14. >>> cursor.fetchall()
(('Py9098', 'Programming With Python', 100L, 50L), ('Py9099', 'Programming With
Python', 100L, 50L))
In this example, the fetchall() function is used to fetch the result sets.

You might also like