0% found this document useful (0 votes)
3 views251 pages

Advanced Python Programming - Final

Book

Uploaded by

vjay2003
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)
3 views251 pages

Advanced Python Programming - Final

Book

Uploaded by

vjay2003
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

UNIT - 1 OBJECT ORIENTED PROGRAMMING IN PYTHON

Applications: OOPs concepts in Client Server Systems, OO Databases, Simulation and modeling.

OOPs in python: Introduction to Python-Benefits of using python over other programming


languages-Features of Object Oriented Programming system (OOPs) - classes and objects -
Creating a class - the self-variable, types of variables, namespaces – inheritance in python, types
of inheritance – polymorphism – overloading – overriding – data hiding.

1. OBJECT ORIENTED PROGRAMMING IN PYTHON


1.1 Introduction to Python

Python is a popular programming language. It was created by Guido van Rossum, and released in
1991.

It is used for:

• web development (server-side),

• software development,

• mathematics,

• system scripting.

What can Python do?

• Python can be used on a server to create web applications.

• Python can be used alongside software to create workflows.

• Python can connect to database systems. It can also read and modify files.

• Python can be used to handle big data and perform complex mathematics.

• Python can be used for rapid prototyping, or for production-ready software development.

Why Python?

• Python works on different platforms (Windows, Mac, Linux, Raspberry Pi, etc).

• Python has a simple syntax similar to the English language.

1
• Python has syntax that allows developers to write programs with fewer lines than some
other programming languages.

• Python runs on an interpreter system, meaning that code can be executed as soon as it is
written. This means that prototyping can be very quick.

• Python can be treated in a procedural way, an object-oriented way or a functional way.

Python Syntax compared to other programming languages

• Python was designed for readability, and has some similarities to the English language with
influence from mathematics.

• Python uses new lines to complete a command, as opposed to other programming


languages which often use semicolons or parentheses.

• Python relies on indentation, using whitespace, to define scope; such as the scope of loops,
functions and classes. Other programming languages often use curly-brackets for this
purpose.

Example:

print("Hello, World!")

1.2. Benefits of using python over other programming languages:

Python has emerged as one of the most popular programming languages in recent years, and for
good reason. Its simplicity, versatility, and extensive ecosystem make it a top choice for developers
across various industries. This essay explores the benefits of Python compared to other
programming languages, focusing on its features, usability, and applications.

Simplicity and Readability

One of Python’s most significant advantages is its simplicity. Designed with readability in mind,
Python uses straightforward syntax that closely resembles natural language. This feature reduces
the learning curve for beginners and allows experienced developers to write clear and concise
code. For instance, tasks that might require multiple lines of code in languages like Java or C++
can often be accomplished with a single line in Python. This simplicity fosters a more efficient
development process and minimizes the likelihood of errors.

Versatility

Python is a general-purpose language, meaning it can be used for a wide range of applications.
Whether you're building web applications, analyzing data, developing machine learning models,
or automating tasks, Python provides the tools needed to get the job done. Its extensive standard

2
library and the availability of third-party packages through the Python Package Index (PyPI) make
it a one-stop solution for many programming needs.

Extensive Ecosystem and Libraries

Python’s ecosystem is one of its strongest assets. Developers have access to a vast array of libraries
and frameworks that simplify complex tasks. For instance:

• Data Science and Machine Learning: Libraries like NumPy, pandas, and scikit-learn are
staples for data analysis and machine learning.

• Web Development: Frameworks such as Django and Flask enable rapid web application
development.

• Automation: Tools like Selenium and PyAutoGUI help automate repetitive tasks.

• Scientific Computing: SciPy and Matplotlib support scientific research and visualization.

• Artificial Intelligence: TensorFlow and PyTorch are leading frameworks for AI


development.

This ecosystem reduces the need to write code from scratch, allowing developers to focus on
solving problems rather than reinventing the wheel.

Cross-Platform Compatibility

Python is a cross-platform language, meaning it can run on various operating systems, including
Windows, macOS, and Linux, without modification. This flexibility simplifies development and
deployment processes, particularly for applications intended for diverse user bases.

Community Support

Python boasts a large and active community of developers who contribute to its growth and
improvement. This community support ensures that Python remains up-to-date with the latest
technological advancements. Additionally, the community provides extensive documentation,
tutorials, and forums, making it easier for newcomers to learn the language and for experienced
developers to find solutions to specific problems.

Rapid Development and Prototyping

Python’s simplicity and extensive library support make it ideal for rapid development and
prototyping. Developers can quickly build and test ideas, allowing for iterative improvements and
faster time-to-market. This agility is particularly valuable in industries like technology and
startups, where innovation and speed are crucial.

3
Integration Capabilities

Python excels at integrating with other technologies and languages. Its interoperability allows
developers to call libraries and functions written in languages like C, C++, and Java. This feature
is particularly useful for leveraging existing codebases or optimizing performance-critical
components of an application.

Scalability and Performance

Although Python is not as fast as compiled languages like C++ or Java, it compensates with its
scalability and ability to handle large and complex projects. Many companies, including Google,
Netflix, and Instagram, use Python for various applications, proving its capability to manage high-
performance and scalable systems. Moreover, tools like Cython and JIT compilers such as PyPy
can enhance Python’s performance when necessary.

Ease of Learning and Teaching

Python is often the language of choice for teaching programming due to its straightforward syntax
and readability. Educational institutions and online learning platforms frequently use Python to
introduce coding concepts. Its accessibility lowers barriers for beginners, encouraging more people
to enter the field of programming.

Strong Support for Emerging Technologies

Python’s adaptability has made it a leading language for emerging technologies such as artificial
intelligence, machine learning, and data science. Its frameworks and libraries are designed to
handle the computational and analytical demands of these fields, enabling developers to build
innovative solutions. For example, TensorFlow and Keras simplify neural network development,
while pandas and NumPy facilitate data manipulation and analysis.

Cost-Effectiveness

Python is open-source, meaning it is free to use, distribute, and modify. This cost-effectiveness
makes it an attractive option for startups, educational institutions, and independent developers.
Additionally, its extensive library support reduces development time and costs by minimizing the
need for custom solutions.

Global Adoption and Industry Usage

Python’s widespread adoption across industries underscores its versatility and reliability. It is used
in:

• Finance: For quantitative analysis, risk management, and algorithmic trading.

• Healthcare: In medical imaging, diagnostics, and health monitoring systems.

4
• Entertainment: To develop gaming applications, animations, and visual effects.

• Technology: For backend development, system scripting, and cloud computing.

The language’s universal appeal ensures its relevance in the ever-evolving tech landscape.

Comparison with Other Languages

While Python offers numerous benefits, it’s essential to compare it with other popular
programming languages to understand its unique position:

• Java: Java is known for its performance and scalability, particularly in enterprise
environments. However, its verbose syntax can make development slower compared to
Python’s concise and readable code.

• C++: C++ provides unparalleled control over system resources, making it ideal for
performance-critical applications like game development and embedded systems. Python,
on the other hand, prioritizes ease of use and rapid development.

• JavaScript: While JavaScript dominates web development, Python’s versatility allows it


to excel in fields beyond the web, such as data science and AI.

• R: R is tailored for statistical computing and data visualization, but Python’s broader
applicability and strong libraries for data analysis make it a more versatile choice.

Limitations and Considerations

Despite its advantages, Python has some limitations. Its slower execution speed compared to
compiled languages can be a drawback for performance-critical applications. Additionally, its
memory consumption may not be ideal for resource-constrained systems. However, these
limitations are often mitigated by Python’s extensive ecosystem and the availability of tools to
optimize performance.

1.3. Features of Object Oriented Programming system (OOPs)

What is OOPS?

Object-Oriented Programming (OOP) is a programming model that uses classes and objects. It’s
utilized to break down a software program into reusable code blueprints (called classes) that you
may use to build specific instances of things. Object-oriented programming languages include
JavaScript, C++, Java, and Python, to name a few.

Individual objects are created using class templates as a blueprint. For example, MyCar and
goldenRetriever are two particular instances of the abstract class. The attributes specified in the
class may have unique values for each object.

5
A class is a generic template that you may use to create more specialized, concrete things. Classes
are commonly used to indicate large groupings with similar characteristics. Classes may also have
functions known as methods that are exclusively accessible to objects of that kind. These functions
are specified inside the class and execute an action beneficial to that particular object type.

Top Features of OOPS

1. Inheritance

In layman’s terms, the attributes that you inherit from your parents are a simple illustration of
inheritance. Classes may inherit characteristics from other classes thanks to inheritance. Parent
classes, in other words, extend properties and behaviors to child classes. Reusability is aided via
inheritance. Prototyping is another name for inheritance in JavaScript. A prototype object serves
as a base from which another object may derive its features and actions. Thus, you may use
multiple prototype object templates to form a prototype chain. Inheritance is passed down from
one generation to the next. parent

6
Consider the application Polygon, which represents several Shapes. We’re expected to make two
distinct sorts of polygons: a Rectangle and a Triangle.

2. Encapsulation

Encapsulation is the process of enclosing all critical information inside an object and only
revealing a subset of it to the outside world. For example, code inside the class template defines
attributes and behaviors.

The data and methods are then enclosed in the object when it is created from the class. Inside a
class, encapsulation conceals the underlying software code implementation and the internal data
of the objects. Encapsulation necessitates designating certain fields as private while others are
made public.

• Methods and attributes only available from other methods in the same class make up the
private/internal interface.

• Methods and attributes that are available from outside the class are known as the public /
external interface.

Encapsulation Demonstration in Real-Time

One of the most practical examples of encapsulation is a school bag. Our books, pencils, and other
items may be kept in our school bag.

The following are some of the advantages of encapsulation:

• Data Hiding: In this case, the user will be unaware of the class’s internal implementation.
Even the user will have no idea how the class stores data in variables. He or she will only
be aware that the values are sent to a setter method and that variables are initialised with
that value.

• Increased Flexibility: Depending on our needs, we may make the variables of the class
read-only or write-only. If you want to make the variables read-only, remove the setter
methods like setName(), setAge(), and so on from the above programme. If you want to
make the variables write-only, remove the get methods like getName(), getAge(), and so
on from the above programme.

• It also promotes reusability and makes it simple to alter to meet new needs.

3. Abstraction

Abstraction refers to the user’s interaction with just a subset of an object’s characteristics and
operations. To access a complicated item, abstraction uses simpler, high-level techniques.

• Simple items are used to show complexity.

7
• Keep complicated information hidden from the user.

Simple classes are used to indicate complexity in abstraction. Encapsulation is an extension of


abstraction.

A Real-Life Example of Abstraction

Abstraction reveals just the most significant facts to the user while hiding the underlying
intricacies. For example, when we ride a bike, we only know how to ride it but not how it works.
We also have no idea how a bike works on the inside.

Advantages of Abstraction

• It simplifies the process of seeing things in their entirety.

• Code duplication is avoided, and reusability is increased.

• Because just the most necessary information is shown to the user, it helps to enhance the
security of an application or software.

4. Polymorphism

Polymorphism refers to the creation of items that have similar behavior. For example, objects may
override common parent behaviors with particular child behaviors through inheritance. Method
overriding and method overloading are two ways that polymorphism enables the same method to
perform various actions.

Examine how Polymorphism and the actual world are interconnected with examples.

Take, for example, your mobile phone. It has the capability of storing your Contacts. Consider the
following scenario: you wish to store two numbers for one individual. You may do this by storing
the second number under the same name as the first.

Consider the following scenario: you wish to store two numbers for the same individual in an
object-oriented language such as Java. Create a function that will accept as arguments two integers
and the name of the individual to some function void createContact that will be defined later (String
name, int number1, int number2).

5. Method Overriding

Method overriding is used in runtime polymorphism. When a child class overrides a parent class’s
method, the child class might offer an alternative implementation.

Consider a family of three, consisting of the father, mother, and son. The father makes the decision
to teach his kid to shoot. As a result, he brings him to the range with his favorite rifle and teaches
him how to aim and fire at targets. The father, on the other hand, is right-handed, while the kid is

8
left-handed. So they each have their own way of handling the pistol! Because of their differing
orientations, the father was concerned that he may not be able to teach his son how to shoot.

The son, on the other hand, was astute and chose to flip his father’s hands, putting his dominant
hand on the trigger rather than the father’s. Specifically, the right hand. By significantly changing
the learning process, the son was able to grasp the skill of shooting!

Method overriding is the term used in programming to describe this idea.

6. Method Overloading

Method overloading is used in Compile Time Polymorphism. Although two methods or functions
may have the same name, the number of arguments given into the method call may vary. Therefore,
depending on the number of parameters entered, you may obtain different results.

With the help of a simple example, it may be comprehended in simple words. A class addition
contains two add() methods, one with arguments int a and int b and the other with three integer
parameters, int a, int b, and int c. As a result, the add() function is considered overloaded.

The amount of arguments given in the method calling statement determines which method is
performed. For example, add(20,30) calls the two-parameter add() function, whereas
add(10,20,30) calls the three-parameter add method

7. Objects

An object is a self-contained segment with the attributes and processes needed to make data usable
in programming terms. From an object-oriented perspective, objects are the main building pieces
of programs. In each application you create, you may employ a variety of objects of various sorts.
Each kind of object is derived from a specific class of that type. Consider an object to be a sculpt
of the real-world perceptions, processes, or objects that are important to the application you’re
designing.

A variable, function, or data structure may all be considered an object. The term “object” in object-
oriented programming refers to a specific instance of a class. Objects are used in software
development to combine data components with methods that alter them, allowing for the usage of
abstract data structures. Objects in object-oriented programming are answers to the idea of
inheritance, resulting in improved program dependability, simpler software maintenance, library
administration, and task division in programmer teams. Of basic terms, “Objects” are the
fundamental data types in object-oriented programming languages and are used to build object-
oriented programming.

8. Classes

In the oops concept, a class is a construct that is used to describe an individual type. The class is
instantiated into instances of itself – referred to as class instances or simply objects. A class defines
9
ingredient members that allow its instances to have position and behavior. Member variables or
instance variables facilitate a class instance to maintain its position. On the other hand, other kinds
of members, especially methods, allow the behavior of class instances. Simply classes
consequently define the type of their instances. A class usually represents a person, place or thing,
or something.

For example, a “Bird” class would symbolize the properties and functionality of birds. A single,
particular bird would be an instance of the “Bird” class, an object of the type “Bird”. There is a set
of access specifiers in classes. private (or class-private) specifiers restrict the entrance to the class
itself. Only the methods that are elements of a similar class only can access private members.
protected (or class-protected) specifies enables the class itself and all classes under it (sub-classes)
to access the member and public means that member can be accessed by its name using any code.

9. Constructors and Destructors

Constructors in most object-oriented languages have the same name as the class and are public.
Constructors may be overloaded, which means that multiple argument lists can be used with the
same name. The function Object() { [native code] } in PHP 5.0 is the function _construct ().
Normally, attribute values would be initialised in a function Object() { [native code] }. The
_destruct() method is optional, although it might be used to implement code that cleans up once
an object is destroyed, such as shutting files or database connections.

OOP Advantages

• Complex things are modeled as repeatable, basic structures in OOP.

• Thus, OOP objects are reusable and may be utilized in several applications.

• Modularity for easier troubleshooting.

• Classes are easier to debug since they generally include all relevant information.

• Reuse of code through inheritance.

[Link] and objects

1.4.1. Class:

A class is a user-defined data type. It consists of data members and member functions, which can
be accessed and used by creating an instance of that class. It represents the set of properties or
methods that are common to all objects of one type. A class is like a blueprint for an object.

For Example: Consider the Class of Cars. There may be many cars with different names and
brands but all of them will share some common properties like all of them will have 4 wheels,

10
Speed Limit, Mileage range, etc. So here, Car is the class, and wheels, speed limits, mileage are
their properties.

1.4.2. Object:

It is a basic unit of Object-Oriented Programming and represents the real-life entities. An Object
is an instance of a Class. When a class is defined, no memory is allocated but when it is instantiated
(i.e. an object is created) memory is allocated. An object has an identity, state, and behavior. Each
object contains data and code to manipulate the data. Objects can interact without having to know
details of each other’s data or code, it is sufficient to know the type of message accepted and type
of response returned by the objects.

For example “Dog” is a real-life Object, which has some characteristics like color, Breed, Bark,
Sleep, and Eats.

Creating a class in python:


Python is a multiparadigm programming language that supports object-oriented programming
(OOP) through classes that you can define with the class keyword. You can think of a class as a
piece of code that specifies the data and behavior that represent and model a particular type of
object.

What is a class in Python? A common analogy is that a class is like the blueprint for a house. You
can use the blueprint to create several houses and even a complete neighborhood. Each concrete
house is an object or instance that’s derived from the blueprint.

Each instance can have its own properties, such as color, owner, and interior design. These
properties carry what’s commonly known as the object’s state. Instances can also have different
behaviors, such as locking the doors and windows, opening the garage door, turning the lights on
and off, watering the garden, and more.

In OOP, you commonly use the term attributes to refer to the properties or data associated with a
specific object of a given class. In Python, attributes are variables defined inside a class with the
purpose of storing all the required data for the class to work.

11
Similarly, you’ll use the term methods to refer to the different behaviors that objects will show.
Methods are functions that you define within a class. These functions typically operate on or with
the attributes of the underlying instance or class. Attributes and methods are collectively referred
to as members of a class or object.

You can write classes to model the real world. These classes will help you better organize your
code and solve complex programming problems.

For example, you can use classes to create objects that emulate people, animals, vehicles, books,
buildings, cars, or other objects. You can also model virtual objects, such as a web server, directory
tree, chatbot, file manager, and more.

Finally, you can use classes to build class hierarchies. This way, you’ll promote code reuse and
remove repetition throughout your codebase.

Defining a Class in Python

To define a class, you need to use the class keyword followed by the class name and a colon, just
like you’d do for other compound statements in Python. Then you must define the class body,
which will start at the next indentation level:

Python Syntax

class ClassName:

<body>

In a class’s body, you can define attributes and methods as needed. As you already learned,
attributes are variables that hold the class data, while methods are functions that provide behavior
and typically act on the class data.

As an example of how to define attributes and methods, say that you need a Circle class to model
different circles in a drawing application. Initially, your class will have a single attribute to hold
the radius. It’ll also have a method to calculate the circle’s area:

[Link]

import math

class Circle:

def __init__(self, radius):

[Link] = radius

def calculate_area(self):

12
return [Link] * [Link] ** 2

In this code snippet, you define Circle using the class keyword. Inside the class, you write two
methods. The .__init__() method has a special meaning in Python classes. This method is known
as the object initializer because it defines and sets the initial values for the object’s attributes.
You’ll learn more about this method in the Instance Attributes section.

The second method of Circle is conveniently named .calculate_area() and will compute the area
of a specific circle by using its radius. In this example, you’ve used the math module to access
the pi constant as it’s defined in that module.

Creating Objects From a Class in Python

The action of creating concrete objects from an existing class is known as instantiation. With
every instantiation, you create a new object of the target class.

>>> from circle import Circle

>>> circle_1 = Circle(42)

>>> circle_2 = Circle(7)

>>> circle_1

<__main__.Circle object at 0x102b835d0>

>>> circle_2

<__main__.Circle object at 0x1035e3910>

To create an object of a Python class like Circle, you must call the Circle() class constructor with
a pair of parentheses and a set of appropriate arguments. What arguments? In Python, the class
constructor accepts the same arguments as the .__init__() method. In this example, the Circle class
expects the radius argument.

Calling the class constructor with different argument values will allow you to create different
objects or instances of the target class. In the above example, circle_1 and circle_2 are separate
instances of Circle. In other words, they’re two different and concrete circles, as you can conclude
from the code’s output.

Accessing Attributes and Methods

In Python, you can access the attributes and methods of an object by using dot notation with
the dot operator. The following snippet of code shows the required syntax:

Python Syntax

13
obj.attribute_name

obj.method_name()

Note that the dot (.) in this syntax basically means give me the following attribute or method from
this object. The first line returns the value stored in the target attribute, while the second line
accesses the target method and calls it.

the self-variable in Python:


Python self variable is used to bind the instance of the class to the instance method. We have to
explicitly declare it as the first method argument to access the instance variables and methods.
This variable is used only with the instance methods.

Example:

class Dog:

def __init__(self, breed):

[Link] = breed

def bark(self):

print(f'{[Link]} is barking.')

d = Dog('Labrador')

[Link]()

Output: Labrador is barking.

• The __init__() function is defined with two variables but when we are creating the Dog
instance, we have to provide only one argument. The “self” is automatically assigned to
the newly created instance of Dog class.

• The bark() method has only one argument – “self” – which gets bind to the Dog instance
that calls this method. That’s why we are not passing any argument when calling the bark()
method.

• If we have to access any instance variable in the function, we can use the dot operator.

Types of variables:
What are Variables in Python

14
Variables in Python are used to store and manage data values in your program. A variable in
Python is created by assigning a value to a name, and this value can be changed or used later in
the code. With variables in Python, you can work with different data types in Python, such
as numbers, strings, or lists, making your code more flexible and efficient.

• A variable is a named memory location in which a value is stored.

• Variables are used to store information that will be needed during the program.

• In Python, you do not need to define a variable before using it.

• When you assign a value to a variable, it is created.

• You can change a variable's value at any moment. This will override its previous value.

Python Variable Naming Conventions


When working with variables in Python, it’s essential to follow proper naming conventions to
make your code readable and maintainable. Here are some key rules for naming variables in
Python

1. Variable names should start with a letter (a-z, A-Z) or an underscore (_), followed by
letters, numbers, or underscores.

2. Variables in Python are case-sensitive, meaning myVariable and myvariable are


considered different.

3. Avoid using Python keywords or built-in function names (like print, input, etc.) as variable
names in Python.

4. Use descriptive names for variables in Python to make your code easier to understand. For
example, use age instead of x.

5. If a variable in Python consists of multiple words, separate them with


underscores (snake_case), such as student_score.

6. Try to keep variable names in Python short but meaningful, balancing clarity and brevity.
For example, count instead of number_of_items.

Declaration and Initialization of Variables in Python

Let's break down the declaration and initialization of variables in Python step by step:

1. Declaration of Variables in Python

15
In Python, you don’t need to explicitly declare a variable in Python before using it. You simply
create a variable in Python by assigning a value to it. This is different from other programming
languages, where you usually declare a variable before using it.

Example

age = 25

name = "John"

In the example above, age and name are the variables in Python, and they are automatically
declared when assigned the values 25 and "John", respectively.

2. Initialization of Variables in Python

Initialization means giving a value to a variable in Python at the time of its creation. When you
assign a value to a variable in Python, you are initializing it.

Example

height = 5.9

is_student = True

Here, height is initialized with the value 5.9, and is_student is initialized with the boolean
value True.

3. Assigning Values to Variables in Python

You assign values to variables in Python using the assignment operator =. The value can be of any
data type, such as integers, strings, floats, or booleans.

Example

score = 90 # Integer value

greeting = "Hello, World!" # String value

temperature = 98.6 # Float value

is_active = False # Boolean value

The variable score is assigned an integer value of 90, the greeting gets a string"Hello, World!"
the temperature gets a float value of 98.6, and is_active is set to False.

4. No Explicit Declaration in Python

16
Unlike some other languages, you don't have to specify the data type of a variable in
Python explicitly. Python automatically understands the type based on the value assigned to
the variables in Python.

Example

number = 10 # Python understands this as an integer

name = "Aman" # Python understands this as a string

Here, Python automatically detects that number is an integer and name is a string based on the
assigned values.

Example of Declaration and Initialization of Variables in Python Compiler

Let's run this code in the Python Compiler:

# Declare a variable named 'age'

age = 25

# Declare a variable named 'name'

name = "Ram"

# Print the values of the variables 'age' and 'name'

print("My name is", name, "and I am", age, "years old.")

Run Code >>

Output

My name is Ram and I am 25 years old.

Explanation

• In the above example, The code declares two variables in Python: age is assigned the
value 25 and name is assigned the string "Ram".

• The print() function is used to display the values of these variables in Python, printing the
sentence: "My name is Ram and I am 25 years old."

How do you work with Variables in Python?

When you're building a program, variables in Python are used in many smart ways to store, update,
and check values. Let’s go through the most common types of variable use in real programs:

17
1. Expressions with Variables in Python

Expressions are small formulas in coding that are used to perform calculations. These calculations
are done using numbers, operators, and variables in Python.

a = 10

b = 20

result = a + b

print(result)

Try it Yourself >>

Explanation

• Here, we declare two variables in Python, a and b, and assign them values.

• We create a new variable in Python called result to store the sum of a and b.

Output:

30

2. Counting Things (Counters)

A counter is a variable in Python that increases step by step. It is commonly used inside loops.

count = 0

for i in range(5):

count += 1

print("Count is:", count)

Try it Yourself >>

Explanation

• We use a variable in Python called count and set it to 0 before the loop starts.

• Each time the loop runs, the count variable in Python increases by 1.

Output:

Count is: 5

18
3. Adding Repeated Values (Accumulators)

Accumulators are variables in Python used to collect a running total of values inside loops.

total = 0

for num in [5, 10, 15]:

total += num

print("Total sum is:", total)

Try it Yourself >>

Explanation

• We declare a variable in Python named total to store the sum of numbers.

• Inside the loop, we use the total variable in Python to keep adding each number from the
list.

Output:

Total sum is: 30

4. Using Temporary Variables

A temporary variable in Python holds data temporarily while values are being swapped or
changed.

x=5

y = 10

temp = x

x=y

y = temp

print("x =", x)

print("y =", y)

Try it Yourself >>

Explanation

• The temp variable in Python holds the value of x temporarily.

19
• We then safely assign new values to x and y using temp.

Output:

x = 10

y=5

5. True/False Checking (Boolean Flags)

A boolean flag is a variable in Python that tells us if something is true or false.

found = False

for item in [1, 2, 3]:

if item == 2:

found = True

print("Found 2?", found)

Try it Yourself >>

Explanation

• We use a found variable in Python to check if number 2 is in the list.

• If the item is found, we set the found variable in Python to True.

Output:

Found 2? True

6. Loop Helper Variables

Loop helper variables in Python help you repeat actions for multiple items in a list.

for fruit in ["apple", "banana", "cherry"]:

print(fruit)

Try it Yourself >>

Explanation

• The variable in Python fruit changes on every loop to show each item in the list.

• This variable helps you work with each value one at a time using simple code.

20
Output:

apple

banana

cherry

7. Data Storage Using Variables in Python

You can use variables in Python to store and manage big data using lists and dictionaries.

students = ["Aman", "Riya"]

marks = {"Aman": 90, "Riya": 85}

print("Students:", students)

print("Marks:", marks)

Try it Yourself >>

Explanation

• We use two variables in Python to store student names and their marks.

• Lists and dictionaries are useful variables in Python for storing related data.

Output:

Students: ['Aman', 'Riya']

Marks: {'Aman': 90, 'Riya': 85}

Understanding the Main Features of Variables in Python

When we talk about variables in Python, we are discussing the basic building blocks of any Python
program. These variables in Python help us store data, reuse it, and work with it in smart ways.
Unlike other languages, variables in Python are flexible, easy to use, and don't need a fixed data
type. Understanding how variables in Python work will help you write better, cleaner, and more
readable code.

1. How Variables in Python Point to Data Objects

One of the special things about variables in Python is that they store references to data objects
rather than the actual data itself. When you assign a value to a variable in Python, you're not
copying the data; you're pointing to it.

21
Example

x = [1, 2, 3]

y=x

[Link](4)

print(x)

Try it Yourself >>

Output:

[1, 2, 3, 4]

Explanation

• Variables in Python such as x and y both point to the same list object in memory.

• This shows that variables in Python work as references to data, not as separate containers.

2. Why Variables in Python Can Change Their Data Type

Another great feature of variables in Python is that they are dynamically typed. This means you
don't need to declare a data type before using a variable. A variable in Python can first store an
integer and then store a string, all without any errors. This makes variables in Python very flexible
for both beginners and advanced programmers.

Example

data = 100 # data is an integer

data = "hello" # now data is a string

print(data)

Try it Yourself >>

Output:

hello

Explanation:

• Variables in Python do not need a fixed type, which makes them very versatile.

• You can easily reuse the same variable in Python for different types of data as your logic
changes.
22
3. Using Type Hints to Describe Variables in Python

While variables in Python don’t require a declared type, you can still use type hints to make your
code easier to read. Type hints show what kind of data each variable in Python is expected to store.

Example

name: str = "Aman"

age: int = 22

print("My name is", name)

print("I am", age, "years old.")

Try it Yourself >>

Output:

My name is Aman

I am 22 years old.

Explanation

• Using type hints with variables in Python makes it easier for others to read your code.

• Although not required, type hints improve clarity when you use multiple variables in
Python.

Understanding Variable Scopes in Python

Understanding how variables in Python work across different scopes is crucial for writing effective
code. Scope determines where a variable in Python can be accessed and modified. Whether you
are dealing with global, local, or non-local variables in Python, knowing how the scope works
helps avoid errors and unexpected behavior.

1. Global, Local, and Non-Local Variables

In Python, the scope of variables in Python determines where they are accessible. A global variable
in Python can be used anywhere in the code, while a local variable in Python is confined to the
function or block where it’s defined. Non-local variables in Python are used within nested
functions to refer to a variable in the enclosing (but non-global) scope.

Example

23
x = "global"

def outer():

x = "non-local"

def inner():

nonlocal x

x = "local to outer"

inner()

print("Outer x:", x)

outer()

print("Global x:", x)

Try it Yourself >>

Output:

Outer x: local to outer

Global x: global

Explanation:

• This example demonstrates the difference between global, local, and non-local variables in
Python.

• By using the nonlocal keyword, we can modify the variable in Python in the outer function
scope.

2. Class and Instance Variables (Attributes)

In object-oriented programming with Python, variables in Python can be either class variables or
instance variables. Class variables are shared by all instances of a class, while instance variables
are specific to each instance of the class. This distinction helps you manage how data is stored and
accessed in an object-oriented design.

Example

class Student:

school = "ABC School" # class variable

24
def __init__(self, name):

[Link] = name # instance variable

s1 = Student("Ram")

s2 = Student("Shyam")

print([Link], "-", [Link])

print([Link], "-", [Link])

Try it Yourself >>

Output:

Ram - ABC School

Shyam - ABC School

Explanation:

• Variables in Python, like school, are class variables, meaning all instances of the class share
them.

• Variables in Python, such as name, are instance variables, and each instance of the class
will have its own copy.

3. Deleting Variables From Their Scope

In Python, you can use the del keyword to remove variables in Python from their scope. This is
particularly useful when you want to free up memory or ensure that a variable in Python is no
longer accessible. Once a variable in Python is deleted, trying to access it will raise an error.

Example

x = 10

print("Before deleting:", x)

del x

# print(x) # This will give an error if uncommented

Try it Yourself >>

Output:

Before deleting: 10
25
Explanation:

• The del keyword removes a variable in Python from the scope where it is defined.

• After deleting a variable in Python, attempting to use it will result in an error.

Namespaces in Python:
What is namespace:

A namespace is a system that has a unique name for each and every object in Python. An object
might be a variable or a method. Python itself maintains a namespace in the form of a Python
dictionary. Let's go through an example, a directory-file system structure in computers. Needless
to say, that one can have multiple directories having a file with the same name inside every
directory. But one can get directed to the file, one wishes, just by specifying the absolute path to
the file.
Real-time example, the role of a namespace is like a surname. One might not find a single "Alice" in the
class there might be multiple "Alice" but when you particularly ask for "Alice Lee" or "Alice Clark" (with
a surname), there will be only one (time being don't think of both first name and surname are same for
multiple students).
On similar lines, the Python interpreter understands what exact method or variable one is trying
to point to in the code, depending upon the namespace. So, the division of the word itself gives a
little more information. Its Name (which means name, a unique identifier) + Space(which talks
something related to scope). Here, a name might be of any Python method or variable and space
depends upon the location from where is trying to access a variable or a method.

Types of namespaces :

When Python interpreter runs solely without any user-defined modules, methods, classes, etc.
Some functions like print(), id() are always present, these are built-in namespaces. When a user
creates a module, a global namespace gets created, later the creation of local functions creates the
local namespace. The built-in namespace encompasses the global namespace and the global

namespace encompasses the local namespace.

26
The lifetime of a namespace :
A lifetime of a namespace depends upon the scope of objects, if the scope of an object ends, the
lifetime of that namespace comes to an end. Hence, it is not possible to access the inner
namespace's objects from an outer namespace.

Example:

# var1 is in the global namespace

var1 = 5

def some_func():

# var2 is in the local namespace

var2 = 6

def some_inner_func():

# var3 is in the nested local

27
# namespace

var3 = 7

Inheritance in python:
What is Inheritance in Python?

Inheritance is one of the most important features of object-oriented programming languages like
Python. It is used to inherit the properties and behaviours of one class to another. The class that
inherits another class is called a child class and the class that gets inherited is called a base class
or parent class.

If you have to design a new class whose most of the attributes are already well defined in an
existing class, then why redefine them? Inheritance allows capabilities of existing class to be
reused and if required extended to design a new class.

Inheritance comes into picture when a new class possesses 'IS A' relationship with an existing
class. For example, Car IS a vehicle, Bus IS a vehicle, Bike IS also a vehicle. Here, Vehicle is the
parent class, whereas car, bus and bike are the child classes.

28
Creating a Parent Class

The class whose attributes and methods are inherited is called as parent class. It is defined just like
other classes i.e. using the class keyword.

Syntax

The syntax for creating a parent class is shown below −

class ParentClassName:

{class body}

Creating a Child Class

Classes that inherit from base classes are declared similarly to their parent class, however, we need
to provide the name of parent classes within the parentheses.

Syntax

Following is the syntax of child class −

class SubClassName (ParentClass1[, ParentClass2, ...]):

{sub class body}

Types of Inheritance

In Python, inheritance can be divided in five different categories −

• Single Inheritance
29
• Multiple Inheritance

• Multilevel Inheritance

• Hierarchical Inheritance

• Hybrid Inheritance

Single Inheritance:

Single inheritance enables a derived class to inherit properties from a single parent class, thus
enabling code reusability and the addition of new features to existing code.

30
Example:

# Python program to demonstrate

# single inheritance

# Base class

class Parent:

def func1(self):

print("This function is in parent class.")

# Derived class

class Child(Parent):

def func2(self):

print("This function is in child class.")

# Driver's code

object = Child()

object.func1()

object.func2()

Output:

This function is in parent class.

This function is in child class.

Multiple Inheritance:

When a class can be derived from more than one base class this type of inheritance is called
multiple inheritances. In multiple inheritances, all the features of the base classes are inherited into
the derived class.

31
# Python program to demonstrate

# multiple inheritance

# Base class1

class Mother:

mothername = ""

def mother(self):

print([Link])

# Base class2

class Father:

fathername = ""

def father(self):

print([Link])

# Derived class

class Son(Mother, Father):

32
def parents(self):

print("Father :", [Link])

print("Mother :", [Link])

# Driver's code

s1 = Son()

[Link] = "RAM"

[Link] = "SITA"

[Link]()

Output:

Father : RAM

Mother : SITA

Multilevel Inheritance :

In multilevel inheritance, features of the base class and the derived class are further inherited into
the new derived class. This is similar to a relationship representing a child and a grandfather.

33
# Python program to demonstrate

# multilevel inheritance

# Base class

class Grandfather:

def __init__(self, grandfathername):

[Link] = grandfathername

# Intermediate class

class Father(Grandfather):

def __init__(self, fathername, grandfathername):

[Link] = fathername

# invoking constructor of Grandfather class

Grandfather.__init__(self, grandfathername)

# Derived class

class Son(Father):

def __init__(self, sonname, fathername, grandfathername):

[Link] = sonname

# invoking constructor of Father class

Father.__init__(self, fathername, grandfathername)

def print_name(self):

print('Grandfather name :', [Link])

print("Father name :", [Link])

print("Son name :", [Link])

# Driver code

s1 = Son('Prince', 'Rampal', 'Lal mani')

print([Link])

34
s1.print_name()

Output:

Lal mani

Grandfather name : Lal mani

Father name : Rampal

Son name : Prince

Hierarchical Inheritance:

When more than one derived class are created from a single base this type of inheritance is called
hierarchical inheritance. In this program, we have a parent (base) class and two child (derived)
classes.

Example:

# Python program to demonstrate

# Hierarchical inheritance

# Base class

class Parent:

def func1(self):

print("This function is in parent class.")

35
# Derived class1

class Child1(Parent):

def func2(self):

print("This function is in child 1.")

# Derivied class2

class Child2(Parent):

def func3(self):

print("This function is in child 2.")

# Driver's code

object1 = Child1()

object2 = Child2()

object1.func1()

object1.func2()

object2.func1()

object2.func3()

Output:

This function is in parent class.

This function is in child 1.

This function is in parent class.

This function is in child 2.

Hybrid Inheritance:

Inheritance consisting of multiple types of inheritance is called hybrid inheritance.

36
Example:

# Python program to demonstrate

# hybrid inheritance

class School:

def func1(self):

print("This function is in school.")

class Student1(School):

def func2(self):

print("This function is in student 1. ")

class Student2(School):

def func3(self):

print("This function is in student 2.")

class Student3(Student1, School):

37
def func4(self):

print("This function is in student 3.")

# Driver's code

object = Student3()

object.func1()

object.func2()

Output:

This function is in school.

This function is in student 1.

Polymorphism in python:
Polymorphism is a foundational concept in programming that allows entities like functions,
methods or operators to behave differently based on the type of data they are handling. Derived
from Greek, the term literally means "many forms".

Python's dynamic typing and duck typing make it inherently polymorphic. Functions, operators
and even built-in objects like loops exhibit polymorphic behavior.

Polymorphism in Built-in Functions

Python's built-in functions exhibit polymorphism, adapting to various data types.

Example:

print(len("Hello")) # String length

print(len([1, 2, 3])) # List length

print(max(1, 3, 2)) # Maximum of integers

print(max("a", "z", "m")) # Maximum in strings

Polymorphism in Functions

def add(a, b):

return a + b

print(add(3, 4)) # Integer addition

38
print(add("Hello, ", "World!")) # String concatenation

print(add([1, 2], [3, 4])) # List concatenation

Polymorphism in Operators

Operator Overloading

In Python, operators like + behave polymorphically, performing addition, concatenation or


merging based on the data type.

Example:

print(5 + 10) # Integer addition

print("Hello " + "World!") # String concatenation

print([1, 2] + [3, 4]) # List concatenation

Types of Polymorphism

Compile-time Polymorphism

• Found in statically typed languages like Java or C++, where the behavior of a function or
operator is resolved during the program's compilation phase.

• Examples include method overloading and operator overloading, where multiple functions
or operators can share the same name but perform different tasks based on the context.

• In Python, which is dynamically typed, compile-time polymorphism is not natively


supported. Instead, Python uses techniques like dynamic typing and duck typing to achieve
similar flexibility.

Runtime Polymorphism

• Occurs when the behavior of a method is determined at runtime based on the type of the
object.

• In Python, this is achieved through method overriding: a child class can redefine a method
from its parent class to provide its own specific implementation.

• Python's dynamic nature allows it to excel at runtime polymorphism, enabling flexible and
adaptable code.

Example:

class Animal:

39
def so

class Animal:

def sound(self):

return "Some generic sound"

class Dog(Animal):

def sound(self):

return "Bark"

class Cat(Animal):

def sound(self):

return "Meow"

# Polymorphic behavior

animals = [Dog(), Cat(), Animal()]

for animal in animals:

print([Link]()) # Calls the overridden method based on the object type

Output

Bark

Meow

Some generic sound

Explanation: Here, the sound method behaves differently depending on whether the object is a
Dog, Cat or Animal and this decision happens at runtime. This dynamic nature makes Python
particularly powerful for runtime polymorphism.

Inheritance Class Polymorphism

Inheritance-based polymorphism occurs when a subclass overrides a method from its parent class,
providing a specific implementation. This process of re-implementing a method in the child class
is known as Method Overriding.

Example:

class Animal:
40
def sound(self):

return "Some generic animal sound"

class Dog(Animal):

def sound(self):

return "Bark"

class Cat(Animal):

def sound(self):

return "Meow

Explanation:

• Class Animal: Acts as the base (parent) class. Contains a method sound that provides a
default behavior, returning "Some generic animal sound". This serves as a generic
representation of the sound method for all animals.

• Class Dog: Inherits from the Animal class (denoted by class Dog(Animal)). Overrides the
sound method to return "Bark", a behavior specific to dogs. This demonstrates method
overriding, where the subclass modifies the implementation of the parent class’s method.

• Class Cat: Inherits from the Animal class (denoted by class Cat(Animal)). Overrides the
sound method to return "Meow", a behavior specific to cats. Like Dog, this also
demonstrates method overriding.

• Method Overloading:
• Two or more methods have the same name but different numbers of parameters or
different types of parameters, or both. These methods are called overloaded methods and
this is called method overloading.
• Like other languages (for example, method overloading in C++) do, python does not
support method overloading by default. But there are different ways to achieve method
overloading in Python.
• The problem with method overloading in Python is that we may overload the
methods but can only use the latest defined method.
# First product method.

# Takes two argument and print their

# product

def product(a, b):

41
p=a*b

print(p)

# Second product method

# Takes three argument and print their

# product

def product(a, b, c):

p = a * b*c

print(p)

# Uncommenting the below line shows an error

# product(4, 5)

# This line will call the second product method

product(4, 5, 5)

Output

100

In the above code, we have defined two product methods we can only use the second product
method, as python does not support method overloading. We may define many methods of the
same name and different arguments, but we can only use the latest defined method. Calling the
other method will produce an error. Like here calling product(4,5) will produce an error as the
latest defined product method takes three arguments.

Example of Overriding:

class Parent:
def show(self):
print("Inside Parent")

class Child(Parent):
def show(self):
print("Inside Child")

c = Child()
[Link]() # Output: Inside Child

42
• Overriding refers to the ability of a subclass to provide a specific implementation of a
method that is already defined in its superclass. This is a common feature in object-oriented
programming and is fully supported in Python. This allows a method to behave differently
depending on the subclass that implements it.

• Overloading in Python is not supported in the traditional sense where multiple methods
can have the same name but different parameters. However, Python supports operator
overloading and allows methods to handle arguments of different types, effectively
overloading by type checking inside methods.

Does Python Allow Operator Overloading?

Yes, Python allows operator overloading. You can define your own behavior for built-in operators
when they are applied to objects of classes you define. This is done by redefining special methods
in your class, such as __add__ for +, __mul__ for *, etc.

Example of Operator Overloading:

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

def __str__(self):
return f"({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 is __init__ in Python?

The __init__ method in Python is a special method used for initializing newly created objects. It's
called automatically when a new object of a class is created. This method can have arguments
through which you can pass values for initializing object attributes.

Example of __init__:

43
class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age

def greet(self):
print(f"Hello, my name is {[Link]} and I am {[Link]} years old.")

p = Person("John", 30)
[Link]() # Output: Hello, my name is John and I am 30 years old.

What is Data Hiding?

Data hiding is a concept which underlines the hiding of data or information from the user. It is one
of the key aspects of Object-Oriented programming strategies. It includes object details such as
data members, internal work. Data hiding excludes full data entry to class members and defends
object integrity by preventing unintended changes. Data hiding also minimizes system complexity
for increase robustness by limiting interdependencies between software requirements. Data hiding
is also known as information hiding. In class, if we declare the data members as private so that no
other class can access the data members, then it is a process of hiding data.

Data Hiding in Python:

The Python document introduces Data Hiding as isolating the user from a part of program
implementation. Some objects in the module are kept internal, unseen, and unreachable to the user.
Modules in the program are easy enough to understand how to use the application, but the client
cannot know how the application functions. Thus, data hiding imparts security, along with
discarding dependency. Data hiding in Python is the technique to defend access to specific users
in the application. Python is applied in every technical area and has a user-friendly syntax and vast
libraries. Data hiding in Python is performed using the __ double underscore before done prefix.
This makes the class members non-public and isolated from the other classes.

Example:

class Solution:

__privateCounter = 0

def sum(self):

self.__privateCounter += 1

print(self.__privateCounter)

count = Solution()
44
[Link]()

[Link]()

# Here it will show error because it unable

# to access private member

print(count.__privateCount)

Output:

Traceback (most recent call last):

File "/home/[Link]", line 11, in <module>

print(count.__privateCount)

AttributeError: 'Solution' object has no attribute '__privateCount'

Advantages of Data Hiding:

1. It helps to prevent damage or misuse of volatile data by hiding it from the public.

2. The class objects are disconnected from the irrelevant data.

3. It isolates objects as the basic concept of OOP.

4. It increases the security against hackers that are unable to access important data.

Disadvantages of Data Hiding:

1. It enables programmers to write lengthy code to hide important data from common clients.

2. The linkage between the visible and invisible data makes the objects work faster, but data
hiding prevents this linkage.

45
UNIT - 2 THREADS AND ADVANCED FILE OPERATIONS

Applications: Multiprocessing, better resource utilization, rendering graphics.

Threads in python: Difference between process and thread - types of threads - benefits of threads
- creating threads – multithreading – starting a thread - thread synchronization. File operations –
modes of opening a file – seek( ) and tell( ) - working with text file , binary file and CSV file –
preparing a pdf file after data processing.

Threads in python
A thread is a separate flow of execution. This means that your program will have two things
happening at once. But for most Python 3 implementations the different threads do not actually
execute at the same time.

Threading allows you to have different parts of your process run concurrently These different parts
are usually individual and have a separate unit of execution belonging to the same process. The
process is nothing but a running program that has individual units that can be run concurrently.
For example, A web-browser could be a process, an application running multiple cameras
simultaneously could be a process; a video game is another example of a process.

Inside a process comes the concept of multiple threading or commonly known as multi-threading,
where multiple threads work together to achieve a common goal. The most crucial benefit of using
threads is that it allows you to run the program in parallel.

46
Let's understand the concept of threading with the help of an example. Imagine you have an
application which counts the number of cars entering and exiting the mall's parking. Your
apparatus has various cameras that monitor the entry and exit connecting to a central device. Each
camera will have an algorithm to monitor the flow of cars, which will belong to the same process
or program. However, each camera, along with the algorithm it is being run on, could be part of a
separate thread. Not only that, but even the frames being read from the camera and the algorithm
predicting on the frames could also be two separate threads.

There are different types of threads:

• Kernel thread

• User thread

• Combination of kernel and user thread

Advantages of having threading in your program:

• Multi-threading allows the program to speed up the execution provided that it has multiple
CPUs.

• It also lets you perform other tasks while the I/O operations are being performed with the
help of multiple threads or even main thread along with a single thread. For example, the
speed at which the frames from the camera are read and inferred by the algorithm will be
handled by different threads. Hence, the algorithm will not have to wait for the frame to be
inputted, and the frame reading part will not have to wait for the algorithm execution to
complete to be able to read the next frame.

• Threads within the same process can share the memory and resources of the main thread.

Challenges of Threading

• Remember that Python works based on the CPython implementation, which limits only
one thread to be run at a time, hence; threading may not speed up all tasks. And the essential
reason behind this is Global Interpreter Lock (GIL).

If you would like to learn about GIL, then feel free to check out this tutorial.

• If you are looking for speeding up the CPU intensive task, then threading may not be the
best solution for you. In such cases, multi-processing is considered to be useful.

• To execute a program comprising of various threads, it needs to switch quickly across


threads; hence, scheduling needs to be taken care of in programs where you have a lot of
threads.

47
• Resource sharing can also be a problem since all the threads share the same resources and
memory of the global variables. Hence, operations performed in one thread could cause a
memory error for another thread, or the other thread might not get the memory to perform
its task.

Threading in Python

• In Python, the threading module is a built-in module which is known as threading and can
be directly imported.

• Since almost everything in Python is represented as an object, threading also is an object


in Python. A thread is capable of

• Holding data,

• Stored in data structures like dictionaries, lists, sets, etc.

• Can be passed as a parameter to a function.

• A thread can also be executed as a process.

• A thread in Python can have various states like:

• Wait,

• Locked.

Difference between process and thread:

Process Thread

Process means a program in execution. Thread means a segment of a process.

A process takes more time to terminate. A thread takes less time to terminate.

It takes more time for creation. It takes less time for creation.

48
Process Thread

It also takes more time for context


It takes less time for context switching.
switching.

A process is less efficient in terms of Thread is more efficient in terms of


communication. communication.

We don't need multi programs in action for


Multiprogramming holds the concepts of
multiple threads because a single process
multi-process.
consists of multiple threads.

Every process runs in its own memory. Threads share memory.

A process is heavyweight compared to a A Thread is lightweight as each thread in a


thread. process shares code, data, and resources.

Process switching uses an interface in an Thread switching may not require calling
operating system. involvement of operating system.

If one process is blocked, then it will not If a user-level thread is blocked, then all other
affect the execution of other processes. user-level threads are blocked.

Thread has Parents' PCB, its own Thread


A process has its own Process Control
Control Block, and Stack and common
Block, Stack, and Address Space.
Address space.

Changes to the parent process do not affect Since all threads of the same process share
child processes. address space and other resources so any

49
Process Thread

changes to the main thread may affect the


behavior of the other threads of the process.

No system call is involved, it is created


A system call is involved in it.
using APIs.

A process does not share data with


Threads share data with each other
each other.

Creating threads in Python:

1. Creating python threads using class

# import the threading module

import threading

class thread([Link]):

def __init__(self, thread_name, thread_ID):

[Link].__init__(self)

self.thread_name = thread_name

self.thread_ID = thread_ID

# helper function to execute the threads

def run(self):

print(str(self.thread_name) +" "+ str(self.thread_ID));

thread1 = thread("GFG", 1000)

thread2 = thread("GeeksforGeeks", 2000);

[Link]()

50
[Link]()

print("Exit")

Output:

GFG 1000

GeeksforGeeks 2000

Exit

2. Creating python threads using function

from threading import Thread

from time import sleep

# function to create threads

def threaded_function(arg):

for i in range(arg):

print("running")

# wait 1 sec in between each thread

sleep(1)

if __name__ == "__main__":

thread = Thread(target = threaded_function, args = (10, ))

[Link]()

[Link]()

print("thread finished...exiting")

Output:

running

running

running

running

51
running

running

running

running

running

running

thread finished...exiting

Multithreading in Python:
In Python , the threading module provides a very simple and intuitive API for spawning multiple
threads in a program. Let us try to understand multithreading code step-by-step.

Step 1: Import Module

First, import the threading module.

import threading

Step 2: Create a Thread

To create a new thread, we create an object of the Thread class. It takes the 'target' and 'args' as
the parameters. The target is the function to be executed by the thread whereas the args is the
arguments to be passed to the target function.

t1 = [Link](target, args)
t2 = [Link](target, args)

Step 3: Start a Thread

To start a thread, we use the start() method of the Thread class.

[Link]()
[Link]()

Step 4: End the thread Execution

Once the threads start, the current program (you can think of it like a main thread) also keeps on
executing. In order to stop the execution of the current program until a thread is complete, we use
the join() method.

52
[Link]()
[Link]()

As a result, the current program will first wait for the completion of t1 and then t2 . Once, they are
finished, the remaining statements of the current program are executed.

Python ThreadPool

A thread pool is a collection of threads that are created in advance and can be reused to execute
multiple tasks. The [Link] module in Python provides a ThreadPoolExecutor class that
makes it easy to create and manage a thread pool.

In this example, we define a function worker that will run in a thread. We create a
ThreadPoolExecutor with a maximum of 2 worker threads. We then submit two tasks to the pool
using the submit method. The pool manages the execution of the tasks in its worker threads. We
use the shutdown method to wait for all tasks to complete before the main thread continues.

Multithreading can help you make your programs more efficient and responsive. However, it's
important to be careful when working with threads to avoid issues such as race conditions and
deadlocks.

This code uses a thread pool created with [Link] to run two
worker tasks concurrently. The main thread waits for the worker threads to finish
using [Link](wait=True) . This allows for efficient parallel processing of tasks in a
multi-threaded environment.

import [Link]

def worker():

print("Worker thread running")

pool = [Link](max_workers=2)

[Link](worker)

[Link](worker)

[Link](wait=True)

print("Main thread continuing to run")

Output

Worker thread running

Worker thread running

53
Main thread continuing to run

Starting a New Thread

To create and start a new thread in Python, you can use either the low-level _thread module or the
higher-level threading module. The threading module is generally recommended due to its
additional features and ease of use. Below, you can see both approaches.

Starting a New Thread Using the _thread Module

The start_new_thread() method of the _thread module provides a basic way to create and start
new threads. This method provides a fast and efficient way to create new threads in both Linux
and Windows. Following is the syntax of the method −

thread.start_new_thread(function, args[, kwargs] )

This method call returns immediately, and the new thread starts executing the specified function
with the given arguments. When the function returns, the thread terminates.

Example

This example demonstrates how to use the _thread module to create and run threads. Each thread
runs the print_name function with different arguments. The [Link](0.5) call ensures that the
main program waits for the threads to complete their execution before exiting.

Open Compiler

import _thread

import time

def print_name(name, *arg):

print(name, *arg)

name="Tutorialspoint..."

_thread.start_new_thread(print_name, (name, 1))

_thread.start_new_thread(print_name, (name, 1, 2))

[Link](0.5)

When the above code is executed, it produces the following result −

Tutorialspoint... 1

Tutorialspoint... 1 2

54
Although it is very effective for low-level threading, but the _thread module is limited compared
to the threading module, which offers more features and higher-level thread management.

Starting a New Thread Using the Threading Module

The threading module provides the Thread class, which is used to create and manage threads.

Here are a few steps to start a new thread using the threading module −

• Create a function that you want the thread to execute.

• Then create a Thread object using the Thread class by passing the target function and its
arguments.

• Call the start method on the Thread object to begin execution.

• Optionally, call the join method to wait for the thread to complete before proceeding.

Synchronizing Threads
The threading module provided with Python includes a simple-to-implement locking mechanism
that allows you to synchronize threads. A new lock is created by calling the Lock() method, which
returns the new lock.

The acquire(blocking) method of the new lock object is used to force threads to run synchronously.
The optional blocking parameter enables you to control whether the thread waits to acquire the
lock.

If blocking is set to 0, the thread returns immediately with a 0 value if the lock cannot be acquired
and with a 1 if the lock was acquired. If blocking is set to 1, the thread blocks and wait for the lock
to be released.

The release() method of the new lock object is used to release the lock when it is no longer
required.

Multithreaded Priority Queue

The Queue module allows you to create a new queue object that can hold a specific number of
items. There are following methods to control the Queue −

• get() − The get() removes and returns an item from the queue.

• put() − The put adds item to a queue.

• qsize() − The qsize() returns the number of items that are currently in the queue.

• empty() − The empty( ) returns True if queue is empty; otherwise, False.

55
• full() − the full() returns True if queue is full; otherwise, False.

File Handling in Python


File handling refers to the process of performing operations on a file such as creating, opening,
reading, writing and closing it, through a programming interface. It involves managing the data
flow between the program and the file system on the storage device, ensuring that data is handled
safely and efficiently.

Opening a File in Python

To open a file we can use open() function, which requires file path and mode as arguments:

# Open the file and read its contents

with open('[Link]', 'r') as file:

File Modes in Python

When opening a file, we must specify the mode we want to which specifies what we want to do
with the file. Here’s a table of the different modes available:

Mode Description Behavior

Opens the file for reading. File must exist; otherwise,


Read-only mode.
r it raises an error.

Opens the file for reading binary data. File must


Read-only in binary mode.
rb exist; otherwise, it raises an error.

Opens the file for both reading and writing. File must
Read and write mode.
r+ exist; otherwise, it raises an error.

Opens the file for both reading and writing binary


Read and write in binary mode.
rb+ data. File must exist; otherwise, it raises an error.

56
Mode Description Behavior

Opens the file for writing. Creates a new file or


Write mode.
w truncates the existing file.

Opens the file for writing binary data. Creates a new


Write in binary mode.
wb file or truncates the existing file.

Opens the file for both writing and reading. Creates


Write and read mode.
w+ a new file or truncates the existing file.

Opens the file for both writing and reading binary


Write and read in binary mode.
wb+ data. Creates a new file or truncates the existing file.

Opens the file for appending data. Creates a new file


Append mode.
a if it doesn't exist.

Opens the file for appending binary data. Creates a


Append in binary mode.
ab new file if it doesn't exist.

Opens the file for appending and reading. Creates a


Append and read mode.
a+ new file if it doesn't exist.

Append and read in binary Opens the file for appending and reading binary data.
ab+ mode. Creates a new file if it doesn't exist.

Creates a new file. Raises an error if the file already


Exclusive creation mode.
x exists.

57
Mode Description Behavior

Exclusive creation in binary Creates a new binary file. Raises an error if the file
xb mode. already exists.

Exclusive creation with read Creates a new file for reading and writing. Raises an
x+ and write mode. error if the file exists.

Exclusive creation with read Creates a new binary file for reading and writing.
xb+ and write in binary mode. Raises an error if the file exists.

Reading a File

Reading a file can be achieved by [Link]() which reads the entire content of the file. After
reading the file we can close the file using [Link]() which closes the file after reading it, which
is necessary to free up system resources.

file = open("[Link]", "r")

content = [Link]()

print(content)

[Link]()

Output:

Hello world

GeeksforGeeks

123 456

Reading a File in Binary Mode (rb):

file = open("[Link]", "rb")

content = [Link]()

print(content)

58
[Link]()

Output:

b'Hello world\r\nGeeksforGeeks\r\n123 456'

Writing to a File

Writing to a file is done using [Link]() which writes the specified string to the file. If the file
exists, its content is erased. If it doesn't exist, a new file is created.

Example: Writing to a File in Write Mode (w)

file = open("[Link]", "w")

[Link]("Hello, World!")

[Link]()

Writing to a File in Append Mode (a)

It is done using [Link]() which adds the specified string to the end of the file without erasing its
existing content.

Example: For this example, we will use the Python file created in the previous example.

# Python code to illustrate append() mode

file = open('[Link]', 'a')

[Link]("This will add this line")

[Link]()

Closing a File

Closing a file is essential to ensure that all resources used by the file are properly
released. [Link]() method closes the file and ensures that any changes made to the file are saved.

file = open("[Link]", "r")

# Perform file operations

[Link]()

file = open("[Link]", "r")

# Perform file operations

59
[Link]()

Advantages of File Handling in Python

• Versatility : File handling in Python allows us to perform a wide range of operations, such
as creating, reading, writing, appending, renaming and deleting files.

• Flexibility : File handling in Python is highly flexible, as it allows us to work with different
file types (e.g. text files, binary files, CSV files , etc.) and to perform different operations
on files (e.g. read, write, append, etc.).

• User - friendly : Python provides a user-friendly interface for file handling, making it easy
to create, read and manipulate files.

• Cross-platform : Python file-handling functions work across different platforms (e.g.


Windows, Mac, Linux), allowing for seamless integration and compatibility.

Disadvantages of File Handling in Python

• Error-prone: File handling operations in Python can be prone to errors, especially if the
code is not carefully written or if there are issues with the file system (e.g. file permissions,
file locks, etc.).

• Security risks : File handling in Python can also pose security risks, especially if the
program accepts user input that can be used to access or modify sensitive files on the
system.

• Complexity : File handling in Python can be complex, especially when working with more
advanced file formats or operations. Careful attention must be paid to the code to ensure
that files are handled properly and securely.

• Performance : File handling operations in Python can be slower than other programming
languages, especially when dealing with large files or performing complex operations.

Python seek() function

seek() method

In Python, seek() function is used to change the position of the File Handle to a given
specific position. File handle is like a cursor, which defines from where the data has to be
read or written in the file.
Syntax: [Link](offset, from_what), where f is file pointer
Parameters:
Offset: Number of positions to move forward

60
from_what: It defines point of reference.
Returns: Return the new absolute position.

The reference point is selected by the from_what argument. It accepts three values:
0: sets the reference point at the beginning of the file
1: sets the reference point at the current file position
2: sets the reference point at the end of the file
By default from_what argument is set to 0.
Note: Reference point at current position / end of file cannot be set in text mode except
when offset is equal to 0.
Example 1: Let’s suppose we have to read a file named “[Link]” which contains
the following text:
"Code is like humor. When you have to explain it, it’s bad."

# Python program to demonstrate

# seek() method

# Opening "[Link]" text file

f = open("[Link]", "r")

# Second parameter is by default 0

# sets Reference point to twentieth

# index position from the beginning

[Link](20)

# prints current position

print([Link]())

print([Link]())

[Link]()

Output:
20

tell

The seek() function is used to set the position of the file cursor, whereas
the tell() function returns the position where the cursor is set to begin reading.

61
# Opening a file

with open('[Link]', 'r') as file:

# Using tell() function

pos = [Link]()

# Printing the position of the cursor

print(f'File cursor position: {pos}')

# Printing the content

data = [Link]()

print(data)

Output

File cursor position: 0


Python is a high-level, general-purpose programming language. Its design philosophy
emphasizes code readability with the use of significant indentation.

Syntax

tell()

The tell() function takes no parameter.

Examples

As previously stated, we can use the tell() function to return the cursor position set by
the seek() function. To determine the position of the cursor, we’ll experiment with
the seek() function parameter values.

Example 1 – Setting cursor position from the end and printing the cursor position

# Opening a file in binary mode

with open('[Link]', 'rb') as file:

# Setting cursor at the 25th pos from the end

[Link](-25, 2)

# Using tell() function

pos = [Link]()

62
# Printing the position of the cursor

print(f'File cursor position: {pos}')

# Printing the content

data = [Link]()

print(data)

Output

2 File cursor position: 127

b' significant indentation

Difference

Seek() tell()

Used to set the file cursor to the specific position. Used to tell the position of the file cursor.

Takes two parameters: the first is offset and the second Takes no parameter
is whence.

By using seek() function, we can manipulate the reading By using the tell() function, we can only get the
position of the file’s content. position of the file cursor.

Reading and Writing to text files in Python

Python provides built-in functions for creating, writing, and reading files. Two types of files can be
handled in Python, normal text files and binary files (written in binary language, 0s, and 1s).

• Text files: In this type of file, Each line of text is terminated with a special character called
EOL (End of Line), which is the new line character ('\n') in Python by default.

• Binary files: In this type of file, there is no terminator for a line, and the data is stored after
converting it into machine-understandable binary language.

Opening a Text File in Python

It is done using the open() function. No module is required to be imported for this function.

63
File_object = open(r"File_Name","Access_Mode")

# Open function to open the file "[Link]"

# (same directory) in append mode and

file1 = open("[Link]","a")

# store its reference in the variable file1

# and "[Link]" in D:\Text in file2

file2 = open(r"D:\Text\[Link]","w+")

Reading From a File Using read()

read(): Returns the read bytes in form of a string. Reads n bytes, if no n specified, reads the entire
file.

File_object.read([n])

Reading a Text File Using readline()

readline(): Reads a line of the file and returns in form of a [Link] specified n, reads at most n
bytes. However, does not reads more than one line, even if n exceeds the length of the line.

File_object.readline([n])

Reading a File Using readlines()

readlines(): Reads all the lines and return them as each line a string element in a list.

File_object.readlines()

Note: '\n' is treated as a special character of two bytes.

In this example, a file named "[Link]" is created and opened in write mode ( "w" ). Data is
written to the file using write and writelines methods. The file is then reopened in read and append
mode ( "r+" ). Various read operations, including read , readline , readlines , and the use of seek ,
demonstrate different ways to retrieve data from the file. Finally, the file is closed.

file1 = open("[Link]", "w")

L = ["This is Delhi \n", "This is Paris \n", "This is London \n"]

# \n is placed to indicate EOL (End of Line)

[Link]("Hello \n")

64
[Link](L)

[Link]() # to change file access modes

file1 = open("[Link]", "r+")

print("Output of Read function is ")

print([Link]())

print()

# seek(n) takes the file handle to the nth

# byte from the beginning.

[Link](0)

print("Output of Readline function is ")

print([Link]())

print()

[Link](0)

# To show difference between read and readline

print("Output of Read(9) function is ")

print([Link](9))

print()

[Link](0)

print("Output of Readline(9) function is ")

print([Link](9))

[Link](0)

# readlines function

print("Output of Readlines function is ")

print([Link]())

print()

65
[Link]()

Output:

Output of Read function is


Hello
This is Delhi
This is Paris
This is London
Output of Readline function is
Hello
Output of Read(9) function is
Hello
Th
Output of Readline(9) function is
Hello
Output of Readlines function is
['Hello \n', 'This is Delhi \n', 'This is Paris \n', 'This is London \n']

Write to Text File in Python

There are two ways to write in a file:

• Using write()

• Using writelines()

Writing to a Python Text File Using write()

write(): Inserts the string str1 in a single line in the text file.

File_object.write(str1)

file = open("[Link]", "w")

for i in range(3):

name = input("Enter the name of the employee: ")

[Link](name)

[Link]("\n")

[Link]()

print("Data is written into the file.")

66
Output:

Data is written into the file.

Writing to a Text File Using writelines()

writelines(): For a list of string elements, each string is inserted in the text [Link] to insert
multiple strings at a single time.

File_object.writelines(L) for L = [str1, str2, str3]

file1 = open("[Link]", "w")

lst = []

for i in range(3):

name = input("Enter the name of the employee: ")

[Link](name + '\n')

[Link](lst)

[Link]()

print("Data is written into the file.")

file1 = open("[Link]", "w")

lst = []

for i in range(3):

name = input("Enter the name of the employee: ")

[Link](name + '\n')

[Link](lst)

[Link]()

print("Data is written into the file.")

Output:

Data is written into the file.

Appending to a File in Python

67
In this example, a file named "[Link]" is initially opened in write mode ( "w" ) to write lines of
text. The file is then reopened in append mode ( "a" ), and "Today" is added to the existing content.
The output after appending is displayed using readlines . Subsequently, the file is reopened in write
mode, overwriting the content with "Tomorrow". The final output after writing is displayed
using readlines.

file1 = open("[Link]", "w")

L = ["This is Delhi \n", "This is Paris \n", "This is London \n"]

[Link](L)

[Link]()

# Append-adds at last

file1 = open("[Link]", "a") # append mode

[Link]("Today \n")

[Link]()

file1 = open("[Link]", "r")

print("Output of Readlines after appending")

print([Link]())

print()

[Link]()

# Write-Overwrites

file1 = open("[Link]", "w") # write mode

[Link]("Tomorrow \n")

[Link]()

file1 = open("[Link]", "r")

print("Output of Readlines after writing")

print([Link]())

print()

[Link]()
68
Output:

Output of Readlines after appending


['This is Delhi \n', 'This is Paris \n', 'This is London \n', 'Today \n']
Output of Readlines after writing
['Tomorrow \n']

Closing a Text File in Python

Python close() function closes the file and frees the memory space acquired by that file. It is used at
the time when the file is no longer needed or if it is to be opened in a different file mode.
File_object.close()

# Opening and Closing a file "[Link]"

# for object name file1.

file1 = open("[Link]","a")

[Link]()

Reading binary files in Python

Reading binary files means reading data that is stored in a binary format, which is not human-
readable. Unlike text files, which store data as readable characters, binary files store data as raw
bytes. Binary files store data as a sequence of bytes. Each byte can represent a wide range of values,
from simple text characters to more complex data structures like images, videos and executable
programs.

Different Modes for Binary Files in Python

When working with binary files in Python, there are specific modes we can use to open them:

• 'rb': Read binary - Opens the file for reading in binary mode.

• 'wb': Write binary - Opens the file for writing in binary mode.

• 'ab': Append binary - Opens the file for appending in binary mode.

Opening a Binary File

To read a binary file, you need to use Python’s built-in open() function, but with the mode 'rb',
which stands for read binary. The 'rb' mode tells Python that you intend to read the file in binary
format, and it will not try to decode the data into a string (as it would with text files).

file = open("file_name", "rb")

69
After opening the binary file, you can use different methods to read its content.

Using read()

The open() function is used to open files in Python. When dealing with binary files, we need to
specify the mode as 'rb' (read binary) and then use read() to read the binary file.

f = open('[Link]', 'rb')

bin = [Link]()

print(bin)

[Link]()

Output:

b"b'\\x00\\nNotoSanSha\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0
0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\\r\nx00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x
00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00
LWFNGWp1\\'"

Explanation: This code opens a binary file ([Link]) in read binary mode ('rb'). It reads the
entire content of the file into the variable bin as bytes using the read() method. After reading the
content, it prints the binary data. Finally, it closes the file using [Link]() to release system resources.

Using readlines()

By using readlines() method we can read all lines in a file. However, in binary mode, it returns a
list of lines, each ending with a newline byte (b'\n').

with open('[Link]', 'rb') as f:

lines = [Link]()

for i in lines:

print(i)

Output:

b"b'\\x00\\nNotoSanSha\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0
0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\\r\n"
b'x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x
00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00LWFNGWp1\\'

Explanation:

70
• The code opens a binary file ([Link]) in read-binary mode ('rb').

• readlines() reads all lines from the file into a list. Each item in the list is a byte object,
representing a line in the binary file.

• The for loop iterates over each line, printing it as it goes.

Reading Binary File in Chunks

Reading a binary file in chunks is useful when dealing with large files that cannot be read into
memory all at once. This uses read(size) method which reads up to size bytes from the file. If the
size is not specified, it reads until the end of the file.

size = 1024

with open('[Link]', 'rb') as f:

while True:

chunk = [Link](size)

if not chunk:

break

print(chunk)

Output:

b"b'\\x00\\nNotoSanSha\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0
0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\\r\nx00
\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x
00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00LWFNGWp1\\"

Explanation:

• The file [Link] is opened in read-binary mode ('rb').

• The code reads the file in chunks of 1024 bytes using [Link](size).

• The while True loop continues until the file is fully read, breaking when no more data is
available ([Link](size) returns an empty chunk). Each chunk is printed to the console.

Creating PDF Documents With Python:

pip install reportlab

Step-by-step Approach:

71
Step 1:

We start by importing the modules and classes. Canvas is used to draw things on the pdf, ttfonts and
pdfmetrics will help us to use custom TTF fonts in the pdf, and colours would help us to pick
colours easily without remembering their hex values.

# importing modules

from [Link] import canvas

from [Link] import TTFont

from [Link] import pdfmetrics

from [Link] import colors

Step 2:

Next, we initialize all the things we would b writing and drawing in the document to specific
variables to easily call them when needed.

# initializing variables with values

fileName = '[Link]'

documentTitle = 'sample'

title = 'Technology'

subTitle = 'The largest thing now!!'

textLines = [

'Technology makes us aware of',

'the world around us.',

image = '[Link]'

Step 3:

Next, we initialize a canvas object with the name of the pdf and set the title to be the document title.

# creating a pdf object

pdf = [Link](fileName)

72
# setting the title of the document

[Link](documentTitle)

Step 4:

Next, we register our external font to the reportlab fonts using pdfmetrics and TTFont and assigned
it a name. Next, we set the new font with a size. Then we draw the string on the pdf using the
drawCentredString function that takes the x and y values as the centre of the text to the written and
the left, right, top and bottom of the text are adjusted accordingly. Note that we need the TTF file to
be present in the folder to execute the commands.

# registering a external font in python

[Link](

TTFont('abc', '[Link]')

# creating the title by setting it's font

# and putting it on the canvas

[Link]('abc', 36)

[Link](300, 770, title)

Step 5:

Next for the subtitle, we do the same thing except this time the colour of the subtitle be blue, and
this time we use a standard font that ships natively with report lab.

# creating the subtitle by setting it's font,

# colour and putting it on the canvas

[Link](0, 0, 255)

[Link]("Courier-Bold", 24)

[Link](290, 720, subTitle)

Step 6:

Next, we draw a line and then enter several lines of text that we defined earlier inside a list. The first
line defines the starting x and y position of the text. The next two lines set the font, font size and

73
font colour of the text. The next two lines traverse through each element in the list and add it as a
line to the text. The last line draws the text to the screen.

# drawing a line

[Link](30, 710, 550, 710)

# creating a multiline text using

# textline and for loop

text = [Link](40, 680)

[Link]("Courier", 18)

[Link]([Link])

for line in textLines:

[Link](line)

[Link](text)

Step 7:

At last, we draw a picture on the pdf using the drawInlineImage function in which the parameters
are the path of the image and the x and y coordinates of the image. In this case, the image was in the
same directory as the py file, so according to the relative path, we need to write only the name of the
file with the extension, if it was in some other directory, a relevant correct relative path should be
used.

# drawing a image at the

# specified (x.y) position

[Link](image, 130, 400)

# saving the pdf

[Link]()

74
75
UNIT - 3 LAMBDA FUNCTION AND REGULAR EXPRESSION

Applications: Quick data manipulation, less number of lines in coding, flexibility, pattern
matching, word (or) character searching.

Lambda function – syntax - advantages over normal function – difference between lambda and def
- Regular expression - sequence characters in regular expressions - quantifiers in regular
expressions - special characters in regular expressions - using regular expression on files -
retrieving information from a file.

Lambda function in Python:


A lambda function in Python is a small, anonymous function defined using
the lambda keyword. Unlike regular functions defined with def, lambda functions are typically
used for simple, single-expression operations and do not require a name.

Key characteristics of lambda functions:

• Anonymous: They do not have a formal name like functions defined with def.

• Single Expression: They can only contain one expression, the result of which is implicitly
returned. There is no explicit return statement.

• Concise: They offer a compact syntax for defining simple functions inline.

Syntax:

lambda arguments : expression

• lambda: The keyword used to define a lambda function.

• arguments: Zero or more arguments that the lambda function accepts.

• expression: The single expression that the lambda function evaluates and returns.

Example:

# A lambda function to double a number

double = lambda x: x * 2

print(double(5)) # Output: 10

# Using a lambda function with filter to get even numbers

numbers = [1, 2, 3, 4, 5, 6]

even_numbers = list(filter(lambda x: x % 2 == 0, numbers))

76
print(even_numbers) # Output: [2, 4, 6]

Use Cases:

Lambda functions are commonly used in scenarios where a small, throw-away function is needed,
especially as arguments to higher-order functions like:

• map(): Applies a function to each item in an iterable.

• filter(): Constructs an iterator from elements of an iterable for which a function returns
true.

• sorted(): Sorts an iterable using a custom key.

• reduce(): Applies a function of two arguments cumulatively to the items of an iterable


(from the functools module).

Limitations:

While convenient for simple tasks, lambda functions are not suitable for complex logic or functions
requiring multiple statements, as they are restricted to a single expression. For more involved
functions, a traditional def function is preferred.

Advantages Over Normal Function:


Lambda functions, also known as anonymous functions, offer advantages over
traditional def functions, primarily in terms of conciseness, especially for simple, single-
expression operations. They excel when used as arguments to higher-order functions or when
defined inline for immediate use. However, for complex logic or when reusability is
key, def functions are generally preferred.

Advantages of Lambda Functions:


• Conciseness and Readability:

Lambda functions allow for a more compact and streamlined way to define simple functions,
eliminating the need for separate def statements and reducing boilerplate code.

• Inline Usage:

They can be defined and used directly within the context where they are needed, without requiring
a separate function definition. This is particularly useful when passing functions as arguments to
other functions, like filter(), map(), or reduce().

• Functional Programming:

77
Lambda functions are a core feature of functional programming paradigms, enabling operations
on data in a concise and expressive manner.

• Capture Local Variables:

Lambda expressions can capture variables from their enclosing scope, which can be useful when
the function's behavior depends on the surrounding context.

When def Functions are Preferred:

• Complex Logic:

When a function involves multiple statements or more complex logic, a def function is generally
more readable and maintainable.

• Reusability:

If a function is going to be used multiple times or needs a name for clarity and documentation,
a def function is the better choice.

• Docstrings:

def functions can have docstrings, which are essential for documenting the purpose and usage of
the function.

Difference Between Lambda And Def


The main difference between def and lambda in Python lies in their syntax, functionality, and
intended use. def is used to define named functions with a block of code, while lambda creates
anonymous functions with a single expression. def functions can be more complex and reusable,
whereas lambda functions are typically used for short, simple operations, often within higher-order
functions like map and filter.

Here's a more detailed breakdown:

def (Named Functions):

• Syntax: Defined using the def keyword, followed by the function name, parameters in
parentheses, and a colon, with the function body indented below.

• Functionality: Can contain multiple statements, loops, and conditional logic within its
body.

• Return Value: Requires an explicit return statement to specify the output.

• Use Cases: Suitable for complex operations, functions that need to be reused, and
situations where multiple statements are required.
78
• Example:

def add_numbers(x, y):

return x + y

lambda (Anonymous Functions):

• Syntax: Defined using the lambda keyword, followed by parameters, a colon, and a single
expression.

• Functionality: Limited to a single expression, which is automatically returned.

• Return Value: Implicitly returns the value of the expression; no explicit return statement
needed.

• Use Cases: Suitable for short, simple operations, especially when passing functions as
arguments to other functions (e.g., map, filter, sorted).

• Example:

add_numbers = lambda x, y: x + y

Key Differences Summarized:

Feature def lambda

Definition Named function Anonymous function

Syntax def function_name(parameters): ... lambda parameters: expression

Functionality Multiple statements Single expression

Return Explicit return statement Implicit return of expression value

Use Cases Complex, reusable functions Simple, short operations

79
Regular Expression In Python:
A Regular Expression or RegEx is a special sequence of characters that uses a search pattern to
find a string or set of strings.

It can detect the presence or absence of a text by matching it with a particular pattern and also can
split a pattern into one or more sub-patterns.

Regex Module in Python

Python has a built-in module named "re" that is used for regular expressions in Python. We can
import this module by using the import statement.

Example: Importing re module in Python

# importing re module

import re

Example:

This Python code uses regular expressions to search for the word "portal" in the given string and
then prints the start and end indices of the matched word within the string.

import re

s = 'GeeksforGeeks: A computer science portal for geeks'

match = [Link](r'portal', s)

print('Start Index:', [Link]())

print('End Index:', [Link]())

Output

Start Index: 34

End Index: 40

Note: Here r character (r’portal’) stands for raw, not regex. The raw string is slightly different from
a regular string, it won’t interpret the \ character as an escape character. This is because the regular
expression engine uses \ character for its own escaping purpose.

Before starting with the Python regex module let's see how to actually write regex using
metacharacters or special sequences.

RegEx Functions

80
re module contains many functions that help us to search a string for a match.

Let's see various functions provided by this module to work with regex in Python.

Let's see the working of these RegEx functions with definition and examples:

1. [Link]()

Return all non-overlapping matches of pattern in string, as a list of strings. The string is scanned
left-to-right, and matches are returned in the order found.

Finding all occurrences of a pattern

This code uses a regular expression (\d+) to find all the sequences of one or more digits in the
given string. It searches for numeric values and stores them in a list. In this example, it finds and
prints the numbers "123456789" and "987654321" from the input string.

import re

string = """Hello my Number is 123456789 and

my friend's number is 987654321"""

regex = '\d+'

import re

string = """Hello my Number is 123456789 and

my friend's number is 987654321"""

regex = '\d+'

match = [Link](regex, string)

print(match)

Output

['123456789', '987654321']

2. [Link]()

Regular expressions are compiled into pattern objects, which have methods for various operations
such as searching for pattern matches or performing string substitutions.

Example 1:

81
The code uses a regular expression pattern[a-e] to find and list all lowercase letters from 'a' to 'e'
in the input string "Aye, said Mr. Gibenson Stark". The output will be ['e', 'a', 'd', 'b', 'e'],
which are the matching characters.

import re

p = [Link]('[a-e]')

print([Link]("Aye, said Mr. Gibenson Stark"))

Output

['e', 'a', 'd', 'b', 'e', 'a']

Understanding the Output:

• First occurrence is 'e' in "Aye" and not 'A', as it is Case Sensitive.

• Next Occurrence is 'a' in "said", then 'd' in "said", followed by 'b' and 'e' in "Gibenson", the
Last 'a' matches with "Stark".

• Metacharacter backslash '\' has a very important role as it signals various sequences. If the
backslash is to be used without its special meaning as metacharacter, use'\\'

Example 2: Set class [\s,.] will match any whitespace character, ',', or, '.' .

The code uses regular expressions to find and list all single digits and sequences of digits in the
given input strings. It finds single digits with \dand sequences of digits with \d+.

import re

p = [Link]('\d')

print([Link]("I went to him at 11 A.M. on 4th July 1886"))

p = [Link]('\d+')

print([Link]("I went to him at 11 A.M. on 4th July 1886"))

Output

['1', '1', '4', '1', '8', '8', '6']

['11', '4', '1886']

3. [Link]()

82
Split string by the occurrences of a character or a pattern, upon finding that pattern, the remaining
characters from the string are returned as part of the resulting list.

Syntax :

[Link](pattern, string, maxsplit=0, flags=0)

The First parameter, pattern denotes the regular expression, string is the given string in which
pattern will be searched for and in which splitting occurs, maxsplit if not provided is considered
to be zero '0', and if any nonzero value is provided, then at most that many splits occur. If maxsplit
= 1, then the string will split once only, resulting in a list of length 2. The flags are very useful and
can help to shorten code, they are not necessary parameters, eg: flags = [Link], in this
split, the case, i.e. the lowercase or the uppercase will be ignored.

Example 1:

Splits a string using non-word characters and spaces as delimiters, returning words: ['Words',
'words', 'Words']. Considers apostrophes as non-word characters: ['Word', 's', 'words',
'Words']. Splits using non-word characters and digits:['On', '12th', 'Jan', '2016', 'at', '11', '02',
'AM']. Splits using digits as the delimiter: ['On ', 'th Jan ', ', at ', ':', ' AM'].

from re import split

print(split('\W+', 'Words, words , Words'))

print(split('\W+', "Word's words Words"))

print(split('\W+', 'On 12th Jan 2016, at 11:02 AM'))

print(split('\d+', 'On 12th Jan 2016, at 11:02 AM'))

Output

['Words', 'words', 'Words']

['Word', 's', 'words', 'Words']

['On', '12th', 'Jan', '2016', 'at', '11', '02', 'AM']

['On ', 'th Jan ', ', at ', ':', ' AM']

4. [Link]()

The 'sub' in the function stands for SubString, a certain regular expression pattern is searched in
the given string(3rd parameter), and upon finding the substring pattern is replaced by repl(2nd
parameter), count checks and maintains the number of times this occurs.

83
Syntax:

[Link](pattern, repl, string, count=0, flags=0)

Example 1:

• First statement replaces all occurrences of 'ub' with '~*' (case-insensitive): 'S~*ject has
~*er booked already' .

• Second statement replaces all occurrences of 'ub' with '~*' (case-sensitive): 'S~*ject has
Uber booked already' .

• Third statement replaces the first occurrence of 'ub' with '~*' (case-insensitive): 'S~*ject
has Uber booked already' .

• Fourth replaces 'AND' with ' & ' (case-insensitive): 'Baked Beans & Spam' .

import re

print([Link]('ub', '~*', 'Subject has Uber booked already',

flags=[Link]))

print([Link]('ub', '~*', 'Subject has Uber booked already'))

print([Link]('ub', '~*', 'Subject has Uber booked already',

count=1, flags=[Link]))

print([Link](r'\sAND\s', ' & ', 'Baked Beans And Spam',

flags=[Link]))

Output

S~*ject has ~*er booked already

S~*ject has Uber booked already

S~*ject has Uber booked already

Baked Beans & Spam

5. [Link]()

subn() is similar to sub() in all ways, except in its way of providing output. It returns a tuple with
a count of the total of replacement and the new string rather than just the string.

Syntax:
84
[Link](pattern, repl, string, count=0, flags=0)

Example:

[Link]() replaces all occurrences of a pattern in a string and returns a tuple with the modified
string and the count of substitutions made. It's useful for both case-sensitive and case-insensitive
substitutions.

import re

print([Link]('ub', '~*', 'Subject has Uber booked already'))

t = [Link]('ub', '~*', 'Subject has Uber booked already',

flags=[Link])

print(t)

print(len(t))

print(t[0])

Output

('S~*ject has Uber booked already', 1)

('S~*ject has ~*er booked already', 2)

S~*ject has ~*er booked already

6. [Link]()

Returns string with all non-alphanumerics backslashed, this is useful if you want to match an
arbitrary literal string that may have regular expression metacharacters in it.

Syntax:

[Link](string)

Example:

[Link]() is used to escape special characters in a string, making it safe to be used as a pattern
in regular expressions. It ensures that any characters with special meanings in regular expressions
are treated as literal characters.

import re

85
print([Link]("This is Awesome even 1 AM"))

print([Link]("I Asked what is this [a-9], he said \t ^WoW"))

Output

This\ is\ Awesome\ even\ 1\ AM

I\ Asked\ what\ is\ this\ \[a\-9\]\,\ he\ said\ \ \ \^WoW

7. [Link]()

This method either returns None (if the pattern doesn’t match), or a [Link] contains
information about the matching part of the string. This method stops after the first match, so this
is best suited for testing a regular expression more than extracting data.

Example: Searching for an occurrence of the pattern

This code uses a regular expression to search for a pattern in the given string. If a match is found,
it extracts and prints the matched portions of the string.

In this specific example, it searches for a pattern that consists of a month (letters) followed by a
day (digits) in the input string "I was born on June 24". If a match is found, it prints the full match,
the month, and the day.

import re

regex = r"([a-zA-Z]+) (\d+)"

match = [Link](regex, "I was born on June 24")

if match != None:

print ("Match at index %s, %s" % ([Link](), [Link]()))

print ("Full match: %s" % ([Link](0)))

print ("Month: %s" % ([Link](1)))

print ("Day: %s" % ([Link](2)))

else:

print ("The regex pattern does not match.")

Meta-characters

Metacharacters are the characters with special meaning.

86
To understand the RE analogy, Metacharacters are useful and important. They will be used in
functions of module re. Below is the list of metacharacters.

Meta Characters Description

Used to drop the special meaning of


\
character following it

[] Represent a character class

^ Matches the beginning

$ Matches the end

. Matches any character except newline

Means OR (Matches with any of the


|
characters separated by it.

? Matches zero or one occurrence

Any number of occurrences (including 0


*
occurrences)

+ One or more occurrences

Indicate the number of occurrences of a


{}
preceding regex to match.

87
Meta Characters Description

() Enclose a group of Regex

1. \ - Backslash

The backslash (\) makes sure that the character is not treated in a special way. This can be
considered a way of escaping metacharacters.

For example, if you want to search for the dot(.) in the string then you will find that dot(.) will be
treated as a special character as is one of the metacharacters (as shown in the above table). So for
this case, we will use the backslash(\) just before the dot(.) so that it will lose its specialty. See the
below example for a better understanding.

Example:

The first search ([Link](r'.', s)) matches any character, not just the period, while the second
search ([Link](r'\.', s)) specifically looks for and matches the period character.

import re

s = '[Link]'

# without using \

match = [Link](r'.', s)

print(match)

# using \

match = [Link](r'\.', s)

print(match)

Output

<[Link] object; span=(0, 1), match='g'>

<[Link] object; span=(5, 6), match='.'>

2. [] - Square Brackets

88
Square Brackets ([]) represent a character class consisting of a set of characters that we wish to
match. For example, the character class [abc] will match any single a, b, or c.

We can also specify a range of characters using - inside the square brackets. For example,

• [0, 3] is sample as [0123]

• [a-c] is same as [abc]

We can also invert the character class using the caret(^) symbol. For example,

• [^0-3] means any character except 0, 1, 2, or 3

• [^a-c] means any character except a, b, or c

Example:

In this code, you're using regular expressions to find all the characters in the string that fall within
the range of 'a' to 'm'. The [Link]() function returns a list of all such characters. In the given
string, the characters that match this pattern are: 'c', 'k', 'b', 'f', 'j', 'e', 'h', 'l', 'd', 'g'.

import re

string = "The quick brown fox jumps over the lazy dog"

pattern = "[a-m]"

result = [Link](pattern, string)

print(result)

Output

['h', 'e', 'i', 'c', 'k', 'b', 'f', 'j', 'm', 'e', 'h', 'e', 'l', 'a', 'd', 'g']

3. ^ - Caret

Caret (^) symbol matches the beginning of the string i.e. checks whether the string starts with the
given character(s) or not. For example -

• ^g will check if the string starts with g such as geeks, globe, girl, g, etc.

• ^ge will check if the string starts with ge such as geeks, geeksforgeeks, etc.

Example:

This code uses regular expressions to check if a list of strings starts with "The". If a string begins
with "The," it's marked as "Matched" otherwise, it's labeled as "Not matched".

89
import re

regex = r'^The'

strings = ['The quick brown fox', 'The lazy dog', 'A quick brown fox']

for string in strings:

if [Link](regex, string):

print(f'Matched: {string}')

else:

print(f'Not matched: {string}')

Output

Matched: The quick brown fox

Matched: The lazy dog

Not matched: A quick brown fox

4. $ - Dollar

Dollar($) symbol matches the end of the string i.e checks whether the string ends with the given
character(s) or not. For example-

• s$ will check for the string that ends with a such as geeks, ends, s, etc.

• ks$ will check for the string that ends with ks such as geeks, geeksforgeeks, ks, etc.

Example:

This code uses a regular expression to check if the string ends with "World!". If a match is found,
it prints "Match found!" otherwise, it prints "Match not found".

import re

string

import re

string = "Hello World!"

pattern = r"World!$"

match = [Link](pattern, string)

90
if match:

print("Match found!")

else:

print("Match not found.")

Output

Match found!

5. . - Dot

Dot(.) symbol matches only a single character except for the newline character (\n). For example
-

• a.b will check for the string that contains any character at the place of the dot such as acb,
acbd, abbb, etc

• .. will check if the string contains at least 2 characters

Example:

This code uses a regular expression to search for the pattern "[Link]" within the string. The
dot (.) in the pattern represents any character. If a match is found, it prints "Match
found!" otherwise, it prints "Match not found".

import re

string = "The quick brown fox jumps over the lazy dog."

pattern = r"[Link]"

match = [Link](pattern, string)

if match:

print("Match found!")

else:

print("Match not found.")

Output

Match found!

6. | - Or
91
Or symbol works as the or operator meaning it checks whether the pattern before or after the or
symbol is present in the string or not. For example -

• a|b will match any string that contains a or b such as acd, bcd, abcd, etc.

7. ? - Question Mark

The question mark (?) is a quantifier in regular expressions that indicates that the preceding
element should be matched zero or one time. It allows you to specify that the element is optional,
meaning it may occur once or not at all. For example,

• ab?c will be matched for the string ac, acb, dabc but will not be matched for abbc because
there are two b. Similarly, it will not be matched for abdc because b is not followed by c.

8.* - Star

Star (*) symbol matches zero or more occurrences of the regex preceding the * symbol. For
example -

• ab*c will be matched for the string ac, abc, abbbc, dabc, etc. but will not be matched for
abdc because b is not followed by c.

9. + - Plus

Plus (+) symbol matches one or more occurrences of the regex preceding the + symbol. For
example -

• ab+c will be matched for the string abc, abbc, dabc, but will not be matched for ac, abdc,
because there is no b in ac and b, is not followed by c in abdc.

10. {m, n} - Braces

Braces match any repetitions preceding regex from m to n both inclusive. For example -

• a{2, 4} will be matched for the string aaab, baaaac, gaad, but will not be matched for strings
like abc, bc because there is only one a or no a in both the cases.

11. (<regex>) - Group

Group symbol is used to group sub-patterns. For example -

• (a|b)cd will match for strings like acd, abcd, gacd, etc.

Special Sequences

92
Special sequences do not match for the actual character in the string instead it tells the specific
location in the search string where the match must occur. It makes it easier to write commonly
used patterns.

List of special sequences

Special
Sequence Description Examples

Matches if the for geeks


string begins with
\A \Afor
the given
character for the world

Matches if the geeks


word begins or
ends with the given
character.
\b(string) will
check for the
\b \bge
beginning of the
word and get
(string)\b will
check for the
ending of the
word.

It is the opposite of together


the \b i.e. the string
\B should not start or \Bge
end with the given
regex. forge

\d \d 123

93
Special
Sequence Description Examples

Matches any
decimal digit, this
is equivalent to the gee1
set class [0-9]

Matches any non- geeks


digit character,
\D this is equivalent \D
to the set class [^0-
9] geek1

Matches any gee ks


\s whitespace \s
character.
a bc a

Matches any non- a bd


\S whitespace \S
character
abcd

Matches any 123


alphanumeric
\w character, this is \w
equivalent to the
class [a-zA-Z0-9_]. geeKs4

Matches any non- >$


\W alphanumeric \W
character.
gee<>

94
Special
Sequence Description Examples

Matches if the abcdab


\Z string ends with ab\Z
the given regex
abababab

Sets for character matching

A Set is a set of characters enclosed in '[]' brackets. Sets are used to match a single character in the
set of characters specified between brackets. Below is the list of Sets:

Set Description

Quantifies the preceding character or group


\{n,\}
and matches at least n occurrences.

Quantifies the preceding character or group


*
and matches zero or more occurrences.

[0123] Matches the specified digits (0, 1, 2, or 3)

[^arn] matches for any character EXCEPT a, r, and n

\d Matches any digit (0-9).

matches for any two-digit numbers from 00


[0-5][0-9]
and 59

Matches any alphanumeric character (a-z, A-


\w
Z, 0-9, or _).

95
Set Description

Matches any lower case alphabet between a


[a-n]
and n.

\D Matches any non-digit character.

matches where one of the specified characters


[arn]
(a, r, or n) are present

matches any character between a and z, lower


[a-zA-Z]
case OR upper case

[0-9] matches any digit between 0 and 9

Using Regular Expression On Files In Python:


Open a File by Regular Expression in Python

Regular expressions (regex) are powerful tools for pattern matching and manipulation of text data.
When it comes to opening files based on a specific pattern or criteria, regular expressions can be
a handy solution. In this article, we will explore how to open a file using regular expressions in
three different programming languages: Python, JavaScript, and Ruby.

What is Regular Expression?

A regular expression, often abbreviated as "regex" or "regexp," is a sequence of characters that


defines a search pattern. It is a powerful tool used for pattern matching within strings. Regular
expressions are a domain-specific language (DSL) embedded in many programming languages
and tools, allowing developers to describe and match complex patterns of characters.

How to Open a File by Regular Expression?

Below, are the methods for How To Open A File By Regular Expression In Python.

Example 1: Using Basic Pattern Matching

96
In this example, the [Link] function is used to create a regex pattern based on the
provided file_pattern. The search method is then applied to each file in the directory, and
matching files are opened and their content is printed.

import re

def open_file_by_regex(file_pattern):

# List all files in the current directory

files = [&quot;[Link]&quot;, &quot;[Link]&quot;, &quot;[Link]&quot;,


&quot;[Link]&quot;]

# Use regex to match files based on the provided pattern

pattern = [Link](file_pattern)

matching_files = [file for file in files if [Link](file)]

# Open and print the content of each matching file

for file_name in matching_files:

with open(file_name, 'r') as file:

content = [Link]()

print(f&quot;Content of {file_name}:\n{content}\n&quot;)

# Example usage

open_file_by_regex(r'.*\.txt')

Output

Content of [Link]:
Hello GeeksforGeeks

Example 2 : Extracting Information from File Name

In this example, the regex pattern includes groups ((\d{4})(\d{2})(\d{2})) to extract year, month,
and day from file names containing timestamps. The extracted information is then printed
alongside the file name.

import re

def open_file_by_regex_and_extract(file_pattern):

97
# List all files with timestamps in their names

files = [&quot;20220101_report.txt&quot;, &quot;20220215_data.csv&quot;,


&quot;20220320_summary.docx&quot;]

# Use regex groups to extract relevant information

pattern = [Link](r'(\d{4})(\d{2})(\d{2})_' + file_pattern)

for file_name in files:

match = [Link](file_name)

if match:

year, month, day = [Link]()

print(f&quot;Date: {year}-{month}-{day}, File: {file_name}&quot;)

# Example usage

open_file_by_regex_and_extract(r'.*\.txt')

Output

Date: 2022-01-01, File: 20220101_report.txt:


Hi, GeeksforGeeks

98
UNIT - 4 GUI IN PYTHON & NUMPY AND PANDAS PACKAGES

Applications: Self ticket booking system, Video games, Designing Web pages, handling multi-
dimensional arrays, data manipulation.

Graphical user interface: Creating a GUI in python - widget classes - working with Fonts and
Colors, working with Frames, Layout manager, Event handling - Numpy – installation – Numpy
arrays – array manipulation - Pandas Series and Data frames.

Graphical user interface:


Graphical User Interface (GUI) programming in Python involves creating visual interfaces for
software applications, allowing users to interact with the program through elements like buttons,
menus, text boxes, and windows, rather than command-line input.

Several frameworks and libraries are available for Python GUI development:

1. Tkinter:

• Standard Library:

Tkinter is Python's standard GUI library and is included with most Python installations, making it
readily accessible.

• Simplicity:

It is known for its simplicity and ease of use, making it a good choice for beginners and smaller
applications.

• Widgets:

Provides a range of widgets like Label, Button, Entry, Text, and Frame for building interfaces.

• Event-driven:

Supports event-driven programming, where actions are triggered by user interactions (e.g., button
clicks, key presses).

2. PyQt/PySide:

• Qt Framework:

These are Python bindings for the powerful, cross-platform Qt framework, widely used for
developing desktop and mobile applications.

• Feature-rich:

99
Offer extensive features and tools for creating sophisticated and visually appealing GUIs, including
advanced widgets, graphics, and multimedia capabilities.

• Commercial Licensing:

PyQt has a dual licensing model (GPL and commercial), while PySide (Qt for Python) is LGPL
licensed.

3. wxPython:

• Cross-platform:

Another popular cross-platform toolkit that provides a native look and feel on different operating
systems.

• Object-oriented:

Follows an object-oriented approach and offers a comprehensive set of widgets and functionalities.

4. Kivy:

• Multi-touch and Mobile:

Designed specifically for developing multi-touch applications and is well-suited for mobile
development (Android, iOS).

• Declarative UI:

Uses a declarative language (KV language) for defining the user interface, separating it from the
application logic.

5. PySimpleGUI:

• Simplified Interface:

Built on top of other GUI frameworks (like Tkinter, Qt, WxPython, Remi) to provide a simpler and
more intuitive interface for rapid GUI development.

• Ease of Use:

Aims to reduce the complexity of GUI programming, making it easier to create functional interfaces
with less code.

The choice of GUI framework depends on factors such as project requirements, desired features,
target platforms, and developer experience. Tkinter is often recommended for beginners due to its
simplicity and built-in availability, while PyQt/PySide offer more power and flexibility for complex
applications.

100
Creating a GUI in python
What is Tkinter?

Tkinter is a Python Package for creating GUI applications. Python has a lot of GUI frameworks, but
Tkinter is the only framework that’s built into the Python standard library.

Tkinter has several strengths; it’s cross-platform, so the same code works on Windows, macOS, and
Linux.

Tkinter is lightweight and relatively painless to use compared to other frameworks. This makes it a
compelling choice for building GUI applications in Python, especially for applications where a
modern shine is unnecessary, and the top priority is to build something functional and cross-
platform quickly.

Use Cases of Tkinter

1. Creating windows and dialog boxes: Tkinter can be used to create windows and dialog boxes
that allow users to interact with your program. These can be used to display information, gather
input, or present options to the user.

To create a window or dialog box, you can use the Tk() function to create a root window, and then
use functions like Label, Button, and Entry to add widgets to the window.

2. Building a GUI for a desktop application: Tkinter can be used to create the interface for a
desktop application, including buttons, menus, and other interactive elements.

To build a GUI for a desktop application, you can use functions like Menu, Checkbutton,
and RadioButton to create menus and interactive elements and use layout managers
like pack and grid to arrange the widgets on the window.

3. Adding a GUI to a command-line program: Tkinter can be used to add a GUI to a command-
line program, making it easier for users to interact with the program and input arguments.

To add a GUI to a command-line program, you can use functions like Entry and Button to create
input fields and buttons, and use event handlers like command and bind to handle user input.

4. Creating custom widgets: Tkinter includes a variety of built-in widgets, such as buttons, labels,
and text boxes, but it also allows you to create your own custom widgets.

To create a custom widget, you can define a class that inherits from the Widget class and overrides
its methods to define the behavior and appearance of the widget.

5. Prototyping a GUI: Tkinter can be used to quickly prototype a GUI, allowing you to test and
iterate on different design ideas before committing to a final implementation.

101
To prototype a GUI with Tkinter, you can use the Tk() function to create a root window, and then
use functions like Label, Button, and Entry to add widgets to the window and test different layouts
and design ideas.

Tkinter Alternatives

There are several libraries that are similar to Tkinter and can be used for creating graphical user
interfaces (GUIs) in Python. Some examples include:

[Link]: PyQt is a GUI library that allows you to create GUI applications using the Qt
framework. It is a comprehensive library with a large number of widgets and features.

[Link]: wxPython is a library that allows you to create GUI applications using the
wxWidgets framework. It includes a wide range of widgets in it's GUI toolkit and is
cross-platform, meaning it can run on multiple operating systems.

[Link]: PyGTK is a GUI library that allows you to create GUI applications using the
GTK+ framework. It is a cross-platform library with a wide range of widgets and
features.

[Link]: Kivy is a library that allows you to create GUI applications using a modern,
responsive design. It is particularly well-suited for building mobile apps and games.

[Link]: PyForms is a library that allows you to create GUI applications using a simple,
declarative syntax. It is designed to be easy to use and has a small footprint.

[Link]: PyForms is a library that is popular because you can develop video games using it.
It is a free, open source, and cross-platform wrapper for the Simple DirectMedia Library
(SDL).

Getting Started with Tkinter

1. Import tkinter package and all of its modules.


2. Create a root window. Give the root window a title(using title()) and
dimension(using geometry()). All other widgets will be inside the root window.
3. Use mainloop() to call the endless loop of the window. If you forget to call this nothing
will appear to the user. The window will wait for any user interaction till we close it.

# Import Module

from tkinter import *

# create root window

root = Tk()

102
# root window title and dimension

[Link]("Welcome to GeekForGeeks")

# Set geometry (widthxheight)

[Link]('350x200')

# all widgets will be here

# Execute Tkinter

[Link]()

[Link]'ll add a label using the Label Class and change its text configuration as
desired. The grid() function is a geometry manager which keeps the label in the desired
location inside the window. If no parameters are mentioned by default it will place it in
the empty cell; that is 0,0 as that is the first location.
# Import Module
from tkinter import *

# create root window


root = Tk()
# root window title and dimension
[Link]("Welcome to GeekForGeeks")
# Set geometry(widthxheight)
[Link]('350x200')
#adding a label to the root window
lbl = Label(root, text = "Are you a Geek?")
[Link]()
# Execute Tkinter
[Link]()

103
5. Now add a button to the root window. Changing the button configurations gives us a lot
of options. In this example we will make the button display a text once it is clicked and
also change the color of the text inside the button.

# Import Module
from tkinter import *
# create root window
root = Tk()
# root window title and dimension
[Link]("Welcome to GeekForGeeks")
# Set geometry(widthxheight)
[Link]('350x200')
# adding a label to the root window
lbl = Label(root, text = "Are you a Geek?")
[Link]()
# function to display text when
# button is clicked
def clicked():
[Link](text = "I just got clicked")
# button widget with red color text
# inside
btn = Button(root, text = "Click me" ,
fg = "red", command=clicked)
# set Button grid
[Link](column=1, row=0)
# Execute Tkinter
[Link]()

104
Widget Classes:
In Python, "widget classes" primarily refer to the building blocks used to construct Graphical
User Interfaces (GUIs). The most common library for GUI development in Python is tkinter,
which provides a wide array of pre-built widget classes.

These widget classes represent various interactive and display elements of a GUI, such as:

• Label: Used to display static text or images.

• Button: Creates clickable buttons that can trigger actions.

• Entry: Provides a single-line text input field.

• Text: Offers a multi-line text area for displaying or editing text.

• Frame: Acts as a container to organize and group other widgets.

• Checkbutton: Implements checkboxes for on/off selections.

• Radiobutton: Creates radio buttons for selecting one option from a group.

• Scale: Provides a slider for selecting a value within a range.

• Scrollbar: Adds scrolling functionality to widgets like Listbox or Text.

• Canvas: A versatile widget for drawing graphics and creating custom interactive
elements.

• Toplevel: Creates a separate, independent window.

• Menubutton: and Menu: Used to create menus and sub-menus.

• Spinbox: A variant of Entry for selecting from a fixed set of values.

105
How Widget Classes are Used:

• Instantiation: You create an instance of a widget class, typically passing the parent
widget (where it will be placed) as an argument to its constructor.

import tkinter as tk

root = [Link]()

my_label = [Link](root, text="Hello, Tkinter!")

• Configuration: You can configure the appearance and behavior of a widget by setting its
options (e.g., text, color, font).

my_label.config(fg="blue", font=("Arial", 16))

• Geometry Management: Widgets are not automatically displayed after creation. You
use geometry managers (like pack(), grid(), or place()) to arrange them within the parent
widget.

my_label.pack()

Beyond tkinter, other Python GUI frameworks like PyQt, Kivy, and WxPython also
utilize their own sets of widget classes for building graphical applications. The core
concept remains the same: these classes encapsulate the visual and functional properties
of GUI elements.

• Event Handling: You can associate functions or methods with widget events (e.g.,
button clicks) to define their interactive behavior.

def on_button_click():

print("Button clicked!")

my_button = [Link](root, text="Click Me", command=on_button_click)

my_button.pack()

Working with fonts and colors in Python:


Working with fonts and colors in Python typically refers to manipulating the appearance
of text, either in a terminal, a graphical user interface (GUI), or within document
generation.

1. Terminal Output (Console Applications):

106
• ANSI Escape Codes: The most common method involves using ANSI escape sequences
directly in print statements. These codes are special character sequences that terminals
interpret to change text attributes like color, background color, and style (bold,
underline).

print("\033[91mThis text is red.\033[0m") # Red text

print("\033[1;32mThis text is bold green.\033[0m") # Bold green text

• \033[: Introduces the escape sequence.

• 91m: Sets the foreground color to red.

• 1;32m: Sets the style to bold and foreground color to green.

• 0m: Resets all attributes to default.

• Libraries like Colorama or Termcolor: These libraries simplify the use of ANSI escape
codes by providing more readable functions and constants for colors and styles, often
handling cross-platform compatibility issues.

from colorama import Fore, Style

print([Link] + "This text is red." + Style.RESET_ALL)

2. Graphical User Interfaces (GUI Applications):

• GUI Toolkits (Tkinter, PyQt, Kivy, etc.): When building GUI applications, you interact
with widgets that have properties for controlling font families, sizes, styles (bold, italic),
and text/background colors.

import tkinter as tk

root = [Link]()

label = [Link](root, text="Hello, GUI!", font=("Arial", 24, "bold"), fg="blue",


bg="lightgray")

[Link]()

[Link]()

• The specific methods and properties vary depending on the chosen GUI toolkit.

3. Document Generation (e.g., PDFs, Word Documents):

107
• Libraries like ReportLab (for PDFs) or python-docx (for Word): These libraries provide
functionalities to define and apply fonts and colors to text elements within the documents
they generate.

o You would typically specify font family, size, and color when adding text to the
document structure.

4. Data Visualization (e.g., Matplotlib):

• Libraries like Matplotlib: When creating plots and charts, you can control the appearance
of text elements (titles, labels, legends) by setting font properties and colors

import [Link] as plt

[Link]("My Plot", fontdict={'fontsize': 16, 'fontweight': 'bold', 'color': 'darkblue'})

[Link]()

Working With Frames In Python:


In Python, "frames" commonly refers to either: Tkinter Frames (GUI Programming).

A Frame in Tkinter is a container widget used to group and organize other widgets within a GUI
application. It provides a rectangular area on the screen to arrange and manage the layout of
elements like buttons, labels, and entry fields.

Creating a Tkinter Frame:

import tkinter as tk

root = [Link]()

[Link]("Frame Example")

# Create a frame

my_frame = [Link](root, borderwidth=2, relief="groove")

my_frame.pack(padx=10, pady=10)

# Add widgets to the frame

[Link](my_frame, text="Inside the Frame").pack(pady=5)

[Link](my_frame, text="Click Me").pack(pady=5)

108
[Link]()

Key Options for Tkinter Frames:

• master: The parent window or widget the frame belongs to.

• bd or borderwidth: The width of the border around the frame.

• bg or background: The background color of the frame.

• height, width: Dimensions of the frame.

• relief: The style of the border (e.g., "flat", "raised", "sunken", "groove", "ridge").

Execution Frames (Internal Python Mechanism).

In the context of Python's internal workings, a "frame" refers to an execution frame or stack
frame. Each time a Python function is called, a new frame is created to manage the function's
local variables, arguments, and execution state. This is a low-level concept primarily relevant for
debugging, introspection, or understanding how Python manages function calls.

Accessing Frame Information (for advanced use):

import sys

def my_function():

local_var = "hello"

frame = sys._getframe(0) # Get the current frame

print(f"Function name: {frame.f_code.co_name}")

print(f"Local variables: {frame.f_locals}")

my_function()

Layout manager:
In Python GUI programming, a layout manager (or geometry manager) is a mechanism used to
arrange and position widgets within a window or frame. Instead of manually specifying the exact
coordinates for each widget, layout managers handle the placement and resizing automatically,
leading to more flexible and responsive user interfaces.

The most common GUI library in Python, Tkinter, provides three primary layout managers:

• pack():

109
This manager arranges widgets in blocks within a container, either horizontally or vertically. It's
suitable for simple layouts where widgets are stacked or aligned along one dimension. Options
like side (top, bottom, left, right), fill (x, y, both), and expand control how widgets occupy
available space.

Example:

import tkinter as tk

root = [Link]()

w = [Link](root, text="Red Sun", bg="red", fg="white")

[Link]()

w = [Link](root, text="Green Grass", bg="green", fg="black")

[Link]()

w = [Link](root, text="Blue Sky", bg="blue", fg="white")

[Link]()

[Link]()

• grid():

This manager organizes widgets in a table-like structure of rows and columns. You specify the
row and column for each widget, and it automatically adjusts sizes based on content and
available space. Options like rowspan, columnspan, padx, pady, ipadx, ipady, and sticky offer
fine-grained control over placement and spacing.

Example with grid

import tkinter as tk

colours = ['red','green','orange','white','yellow','blue']

110
r=0

for c in colours:

[Link](text=c, relief=[Link], width=15).grid(row=r,column=0)

[Link](bg=c, relief=[Link], width=10).grid(row=r,column=1)

r=r+1

[Link]()

• place():

This manager allows for precise positioning of widgets using absolute or relative
coordinates. You specify x, y, relx, rely, width, height, relwidth, and relheight to control the
widget's position and size. While offering the most control, it can be less flexible for dynamic
layouts compared to pack() or grid().

import tkinter as tk

import random

root = [Link]()

# width x height + x_offset + y_offset:

[Link]("170x200+30+30")

languages = ['Python','Perl','C++','Java','Tcl/Tk']

labels = range(5)

for i in range(5):

ct = [[Link](256) for x in range(3)]

111
brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2]))

ct_hex = "%02x%02x%02x" % tuple(ct)

bg_colour = '#' + "".join(ct_hex)

l = [Link](root,

text=languages[i],

fg='White' if brightness < 120 else 'Black',

bg=bg_colour)

[Link](x = 20, y = 30 + i*30, width=120, height=25)

[Link]()

Event handling in python:


Event handling in Python refers to the process of detecting and responding to specific
occurrences or actions within a program. These occurrences, known as "events," can range from
user interactions (like mouse clicks or key presses) to system-level notifications or data changes.

Types of Events

1) Keyboard event:

As mentioned above, an event is an action conducted by the user. So let us wonder, what actions
can be performed on the keyboard? The simple answer is either pressing the key or releasing it.
Pressing the key is known as KEYDOWN and releasing it is known as KEYUP. The attribute
associated with these events is known as the key of type integer. Its use is to represent the key of

112
the keyboard. The common keys are represented by a pre-defined integer constant which is a
capital K. This K is followed by an underscore and then the name of the key is written. For
example K_s, K_F7.

The fact of the matter is that capital letters do not have an integer constant. The solution to this
problem is something known as a modifier also known as a mod which is the modifier such as
for shift, alt, ctrl, etc. that are being pressed simultaneously as the key. The integer value of mod
is stored in something known as KMOD_ which is followed by the name of the key. For
example KMOD_RSHIFT, KMOD_CTRL, etc. Let us revise the concepts that we have learned
in the keyboard event topic with the help of a small code.

for event in [Link]():

if [Link] == [Link]:

if [Link] == pygame.K_w:

print("Move the character forwards")

elif [Link] == pygame.K_s:

print("Move the character backwards")

elif [Link] == pygame.K_a:

print("Move the character left")

elif [Link] == pygame.K_d:

print("Move the character right")

2) Mouse events

Let us now understand the different types of mouse events. The first two are
MOUSEBUTTONDOWN and MOUSEBUTTONUP which are similar to KEYDOWN and
KEYUP except for the fact that here we are using a mouse. In addition to them, there is another
mouse event known as MOUSEMOTION. Let us understand all 3 mouse events in detail.

i) MOUSEBUTTONDOWN: The MOUSEBUTTONDOWN event occurs when the user


presses the mouse button. It has a couple of attributes which are as follows :

• button: It is an integer that represents the button that has been pressed. The left button
of the mouse is represented by 1, for mouse-wheel the integer is 2, and integer 3 is when
the right button of the mouse is pressed.

113
• pos: It is the absolute position of the mouse (x, y) when the user presses the mouse
button.

ii) MOUSEBUTTONUP: The MOUSEBUTTONUP event occurs when the user releases the
mouse button. It has the same button and pos attributes that the MOUSEBUTTONDOWN has
which have been mentioned above.

iii) MOUSEMOTION: This event occurs when the user moves his mouse in the display
window. It has the attributes buttons, pos, and rel.

• buttons: It is a tuple that represents whether the mouse buttons (left, mouse-wheel, right)
are pressed or not.

• pos: It is the absolute position (x, y) of the cursor in pixels.

• rel: It represents the relative position to the previous position (rel_x, rel_y) in pixels.

SR No. Button Value

1. Left mouse button 1

2. Mouse wheel button 2

3. Right mouse button 3

4. Mouse wheel scroll up 4

5. Mouse wheel scroll down 5

The following program will check whether we have pressed the left key or the right key and
display output accordingly.

import pygame

[Link]()

114
# Creating window

gameWindow = [Link].set_mode((800, 300))

[Link].set_caption("Event Handling")

exit_game = False

game_over = False

# Creating a game loop

while not exit_game:

for event in [Link](): # For Loop

if [Link] == [Link]:

exit_game = True

if [Link] == [Link]:

if [Link] == pygame.K_RIGHT:

print("You have pressed right arrow key")

elif [Link] == pygame.K_LEFT:

print("You have pressed left arrow key")

[Link]()

quit()

115
Graphics in Python:
Python offers various options for creating graphics, ranging from simple drawing tools to
powerful data visualization and GUI libraries.

1. Basic Drawing and Animation:

• Turtle Graphics:

This built-in module is excellent for beginners to learn programming concepts through visual
drawing. It simulates a "turtle" that can be moved around a screen, leaving a trail to create shapes
and patterns. It's particularly useful for understanding coordinate systems and basic
programming logic.

• [Link]:

A simplified graphics module, often used in introductory programming courses, that allows for
creating windows and drawing basic geometric shapes like points, circles, lines, and rectangles.

2. Data Visualization:

• Matplotlib:

A comprehensive library for creating static, animated, and interactive visualizations. It offers
extensive control over plot elements and supports various plot types, including line plots, scatter
plots, bar charts, histograms, and more. It's widely used in scientific computing and data
analysis.

• Plotly:

An open-source graphing library that enables the creation of interactive, publication-quality


graphs. It excels at generating web-based visualizations that can be embedded in various
applications.

3. Graphical User Interfaces (GUIs):

• Tkinter:

Python's standard GUI toolkit, included with most Python installations. It allows you to create
desktop applications with graphical elements like windows, buttons, text fields, and more.

• PyQt/PySide:

Powerful and feature-rich GUI frameworks based on the Qt library, offering advanced widgets
and customization options for building complex desktop applications.

• Kivy:
116
A framework for developing multi-touch applications with a focus on innovative user interfaces,
suitable for desktop and mobile platforms.

4. Advanced Graphics and Game Development:

• Pygame:

A set of Python modules designed for writing video games. It provides functionalities for
handling graphics, sound, input, and game logic, making it suitable for 2D game development.

• Pyglet:

A cross-platform windowing and multimedia library for Python, offering capabilities for creating
2D and 3D graphics, playing audio and video, and handling user input.

The choice of library depends on the specific needs of the project, whether it's for learning
programming basics, visualizing data, building a desktop application, or developing a game.

Turtle graphics:
In a Python shell, import all the objects of the turtle module:

from turtle import *

If you run into a No module named '_tkinter' error, you’ll have to install
the Tk interface package on your system.

Basic drawing

Send the turtle forward 100 steps:

forward(100)

You should see (most likely, in a new window on your display) a line drawn by the turtle,
heading East. Change the direction of the turtle, so that it turns 120 degrees left (anti-clockwise):

left(120)

Let’s continue by drawing a triangle:

forward(100)

left(120)

forward(100)

Notice how the turtle, represented by an arrow, points in different directions as you steer it.

117
Experiment with those commands, and also with backward() and right().

Pen control

Try changing the color - for example, color('blue') - and width of the line - for
example, width(3) - and then drawing again.

You can also move the turtle around without drawing, by lifting up the pen: up() before moving.
To start drawing again, use down().

The turtle’s position

Send your turtle back to its starting-point (useful if it has disappeared off-screen):

home()

The home position is at the center of the turtle’s screen. If you ever need to know them, get the
turtle’s x-y coordinates with:

pos()

Home is at (0, 0).

And after a while, it will probably help to clear the window so we can start anew:

clearscreen()

Making algorithmic patterns

Using loops, it’s possible to build up geometric patterns:

for steps in range(100):

for c in ('blue', 'red', 'green'):

color(c)

forward(steps)

right(30)

- which of course, are limited only by the imagination!

Let’s draw the star shape at the top of this page. We want red lines, filled in with yellow:

color('red')

fillcolor('yellow')

118
Just as up() and down() determine whether lines will be drawn, filling can be turned on and off:

begin_fill()

Next we’ll create a loop:

while True:

forward(200)

left(170)

if abs(pos()) < 1:

break

abs(pos()) < 1 is a good way to know when the turtle is back at its home position.

Finally, complete the filling:

end_fill()

Use turtle graphics in a script

It’s recommended to use the turtle module namespace as described immediately above, for
example:

import turtle as t

from random import random

for i in range(100):

steps = int(random() * 100)

angle = int(random() * 360)

[Link](angle)

[Link](steps)

Another step is also required though - as soon as the script ends, Python will also close the
turtle’s window. Add:

[Link]()

to the end of the script. The script will now wait to be dismissed and will not exit until it is
terminated, for example by closing the turtle graphics window.

119
Turtle Attributes And Methods

Python's turtle graphics give you a lot of options for controlling the turtle cursor and drawing
various shapes and patterns on the screen.

Turtle Attributes

• position() -provides a tuple of coordinates as the current position of the turtle.

• heading() -returns the current heading angle of the turtle in degrees.

• color() -returns a tuple of RGB values representing the turtle's current color.

• pensize() -returns the current pen size of the turtle.

• speed() -returns the current speed of the turtle.

Turtle Methods

1. forward(distance): This option propels the turtle forward by a predetermined amount.

2. backward(distance): This option sends the turtle back the specified amount of time.

3. right(angle): This option moves the turtle to the right at the specified degree angle.

4. left(angle): Moves the turtle to the left at the specified degree angle.

5. penup() : raises the turtle's pen so that it can't draw while it moves.

6. pendown():puts the pen down on the turtle so it can draw while it moves.

7. setposition(x, y):sets the position of the turtle to the specified x and y coordinates.

8. setheading(angle) :sets the heading angle of the turtle to the specified degree.

9. dot(size, color) :draws a dot of the specified size and color at the turtle's current
position.

10. circle(radius, extent):draws a circle with the radius and extent you specify (the
percentage of the circle to be drawn).

11. begin_fill():begins to fill the space that the turtle's movements have enclosed.

12. end_fill():stops occupying the space that the turtle's movements have enclosed.

120
Creating drawings and animations:
Animations are a great way to make Visualizations more attractive and user-appealing. It helps
us to demonstrate Data Visualization in a Meaningful Way. Python helps us to create Animation
Visualization using existing powerful Python libraries. Matplotlib is a very popular Data
Visualisation Library and is the commonly used for the graphical representation of data and also
for animations using inbuilt functions.

Using pause() Function

The pause() function in the pyplot module of the Matplotlib library is used to pause for interval
seconds mentioned in the argument. Consider the below example in which we will create a
simple linear graph using matplotlib and show Animation in it:

Example 1: Animated Plotting with Matplotlib in Python

In this example , below Python code uses Matplotlib to create an animated graph. Basically its
generates points in a loop, updating the plot in real-time with a brief pause after each iteration
then xlim and ylim functions set the graph's axis limits, and [Link]() displays the final
animated plot.

Python

from matplotlib import pyplot as plt

x = []

y = []

for i in range(100):

[Link](i)

[Link](i)

# Mention x and y limits to define their range

[Link](0, 100)

[Link](0, 100)

# Plotting graph

[Link](x, y, color = 'green')

[Link](0.01)

121
[Link]()

Output :

Similarly, you can use the pause() function to create Animation in various plots.

Using FuncAnimation() Function

This FuncAnimation() Function does not create the Animation on its own, but it creates
Animation from series of Graphics that we pass. Now there are Multiple types of Animation you
can make using the FuncAnimation function:

• Linear Graph Animation

• Bar Plot Race Animation in Python

• Scatter Plot Animation in Python

• Horizontal Movement in Bar Chart Race

Linear Graph Animation:

122
In this example, we are creating a simple linear graph that will show an animation of a Line.
Similarly, using FuncAnimation, we can create many types of Animated Visual Representations.
We just need to define our animation in a function and then pass it to FuncAnimation with
suitable parameters.

Python

from matplotlib import pyplot as plt

from [Link] import FuncAnimation

import numpy as np

x = []

y = []

figure, ax = [Link]()

# Setting limits for x and y axis

ax.set_xlim(0, 100)

ax.set_ylim(0, 12)

# Since plotting a single graph

line, = [Link](0, 0)

def animation_function(i):

[Link](i * 15)

[Link](i)

line.set_xdata(x)

line.set_ydata(y)

return line,

animation = FuncAnimation(figure,

func = animation_function,

frames = [Link](0, 10, 0.1),

interval = 10)

123
[Link]()

Output:

Bar Plot Race Animation in Python

In this example, we are creating a simple Bar Chart animation that will show an animation of
each bar.

Python

from matplotlib import pyplot as plt

from [Link] import FuncAnimation, writers

import numpy as np

fig = [Link](figsize = (7,5))

axes = fig.add_subplot(1,1,1)

124
axes.set_ylim(0, 300)

palette = ['blue', 'red', 'green',

'darkorange', 'maroon', 'black']

y1, y2, y3, y4, y5, y6 = [], [], [], [], [], []

def animation_function(i):

y1 = i

y2 = 5 * i

y3 = 3 * i

y4 = 2 * i

y5 = 6 * i

y6 = 3 * i

[Link]("Country")

[Link]("GDP of Country")

[Link](["India", "China", "Germany",

"USA", "Canada", "UK"],

[y1, y2, y3, y4, y5, y6],

color = palette)

[Link]("Bar Chart Animation")

animation = FuncAnimation(fig, animation_function,

interval = 50)

[Link]()

Output:

125
Scatter Plot Animation in Python

In this example, we will Animate Scatter Plot in python using the random function. We will be
Iterating through the animation_func and while iterating we will plot random values of the x
and y-axis.

Python

from matplotlib import pyplot as plt

from [Link] import FuncAnimation

import random

import numpy as np

x = []

y = []

colors = []

126
fig = [Link](figsize=(7,5))

def animation_func(i):

[Link]([Link](0,100))

[Link]([Link](0,100))

[Link]([Link](1))

area = [Link](0,30) * [Link](0,30)

[Link](0,100)

[Link](0,100)

[Link](x, y, c = colors, s = area, alpha = 0.5)

animation = FuncAnimation(fig, animation_func,

interval = 100)

[Link]()

Output:

127
Horizontal Movement in Bar Chart Race:

In this example , we are creating animated graphs with Pandas in Python , as below Python code
utilizes the Matplotlib library to create a real-time animated plot. It generates a sequence of
points in a loop and updates the graph with a brief pause after each iteration, showcasing a
dynamic representation of the data.

Dataset can be download from here: city_populations

Python

import pandas as pd

import [Link] as plt

import [Link] as ticker

from [Link] import FuncAnimation

df = pd.read_csv('city_populations.csv',

usecols=['name', 'group', 'year', 'value'])

colors = dict(zip(['India','Europe','Asia',

'Latin America','Middle East',

'North America','Africa'],

['#adb0ff', '#ffb3ff', '#90d595',

'#e48381', '#aafbff', '#f7bb5f',

'#eafb50']))

group_lk = df.set_index('name')['group'].to_dict()

def draw_barchart(year):

dff = df[df['year'].eq(year)].sort_values(by='value',

ascending=True).tail(10)

[Link]()

[Link](dff['name'], dff['value'],

color=[colors[group_lk[x]] for x in dff['name']])

128
dx = dff['value'].max() / 200

for i, (value, name) in enumerate(zip(dff['value'],

dff['name'])):

[Link](value-dx, i, name,

size=14, weight=600,

ha='right', va='bottom')

[Link](value-dx, i-.25, group_lk[name],

size=10, color='#444444',

ha='right', va='baseline')

[Link](value+dx, i, f'{value:,.0f}',

size=14, ha='left', va='center')

# polished styles

[Link](1, 0.4, year, transform=[Link],

color='#777777', size=46, ha='right',

weight=800)

[Link](0, 1.06, 'Population (thousands)',

transform=[Link], size=12,

color='#777777')

[Link].set_major_formatter([Link]('{x:,.0f}'))

[Link].set_ticks_position('top')

ax.tick_params(axis='x', colors='#777777', labelsize=12)

ax.set_yticks([])

[Link](0, 0.01)

[Link](which='major', axis='x', linestyle='-')

ax.set_axisbelow(True)

129
[Link](0, 1.12, 'The most populous cities in the world from 1500 to 2018',

transform=[Link], size=24, weight=600, ha='left')

[Link](1, 0, 'by @pratapvardhan; credit @jburnmurdoch',

transform=[Link], ha='right', color='#777777',

bbox=dict(facecolor='white', alpha=0.8, edgecolor='white'))

[Link](False)

[Link]()

fig, ax = [Link](figsize=(15, 8))

animator = FuncAnimation(fig, draw_barchart,

frames = range(1990, 2019))

[Link]()

Output:

130
Using loops and functions:
1. for Loops

For loops allow us to execute code a specific number of times.

for n in [2, 7, -1, 5]:

print(f"The number is {n} and its square is {n**2}")

print("I'm outside the loop!")

The number is 2 and its square is 4

The number is 7 and its square is 49

The number is -1 and its square is 1

The number is 5 and its square is 25

I'm outside the loop!

The main points to notice:

• Keyword for begins the loop. Colon : ends the first line of the loop.

• Block of code indented is executed for each value in the list (hence the name “for” loops)

• The loop ends after the variable n has taken all the values in the list

• We can iterate over any kind of “iterable”: list, tuple, range, set, string.

• An iterable is really just any object with a sequence of values that can be looped over. In
this case, we are iterating over the values in a list.

word = "Python"

for letter in word:

print("Gimme a " + letter + "!")

print(f"What's that spell?!! {word}!")

131
Gimme a P!

Gimme a y!

Gimme a t!

Gimme a h!

Gimme a o!

Gimme a n!

What's that spell?!! Python!

A very common pattern is to use for with the range(). range() gives you a sequence of
integers up to some value (non-inclusive of the end-value) and is typically used for looping.

range(10)

range(0, 10)

list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

for i in range(10):

print(i)

6
132
7

We can also specify a start value and a skip-by value with range:

for i in range(1, 101, 10):

print(i)

11

21

31

41

51

61

71

81

91

We can write a loop inside another loop to iterate over multiple dimensions of data:

for x in [1, 2, 3]:

for y in ["a", "b", "c"]:

print((x, y))

(1, 'a')

(1, 'b')

(1, 'c')

133
(2, 'a')

(2, 'b')

(2, 'c')

(3, 'a')

(3, 'b')

(3, 'c')

list_1 = [0, 1, 2]

list_2 = ["a", "b", "c"]

for i in range(3):

print(list_1[i], list_2[i])

0a

1b

2c

There are many clever ways of doing these kinds of things in Python. When looping over
objects, I tend to use zip() and enumerate() quite a lot in my work. zip() returns a zip object
which is an iterable of tuples.

for i in zip(list_1, list_2):

print(i)

(0, 'a')

(1, 'b')

(2, 'c')

We can even “unpack” these tuples directly in the for loop:

for i, j in zip(list_1, list_2):

134
print(i, j)

0a

1b

2c

enumerate() adds a counter to an iterable which we can use within the loop.

for i in enumerate(list_2):

print(i)

(0, 'a')

(1, 'b')

(2, 'c')

for n, i in enumerate(list_2):

print(f"index {n}, value {i}")

index 0, value a

index 1, value b

index 2, value c

We can loop through key-value pairs of a dictionary using .items(). The general syntax
is for key, value in [Link]().

courses = {521 : "awesome",

551 : "riveting",

511 : "naptime!"}

for course_num, description in [Link]():

print(f"DSCI {course_num}, is {description}")

DSCI 521, is awesome

DSCI 551, is riveting

DSCI 511, is naptime!

135
We can even use enumerate() to do more complex un-packing:

for n, (course_num, description) in enumerate([Link]()):

print(f"Item {n}: DSCI {course_num}, is {description}")

Item 0: DSCI 521, is awesome

Item 1: DSCI 551, is riveting

Item 2: DSCI 511, is naptime!

2. while loops¶

We can also use a while loop to excute a block of code several times. But beware! If the
conditional expression is always True, then you’ve got an infintite loop!

n = 10

while n > 0:

print(n)

n -= 1

print("Blast off!")

10

136
Let’s read the while statement above as if it were in English. It means, “While n is greater than 0,
display the value of n and then decrement n by 1. When you get to 0, display the word Blast off!”

For some loops, it’s hard to tell when, or if, they will stop! Take a look at the Collatz conjecture.
The conjecture states that no matter what positive integer n we start with, the sequence will
always eventually reach 1 - we just don’t know how many iterations it will take.

n = 11

while n != 1:

print(int(n))

if n % 2 == 0: # n is even

n=n/2

else: # n is odd

n=n*3+1

print(int(n))

11

34

17

52

26

13

40

20

10

16

137
2

Hence, in some cases, you may want to force a while loop to stop based on some criteria, using
the break keyword.

n = 123

i=0

while n != 1:

print(int(n))

if n % 2 == 0: # n is even

n=n/2

else: # n is odd

n=n*3+1

i += 1

if i == 10:

print(f"Ugh, too many iterations!")

break

123

370

185

556

278

139

418

209

628

138
314

The continue keyword is similar to break but won’t stop the loop. Instead, it just restarts the loop
from the top.

n = 10

while n > 0:

if n % 2 != 0: # n is odd

n=n-1

continue

break # this line is never executed because continue restarts the loop from the top

print(n)

n=n-1

print("Blast off!")

10

3. Comprehensions

Comprehensions allow us to build lists/tuples/sets/dictionaries in one convenient, compact line of


code. I use these quite a bit! Below is a standard for loop you might use to iterate over an iterable
and create a list:

subliminal = ['Tom', 'ingests', 'many', 'eggs', 'to', 'outrun', 'large', 'eagles', 'after', 'running', 'near',
'!']

first_letters = []

for word in subliminal:

139
first_letters.append(word[0])

print(first_letters)

['T', 'i', 'm', 'e', 't', 'o', 'l', 'e', 'a', 'r', 'n', '!']

List comprehension allows us to do this in one compact line:

letters = [word[0] for word in subliminal] # list comprehension

letters

['T', 'i', 'm', 'e', 't', 'o', 'l', 'e', 'a', 'r', 'n', '!']

We can make things more complicated by doing multiple iteration or conditional iteration:

[(i, j) for i in range(3) for j in range(4)]

[(0, 0),

(0, 1),

(0, 2),

(0, 3),

(1, 0),

(1, 1),

(1, 2),

(1, 3),

(2, 0),

(2, 1),

(2, 2),

(2, 3)]

[i for i in range(11) if i % 2 == 0] # condition the iterator, select only even numbers

[0, 2, 4, 6, 8, 10]

[-i if i % 2 else i for i in range(11)] # condition the value, -ve odd and +ve even numbers

140
[0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

There is also set comprehension:

words = ['hello', 'goodbye', 'the', 'antidisestablishmentarianism']

y = {word[-1] for word in words} # set comprehension

y # only has 3 elements because a set contains only unique items and there would have been two
e's

{'e', 'm', 'o'}

Dictionary comprehension:

word_lengths = {word:len(word) for word in words} # dictionary comprehension

word_lengths

{'hello': 5, 'goodbye': 7, 'the': 3, 'antidisestablishmentarianism': 28}

Tuple comprehension doesn’t work as you might expect… We get a “generator” instead (more
on that later).

y = (word[-1] for word in words) # this is NOT a tuple comprehension - more on generators
later

print(y)

<generator object <genexpr> at 0x104bac120>

4. try / except

141
Above: the Blue Screen of Death at a Nine Inch Nails concert! Source: [Link].

If something goes wrong, we don’t want our code to crash - we want it to fail gracefully. In
Python, this can be accomplished using try/except. Here is a basic example:

this_variable_does_not_exist

print("Another line") # code fails before getting to this line

---------------------------------------------------------------------------

NameError Traceback (most recent call last)

<ipython-input-27-dd878f68d557> in <module>

----> 1 this_variable_does_not_exist

2 print("Another line") # code fails before getting to this line

NameError: name 'this_variable_does_not_exist' is not defined

try:

this_variable_does_not_exist

except:

pass # do nothing

print("You did something bad! But I won't raise an error.") # print something

print("Another line")

You did something bad! But I won't raise an error.

Another line

Python tries to execute the code in the try block. If an error is encountered, we “catch” this in
the except block (also called try/catch in other languages). There are many different error types,
or exceptions - we saw NameError above.

5/0 # ZeroDivisionError

---------------------------------------------------------------------------

ZeroDivisionError Traceback (most recent call last)

<ipython-input-29-9866726f0353> in <module>

142
----> 1 5/0 # ZeroDivisionError

ZeroDivisionError: division by zero

my_list = [1,2,3]

my_list[5] # IndexError

---------------------------------------------------------------------------

IndexError Traceback (most recent call last)

<ipython-input-30-8f0c4b3b2ce1> in <module>

1 my_list = [1,2,3]

----> 2 my_list[5] # IndexError

IndexError: list index out of range

my_tuple = (1,2,3)

my_tuple[0] = 0 # TypeError

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-31-90cd0bd9ddec> in <module>

1 my_tuple = (1,2,3)

----> 2 my_tuple[0] = 0 # TypeError

TypeError: 'tuple' object does not support item assignment

Ok, so there are apparently a bunch of different errors one could run into. With try/except you
can also catch the exception itself:

try:

this_variable_does_not_exist

except Exception as ex:

print("You did something bad!")

143
print(ex)

print(type(ex))

You did something bad!

name 'this_variable_does_not_exist' is not defined

<class 'NameError'>

In the above, we caught the exception and assigned it to the variable ex so that we could print it
out. This is useful because you can see what the error message would have been, without
crashing your program. You can also catch specific exceptions types. This is typically the
recommended way to catch errors, you want to be specific in catching your error so you know
exactly where and why your code failed.

try:

this_variable_does_not_exist # name error

# (1, 2, 3)[0] = 1 # type error

# 5/0 # ZeroDivisionError

except TypeError:

print("You made a type error!")

except NameError:

print("You made a name error!")

except:

print("You made some other sort of error")

You made a name error!

The final except would trigger if the error is none of the above types, so this sort of has
an if/elif/else feel to it. There is also an optional else and finally keyword (which I almost never
used), but you can read more about here.

try:

this_variable_does_not_exist

except:

144
print("The variable does not exist!")

finally:

print("I'm printing anyway!")

The variable does not exist!

I'm printing anyway!

We can also write code that raises an exception on purpose, using raise:

def add_one(x): # we'll get to functions in the next section

return x + 1

add_one("blah")

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-36-96e0142692a3> in <module>

----> 1 add_one("blah")

<ipython-input-35-eabf290fc405> in add_one(x)

1 def add_one(x): # we'll get to functions in the next section

----> 2 return x + 1

TypeError: can only concatenate str (not "int") to str

def add_one(x):

if not isinstance(x, float) and not isinstance(x, int):

raise TypeError(f"Sorry, x must be numeric, you entered a {type(x)}.")

return x + 1

add_one("blah")

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-38-96e0142692a3> in <module>
145
----> 1 add_one("blah")

<ipython-input-37-3a3a8b564774> in add_one(x)

1 def add_one(x):

2 if not isinstance(x, float) and not isinstance(x, int):

----> 3 raise TypeError(f"Sorry, x must be numeric, you entered a {type(x)}.")

5 return x + 1

TypeError: Sorry, x must be numeric, you entered a <class 'str'>.

This is useful when your function is complicated and would fail in a complicated way, with a
weird error message. You can make the cause of the error much clearer to the user of the
function. If you do this, you should ideally describe these exceptions in the function
documentation, so a user knows what to expect if they call your function.

Finally, we can even define our own exception types. We do this by inheriting from
the Exception class - we’ll explore classes and inheritance more in the next chapter!

class CustomAdditionError(Exception):

pass

def add_one(x):

if not isinstance(x, float) and not isinstance(x, int):

raise CustomAdditionError("Sorry, x must be numeric")

return x + 1

add_one("blah")

---------------------------------------------------------------------------

CustomAdditionError Traceback (most recent call last)

<ipython-input-41-96e0142692a3> in <module>

----> 1 add_one("blah")

146
<ipython-input-40-25db54189b4f> in add_one(x)

1 def add_one(x):

2 if not isinstance(x, float) and not isinstance(x, int):

----> 3 raise CustomAdditionError("Sorry, x must be numeric")

5 return x + 1

CustomAdditionError: Sorry, x must be numeric

5. Functions

A function is a reusable piece of code that can accept input parameters, also known as
“arguments”. For example, let’s define a function called square which takes one input
parameter n and returns the square n**2:

def square(n):

n_squared = n**2

return n_squared

square(2)

square(100)

10000

square(12345)

152399025

Functions begin with the def keyword, then the function name, arguments in parentheses, and
then a colon (:). The code executed by the function is defined by indentation. The output or
“return” value of the function is specified using the return keyword.

Side Effects & Local Variables

When you create a variable inside a function, it is local, which means that it only exists inside the
function. For example:

147
def cat_string(str1, str2):

string = str1 + str2

return string

cat_string('My name is ', 'Tom')

'My name is Tom'

string

---------------------------------------------------------------------------

NameError Traceback (most recent call last)

<ipython-input-48-edbf08a562d5> in <module>

----> 1 string

NameError: name 'string' is not defined

If a function changes the variables passed into it, then it is said to have side effects. For example:

def silly_sum(my_list):

my_list.append(0)

return sum(my_list)

l = [1, 2, 3, 4]

out = silly_sum(l)

out

10

The above looks like what we wanted? But wait… it changed our l object…

[1, 2, 3, 4, 0]

If your function has side effects like this, you must mention it in the documentation (which we’ll
touch on later in this chapter).

Null Return Type

148
If you do not specify a return value, the function returns None when it terminates:

def f(x):

x + 1 # no return!

if x == 999:

return

print(f(0))

None

Optional & Required Arguments¶

Sometimes it is convenient to have default values for some arguments in a function. Because
they have default values, these arguments are optional, and are hence called “optional
arguments”. For example:

def repeat_string(s, n=2):

return s*n

repeat_string("mds", 2)

'mdsmds'

repeat_string("mds", 5)

'mdsmdsmdsmdsmds'

repeat_string("mds") # do not specify `n`; it is optional

'mdsmds'

Ideally, the default value for optional arguments should be carefully chosen. In the function
above, the idea of “repeating” something makes me think of having 2 copies, so n=2 feels like a
reasonable default.

You can have any number of required arguments and any number of optional arguments. All the
optional arguments must come after the required arguments. The required arguments are mapped
by the order they appear. The optional arguments can be specified out of order when using the
function.

def example(a, b, c="DEFAULT", d="DEFAULT"):

print(a, b, c, d)

149
example(1, 2, 3, 4)

1234

Using the defaults for c and d:

example(1, 2)

1 2 DEFAULT DEFAULT

Specifying c and d as keyword arguments (i.e. by name):

example(1, 2, c=3, d=4)

1234

Specifying only one of the optional arguments, by keyword:

example(1, 2, c=3)

1 2 3 DEFAULT

Specifying all the arguments as keyword arguments, even though only c and d are optional:

example(a=1, b=2, c=3, d=4)

1234

Specifying c by the fact that it comes 3rd (I do not recommend this because I find it is
confusing):

example(1, 2, 3)

1 2 3 DEFAULT

Specifying the optional arguments by keyword, but in the wrong order (this can also be
confusing, but not so terrible - I am fine with it):

example(1, 2, d=4, c=3)

1234

Specifying the non-optional arguments by keyword (I am fine with this):

example(a=1, b=2)

150
1 2 DEFAULT DEFAULT

Specifying the non-optional arguments by keyword, but in the wrong order (not recommended, I
find it confusing):

example(b=2, a=1)

1 2 DEFAULT DEFAULT

Specifying keyword arguments before non-keyword arguments (this throws an error):

example(a=2, 1)

File "<ipython-input-66-a37b920e8205>", line 1

example(a=2, 1)

SyntaxError: positional argument follows keyword argument

Multiple Return Values

In many programming languages, functions can only return one object. That is technically true in
Python too, but there is a “workaround”, which is to return a tuple.

def sum_and_product(x, y):

return (x + y, x * y)

sum_and_product(5, 6)

(11, 30)

The parentheses can be omitted (and often are), and a tuple is implicitly returned as defined by
the use of the comma:

def sum_and_product(x, y):

return x + y, x * y

sum_and_product(5, 6)

(11, 30)

151
It is common to immediately unpack a returned tuple into separate variables, so it really feels
like the function is returning multiple values:

s, p = sum_and_product(5, 6)

11

30

As an aside, it is conventional in Python to use _ for values you don’t want:

s, _ = sum_and_product(5, 6)

11

11

Functions with Arbitrary Number of Arguments

You can also call/define functions that accept an arbitrary number of positional or keyword
arguments using *args and **kwargs.

def add(*args):

print(args)

return sum(args)

add(1, 2, 3, 4, 5, 6)

(1, 2, 3, 4, 5, 6)

21

def add(**kwargs):

print(kwargs)

return sum([Link]())

add(a=3, b=4, c=5)

152
{'a': 3, 'b': 4, 'c': 5}

12

6. Functions as a Data Type

In Python, functions are actually a data type:

def do_nothing(x):

return x

type(do_nothing)

function

print(do_nothing)

<function do_nothing at 0x105c45a60>

This means you can pass functions as arguments into other functions.

def square(y):

return y**2

def evaluate_function_on_x_plus_1(fun, x):

return fun(x+1)

evaluate_function_on_x_plus_1(square, 5)

36

So what happened above?

• fun(x+1) becomes square(5+1)

• square(6) becomes 36

7. Anonymous Functions

There are two ways to define functions in Python. The way we’ve beenusing up until now:

def add_one(x):

153
return x+1

add_one(7.2)

8.2

Or by using the lambda keyword:

add_one = lambda x: x+1

type(add_one)

function

add_one(7.2)

8.2

The two approaches above are identical. The one with lambda is called an anonymous function.
Anonymous functions can only take up one line of code, so they aren’t appropriate in most cases,
but can be useful for smaller things.

evaluate_function_on_x_plus_1(lambda x: x ** 2, 5)

36

Above:

• First, lambda x: x**2 evaluates to a value of type function (otice that this function is
never given a name - hence “anonymous functions”).

• Then, the function and the integer 5 are passed into evaluate_function_on_x_plus_1

• At which point the anonymous function is evaluated on 5+1, and we get 36.

8. DRY Principle, Designing Good Functions

DRY stands for Don’t Repeat Yourself.

As an example, consider the task of turning each element of a list into a palindrome.

names = ["milad", "tom", "tiffany"]

name = "tom"

name[::-1] # creates a slice that starts at the end and moves backwards, syntax is
[begin:end:step]
154
'mot'

names_backwards = list()

names_backwards.append(names[0] + names[0][::-1])

names_backwards.append(names[1] + names[1][::-1])

names_backwards.append(names[2] + names[2][::-1])

names_backwards

['miladdalim', 'tommot', 'tiffanyynaffit']

The code above is gross, terrible, yucky code for several reasons:

1. It only works for a list with 3 elements;

2. It only works for a list named names;

3. If we want to change its functionality, we need to change 3 similar lines of code (Don’t
Repeat Yourself!!);

4. It is hard to understand what it does just by looking at it.

Let’s try this a different way:

names_backwards = list()

for name in names:

names_backwards.append(name + name[::-1])

names_backwards

['miladdalim', 'tommot', 'tiffanyynaffit']

The above is slightly better and we have solved problems (1) and (3). But let’s create a function
to make our life easier:

def make_palindromes(names):

names_backwards = list()

for name in names:

names_backwards.append(name + name[::-1])

155
return names_backwards

make_palindromes(names)

['miladdalim', 'tommot', 'tiffanyynaffit']

Okay, this is even better. We have now also solved problem (2), because you can call the
function with any list, not just names. For example, what if we had multiple lists:

names1 = ["milad", "tom", "tiffany"]

names2 = ["apple", "orange", "banana"]

make_palindromes(names1)

['miladdalim', 'tommot', 'tiffanyynaffit']

make_palindromes(names2)

['appleelppa', 'orangeegnaro', 'bananaananab']

Designing Good Functions

How far you go and how you choose to apply the DRY principle is up to you and the
programming context. These decisions are often ambiguous. Should make_palindromes() be a
function if I’m only ever doing it once? Twice? Should the loop be inside the function, or
outside? Should there be TWO functions, one that loops over the other?

In my personal opinion, make_palindromes() does a bit too much to be understandable. I prefer


this:

def make_palindrome(name):

return name + name[::-1]

make_palindrome("milad")

'miladdalim'

From here, if we want to “apply make_palindrome to every element of a list” we could use list
comprehension:

[make_palindrome(name) for name in names]

156
['miladdalim', 'tommot', 'tiffanyynaffit']

There is also the in-built map() function which does exactly this, applies a function to every
element of a sequence:

list(map(make_palindrome, names))

['miladdalim', 'tommot', 'tiffanyynaffit']

9. Generators

Recall list comprehension from earlier in the chapter:

[n for n in range(10)]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Comprehensions evaluate the entire expression at once, and then returns the full data product.
Sometimes, we want to work with just one part of our data at a time, for example, when we can’t
fit all of our data in memory. For this, we can use generators.

(n for n in range(10))

<generator object <genexpr> at 0x105c6f200>

Notice that we just created a generator object. Generator objects are like a “recipe” for
generating values. They don’t actually do any computation until they are asked to. We can get
values from a generator in three main ways:

• Using next()

• Using list()

• Looping

gen = (n for n in range(10))

next(gen)

next(gen)

Once the generator is exhausted, it will no longer return values:

gen = (n for n in range(10))

157
for i in range(11):

print(next(gen))

---------------------------------------------------------------------------

StopIteration Traceback (most recent call last)

<ipython-input-108-14d35f56c593> in <module>

1 gen = (n for n in range(10))

2 for i in range(11):

----> 3 print(next(gen))

StopIteration:

We can see all the values of a generator using list() but this defeats the purpose of using a
generator in the first place:

gen = (n for n in range(10))

list(gen)

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Finally, we can loop over generator objects too:

158
gen = (n for n in range(10))

for i in gen:

print(i)

Above, we saw how to create a generator object using comprehension syntax but with
parentheses. We can also create a generator using functions and the yield keyword (instead of
the return keyword):

def gen():

for n in range(10):

yield (n, n ** 2)

g = gen()

print(next(g))

print(next(g))

print(next(g))

(0, 0)

(1, 1)

(2, 4)

159
Below is some real-world motivation of a case where a generator might be useful. Say we want
to create a list of dictionaries containing information about houses in Canada.

import random # we'll learn about imports in a later chapter

import time

import memory_profiler

city = ['Vancouver', 'Toronto', 'Ottawa', 'Montreal']

def house_list(n):

houses = []

for i in range(n):

house = {

'id': i,

'city': [Link](city),

'bedrooms': [Link](1, 5),

'bathrooms': [Link](1, 3),

'price ($1000s)': [Link](300, 1000)

[Link](house)

return houses

house_list(2)

[{'id': 0,

'city': 'Toronto',

'bedrooms': 3,

'bathrooms': 2,

'price ($1000s)': 567},

{'id': 1,

160
'city': 'Toronto',

'bedrooms': 3,

'bathrooms': 1,

'price ($1000s)': 989}]

What happens if we want to create a list of 1,000,000 houses? How much time/memory will it
take?

start = [Link]()

mem = memory_profiler.memory_usage()

print(f"Memory usage before: {mem[0]:.0f} mb")

people = house_list(500000)

print(f"Memory usage after: {memory_profiler.memory_usage()[0]:.0f} mb")

print(f"Time taken: {[Link]() - start:.2f}s")

Memory usage before: 48 mb

Memory usage after: 209 mb

Time taken: 1.67s

def house_generator(n):

for i in range(n):

house = {

'id': i,

'city': [Link](city),

'bedrooms': [Link](1, 5),

'bathrooms': [Link](1, 3),

'price ($1000s)': [Link](300, 1000)

yield house

161
start = [Link]()

print(f"Memory usage before: {mem[0]:.0f} mb")

people = house_generator(500000)

print(f"Memory usage after: {memory_profiler.memory_usage()[0]:.0f} mb")

print(f"Time taken: {[Link]() - start:.2f}s")

Memory usage before: 48 mb

Memory usage after: 52 mb

Time taken: 0.16s

Although, if we used list() to extract all of the genertator values, we’d lose our memory savings:

print(f"Memory usage before: {mem[0]:.0f} mb")

people = list(house_generator(500000))

print(f"Memory usage after: {memory_profiler.memory_usage()[0]:.0f} mb")

Memory usage before: 48 mb

Memory usage after: 211 mb

10. Docstrings

One problem we never really solved when talking about writing good functions was: “4. It is
hard to understand what it does just by looking at it”. This brings up the idea of function
documentation, called “docstrings”. The docstring goes right after the def line and is wrapped
in triple quotes """.

def make_palindrome(string):

"""Turns the string into a palindrome by concatenating itself with a reversed version of
itself."""

return string + string[::-1]

In Python we can use the help() function to view another function’s documentation. In
IPython/Jupyter, we can use ? to view the documentation string of any function in our
environment.

162
make_palindrome?

But, even easier than that, if your cursor is in the function parentheses, you can use the
shortcut shift + tab to open the docstring at will.

# make_palindrome('uncomment this line and try pressing shift+tab here.')

Creating Designs In Python:


What are Design Patterns?

A design pattern is a generic repeatable solution to a frequently occurring problem in software


design that is used in software engineering. It isn't a complete design that can be written in code
right away. It is a description or model for problem-solving that may be applied in a variety of
contexts.

Types of Software Design Patterns in Python

There are mainly three types of Design Patterns in Python:

1. Creational Design Patterns in Python

Creational design patterns are a subset of design patterns in software development. They deal
with the process of object creation, trying to make it more flexible and efficient. It makes the
system independent and how its objects are created, composed, and represented.

Types of Creational Design Patterns in Python:

1.1 Factory Method

Factory Method is a creational design pattern, that provide an interface for creating objects in
superclass, but subclasses are responsible to create the instance of the class.

1.2 Abstract Factory Method

Abstract Factory Method is a creational design pattern, it provides an interface for creating
families of related or dependent objects without specifying their concrete classes.

1.3 Builder Method

Builder Method is a creational design pattern, it provides an interface for constructing an object
and then have concrete builder classes that implement this interface to create specific objects in a
stepwise manner.

1.4 Prototype Method

163
Prototype Method is a creational design pattern, it provide to create new objects with the same
structure and initial state as an existing object without explicitly specifying their class or
construction details.

1.5 Singleton Method

Singleton Method is a creational design pattern, it provide a class has only one instance, and that
instance provides a global point of access to it.

2. Structural Design Patterns in Python

Structural design patterns are a subset of design patterns in software development that focus on
the composition of classes or objects to form larger, more complex structures. They help in
organizing and managing relationships between objects to achieve greater flexibility, reusability,
and maintainability in a software system.

Types of Structural Design Patterns in Python:

2.1 Adapter Method

Adapter Method is a structural design pattern, it allows you to make two incompatible interfaces
work together by creating a bridge between them.

2.2 Bridge Method

Bridge Method is a structural design pattern,it provide to design separate an object's abstraction
from its implementation so that the two can vary independently.

2.3 Composite Method

Composite Method is structural design pattern, it's used to compose objects into tree structures to
represent part-whole hierarchies. This pattern treats both individual objects and compositions of
objects it allow clients to work with complex structures of objects as if they were individual
objects.

2.4 Decorator Method

Decorator Method is structural design pattern, it allows to add behavior to individual objects,
either statically or dynamically, without affecting the behavior of other objects from the same
class.

2.5 Facade Method

Facade Method is a structural design pattern, it provides a simplified, higher-level interface to a


set of interfaces in a subsystem, making it easier for clients to interact with that subsystem.

164
2.6 Proxy Method

Proxy Method is a structural design pattern, it provide to create a substitute for an object, which
can act as an intermediary or control access to the real object.

2.7 Flyweight Method

Flyweight Method is a structural design pattern, it is used when we need to create a lot of objects
of a class. Since every object consumes memory space that can be crucial for low memory
devices, flyweight design pattern can be applied to reduce the load on memory by sharing
objects.

3. Behavioral Design Patterns in Python

Behavioral design patterns are a subset of design patterns in software development that deal with
the communication and interaction between objects and classes. They focus on how objects and
classes collaborate and communicate to accomplish tasks and responsibilities.

Types of Behavioral Design Pattern in Python:

3.1 Command Method

Command Method is a Behavioral Design Pattern, it promotes loose coupling between the sender
(client) and the receiver (the object that performs the operation) and provides a way to support
undoable operations.

3.2. Observer Method

165
It defines a one-to-many dependency between objects, so that when one object (the subject)
changes its state, all its dependents (observers) are notified and updated automatically.

3.3 Mediator Method

Mediator Method is a Behavioral Design Pattern, it promotes loose coupling between objects by
centralizing their communication through a mediator object. Instead of objects directly
communicating with each other, they communicate through the mediator, which encapsulates the
interaction and coordination logic.

3.4 Memento Method

Momento Method is a Behavioral Design Pattern, it provide to save and restore the previous state
of an object without revealing the details of its implementation.

3.5 Observer method

Observer Method is a Behavioral Design Pattern, it defines a one-to-many dependency between


objects, so that when one object (the subject) changes state, all its dependents (observers) are
notified and updated automatically.

3.6 State Method

State Method is a Behavioral Design Pattern, it allows an object to alter its behavior when its
internal state changes.

3.7 Strategy Method

Strategy Method is a Behavioral Design Pattern, it defines a family of algorithms, encapsulates


each one, and makes them interchangeable and it allows a client to choose an appropriate
algorithm from a family of algorithms at runtime.

3.8 Template Method

Template Method is a Behavioral Design Pattern, it defines the skeleton of an algorithm in a


method but lets subclasses alter some steps of that algorithm without changing its structure.

3.9 Visitor Method

Visitor Method is a Behavioral Design Pattern, it is used when you have a set of structured,
hierarchical objects and you want to perform various operations on these objects without
modifying their classes.

166
3.10 Interpreter Design Pattern

Interpreter pattern is used to defines a grammatical representation for a language and provides an
interpreter to deal with this grammar.

Knowing when to use design patterns in Python(or any programming language) is crucial for
effective software design. Below are guidelines on when to use and when not to use design
patterns:

When to Use Design Patterns in Python

• Recurring Problems: Use design patterns when you encounter recurring design
problems that have well-established solutions. Design patterns provide tested and proven
approaches to common software design challenges.

• Flexibility and Reusability: Use design patterns to promote code reusability, flexibility,
and maintainability. They help in structuring code in a way that makes it easier to modify
and extend as requirements evolve.

• Design Principles: Use design patterns to apply fundamental design principles such as
separation of concerns, encapsulation, and dependency inversion. They help in achieving
better modularity and reducing dependencies between components.

• Communication: Use design patterns to improve communication among team members.


Design patterns provide a common vocabulary and understanding of how to solve
particular problems, facilitating collaboration and code comprehension.

• Performance: In some cases, design patterns can improve performance by optimizing


resource usage, reducing overhead, or improving code execution efficiency.

When not to Use Design Patterns in Python

• Over-Engineering: Avoid using design patterns unnecessarily, especially for small or


simple problems. Over-engineering can lead to unnecessary complexity and overhead,
making the codebase harder to understand and maintain.

• Premature Optimization: Avoid using design patterns solely for the sake of
optimization before performance issues are identified. Premature optimization can lead to
added complexity without significant benefits and can hinder future changes.

• Unfamiliarity: Avoid using design patterns if you or your team are unfamiliar with them
or if their application does not align with the problem at hand. Using patterns incorrectly
can lead to misuse and potential design flaws.

167
• Project Constraints: Consider project constraints such as time, budget, and team
expertise. If applying a design pattern significantly increases development time or
introduces unnecessary complexity, it may not be appropriate for the project.

• Changing Requirements: Be cautious when applying design patterns in highly dynamic


environments where requirements frequently change. Overly rigid designs based on
patterns may struggle to adapt to evolving requirements.

168
UNIT - 5 PACKAGES IN PYTHON

Applications: Data Analysis and Visualization, real time numerical calculations, image
processing, AIML model predictions.

Introduction to Numpy -Creation of vectors and matrices - Matrix manipulation - Pandas - Pandas
data structures – Series and Data Frame - Data wrangling using pandas – Matplotlib - Scatter plot
- Line plot - Bar chart.

Introduction to Numpy:
NumPy, short for Numerical Python, is a foundational Python library for scientific computing. Its
primary feature is the ndarray object, a powerful and efficient multi-dimensional array designed
for numerical operations.

Key features and concepts of NumPy:

• ndarray object:

This is the core data structure in NumPy. Unlike Python lists, ndarrays are homogeneous (all
elements are of the same data type) and optimized for numerical computations, leading to
significant performance advantages, especially with large datasets.

• Efficient numerical operations:

NumPy provides a vast collection of mathematical functions that operate efficiently on arrays,
including linear algebra, Fourier transforms, random number generation, and more. These
operations are often implemented in optimized C or Fortran code, making them much faster than
equivalent operations on standard Python lists.

• Broadcasting:

This feature allows NumPy to perform operations on arrays of different shapes and sizes,
automatically aligning them in a mathematically sensible way without requiring explicit
loops. This simplifies code and enhances performance.

• Array creation and manipulation:

NumPy offers various methods for creating arrays (e.g., from Python lists, with specific values
like zeros or ones, or by generating sequences) and manipulating their shape, size, and content.

• Indexing and slicing:

Similar to Python lists, ndarrays support powerful indexing and slicing techniques to access and
modify specific elements or sub-arrays.

169
• Integration with other libraries:

NumPy serves as the foundation for many other scientific computing libraries in Python, including
SciPy (for advanced scientific and technical computing), Pandas (for data analysis and
manipulation), and Matplotlib (for plotting and visualization).

Example of creating a NumPy array:

Python

import numpy as np
# Create a 1D array from a Python list
arr1d = [Link]([1, 2, 3, 4, 5])
print(f"1D Array: {arr1d}")
# Create a 2D array
arr2d = [Link]([[1, 2, 3], [4, 5, 6]])
print(f"2D Array:\n{arr2d}")

Installation of NumPy

If you have Python and PIP already installed on a system, then installation of NumPy is very easy.

Install it using this command:

C:\Users\Your Name>pip install numpy

If this command fails, then use a python distribution that already has NumPy installed like,
Anaconda, Spyder etc.

Import NumPy

Once NumPy is installed, import it in your applications by adding the import keyword:

import numpy

Now NumPy is imported and ready to use.

Example

import numpy

arr = [Link]([1, 2, 3, 4, 5])

print(arr)

NumPy as np

170
NumPy is usually imported under the np alias.

alias: In Python alias are an alternate name for referring to the same thing.

Create an alias with the as keyword while importing:

import numpy as np

Now the NumPy package can be referred to as np instead of numpy.

Example

import numpy as np

arr = [Link]([1, 2, 3, 4, 5])

print(arr)

Checking NumPy Version

The version string is stored under __version__ attribute.

Example

import numpy as np

print(np.__version__)

Creating NumPy Arrays

• Using ndarray : The array object is called ndarray. NumPy arrays are created using the
array() function.

Example:

import numpy as np

# Creating a 1D array

x = [Link]([1, 2, 3])

# Creating a 2D array

y = [Link]([[1, 2], [3, 4]])

# Creating a 3D array

z = [Link]([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])

171
print(x)

print(y)

print(z)

Output

[1 2 3]

[[1 2]

[3 4]]

[[[1 2]

[3 4]]

[[5 6]

[7 8]]]

NumPy Array Indexing

Knowing the basics of NumPy array indexing is important for analyzing and manipulating the
array object.

• Basic Indexing: Basic indexing in NumPy allows you to access elements of an array using
indices.

Example:

import numpy as np

# Create a 1D array

arr1d = [Link]([10, 20, 30, 40, 50])

# Single element access

print("Single element access:", arr1d[2])

# Negative indexing

print("Negative indexing:", arr1d[-1])

# Create a 2D array

172
arr2d = [Link]([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Multidimensional array access

print("Multidimensional array access:", arr2d[1, 0])

Output

Single element access: 30

Negative indexing: 50

Multidimensional array access: 4

• Slicing: Just like lists in Python, NumPy arrays can be sliced. As arrays can be
multidimensional, you need to specify a slice for each dimension of the array.

Example:

import numpy as np

arr = [Link]([[1, 2, 3], [4, 5, 6]])

#elements from index 1 to 3

print("Range of Elements:",arr[1:4])

#all rows, second column

print("Multidimensional Slicing:", arr[:, 1])

Output

Range of Elements: [[4 5 6]]

Multidimensional Slicing: [2 5]

• Advanced Indexing: Advanced Indexing in NumPy provides more powerful and flexible
ways to access and manipulate array elements.

Example:

import numpy as np

arr = [Link]([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])

# Integer array indexing


173
indices = [Link]([1, 3, 5])

print ("Integer array indexing:", arr[indices])

# boolean array indexing

cond = arr > 0

print ("\nElements greater than 0:\n", arr[cond])

Output

Elements at indices (0, 3), (1, 2), (2, 1),(3, 0):

[4. 6. 0. 3.]

Elements greater than 0:

[2. 4. 4. 6. 2.6 7. 8. 3. 4. 2. ]

NumPy Basic Operations

Element-wise operations in NumPy allow you to perform mathematical operations on each


element of an array individually, without the need for explicit loops.

• Element-wise Operations: We can perform arithmetic operations like addition,


subtraction, multiplication, and division directly on NumPy arrays.

Example:

import numpy as np

x = [Link]([1, 2, 3])

y = [Link]([4, 5, 6])

# Addition

add = x + y

print("Addition:",add)

# Subtraction

subtract = x - y

print("substration:",subtract)

174
# Multiplication

multiply = x * y

print("multiplication:",multiply)

# Division

divide = x / y

print("division:", divide)

Output

Addition: [5 7 9]

substration: [-3 -3 -3]

multiplication: [ 4 10 18]

division: [0.25 0.4 0.5 ]

• Unary Operation: These operations are applied to each individual element in the array,
without the need for multiple arrays (as in binary operations).

Example:

import numpy as np

# Example array with both positive and negative values

arr = [Link]([-3, -1, 0, 1, 3])

# Applying a unary operation: absolute value

result = [Link](arr)

print("Absolute value:", result)

Output

Absolute value: [3 1 0 1 3]

• Binary Operators: Numpy Binary Operations apply to the array elementwise and a new
array is created. We can use all basic arithmetic operators like +, -, /, etc. In the case of
+=, -=, = operators, the existing array is modified.

175
Example:

import numpy as np

# Two example arrays

arr1 = [Link]([1, 2, 3])

arr2 = [Link]([4, 5, 6])

# Applying a binary operation: addition

result = [Link](arr1, arr2)

print("Array 1:", arr1)

print("Array 2:", arr2)

print("Addition Result:", result)

Output

Array 1: [1 2 3]

Array 2: [4 5 6]

Addition Result: [5 7 9]

NumPy ufuncs

NumPy provides familiar mathematical functions such as sin, cos, exp, etc. These functions also
operate elementwise on an array, producing an array as output.

Example:

import numpy as np

# create an array of sine values

a = [Link]([0, [Link]/2, [Link]])

print ("Sine values of array elements:", [Link](a))

# exponential values

a = [Link]([0, 1, 2, 3])

print ("Exponent of array elements:", [Link](a))

176
# square root of array values

print ("Square root of array elements:", [Link](a))

Output:

Sine values of array elements: [ 0.00000000e+00 1.00000000e+00 1.22464680e-16]

Exponent of array elements: [ 1. 2.71828183 7.3890561 20.08553692]

Square root of array elements: [ 0. 1. 1.41421356 1.73205081]

NumPy Sorting Arrays

We can use a simple [Link]() method for sorting Python NumPy arrays.

Example:

import numpy as np

# set alias names for dtypes

dtypes = [('name', 'S10'), ('grad_year', int), ('cgpa', float)]

# Values to be put in array

values = [('Hrithik', 2009, 8.5), ('Ajay', 2008, 8.7),

('Pankaj', 2008, 7.9), ('Aakash', 2009, 9.0)]

# Creating array

arr = [Link](values, dtype = dtypes)

print ("\nArray sorted by names:\n",

[Link](arr, order = 'name'))

print ("Array sorted by graduation year and then cgpa:\n",

[Link](arr, order = ['grad_year', 'cgpa']))

Output

Array sorted by names:

[(b'Aakash', 2009, 9. ) (b'Ajay', 2008, 8.7) (b'Hrithik', 2009, 8.5)

177
(b'Pankaj', 2008, 7.9)]

Array sorted by graduation year and then cgpa:

[(b'Pankaj', 2008, 7.9) (b'Ajay',...

Creation of vectors and matrices:


NumPy is a general-purpose array-processing package. It provides a high-performance
multidimensional array object, and tools for working with these arrays. It is the fundamental
package for scientific computing with Python. Numpy is basically used for creating array of n
dimensions.

Vector are built from components, which are ordinary numbers. We can think of a vector as a list
of numbers, and vector algebra as operations performed on the numbers in the list. In other words
vector is the numpy 1-D array.

In order to create a vector, we use [Link] method.

Syntax : [Link](list)
Argument : It take 1-D list it can be 1 row and n columns or n rows and 1 column
Return : It returns vector which is [Link]

Note: We can create vector with other method as well which return 1-D numpy array for example
[Link](10), [Link]((4, 1)) gives 1-D array, but most appropriate way is using [Link] with
the 1-D list.

Creating a Vector
In this example we will create a horizontal vector and a vertical vector

# importing numpy

import numpy as np

# creating a 1-D list (Horizontal)

list1 = [1, 2, 3]

# creating a 1-D list (Vertical)

list2 = [[10],

178
[20],

[30]]

# creating a vector1

# vector as row

vector1 = [Link](list1)

# creating a vector 2

# vector as column

vector2 = [Link](list2)

# showing horizontal vector

print("Horizontal Vector")

print(vector1)

print("----------------")

# showing vertical vector

print("Vertical Vector")

print(vector2)

Output :

Horizontal Vector

[1 2 3]

----------------

179
Vertical Vector

[[10]

[20]

[30]]

Basic Arithmetic operation:


In this example we will see do arithmetic operations which are element-wise between two
vectors of equal length to result in a new vector with the same length

# importing numpy

import numpy as np

# creating a 1-D list (Horizontal)

list1 = [5, 6, 9]

# creating a 1-D list (Horizontal)

list2 = [1, 2, 3]

# creating first vector

vector1 = [Link](list1)

# printing vector1

print("First Vector : " + str(vector1))

# creating second vector

vector2 = [Link](list2)

# printing vector2

print("Second Vector : " + str(vector2))

# adding both the vector

# a + b = (a1 + b1, a2 + b2, a3 + b3)

addition = vector1 + vector2

# printing addition vector

print("Vector Addition : " + str(addition))

180
# subtracting both the vector

# a - b = (a1 - b1, a2 - b2, a3 - b3)

subtraction = vector1 - vector2

# printing addition vector

print("Vector Subtraction : " + str(subtraction))

# multiplying both the vector

# a * b = (a1 * b1, a2 * b2, a3 * b3)

multiplication = vector1 * vector2

# printing multiplication vector

print("Vector Multiplication : " + str(multiplication))

# dividing both the vector

# a / b = (a1 / b1, a2 / b2, a3 / b3)

division = vector1 / vector2

# printing division vector

print("Vector Division : " + str(division))

Output :

First Vector: [5 6 9]

Second Vector: [1 2 3]

Vector Addition: [ 6 8 12]

Vector Subtraction: [4 4 6]

Vector Multiplication: [ 5 12 27]

Vector Division: [5 3 3]

Vector Dot Product


In mathematics, the dot product or scalar product is an algebraic operation that takes two equal-
length sequences of numbers and returns a single number.
For this we will use dot method.

181
# importing numpy

import numpy as np

# creating a 1-D list (Horizontal)

list1 = [5, 6, 9]

# creating a 1-D list (Horizontal)

list2 = [1, 2, 3]

# creating first vector

vector1 = [Link](list1)

# printing vector1

print("First Vector : " + str(vector1))

# creating second vector

vector2 = [Link](list2)

# printing vector2

print("Second Vector : " + str(vector2))

# getting dot product of both the vectors

# a . b = (a1 * b1 + a2 * b2 + a3 * b3)

# a . b = (a1b1 + a2b2 + a3b3)

dot_product = [Link](vector2)

# printing dot product

print("Dot Product : " + str(dot_product))

Output:

First Vector : [5 6 9]

Second Vector : [1 2 3]

Dot Product : 44

182
Vector-Scalar Multiplication
Multiplying a vector by a scalar is called scalar multiplication. To perform scalar multiplication,
we need to multiply the scalar by each component of the vector.

# importing numpy

import numpy as np

# creating a 1-D list (Horizontal)

list1 = [1, 2, 3]

# creating first vector

vector = [Link](list1)

# printing vector1

print("Vector : " + str(vector))

# scalar value

scalar = 2

# printing scalar value

print("Scalar : " + str(scalar))

# getting scalar multiplication value

# s * v = (s * v1, s * v2, s * v3)

scalar_mul = vector * scalar

# printing dot product

print("Scalar Multiplication : " + str(scalar_mul))

Output

Vector : [1 2 3]

Scalar : 2

Scalar Multiplication : [2 4 6]

Matrix manipulation
Install and Import Numpy

183
To install Numpy, use pip ?

pip install numpy

Import Numpy ?

import numpy

Add, Subtract, Divide and Multiply matrices

We will use the following Numpy methods for matrix manipulations ?

• [Link]() ? Add two matrices

• [Link]() ? Subtract two matrices

• [Link]() ? Divide two matrices

• [Link]() ? Multiply two matrices

The element wise addition of matrix is :


[[ 8 10]
[13 15]]
The element wise subtraction of matrix is :
[[-6 -6]
[-5 -5]]
The element wise division of matrix is :
[[ 0.14285714 0.25 ]
[ 0.44444444 0.5 ]]

4. multiply() :- This function is used to perform element wise matrix multiplication.

5. dot() :- This function is used to compute the matrix multiplication, rather than element wise
multiplication.

# Python code to demonstrate matrix operations

# multiply() and dot()

# importing numpy for matrix operations

import numpy

184
# initializing matrices

x = [Link]([[1, 2], [4, 5]])

y = [Link]([[7, 8], [9, 10]])

# using multiply() to multiply matrices element wise

print ("The element wise multiplication of matrix is : ")

print ([Link](x,y))

# using dot() to multiply matrices

print ("The product of matrices is : ")

print ([Link](x,y))

Output :

The element wise multiplication of matrix is :


[[ 7 16]
[36 50]]
The product of matrices is :
[[25 28]
[73 82]]

6. sqrt() :- This function is used to compute the square root of each element of matrix.

7. sum(x,axis) :- This function is used to add all the elements in matrix. Optional "axis" argument
computes the column sum if axis is 0 and row sum if axis is 1.

8. "T" :- This argument is used to transpose the specified matrix.

Implementation:

# Python code to demonstrate matrix operations

# sqrt(), sum() and "T"

# importing numpy for matrix operations

185
import numpy

# initializing matrices

x = [Link]([[1, 2], [4, 5]])

y = [Link]([[7, 8], [9, 10]])

# using sqrt() to print the square root of matrix

print ("The element wise square root is : ")

print ([Link](x))

# using sum() to print summation of all elements of matrix

print ("The summation of all matrix element is : ")

print ([Link](y))

# using sum(axis=0) print summation of each column of matrix

print ("The column wise summation of all matrix is : ")

print ([Link](y,axis=0))

# using sum(axis=1) print summation of each row of matrix

print ("The row wise summation of all matrix is : ")

print ([Link](y,axis=1))

# using "T" to transpose the matrix

print ("The transpose of given matrix is : ")

print (x.T)

Output :

The element wise square root is :


[[ 1. 1.41421356]
[ 2. 2.23606798]]
The summation of all matrix element is :
34
The column wise summation of all matrix is :

186
[16 18]
The row wise summation of all matrix is :
[15 19]
The transpose of given matrix is :
[[1 4]
[2 5]]

Introduction to Pandas:
Pandas is open-source Python library which is used for data manipulation and analysis. It
consist of data structures and functions to perform efficient operations on data. It is well -suited
for working with tabular data such as spreadsheets or SQL tables. It is used in data science
because it works well with other important libraries. It is built on top of the NumPy
library as it makes easier to manipulate and analyze. Pandas is used in other libraries such as:

• Matplotlib for plotting graphs

• SciPy for statistical analysis

• Scikit-learn for machine learning algorithms.

• It uses many functionalities provided by NumPy library.

Here is a various tasks that we can do using Pandas:

• Data Cleaning, Merging and Joining: Clean and combine data from multiple sources,
handling inconsistencies and duplicates.

• Handling Missing Data: Manage missing values (NaN) in both floating and non-
floating point data.

• Column Insertion and Deletion: Easily add, remove or modify columns in a


DataFrame.

• Group By Operations: Use "split-apply-combine" to group and analyze data.

• Data Visualization: Create visualizations with Matplotlib and Seaborn, integrated with
Pandas.

Installing Pandas

First step in working with Pandas is to ensure whether it is installed in the system or not. If not
then we need to install it on our system using the pip command.

Installing Pandas

187
First step in working with Pandas is to ensure whether it is installed in the system or not. If not
then we need to install it on our system using the pip command.

pip install pandas

Importing Pandas

After the Pandas have been installed in the system we need to import the library. This module
is imported using:

import pandas as pd

Note: pd is just an alias for Pandas. It’s not required but using it makes the code shorter when
calling methods or properties.

Data Structures in Pandas Library

Pandas provide two data structures for manipulating data which are as follows:

1. Pandas Series

A Pandas Series is one-dimensional labeled array capable of holding data of any type (integer,
string, float, Python objects etc.). The axis labels are collectively called indexes.

Pandas Series is created by loading the datasets from existing storage which can be a SQL
database, a CSV file or an Excel file. It can be created from lists, dictionaries, scalar values,
etc.

Example: Creating a series using the Pandas Library.

import pandas as pd

import numpy as np

ser = [Link]()

print("Pandas Series: ", ser)

data = [Link](['g', 'e', 'e', 'k', 's'])

ser = [Link](data)

print("Pandas Series:\n", ser)

Output:

188
Pandas Series

2. Pandas DataFrame

Pandas DataFrame is a two-dimensional data structure with labeled axes (rows and columns).
It is created by loading the datasets from existing storage which can be a SQL database, a CSV
file or an Excel file. It can be created from lists, dictionaries, a list of dictionaries etc.

Example: Creating a DataFrame Using the Pandas Library

import pandas as pd

df = [Link]()

print(df)

lst = ['Geeks', 'For', 'Geeks', 'is', 'portal', 'for', 'Geeks']

df = [Link](lst)

print(df)

Output

Pandas data structures:


189
Python Pandas Data Structures

Data structures in Pandas are designed to handle data efficiently. They allow for the organization,
storage, and modification of data in a way that optimizes memory usage and computational
performance. Python Pandas library provides two primary data structures for handling and
analyzing data −

• Series

• DataFrame

In general programming, the term "data structure" refers to the method of collecting, organizing,
and storing data to enable efficient access and modification. Data structures are collections of data
types that provide the best way of organizing items (values) in terms of memory usage.

Pandas is built on top of NumPy and integrates well within a scientific computing environment
with many other third-party libraries. This tutorial will provide a detailed introduction to these data
structures.

Dimension and Description of Pandas Data Structures

Data
Dimensions Description
Structure

Series 1 A one-dimensional labeled homogeneous array, sizeimmutable.

A two-dimensional labeled, size-mutable tabular structure with


Data Frames 2
potentially heterogeneously typed columns.

Working with two or more dimensional arrays can be complex and time-consuming, as users need
to carefully consider the data's orientation when writing functions. However, Pandas simplifies
this process by reducing the mental effort required. For example, when dealing with tabular data
(DataFrame), it's more easy to think in terms of rows and columns instead of axis 0 and axis 1.

Mutability of Pandas Data Structures

All Pandas data structures are value mutable, meaning their contents can be changed. However,
their size mutability varies −

• Series − Size immutable.

• DataFrame − Size mutable.

190
Series
A Series is a one-dimensional labeled array that can hold any data type. It can
store integers, strings, floating-point numbers, etc. Each value in a Series is
associated with a label (index), which can be an integer or a string.

Name Steve

Age 35

Gender Male

Rating 3.5

Example
Consider the following Series which is a collection of different data types

import pandas as pd

data = ['Steve', '35', 'Male', '3.5']

series = [Link](data, index=['Name', 'Age', 'Gender', 'Rating'])

print(series)

output −

Name Steve

Age 35

Gender Male

Rating 3.5

dtype: object

DataFrame

A DataFrame is a two-dimensional labeled data structure with columns that can hold different data
types. It is similar to a table in a database or a spreadsheet. Consider the following data representing
the performance rating of a sales team −

191
Name Age Gender Rating

Steve 32 Male 3.45

Lia 28 Female 4.6

Vin 45 Male 3.9

Katie 38 Female 2.78

Example

The above tabular data can be represented in a DataFrame as follows −

import pandas as pd

# Data represented as a dictionary

data =

{ 'Name': ['Steve', 'Lia', 'Vin', 'Katie'],

'Age': [32, 28, 45, 38],

'Gender': ['Male', 'Female', 'Male', 'Female'],

'Rating': [3.45, 4.6, 3.9, 2.78] }

# Creating the DataFrame

df = [Link](data)

# Display the DataFrame

print(df)

Output

On executing the above code you will get the following output −

Name Age Gender Rating

0 Steve 32 Male 3.45

1 Lia 28 Female 4.60


192
2 Vin 45 Male 3.90

3 Katie 38 Female 2.78

Purpose of Using More Than One Data Structure

Pandas data structures are flexible containers for lower-dimensional data. For instance, a
DataFrame is a container for Series, and a Series is a container for scalars. This flexibility allows
for efficient data manipulation and storage.

Building and handling multi-dimensional arrays can be boring and require careful consideration
of the data's orientation when writing functions. Pandas reduces this mental effort by providing
intuitive data structures.

Data wrangling using pandas:


Data wrangling with Pandas in Python involves transforming and cleaning raw data into a usable
format for analysis or machine learning. Pandas, a powerful open-source library, provides data
structures like DataFrames and Series, which are central to this process.

Key aspects of data wrangling with Pandas:

• Loading Data:

Data is typically loaded into a Pandas DataFrame from various sources like CSV, Excel, or
databases using functions such as pd.read_csv() or pd.read_excel().

• Data Exploration and Inspection:

• [Link](), [Link](): View the first or last few rows of the DataFrame.

• [Link](): Get a summary of the DataFrame, including data types and non-null
counts.

• [Link](): Generate descriptive statistics for numerical columns.

• df.value_counts(): Count unique values in a Series (column).

• Handling Missing Values:

• [Link]() or [Link](): Identify missing values (NaN).

• [Link](): Fill missing values with a specified value, mean, median, or mode.

• [Link](): Remove rows or columns containing missing values.

• Data Cleaning and Transformation:

193
• Renaming columns: [Link](columns={'old_name': 'new_name'}).

• Changing data types: df['column'].astype('new_dtype').

• Removing duplicates: df.drop_duplicates().

• String manipulation: Using string methods on Series


(e.g., df['column'].[Link](), df['column'].[Link]()).

• Applying functions: [Link]() or [Link]() for custom transformations.

• Data Structuring and Reshaping:

• Filtering: Selecting rows based on conditions (e.g., df[df['column'] > value]).

• Selecting columns: Accessing specific columns (e.g., df[['col1', 'col2']]).

• Grouping and Aggregating: [Link]() combined with aggregation functions


like sum(), mean(), count().

• Merging/Joining: Combining DataFrames based on common columns


using [Link]().

• Concatenating: Stacking DataFrames vertically or horizontally using [Link]().

• Pivoting and Melting: Reshaping data between wide and long formats
using df.pivot_table() or [Link]().

By utilizing these Pandas functionalities, raw and messy datasets can be effectively prepared for
subsequent data analysis, visualization, or machine learning tasks.

Data exploration in Python

Here in Data exploration, we load the data into a dataframe, and then we visualize the data in a
tabular format.

# Import pandas package

import pandas as pd

# Assign data

data = {'Name': ['Jai', 'Princi', 'Gaurav',

'Anuj', 'Ravi', 'Natasha', 'Riya'],

194
'Age': [17, 17, 18, 17, 18, 17, 17],

'Gender': ['M', 'F', 'M', 'M', 'M', 'F', 'F'],

'Marks': [90, 76, 'NaN', 74, 65, 'NaN', 71]}

# Convert into DataFrame

df = [Link](data)

# Display data

df

Output:

defining the dataframe and displaying in tabular


format

Dealing with missing values in Python

As we can see from the previous output, there are NaN values present in the MARKS column which
is a missing value in the dataframe that is going to be taken care of in data wrangling by replacing
them with the column mean.

# Compute average

c = avg = 0

195
for ele in df['Marks']:

if str(ele).isnumeric():

c += 1

avg += ele

avg /= c

# Replace missing values

df = [Link](to_replace="NaN",

value=avg)

# Display data

df

Output:

replacing Nan values with average

Data Replacing in Data Wrangling

in the GENDER column, we can replace the Gender column data by categorizing them into
different numbers.

196
# Categorize gender

df['Gender'] = df['Gender'].map({'M': 0,

'F': 1, }).astype(float)

# Display data

df

Output:

Data encoding for gender variable in data


wrangling

Filtering data in Data Wrangling

suppose there is a requirement for the details regarding name, gender, and marks of the top-scoring
students. Here we need to remove some using the pandas slicing method in data wrangling from
unwanted data.

# Filter top scoring students

df = df[df['Marks'] >= 75].copy()

# Remove age column from filtered DataFrame

[Link]('Age', axis=1, inplace=True)

197
# Display data

df

Output:

Dropping column and filtering rows

Hence, we have finally obtained an efficient dataset that can be further used for various purposes.

Now that we have seen the basics of data wrangling using Python and pandas. Below we will
discuss various operations using which we can perform data wrangling:

Data Wrangling Using Merge Operation

Merge operation is used to merge two raw data into the desired format.

Syntax: [Link]( data_frame1,data_frame2, on="field ")

Here the field is the name of the column which is similar in both data-frame.

For example: Suppose that a Teacher has two types of Data, the first type of Data consists of
Details of Students and the Second type of Data Consist of Pending Fees Status which is taken
from the Account Office. So The Teacher will use the merge operation here in order to merge the
data and provide it meaning. So that teacher will analyze it easily and it also reduces the time and
effort of the Teacher from Manual Merging.

Creating First Dataframe to Perform Merge Operation using Data Wrangling:

# import module

import pandas as pd

# creating DataFrame for Student Details

198
details = [Link]({

'ID': [101, 102, 103, 104, 105, 106,

107, 108, 109, 110],

'NAME': ['Jagroop', 'Praveen', 'Harjot',

'Pooja', 'Rahul', 'Nikita',

'Saurabh', 'Ayush', 'Dolly', "Mohit"],

'BRANCH': ['CSE', 'CSE', 'CSE', 'CSE', 'CSE',

'CSE', 'CSE', 'CSE', 'CSE', 'CSE']})

# printing details

print(details)

Output:

printing dataframe

Creating Second Dataframe to Perform Merge operation using Data Wrangling:

# Import module

import pandas as pd

# Creating Dataframe for Fees_Status

fees_status = [Link](

{'ID': [101, 102, 103, 104, 105,

199
106, 107, 108, 109, 110],

'PENDING': ['5000', '250', 'NIL',

'9000', '15000', 'NIL',

'4500', '1800', '250', 'NIL']})

# Printing fees_status

print(fees_status)

Output:

Define second dataframe

Data Wrangling Using Merge Operation:

# Import module

import pandas as pd

# Creating Dataframe

details = [Link]({

'ID': [101, 102, 103, 104, 105,

106, 107, 108, 109, 110],

'NAME': ['Jagroop', 'Praveen', 'Harjot',

'Pooja', 'Rahul', 'Nikita',

'Saurabh', 'Ayush', 'Dolly', "Mohit"],

200
'BRANCH': ['CSE', 'CSE', 'CSE', 'CSE', 'CSE',

'CSE', 'CSE', 'CSE', 'CSE', 'CSE']})

# Creating Dataframe

fees_status = [Link](

{'ID': [101, 102, 103, 104, 105,

106, 107, 108, 109, 110],

'PENDING': ['5000', '250', 'NIL',

'9000', '15000', 'NIL',

'4500', '1800', '250', 'NIL']})

# Merging Dataframe

print([Link](details, fees_status, on='ID'))

Output:

Merging two dataframes

Data Wrangling Using Grouping Method

The grouping method in Data wrangling is used to provide results in terms of various groups taken
out from Large Data. This method of pandas is used to group the outset of data from the large data
set.

Example: There is a Car Selling company and this company have different Brands of various Car
Manufacturing Company like Maruti, Toyota, Mahindra, Ford, etc., and have data on where
different cars are sold in different years. So the Company wants to wrangle only that data where

201
cars are sold during the year 2010. For this problem, we use another data Wrangling technique
which is a pandas groupby() method.

Creating dataframe to use Grouping methods[Car selling datasets]:

# Import module

import pandas as pd

# Creating Data

car_selling_data = {'Brand': ['Maruti', 'Maruti', 'Maruti',

'Maruti', 'Hyundai', 'Hyundai',

'Toyota', 'Mahindra', 'Mahindra',

'Ford', 'Toyota', 'Ford'],

'Year': [2010, 2011, 2009, 2013,

2010, 2011, 2011, 2010,

2013, 2010, 2010, 2011],

'Sold': [6, 7, 9, 8, 3, 5,

2, 8, 7, 2, 4, 2]}

# Creating Dataframe of car_selling_data

df = [Link](car_selling_data)

# printing Dataframe

print(df)

Output:

202
Creating new dataframe

Creating Dataframe to use Grouping methods[DATA OF THE YEAR 2010]:

# Import module

import pandas as pd

# Creating Data

car_selling_data = {'Brand': ['Maruti', 'Maruti', 'Maruti',

'Maruti', 'Hyundai', 'Hyundai',

'Toyota', 'Mahindra', 'Mahindra',

'Ford', 'Toyota', 'Ford'],

'Year': [2010, 2011, 2009, 2013,

2010, 2011, 2011, 2010,

2013, 2010, 2010, 2011],

'Sold': [6, 7, 9, 8, 3, 5,

2, 8, 7, 2, 4, 2]}

# Creating Dataframe for Provided Data

df = [Link](car_selling_data)

# Group the data when year = 2010

203
grouped = [Link]('Year')

print(grouped.get_group(2010))

Output:

Using groupby method on dataframe

Data Wrangling by Removing Duplication

Pandas duplicates() method helps us to remove duplicate values from Large Data. An important
part of Data Wrangling is removing Duplicate values from the large data set.

Syntax: [Link](subset=None, keep='first')

Here subset is the column value where we want to remove the Duplicate value.

In keeping, we have 3 options :

• if keep ='first' then the first value is marked as the original rest of all values if occur will
be removed as it is considered duplicate.

• if keep='last' then the last value is marked as the original rest the above same values will
be removed as it is considered duplicate values.

• if keep ='false' all the values which occur more than once will be removed as all are
considered duplicate values.

Introduction to Matplotlib:
Matplotlib is a widely-used, open-source plotting library in Python, primarily employed for
creating static, animated, and interactive visualizations. It offers a comprehensive set of tools and
functions for generating various types of plots, including:

• Basic Plots: Line plots, scatter plots, bar charts, histograms, and pie charts.

• Statistical Visualizations: Box plots, violin plots, and error bar plots.

• Specialized Plots: Contour plots, quiver plots, and 3D plots (using mpl_toolkits.mplot3d).

Key Features:

• Flexibility and Customization:

204
Matplotlib provides extensive control over plot elements, allowing users to customize colors,
labels, legends, titles, gridlines, and styles to create publication-quality figures.

• Object-Oriented API:

It offers an object-oriented interface, allowing for fine-grained control over plot elements and
enabling the embedding of plots into GUI applications.

• Integration:

Matplotlib integrates seamlessly with other popular Python libraries like NumPy and Pandas,
facilitating efficient data analysis and visualization workflows.

• Multiple Output Formats:

Plots can be exported to various formats, including PNG, JPEG, PDF, SVG, and GIF.

Core Concepts:

• Figure: The top-level container for all plot elements, analogous to a canvas.

• Axes: Represents the individual plots within a figure, where data is actually plotted. A
figure can contain multiple axes.

• Pyplot: A module within Matplotlib that provides a convenient, MATLAB-like interface


for creating plots with less code, particularly useful for quick visualizations.

Applications:

Matplotlib is widely used in scientific research, data analysis, engineering, and other fields for data
exploration, presentation, and communication of insights through visual representations.

Example of a Plot in Matplotlib:

Let's create a simple line plot using Matplotlib, showcasing the ease with which you can visualize
data.

import [Link] as plt

x = [0, 1, 2, 3, 4]

y = [0, 1, 4, 9, 16]

[Link](x, y)

205
[Link]()

Components or Parts of Matplotlib Figure

Anatomy of a Matplotlib Plot: This section dives into the key components of a Matplotlib plot,
including figures, axes, titles, and legends, essential for effective data visualization.

206
The parts of a Matplotlib figure include (as shown in the figure above):

• Figure: The overarching container that holds all plot elements, acting as the canvas for
visualizations.

• Axes: The areas within the figure where data is plotted; each figure can contain multiple
axes.

• Axis: Represents the x-axis and y-axis, defining limits, tick locations, and labels for data
interpretation.

• Lines and Markers: Lines connect data points to show trends, while markers denote
individual data points in plots like scatter plots.

• Title and Labels: The title provides context for the plot, while axis labels describe what
data is being represented on each axis.

Matplotlib Pyplot

207
Pyplot is a module within Matplotlib that provides a MATLAB-like interface for making plots. It
simplifies the process of adding plot elements such as lines, images, and text to the axes of the
current figure. Steps to Use Pyplot:

• Import Matplotlib: Start by importing [Link] as plt.

• Create Data: Prepare your data in the form of lists or arrays.

• Plot Data: Use [Link]() to create the plot.

• Customize Plot: Add titles, labels, and other elements using methods like [Link](),
[Link](), and [Link]().

• Display Plot: Use [Link]() to display the plot.

Let's visualize a basic plot, and understand basic components of matplotlib figure:

import [Link] as plt

x = [0, 2, 4, 6, 8]

y = [0, 4, 16, 36, 64]

fig, ax = [Link]()

[Link](x, y, marker='o', label="Data Points")

ax.set_title("Basic Components of Matplotlib Figure")

ax.set_xlabel("X-Axis")

ax.set_ylabel("Y-Axis")

[Link]()

Output:

208
Basic
Components of matplotlib figure

Different Types of Plots in Matplotlib

Matplotlib offers a wide range of plot types to suit various data visualization needs. Here are some
of the most commonly used types of plots in Matplotlib:

• 1. Line Graph

• 2. Bar Chart

• 3. Histogram

• 4. Scatter Plot

• 5. Pie Chart

• 6. 3D Plot

and many more..

209
Bar chart and Pie chart

For learning about the different types of plots in Matplotlib, please read Types of Plots in
Matplotlib.

Key Features of Matplotlib

• Versatile Plotting: Create a wide variety of visualizations, including line plots, scatter
plots, bar charts, and histograms.

• Extensive Customization: Control every aspect of your plots, from colors and markers to
labels and annotations.

• Seamless Integration with NumPy: Effortlessly plot data arrays directly, enhancing data
manipulation capabilities.

• High-Quality Graphics: Generate publication-ready plots with precise control over


aesthetics.

• Cross-Platform Compatibility: Use Matplotlib on Windows, macOS, and Linux without


issues.

• Interactive Visualizations: Engage with your data dynamically through interactive


plotting features.

What is Matplotlib Used For?

Matplotlib is a Python library for data visualization, primarily used to create static, animated, and
interactive plots. It provides a wide range of plotting functions to visualize data effectively.

Key Uses of Matplotlib:

210
• Basic Plots: Line plots, bar charts, histograms, scatter plots, etc.

• Statistical Visualization: Box plots, error bars, and density plots.

• Customization: Control over colors, labels, gridlines, and styles.

• Subplots & Layouts: Create multiple plots in a single figure.

• 3D Plotting: Surface plots and 3D scatter plots using mpl_toolkits.mplot3d.

• Animations & Interactive Plots: Dynamic visualizations with FuncAnimation.

• Integration: Works well with Pandas, NumPy and Jupyter Notebooks.

Scatter plots are one of the most fundamental and powerful tools for visualizing relationships
between two numerical variables. [Link]() plots points on a Cartesian plane
defined by X and Y coordinates. Each point represents a data observation, allowing us to visually
analyze how two variables correlate, cluster or distribute. For example:

import [Link] as plt

import numpy as np

x = [Link]([12, 45, 7, 32, 89, 54, 23, 67, 14, 91])

y = [Link]([99, 31, 72, 56, 19, 88, 43, 61, 35, 77])

[Link](x, y)

[Link]("Basic Scatter Plot")

[Link]("X Values")

[Link]("Y Values")

[Link]()

Output

211
Using [Link]()

Explanation: [Link](x, y) creates a scatter plot on a 2D plane to visualize the relationship


between two variables, with a title and axis labels added for clarity and context.

Syntax

[Link](x, y, s=None, c=None, marker=None, cmap=None, alpha=None,


edgecolors=None, label=None)

Parameters:

Parameter Description

x, y Sequences of data points to plot

s Marker size (scalar or array-like)

c Marker color

marker Shape of the marker

cmap Colormap for mapping numeric values to colors

alpha Transparency (0 = transparent, 1 = opaque)

212
Parameter Description

edgecolors Color of marker edges

label Legend label for the dataset

Returns: This function returns a PathCollection object representing the scatter plot points. This
object can be used to further customize the plot or to update it dynamically.

Examples

Example 1: In this example, we compare the height and weight of two different groups using
different colors for each group.

x1 = [Link]([160, 165, 170, 175, 180, 185, 190, 195, 200, 205])

y1 = [Link]([55, 58, 60, 62, 64, 66, 68, 70, 72, 74])

x2 = [Link]([150, 155, 160, 165, 170, 175, 180, 195, 200, 205])

y2 = [Link]([50, 52, 54, 56, 58, 64, 66, 68, 70, 72])

[Link](x1, y1, color='blue', label='Group 1')

[Link](x2, y2, color='red', label='Group 2')

[Link]('Height (cm)')

[Link]('Weight (kg)')

[Link]('Comparison of Height vs Weight between two groups')

[Link]()

[Link]()

Output

213
Using [Link]()

Explanation: We define NumPy arrays x1, y1 and x2, y2 for height and weight data of two
groups. Using [Link](), Group 1 is plotted in blue and Group 2 in red, each with labels. The
x-axis and y-axis are labeled "Height (cm)" and "Weight (kg)" for clarity.

Matplotlib Line

Linestyle

You can use the keyword argument linestyle, or shorter ls, to change the style of the plotted line:

ExampleGet your own Python Server

Use a dotted line:

import [Link] as plt


import numpy as np
ypoints = [Link]([3, 8, 1, 10])
[Link](ypoints, linestyle = 'dotted')
[Link]()

Result:

214
Example

Use a dashed line:

[Link](ypoints, linestyle = 'dashed')

Result:

215
Bar Plot in Matplotlib

A bar plot uses rectangular bars to represent data categories, with bar length or height
proportional to their values. It compares discrete categories, with one axis for categories and the
other for values.

Consider a simple example where we visualize the sales of different fruits:

import [Link] as plt

import numpy as np

fruits = ['Apples', 'Bananas', 'Cherries', 'Dates']

sales = [400, 350, 300, 450]

[Link](fruits, sales)

[Link]('Fruit Sales')

[Link]('Fruits')

[Link]('Sales')

[Link]()

Output:

Simple bar plot for fruits sales

What is a Bar Plot?

216
A bar plot (or bar chart) is a graphical representation that uses rectangular bars to compare
different categories. The height or length of each bar corresponds to the value it represents. The
x-axis typically shows the categories being compared, while the y-axis shows the values
associated with those categories. This visual format makes it easy to compare quantities across
different groups.

This function takes several parameters:

• x: The categories (e.g., fruits).

• height: The corresponding values (e.g., sales).

• width: The width of the bars (default is 0.8).

• bottom: The baseline for the bars (default is 0).

• align: How to align bars ('center' or 'edge')

Why Use Bar Plots?

Bar plots are significant because they provide a clear and intuitive way to visualize categorical
data. They allow viewers to quickly grasp differences in size or quantity among categories,
making them ideal for presenting survey results, sales data, or any discrete variable comparisons.

Syntax: [Link](x, height, width, bottom, align)

Customizing Bar Colors

You can customize the color of the bars by using the color parameter in the bar() function:

import [Link] as plt

import numpy as np

fruits = ['Apples', 'Bananas', 'Cherries', 'Dates']

sales = [400, 350, 300, 450]

[Link](fruits, sales, color='violet')

[Link]('Fruit Sales')

[Link]('Fruits')

[Link]('Sales')

[Link]()

217
Output:

Changed color to Violet

Creating Horizontal Bar Plots

For horizontal bar plots, you can use the barh() function. This function works similarly to bar(),
but it displays bars horizontally:

import [Link] as plt

import numpy as np

fruits = ['Apples', 'Bananas', 'Cherries', 'Dates']

sales = [400, 350, 300, 450]

[Link](fruits, sales)

[Link]('Fruit Sales')

[Link]('Fruits')

[Link]('Sales')

[Link]()

Output:

218
Horizontal Plots

Adjusting Bar Width

You can control the width of the bars using the width parameter:

import [Link] as plt

import numpy as np

fruits = ['Apples', 'Bananas', 'Cherries', 'Dates']

sales = [400, 350, 300, 450]

[Link](fruits, sales, width=0.3)

[Link]('Fruit Sales')

[Link]('Fruits')

[Link]('Sales')

[Link]()

Output:

219
bar plot with low width()

Multiple bar plots

Multiple bar plots are used when comparison among the data set is to be done when one variable
is changing. We can easily convert it as a stacked area bar chart, where each subgroup is
displayed by one on top of the others. It can be plotted by varying the thickness and position of
the bars. Following bar plot shows the number of students passed in the engineering branch:

import numpy as np

import [Link] as plt

barWidth = 0.25

fig = [Link](figsize =(12, 8))

IT = [12, 30, 1, 8, 22]

ECE = [28, 6, 16, 5, 10]

CSE = [29, 3, 24, 25, 17]

br1 = [Link](len(IT))

br2 = [x + barWidth for x in br1]

br3 = [x + barWidth for x in br2]

[Link](br1, IT, color ='r', width = barWidth,

220
edgecolor ='grey', label ='IT')

[Link](br2, ECE, color ='g', width = barWidth,

edgecolor ='grey', label ='ECE')

[Link](br3, CSE, color ='b', width = barWidth,

edgecolor ='grey', label ='CSE')

[Link]('Branch', fontweight ='bold', fontsize = 15)

[Link]('Students passed', fontweight ='bold', fontsize = 15)

[Link]([r + barWidth for r in range(len(IT))],

['2015', '2016', '2017', '2018', '2019'])

[Link]()

[Link]()

Output:

Stacked bar plot

221
Stacked bar plots represent different groups on top of one another. The height of the bar depends
on the resulting height of the combination of the results of the groups. It goes from the bottom to
the value instead of going from zero to value. The following bar plot represents the contribution
of boys and girls in the team.

import numpy as np

import [Link] as plt

N=5

boys = (20, 35, 30, 35, 27)

girls = (25, 32, 34, 20, 25)

boyStd = (2, 3, 4, 1, 2)

girlStd = (3, 5, 2, 3, 3)

ind = [Link](N)

width = 0.35

fig = [Link](figsize =(10, 7))

p1 = [Link](ind, boys, width, yerr = boyStd)

p2 = [Link](ind, girls, width,

bottom = boys, yerr = girlStd)

[Link]('Contribution')

[Link]('Contribution by the teams')

[Link](ind, ('T1', 'T2', 'T3', 'T4', 'T5'))

[Link]([Link](0, 81, 10))

[Link]((p1[0], p2[0]), ('boys', 'girls'))

[Link]()

Output:

222
223
UNIT - 6 REAL TIME APPLICATIONS

Python in Web Development, Data Science , Artificial Intelligence and Machine Learning, Deep
Learning, 3D game development, Web Scrap applications, Search Engine optimization. Familiar
companies uses python – Netflix, Facebook, Spotify, Google, AWS uses Django and Flask.

Python in Web Development:


Python is a versatile language widely used in web development, particularly for building the
server-side logic of web applications. It offers a clean syntax and a rich ecosystem of frameworks
like Django and Flask, making it efficient for developing robust and scalable web
solutions. Python is also used for various other tasks in web development, including data
processing, API integration, and web scraping.

Here's a more detailed look at Python's role in web development:

1. Backend Development:

• Python is a popular choice for backend development, handling tasks like handling HTTP
requests and responses, managing data, and interacting with databases.

• Frameworks like Django and Flask simplify the development of complex web applications
by providing tools for routing, templating, and ORM (Object-Relational Mapping).

• Python's clean syntax and large community support contribute to faster development cycles
and easier maintenance.

2. Integration with Other Technologies:

• Python can be seamlessly integrated with HTML, CSS, and JavaScript, the fundamental
technologies for building web pages.

• Python can be used to generate dynamic content that is then rendered in the browser using
HTML and CSS.

• JavaScript is typically used for client-side scripting and user interface interactions, while
Python handles the server-side logic.

3. Web Scraping and Automation:

• Python is a powerful tool for web scraping, allowing developers to extract data from
websites.

224
• It can also be used to automate various web-related tasks, such as data processing, report
generation, and API interaction.

4. Frameworks:

• Django: A high-level framework that follows the "batteries-included" philosophy,


providing many built-in features for rapid development.

• Flask: A lightweight microframework that offers flexibility and allows developers to


choose the components they need.

• Other Frameworks: Pyramid, Bottle, and FastAPI are also popular choices for specific
needs.

5. Deployment:

• Python web applications can be deployed on various platforms, including cloud services
like AWS, Google Cloud, and Azure.

• Deployment involves setting up the server environment, configuring the application, and
ensuring it's accessible and scalable.

In essence, Python's strengths in web development lie in its:

• Readability and Simplicity:

Python's syntax is easy to learn and understand, making it a great choice for beginners and
experienced developers alike.

• Extensive Libraries and Frameworks:

Python offers a vast collection of libraries and frameworks for various web development tasks,
streamlining the development process.

• Large and Active Community:

A large and supportive community provides ample resources, documentation, and assistance for
developers.

• Versatility:

Python can be used for a wide range of web development tasks, from building simple websites to
complex web applications.

225
Python In Data Science:
Python is a dominant programming language in data science due to its versatility, ease of use, and
extensive libraries. It's widely used for data analysis, visualization, machine learning, and more. Its
libraries like Pandas, NumPy, and Scikit-learn provide robust tools for data manipulation,
numerical computing, and machine learning tasks.

Here's a more detailed look at Python's role in data science:

1. Data Analysis and Manipulation:

Pandas:

A powerful library for data manipulation and analysis, particularly with structured data (like CSV
files). It allows for data cleaning, transformation, and exploration.

NumPy:

Provides support for numerical computing, including array operations, mathematical functions,
and random number generation, essential for many data science tasks.

2. Data Visualization:

• Matplotlib and Seaborn: These libraries enable the creation of various charts and
visualizations to help understand and communicate data insights.

3. Machine Learning:

• Scikit-learn: A comprehensive library offering various machine learning algorithms,


model evaluation tools, and more for building and deploying models.

4. Other Applications:

• Natural Language Processing (NLP):

226
Python is used for text analysis, sentiment analysis, and other NLP tasks using libraries like NLTK
and spaCy.

• Image Processing and Computer Vision:

Libraries like OpenCV and scikit-image enable image manipulation and analysis.

• Deep Learning:

Python is the go-to language for deep learning frameworks like TensorFlow and PyTorch.

5. Why Python is Preferred:

• Ease of Learning:

Python's syntax is relatively easy to learn, making it accessible for beginners in data science.

• Extensive Libraries:

Python boasts a rich ecosystem of libraries specifically designed for data science tasks, simplifying
development and analysis.

• Active Community:

A large and active community provides ample support, resources, and solutions for Python-related
data science problems.

In essence, Python's versatility, powerful libraries, and supportive community make it an


indispensable tool for data scientists across various industries and applications.

Python in Artificial Intelligence and Machine Learning:


Python is the dominant programming language for Artificial Intelligence (AI) and Machine
Learning (ML) due to its clear syntax, extensive libraries, and strong community support. Its
libraries like NumPy, Pandas, Scikit-learn, TensorFlow, and Keras provide essential tools for data
manipulation, analysis, and model building.

Reasons for Python's popularity in AI and ML:

• Readability and Simplicity:

Python's syntax is easy to understand and write, allowing developers to focus on the AI/ML
problem rather than the complexities of the code.

• Extensive Libraries and Frameworks:

227
Python boasts a rich ecosystem of libraries specifically designed for AI and ML, such as
TensorFlow (for deep learning), PyTorch (another deep learning framework), and Scikit-learn (for
general ML tasks).

• Strong Community Support:

A large and active community of AI/ML enthusiasts provides ample resources, tutorials, and
support for learning and troubleshooting.

• Platform Independence:

Python can run on various operating systems, making it versatile for different development
environments.

• GPU Acceleration:

Python allows for the utilization of GPUs for faster processing of computationally intensive ML
tasks.

Key Libraries for AI/ML in Python:

• NumPy:

Provides support for large, multi-dimensional arrays and matrices, along with a collection of
mathematical functions to operate on these arrays.

Pandas:

Offers data structures and data analysis tools, especially for working with labeled data (like
DataFrames).

Scikit-learn:

A comprehensive library for various machine learning algorithms, including classification,


regression, clustering, and dimensionality reduction.

TensorFlow:

An open-source library developed by Google for numerical computation and large-scale machine
learning. It's particularly well-suited for deep learning tasks.

Keras:

A high-level API that runs on top of TensorFlow, Theano, or CNTK, simplifying the process of
building and training neural networks.

• PyTorch:

228
Another popular open-source library for deep learning, known for its flexibility and dynamic
computation graphs.

In essence, Python's combination of ease of use, powerful libraries, and community support makes
it the go-to language for developing AI and ML solutions.

AI With Python Tutorial

This AI with Python tutorial covers the fundamental and advanced artificial intelligence (AI)
concepts using Python. Whether you're a complete beginner or an experienced professional, this
tutorial offers a step-by-step guide to mastering AI techniques.

Why to use Python for AI?

Python provides a clear and readable syntax hence provides a smooth path to learn and build
intelligent models without complex code structures.

• Rich Ecosystem: Offers extensive libraries and frameworks (e.g., TensorFlow, PyTorch,
Scikit-learn) tailored for AI and machine learning.

• Strong Community Support: A large, active community of AI enthusiasts, researchers,


and developers sharing knowledge and resources.

• Collaborative Environment: Ensures accessibility to help, tutorials, and insights for


continuous learning.

Artificial Intelligence requires strong foundation in python and to ensure you have strong solid
starting point, we encourage you to refer to the Python tutorial, which serves as an invaluable
resource for both beginners and seasoned developers.

Artificial Intelligence

Artificial Intelligence (AI) enables computer systems to perform tasks requiring human
intelligence, such as problem-solving, decision-making, and image generation. Its goal is to
replicate human-like cognitive functions, allowing machines to handle complex tasks and adapt to
changing conditions. AI subsets include machine learning (ML), deep learning (DL), natural
language processing, computer vision, robotics, and generative AI.

To develop these complex models, we leverage python frameworks like:

• TensorFlow is developed by Google Brain teams, it provides a comprehensive set of tools


to build and train the neural networks.

• PyTorch is a framework that is developed by Facebook's AI Research lab (FAIR), it


facilitates easy debugging and more intuitive model-building process compared to static
graphs.

229
• Scikit-Learn is a user-friendly machine learning library that focuses in supervised and
unsupervised learning.

These frameworks offer versatility and scalability to empower developers and researchers to create
intelligent solutions across a wide spectrum of applications.

Machine learning

Machine learning allows developers to focus on the development of algorithm and models that
enable computers to learn and make predictions or decisions without being explicitly programmed.

There are three types of machine learning techniques:

1. Supervised Learning

In supervised learning, the algorithm is trained on a labeled dataset, where each input is paired
with its corresponding output.

Regression Algorithms

• Linear Regression

• Polynomial Regression

• Support Vector Regression (SVR)

Classification Algorithm

• Logistic Regression

• Decision trees

• Ensemble Classifiers

• Support Vector Machines (SVM)

• k-Nearest Neighbors (kNN)

• Naive Bayes

Unsupervised Learning

In unsupervised learning, the algorithm is provided unlabeled data and is tasked with finding
patterns or relationships within it. The goal of the algorithm is to inherent structures or groups in
the data.

Clustering Algorithms

230
• K-means

• Hierarchical Clustering

• DBSCAN

Dimensionality Reduction

• Principal Component Analysis (PCA)

• t-Distributed Stochastic Neighbor Embedding (t-SNE)

• Linear Discriminant Analysis (LDA)

Reinforcement Learning

In reinforcement learning, the algorithm learns by interacting with an environment and receiving
feedback in the form of rewards or penalties. The goal of the algorithm is to discover optimal
strategies or actions to maximize cumulative rewards over time.

The application includes game playing, robotics, autonomous systems. The popular reinforcement
learning algorithms are:

• Q-learning

• Model Based Reinforcement Learning

• Deep Q Network (DQN)

• REINFORCE

• Actor Critic

• Monte Carlo Policy Evaluation

• SARSA (State-Action-Reward-State-Action)

ML has limitations like reliance on handcrafted features, struggles with high-dimensional


unstructured data, and limited capacity to model complex relationships, leading to the rise of deep
learning

Deep Learning

Deep learning derives inspiration from structure of human brain. The human brain consists of
billions of neurons that communicate through electrochemical signals and in DL, artificial neural
networks are composed of nodes that are interconnected with weights.

Fundamentals of Deep Learning

231
To understand basic neural network, we need to build a solid groundwork for mastering deep
learning using the following fundamentals:

• Gradient Descent Algorithm

• Backpropagation

• Hyperparameters

o Activation Functions

o Epochs

o Optimizers

o Batch Size

o Learning rate

• Loss Functions

Deep Learning Architecture

Deep learning architectures are structured neural network models designed to facilitate complex
learning tasks by automatically identifying patterns and representations within data. Below are
foundational structures in deep learning:

• Perceptron

• Feedforward Neural Networks (FNN)

• Multi-Layer Perceptron

• Artificial Neural Networks (ANNs)

• Convolutional Neural Networks (CNN)

• Recurrent Neural Networks (RNNs)

• Long Short-Term Memory (LSTM) networks

• Gated Recurrent Units Networks (GRU)

• Autoencoders

• Capsule Networks

Natural Language Processing (NLP)

232
Natural language processing enables machines to understand, interpret and generate human-like
text, allowing for seamless communication. Key components include:

Text Processing and Representation

Text processing is used to manipulate and prepare textual data for analysis and text representation
involves converting textual information into a format that can be efficiently processed and
understood by machines. Below are the methods to process and represent text:

Text Processing

• Tokenization

• Stemming

• Lemmatization

• Stop Words Removal

• Text Normalization

• Part-of-Speech (POS) Tagging

Text Representation

• Named Entity Recognition

• Bag-of-Words (BoW)

• Word Embeddings

o Word2Vec

o GloVe (Global Vectors for Word Representation)

o FastText

o ELMo (Embeddings from Language Models)

o Skip-grams

• TF- IDF (Term Frequency-inverse Document Frequency)

• Doc2Vec

Lexical Semantics

Lexical semantics focuses on the meaning of words and their relationships within a language and
explore how words convey meaning.
233
• Word Sense Disambiguation

• Semantic Similarity

Computer Vision

Computer Vision enables machines to interpret, analyze and understand visual information from
the world, much like the human visual system.

Image Processing and Transformation

Image processing and transformation refer to the techniques and methods used to manipulate and
enhance digital images. These processes involve applying various operations to modify the
appearance, quality, or information content of an image. Here are key concepts related to image
processing and transformation:

• Image Transformation

• Image Enhancement

• Image Sharpening

• Edge Detection

• Smoothing and Blurring Image

• Image Denoising

Image Recognition Architectures

Image recognition architectures are specialized models or neural network structures created for the
purpose of identifying and categorizing objects within images.

• AlexNet

• VGGNet

• GoogleLeNet

• ResNet

• MobileNet

• Xception

• EfficientNet

• DenseNet

234
Object Detection Architectures

Object detection architectures leverage deep learning techniques to detect and classify objects with
varying orientations. There are two main types for object detection techniques:

1. Single Shot Detectors

Single Shot Detectors perform object detection in a single forward pass through the network. They
predict bounding boxes and class probabilities directly from predefined anchor boxes across
multiple scales.

• YOLO (You Only Look Once)

• SSD (Single Shot Detector)

2. Two-stage Detectors

Two-stage detectors follow a two-step process. First, they generate region proposals that are likely
to contain objects using methods like region proposal networks (RPNs). In the second step, these
proposals are classified and refined to obtain the final object detections.

• R-CNN (Region-based Convolutional Neural network)

• Fast R-CNN

• Faster R-CNN

• Cascade R-CNN

Image Segmentation Architectures

Image segmentation architecture models to create partition an input image into distinct regions or
objects. Each pixel in the image is labeled, assigning it to a particular segment. The main
architectures of image segmentation include:

• U-Net

• K means clustering

• Mask R-CNN

• YOLOv8

• Cascade Mask R-CNN

• PSPNet (Pyramid Scene Parsing Network)

235
Computer vision plays a crucial role in various applications, including autonomous vehicles,
medical image analysis, surveillance, augmented reality, and more.

Generative AI

Generative AI are creative models that are capable to generate fresh content, typically
encompassing images, text, audio, or various data form. This area of AI is dedicated to producing
novel and diverse outputs based on learned patterns and structures.

Image Generation Architectures

Image generation architectures refer to specialized models or neural network structures crafted for
the purpose of generating realistic images. These architectures utilize generative models to create
visual content that is both realistic and diverse.

• Variational Autoencoders

• Generative Adversarial Networks (GANs)

• Conditional GAN (cGAN)

• Wasserstein GAN (WGAN)

• Progressive GAN

• BigGAN

• CycleGAN

• VQ-VAE-2 (Vector Quantized Variational Autoencoder)

• Style GANs

Text Generation Architectures

Text generation architectures refer to specialized models or neural network structures created for
the purpose of generating fresh textual content. These architectures utilize generative models to
produce text that is both coherent and contextually appropriate.

• Transformers

• GPT (Generative Pre-trained Transformer)

• BERT (Bidirectional Encoder Representations from Transformers)

• T5 (Text-to-Text Transfer Transformer)

• CTRL (Conditional Transformer Language Model)

236
• UniLM (Unified Language Model)

Audio Generation Architectures

Architectures dedicated to audio generation are specialized neural network models crafted for the
purpose of generating novel audio content. These structures utilize generative models to create
sound sequences that are realistic.

• WaveNet

• WaveGAN

• Tacotron2

• EnCodec

• AudioLM

• Deep Voice

We have navigated through the AI journey and covered interesting topics of ML, DL, computer
vision (CV), generative AI and NLP. Python plays an important role in crafting of intelligent
solutions with elegance and efficiency. Python AI stand at the intersection of code and intelligence.

3D game development using Python:

237
Large and Supportive Community

Python has a large and active developer community that contributes to a diverse set of libraries
and frameworks. Libraries for game development include Pygame, Panda3D, and Godot, which
provide various tools and resources to help you with your project.

Cross-Platform Compatibility

Python's cross-platform interoperability allows you to create games that work on various operating
platforms with few code changes. This versatility enables you to reach a larger audience.

Integration with Other Languages

Python can easily be combined with other programming languages, such as C++ and C#, for
performance-critical areas of your game. Use the strengths of these languages when needed while
benefiting from Python's development features for the rest of your project.

AI Integration

Python's compatibility with prominent machine learning frameworks like TensorFlow, Keras, and
Theano makes it a powerful tool for smoothly incorporating AI capabilities into game
development. This advantage is critical in improving gameplay and involvement, elevating the
gaming experience to new levels.

238
Python's AI integration capabilities enable game creators to create intelligent behaviors, adaptive
NPCs (non-player characters), and dynamic surroundings. These libraries enable developers to
construct AI-driven opponents, realistic decision-making, and adaptive game mechanisms that
respond to player actions.

Popular Games Made with Python

Learning why Python helps develop games is great, but seeing how those benefits have been
applied in the real world is even better. While many companies use Python for experimentation,
many excellent games incorporate Python as an intrinsic design element. Here are a few fan
favorites.

EVE Online

For those unfamiliar, EVE Online is a space-based MMORPG (massively multiplayer online role-
playing game) focusing on the "massive." Players in the EVE universe can participate in trade-
based games such as mining, manufacturing, and a player-driven market, or they can concentrate
on exploration, conflict, and even piracy!

This game relies significantly on Stackless Python, a Python clone.

Battlefield 2

Battlefield 2 is an excellent example of a game made by a major gaming business that requires
Python to function. It was a major first-person shooter game set in a fictional world war. It is an
outdated game that no longer has operating multiplayer servers. However, Python programming
powered much of the game's functionality.

Frets on Fire

Frets on Fire is an open-source music video game akin to Guitar Hero. The primary goal is to time
a particular button press to the action on the screen to play music. This game was created in Python
and is an excellent example of what the language is capable of. The game is released as free
software under the GNU license, and you can access the source code on Sourceforge.

PyGame (for 2D games)

PyGame is a one-stop shop for all the tools required to create a 2D game in Python. It is a low-
level graphics library based on the open-source SDL 2D graphics library.

It is not the platform for creating complicated, graphics-intensive games but ideal for developing
a simple Python game. As developers write, “This library is superior to C language, Python
language, Native and OpenGL. “

Panda3D (for 3D games)

239
Panda3D is the graphics engine used in Disney's ToonTown, demonstrating that it is an excellent
choice for creating a three-dimensional game with Python. Panda3D's core is designed in C++ to
increase efficiency, but most APIs can be accessed via a Python interface, allowing you to create
a whole 3D game with Python scripting!

Cocos2d

Cocos is a Python framework for creating video games, programs, laptop code packages, and
unique cross-platform graphical user interfaces (GUIs). It is a thin layer of platform dependency
that may carry together video games and functions using laptop computer code packages.

Web Scrap applications:


Web scraping is the process of extracting data from websites automatically. Python is widely used
for web scraping because of its easy syntax and powerful libraries like BeautifulSoup, Scrapy,
and Selenium.

Installing Required Libraries

To install the required libraries in this article, run the following commands in the terminal.

pip install requests

pip install beautifulsoup4

pip install selenium

pip install lxml

pip install schedule

pip install pyautogui

• requests: Sends HTTP requests to get webpage content (used for static sites).

• beautifulsoup4: Parses and extracts HTML content (like tags, text, links).

• selenium: Automates browsers (needed for dynamic sites with JavaScript).

• lxml: A fast HTML/XML parser, useful for large or complex pages.

• schedule: Lets you run scraping tasks repeatedly at fixed intervals.

• pyautogui: Automates mouse and keyboard; useful when dealing with UI-based
interactions.

Requests Module

240
The requests library is used for making HTTP requests to a specific URL and returns the response.
Python requests provide inbuilt functionalities for managing both the request and response.

pip install requests

Example: Send a GET request to a webpage

import requests

response = [Link]('[Link]

print(response.status_code)

print([Link])

Output:

Snapshot of the raw html data using request module

Explanation:

• [Link](url): Sends a GET request to the given URL.

• response.status_code: Returns HTTP status code (200 = success).

• [Link]: Returns the raw HTML of the page in bytes.

For more information, refer to our Python Requests Tutorial .

Parsing HTML with BeautifulSoup

241
Once the raw HTML is fetched, the next step is to parse it into a readable structure. That’s where
BeautifulSoup comes in. It helps convert the raw HTML into a searchable tree of elements.

Example: Parse HTML using BeautifulSoup

import requests

from bs4 import BeautifulSoup

response = [Link]('[Link]

soup = BeautifulSoup([Link], '[Link]')

print([Link]())

Output:

Snapshot of the beautified html response using beautifulsoap module

Explanation:

• BeautifulSoup(html, parser): Converts HTML into a searchable object. '[Link]' is


the built-in parser.

• [Link](): Formats the HTML nicely for easier reading.

At this point, the HTML is ready to be searched for tags, classes or content.

242
Extracting Content by Tag and Class

Once we have parsed the HTML using BeautifulSoup, the next step is to locate and extract specific
content from the page. Websites usually wrap their main article content inside tags with
identifiable classes like <div class="article--viewer_content">. We can target such elements and
pull out useful data like text, links or images.

Selenium

Some websites load their content dynamically using JavaScript. This means the data you're trying
to scrape may not be present in the initial HTML source. In such cases, BeautifulSoup alone won’t
work, because it only reads static HTML.

To handle this, we use Selenium that can automate browsers like Chrome or Firefox, wait for
content to load, click buttons, scroll and extract fully rendered web pages just like a real user.

What is a WebDriver

A WebDriver is a software component that Selenium uses to interact with a web browser. It acts
as the bridge between your Python script and the actual browser window.

Each browser (Chrome, Firefox, Edge, etc.) has its own WebDriver:

• Chrome: ChromeDriver

• Firefox: GeckoDriver

• Edge: EdgeDriver

Selenium uses this WebDriver to:

• Open and control the browser

• Load web pages

• Extract elements

• Simulate clicks, scrolls and inputs

You can either manually download the WebDriver or use webdriver-manager which handles the
download and setup automatically.

Example 1: Searching on Google with Firefox

In this example, we're directing the browser to the Google search page with the query parameter
"geeksforgeeks". The browser will load this page and we can then proceed to interact with it

243
programmatically using Selenium. This interaction could involve tasks like extracting search
results, clicking on links or scraping specific content from the page.

# import webdriver

from selenium import webdriver

# create webdriver object

driver = [Link]()

# get [Link]

[Link]("[Link] / search?q = geeksforgeeks")

Output

Search Engine optimization (SEO) :


Basics of SEO and Python

SEO is not just about incorporating relevant keywords into your content or making your website
faster; it’s a strategy aimed at improving your site’s position in the search engine results pages
(SERPs). This is vital because the higher your pages rank in SERPs, the more likely they are to
catch the attention of your target audience, driving organic traffic to your site.

Understanding SEO

244
SEO involves a multitude of strategies and techniques aimed at making your website more
attractive to search engines like Google, Bing, and Yahoo. These strategies can be broadly
categorized into on-page SEO, which includes elements like content, images, and HTML tags, and
off-page SEO, which involves backlinks and other external signals. The ultimate goal is to signal
to search engines that your site is authoritative, relevant, and deserving of being ranked highly for
queries related to your services, products, or information.

The Role of Python in SEO

Python, a powerful and versatile programming language that has become a tool of choice for SEO
professionals. Python stands out due to its simplicity and the rich ecosystem of libraries and
frameworks it offers. For someone delving into the complexities of SEO, Python can simplify tasks
that would otherwise be tedious and time-consuming. Here’s how Python makes a difference in
the world of SEO:

• Automation and Efficiency: Python scripts can automate repetitive SEO tasks such as
keyword research, link analysis, and content optimization. This not only saves valuable
time but also increases efficiency, allowing SEO professionals to focus on strategy and
analysis.

• Data Analysis and Insight: With libraries like Pandas, NumPy, and SciPy, Python is
exceptionally adept at handling, processing, and analyzing large datasets. This capability
is invaluable in SEO, where making data-driven decisions can significantly impact your
website’s performance. Python can help uncover insights from keyword rankings,
competitor analysis, and performance metrics, enabling a more strategic approach to SEO.

• Web Scraping: Gathering data is a crucial part of SEO, and Python’s libraries such as
BeautifulSoup and Scrapy are perfect for scraping information from web pages. This can
include tracking your own site’s content for SEO audits or monitoring competitors’ sites
to identify their SEO strategies.

• SEO Auditing: Python can be used to automate the auditing process, checking for
common SEO issues like broken links, improper use of tags, and slow page load times.
This can greatly aid in maintaining the health of your website and ensuring it remains
compliant with SEO best practices.

Getting Started with Python for SEO

For beginners, starting with Python for SEO doesn’t require you to be an expert programmer.
Many resources are available to help you learn Python basics, and the community is vibrant and
supportive. Starting with simple scripts to automate keyword research or analyze your site’s
performance can be a great way to get familiar with using Python for SEO.

245
Python’s syntax is designed to be readable and straightforward, which means you can focus more
on learning SEO concepts and less on deciphering complex programming constructs. As you grow
more comfortable with Python, you can gradually move on to more sophisticated analyses and
automation tasks.

Blending SEO knowledge with Python’s capabilities opens up a new realm of possibilities for
enhancing your website’s visibility and performance. By automating mundane tasks, analyzing
data more efficiently, and executing comprehensive SEO audits, Python empowers you to take a
data-driven approach to SEO, making it easier to navigate the complexities of optimizing your site
for search engines. No conclusion needed, as this introduction sets the stage for the detailed
exploration of SEO and Python that follows.

Conducting Keyword Research with Python

Keyword research is the foundation of effective SEO strategies. It involves identifying the terms
and phrases that potential customers use in search engines when looking for products, services, or
information. Understanding these keywords allows you to tailor your content to meet the needs
and interests of your audience, ultimately enhancing your visibility in search results.

The Importance of Keyword Research

At its core, keyword research is about understanding the language of your potential customers and
using this knowledge to optimize your content. It’s not just about finding the most searched terms
but identifying the intent behind these searches. Keywords can be categorized based on the
searcher’s intent into informational, navigational, transactional, and commercial. By targeting
keywords across these categories, you can ensure that your content meets users at various stages
of their journey, from awareness to decision-making.

Python’s Role in Streamlining Keyword Research

Python can significantly streamline the keyword research process through automation and data
analysis. By leveraging Python, you can gather extensive keyword data, analyze search trends, and
uncover insights that would be difficult to achieve manually. This section will guide you through
a simple Python project that demonstrates how to conduct keyword research, focusing on
generating keyword ideas and analyzing their search volume and competition.

Generating Keyword Ideas with Python

One of the first steps in keyword research is generating a comprehensive list of keyword ideas.
While there are many tools available for this purpose, Python can offer a customized approach by
scraping search suggestions and related searches directly from search engines.

Familiar companies using python & Why It's Their Go-To:

246
1. Google

Google has been using Python since its early days. And that hasn’t changed in 2025. The language
helps the company move fast, maintain codebases easily, and deploy at scale.

Python is actively used in Google’s search algorithms, YouTube backend, internal systems, and
across AI/ML projects.

What makes Python so valuable for Google is its readability and versatility. It supports
experimentation, which is vital for a company constantly testing new features across products like
Android, Gmail, and Google Assistant.

It’s also one of Google’s official server-side languages, alongside C++, Java, and Go.

2. Netflix

Netflix leans on Python to manage everything from data analysis to backend services. The
language powers tasks like automating alerts, managing security operations, and building internal
tools for monitoring and visualization.

Python is also widely used in Netflix’s machine-learning workflows to improve user


recommendations and personalize thumbnails.

The language’s vast ecosystem helps Netflix experiment and deploy fast. Since the platform runs
on microservices, Python’s simplicity makes it easier to test, update, and manage services
independently, key to keeping a global streaming service smooth and scalable.

3. Dropbox

Dropbox started with Python and stuck with it as it scaled to hundreds of millions of users. Its
desktop client, APIs, and many backend services were originally built using Python. Even Guido
van Rossum, the creator of Python, joined Dropbox to work on improving the language’s
performance in real-world applications.

Python’s role in Dropbox is rooted in its ability to simplify cross-platform development and enable
rapid iteration. The company uses it to build features quickly, write clean server-side code, and
maintain its infrastructure efficiently.

4. Stripe

Stripe is one of the most recognized tech companies that uses Python to build APIs and power its
payment infrastructure. The company uses Python extensively to handle transactions, manage
subscriptions, and integrate fraud detection tools across web and mobile apps.

247
Python’s simplicity allows Stripe’s developers to iterate fast and reduce time-to-market for new
features. It’s also a preferred language among fintech developers, thanks to its reliability in
handling complex calculations and ease of integration with data-heavy systems.

5. Amazon

Amazon depends on Python to drive several core systems, especially those involving big data,
recommendation engines, and automation on AWS.

Amazon’s many features, such as personalized deals, product suggestions, and customer analytics,
are all backed by AI and machine learning algorithms.

Among the tech companies that use Python, Amazon stands out for scale. The language integrates
well with tools like Hadoop and Jupyter notebooks, which Amazon uses across its cloud services.

Python’s flexibility helps Amazon manage vast datasets while keeping operations smooth and
cost-efficient.

6. Reddit

Reddit is another early adopter among the tech companies that use Python. It switched from Lisp
to Python just months after launch.

The decision was driven by Python’s developer-friendly syntax, vast library support, and quick
deployment cycle – ideal for a platform that thrives on constant user interaction and content
updates.

Python powers Reddit’s backend, handling everything from content moderation to real-time
updates and recommendation algorithms. Its flexibility helps Reddit’s team experiment fast while
keeping infrastructure lean and maintainable.

7. Facebook

Facebook is a major player among tech companies that use Python, especially for backend
engineering and infrastructure management.

Python plays a key role in production engineering, supporting automation, system reliability, and
smooth updates across the platform.

Developers at Facebook rely on Python to build internal tools and scripts that help developers test,
monitor, and debug at scale. Python’s simplicity and maintainability help Facebook ship faster
while supporting billions of users across products like Messenger, Instagram, and WhatsApp.

8. Instagram

248
Instagram is one of the most widely used products from the list of tech companies that use Python.
The social platform relies on Python to manage everything from server-side logic to data
processing for billions of daily interactions – photos, videos, reels, and more.

The developers chose Python for its clean structure and ability to scale. Even as user numbers
exploded, Python helped them stay agile, maintain fast development cycles, and reduce overhead.

At present, Instagram runs on Python 3, supporting everything from feature updates to AI-driven
content ranking.

9. Spotify

Spotify is one of the most data-driven tech companies. It uses Python to manage both backend
systems and user-facing features.

The company relies on Python for data analysis, recommendation engines, and internal tools,
ensuring listeners get personalized playlists, smart search results, and relevant music suggestions.

Spotify also uses Luigi, a Python module that handles workflow management with Hadoop. This
setup helps track errors, schedule tasks, and automate big data pipelines across teams working with
machine learning and content discovery.

10. Quora

Quora stands out for using Python to build an intelligent, community-driven platform. The
founders chose Python early for its readability and ease of use, allowing the team to iterate quickly
on features like upvotes, content feeds, and spam filtering.

Python’s compatibility with frameworks like Django and Pylons helped Quora scale fast while
maintaining clean code. It also works well with JavaScript for asynchronous page updates, which
is important for the smooth question-and-answer experience the platform is known for.

11. PayPal

PayPal is one of the largest fintech companies using Python in its backend architecture.

Python supports the systems that keep millions of daily transactions secure and efficient, from
fraud detection to transaction security and real-time analytics.

The engineering team uses Python to automate workflows, manage APIs, and maintain
infrastructure. Its integration with other technologies helps PayPal meet global scalability and
compliance standards without slowing product development.

12. Uber

Uber relies heavily on Python to manage ride-matching, real-time tracking, and dynamic pricing.

249
Among tech companies that use Python, Uber benefits from the language’s speed and scalability,
which is especially important for handling live data from millions of users across cities worldwide.

Python works alongside [Link] and Go in Uber’s backend, but it remains a top choice for fraud
detection, automation, and data visualization services.

Tools like Tornado, a Python web framework, help Uber maintain fast response times and efficient
load handling.

13. Pinterest

Pinterest is a visual discovery platform and one of the most product-focused tech companies. They
use Python for their web servers and application logic.

The backend uses Django for rapid development and consistent performance, supporting billions
of pins and personalized feeds.

Python allows Pinterest’s developers to test and deploy features with minimal friction. Combined
with Tornado and some [Link] components, the platform delivers a smooth, responsive
experience for users exploring lifestyle content, design ideas, and inspiration boards.

14. NASA

NASA might not be the first name that comes to mind, but it’s one of the most innovative tech
companies that uses Python for their scientific research and automation.

Python is used in NASA’s Workflow Automation System (WAS) for shuttle mission planning and
data management.

Python’s clarity and speed help NASA engineers prototype tools quickly and manage large
datasets without unnecessary complexity.

Several of NASA’s open-source projects and simulations today are powered by Python, making
the language a part of real-world space missions.

Amazon: web frameworks, big data, and security automation

Amazon, like Google, is one of the most impressive international companies using Python on
almost every level of its operations.

Backend web development, server-side code, data processing, and Python can do it all, but its
ability to handle big data is why Amazon decided to implement it into their platform. Python's big
data functionality is what makes Amazon's search results efficiently user targeted and catered to
specific product needs.

250
Amazon's web applications, including its website and cloud services, such as Amazon Web
Services (AWS), are built with Python-based web frameworks, including Django and Flask.

Python is a popular web development language because it is simple to learn, flexible, and has a
large library of modules and packages. Many tech companies have invested in Python developers
thanks to Python's wildly successful Amazon data management applications.

251

You might also like