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

Cos 201 - Programming Language 1 Lecture Note-1

The document provides an overview of computer programming fundamentals, including essential concepts, programming environments, and tips for improving programming skills. It explains the nature of computer programs, the role of programming languages, and the importance of algorithms and syntax in coding. Additionally, it discusses debugging, programming paradigms, and the significance of computer programs in various fields.

Uploaded by

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

Cos 201 - Programming Language 1 Lecture Note-1

The document provides an overview of computer programming fundamentals, including essential concepts, programming environments, and tips for improving programming skills. It explains the nature of computer programs, the role of programming languages, and the importance of algorithms and syntax in coding. Additionally, it discusses debugging, programming paradigms, and the significance of computer programs in various fields.

Uploaded by

Amarachi Collins
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 91

COS 201: COMPUTER PROGRAMMING I 3UNITS

FIRST SEMESTER
ONYIANTA JOHN CHIEDOZIE

1.0 INTRODUCTION
ESSENTIALS OF COMPUTER PROGRAMMING
Essentials of Programming are the bedrock on which the structures of code are
built, much like a blueprint for mastering the language of computers. Think of
them as the ABCs of the digital realm, guiding aspiring coders through a maze of
syntax and logic.

At their core, programming basics cover essential concepts and principles that
create the framework for Software Development. From understanding variables
and data types to mastering loops and conditionals and, Object Oriented
Programming (OOP), these fundamentals provide the groundwork for crafting
elegant algorithms and robust applications.

Imagine Programming Fundamentals as the keys to a musical masterpiece. They


are the building blocks of harmony and melody that transform a cacophony of code
into a symphony of functionality. These basics empower programmers to skillfully
wield the tools of their trade, allowing them to turn abstract ideas into tangible
solutions that sculpt the digital landscape.

Mastering Programming Fundamentals is akin to learning the language of


technology—a journey of discovery and innovation that unlocks endless
possibilities in the ever-evolving world of software engineering.

1.0.1 IDEs and Coding Environments


Integrated Development Environment (IDE) is an application programmers use to
write code and organise text groups. It increases a programmer’s productivity and
efficiency through features such as code compilation, code completion, debugging,
syntax highlighting, etc.

Some common examples of IDE’s are:

a) AWS Cloud9

b) Visual Studio

c) NetBeans

d) Eclipse

On the other hand, coding environments might offer a more lightweight and
customisable setup, allowing programmers to select specific tools and
configurations that best fit their preferences and the requirements of their
projects.

1.0.2 Tips to Improve Programming Skills


Here are some tips to improve your programming skills:

1) Take Additional Courses: Consider taking additional courses including


practice tests, quizzes, and capstone projects to enhance your programming skills
and credentials in the IT field.

2) View Source Code: It's highly recommended that you review the modules'
source code for deeper insight into their design structure and implementation
procedure. This will guide you in designing your own custom module for a
program.

3) Work on Mini-projects: By working on end-to-end projects, you learn the


overall structure of a program, along with best coding practices and optimisation
techniques. A project involves various phases, such as data collection, analysis,
algorithm development, code testing, and deployment.

4) Participate in Coding Competitions: Competitive coding can elevate your


algorithmic skills and problem-solving abilities by helping you learn more about
data structures and discrete mathematics.

5) Follow Other Programmers: You can review their codebases on various


platforms, such as Kaggle or GitHub, letting you improve your programming skills
and stay current with the latest IT developments.
1.0.3 What is a Program (Code)?
Suppose I give you 10 numbers and tell you to find the average of the given 10 numbers, then
how do you find the average? You add all those numbers and then divide the sum of the
numbers by the total numbers given.
Easy task yeah. Now, if 10 sets and each set contain 10 numbers then what would you do?
For this problem, there are two solutions to solve the problem.
1. You take one set, add each number then divide it by the total numbers. If you are thinking
to solve this problem by this procedure, then it is right to solve by this but if you are going
to be a software engineer then solving the problem through this approach is not
preferred.
2. You can write a program to solve the problem. Just you need to write a program in which
the computer takes input from the user and then it uses a procedure to find the average.
I have used the word procedure many times, what does it mean?
We define a procedure by giving steps one by one to our computer system and we call it a
program. Like, taking numbers from a user, adding them, and dividing the sum by the total
number is a procedure.
In short, a program is a set of instructions.

1.0.4 Computer Program


Before getting into computer programming, let us first understand computer programs and
what they do.

A computer program is a sequence of instructions written using a Computer Programming


Language to perform a specified task by the computer.

The two important terms that we have used in the above definition are −

 Sequence of instructions
 Computer Programming Language

To understand these terms, consider a situation when someone asks you about how to go to a
nearby KFC. What exactly do you do to tell him the way to go to KFC?

You will use Human Language to tell the way to go to KFC, something as follows −

First go straight, after half kilometer, take left from the red light and then drive around one
kilometer and you will find KFC at the right.
Here, you have used English Language to give several steps to be taken to reach KFC. If they are
followed in the following sequence, then you will reach KFC −

1. Go straight
2. Drive half kilometer
3. Take left
4. Drive around one kilometer
5. Search for KFC at your right side

Now, try to map the situation with a computer program. The above sequence of instructions is
actually a Human Program written in English Language, which instructs on how to reach KFC
from a given starting point. This same sequence could have been given in Spanish, Hindi,
Arabic, or any other human language, provided the person seeking direction knows any of
these languages.

Now, let's go back and try to understand a computer program, which is a sequence of
instructions written in a Computer Language to perform a specified task by the computer.
Following is a simple program written in Python programming Language −

print "Hello, World!"

The above computer program instructs the computer to print "Hello, World!" on the computer
screen.

 A computer program is also called a computer software, which can range from two lines
to millions of lines of instructions.
 Computer program instructions are also called program source code and computer
programming is also called program coding.
 A computer without a computer program is just a dump box; it is programs that make
computers active.

As we have developed so many languages to communicate among ourselves, computer


scientists have developed several computer-programming languages to provide instructions to
the computer (i.e., to write computer programs). We will see several computer programming
languages in the subsequent chapters.

1.0.5 Computer Programming


If you understood what a computer program is, then we will say: the act of writing computer
programs is called computer programming.
As we mentioned earlier, there are hundreds of programming languages, which can be used to
write computer programs and following are a few of them −

 Java
 C
 C++
 Python
 PHP
 Perl
 Ruby
1.0.6 Uses of Computer Programs
Today computer programs are being used in almost every field, household, agriculture,
medical, entertainment, defense, communication, etc. Listed below are a few applications of
computer programs −

 MS Word, MS Excel, Adobe Photoshop, Internet Explorer, Chrome, etc., are examples of
computer programs.
 Computer programs are being used to develop graphics and special effects in movie
making.
 Computer programs are being used to perform Ultrasounds, X-Rays, and other medical
examinations.
 Computer programs are being used in our mobile phones for SMS, Chat, and voice
communication.

1.0.7 Computer Programmer


Someone who can write computer programs or in other words, someone who can do
computer programming is called a Computer Programmer.

Based on computer programming language expertise, we can name a computer programmers


as follows −

 C Programmer
 C++ Programmer
 Java Programmer
 Python Programmer
 PHP Programmer
 Perl Programmer
 Ruby Programmer
1.0.7 Algorithm
From programming point of view, an algorithm is a step-by-step procedure to resolve any
problem. An algorithm is an effective method expressed as a finite set of well-defined
instructions.

Thus, a computer programmer lists down all the steps required to resolve a problem before
writing the actual code. Following is a simple example of an algorithm to find out the largest
number from a given list of numbers −

1. Get a list of numbers L1, L2, L3....LN


2. Assume L1 is the largest, Largest = L1
3. Take next number Li from the list and do the following
4. If Largest is less than Li
5. Largest = Li
6. If Li is last number from the list then
7. Print value stored in Largest and come out
8. Else repeat same process starting from step 3

The above algorithm has been written in a crude way to help beginners understand the
concept. You will come across more standardized ways of writing computer algorithms as you
move on to advanced levels of computer programming.

1.0.8 Programming Language Syntax


We assume you are well aware of English Language, which is a well-known Human Interface
Language. English has a predefined grammar, which needs to be followed to write English
statements in a correct way. Likewise, most of the Human Interface Languages (Hindi, English,
Spanish, French, etc.) are made of several elements like verbs, nouns, adjectives, adverbs,
propositions, and conjunctions, etc.

Similar to Human Interface Languages, Computer Programming Languages are also made of
several elements. They have the rules that govern them the same way we have rules that
governs English language. These rules are known as Syntax.

1.0.9 Syntax
Syntax is a set of rules that defines the structure of a language. Every programming language
follows a different syntax. A programming language isn’t understandable without its syntax.
Syntax helps the computer to read and understand the code. It is like giving instructions to
the code.

For example,
int a =10;
here a is variable
int is data type
10 is value

1.0.10 Bug
Error in a code (computer program) is known as bug and the act of removing the error is
known as debugging.

1.0.11 Debugging
Debugging removes errors from computer programs and enables software development and
engineering teams to produce functioning software. Through debugging they can examine
individual code sections to ensure the program works as intended.

Programmers make mistakes. For whimsical reasons, programming errors are called bugs and
the process of tracking them down is called debugging. Programming, and especially
debugging, sometimes brings out strong emotions. If you are struggling with a difficult bug, you
might feel angry, despondent, or embarrassed.

Learning to debug can be frustrating, but it is a valuable skill that is useful for many activities
beyond programming

Below is a list of potential programming errors:

a) Syntax Error: This is an erroneous sequence of characters or tokens in the code that
doesn't follow the syntax of a programming language. If you do not follow the rules
defined by the programing language, then at the time of compilation, you will get syntax
errors and the program will not be compiled. From syntax point of view, even a single
dot or comma or a single semicolon matters and you should take care of such small
syntax as well. “Syntax” refers to the structure of a program and the rules about that
structure. For example, parentheses have to come in matching pairs, so (1 + 2) is legal,
but 8) is a syntax error. If there is a syntax error anywhere in your program, Python
displays an error message and quits, and you will not be able to run the program. During
the first few weeks of your programming career, you might spend a lot of time tracking
down syntax errors. As you gain experience, you will make fewer errors and find them
faster.
b) Runtime error: The second type of error is a runtime error, so called because the error
does not appear until after the program has started running. These errors are also called
exceptions because they usually indicate that something exceptional (and bad) has
happened. Runtime errors are rare in the simple programs you will see in the first few
chapters, so it might be a while before you encounter one.
c) Semantic error: The third type of error is “semantic”, which means related to meaning.
If there is a semantic error in your program, it will run without generating error
messages, but it will not do the right thing. It will do something else. Specifically, it will
do what you told it to do. Identifying semantic errors can be tricky because it requires
you to work backward by looking at the output of the program and trying to figure out
what it is doing.
2.0TYPES OF PROGRAMMING LANGUAGE:
2.0.1 Programming Paradigms
2.0.1.1 What is a Programming Paradigm?
Programming paradigms are different ways or styles in which a given program or programming
language can be organized. Each paradigm consists of certain structures, features, and opinions
about how common programming problems should be tackled.

The question of why are there many different programming paradigms is similar to why are
there many programming languages. Certain paradigms are better suited for certain types of
problems, so it makes sense to use different paradigms for different kinds of projects.

Also, the practices that make up each paradigm have developed through time. Thanks to the
advances both in software and hardware, different approaches have come up that didn't exist
before.

Human creativity gave birth to programming paradigms. As a species, we just like creating
things, improving what others have built in the past, and adapting tools to our preference or to
what seems more efficient to us.

All this results in the fact that today we have many options to choose from when we want to
write and structure a given program.

2.0.1.2 What a Programming Paradigm is not


Programming paradigms are not languages or tools. You can't "build" anything with a
paradigm. They're more like a set of ideals and guidelines that many people have agreed on,
followed, and expanded upon.

Programming languages aren't always tied to a specific paradigm. There are languages that
have been built with a certain paradigm in mind and have features that facilitate that kind of
programming more than others (Haskel and functional programming is a good example).
But there are also "multi-paradigm" languages, meaning you can adapt your code to fit a
certain paradigm or another (JavaScript and Python are good examples).
2.0.1.3Popular Programming Paradigms
Now that we have introduced what programming paradigms are and are not, let's go through
the most popular ones, explain their main characteristics, and compare them.

Keep in mind this list is not exhaustive. There are other programming paradigms not covered
here, although I'll be covering the most popular and most widely-used ones.

Imperative Programming
Imperative programming consists of sets of detailed instructions that are given to the
computer to execute in a given order. It's called "imperative" because as programmers we
dictate exactly what the computer has to do, in a very specific way.

Imperative programming focuses on describing how a program operates, step by step.


Say you want to bake a cake. Your imperative program to do this might look like this (I'm not a
great cook, so don't judge me )

1- Pour flour in a bowl


2- Pour a couple eggs in the same bowl
3- Pour some milk in the same bowl
4- Mix the ingredients
5- Pour the mix in a mold
6- Cook for 35 minutes
7- Let chill
Using an actual code example, let's say we want to filter an array of numbers to only keep the
elements bigger than 5. Our imperative code might look like this:

const nums = [1,4,3,6,7,8,9,2]


const result = []

for (let i = 0; i < nums.length; i++) {


if (nums[i] > 5) result.push(nums[i])
}
console.log(result) // Output: [ 6, 7, 8, 9 ]

See that we're telling the program to iterate through each element in the array, compare the
item value with 5, and if the item is bigger than 5, push it into an array.
We're being detailed and specific in our instructions, and that's what imperative programming
stands for.

Procedural Programming
Procedural programming is a derivation of imperative programming, adding to it the feature of
functions (also known as "procedures" or "subroutines").

In procedural programming, the user is encouraged to subdivide the program execution into
functions, as a way of improving modularity and organization.

Following our cake example, procedural programming may look like this:

function pourIngredients() {
- Pour flour in a bowl
- Pour a couple eggs in the same bowl
- Pour some milk in the same bowl
}

function mixAndTransferToMold() {
- Mix the ingredients
- Pour the mix in a mold
}

function cookAndLetChill() {
- Cook for 35 minutes
- Let chill
}
pourIngredients()
mixAndTransferToMold()
cookAndLetChill()

You can see that, thanks to the implementation of functions, we could just read the three
function calls at the end of the file and get a good idea of what our program does.

That simplification and abstraction is one of the benefits of procedural programming. But
within the functions, we still got same old imperative code.
Functional Programming
Functional programming takes the concept of functions a little bit further.

In functional programming, functions are treated as first-class citizens, meaning that they can be
assigned to variables, passed as arguments, and returned from other functions.
Another key concept is the idea of pure functions. A pure function is one that relies only on its inputs
to generate its result. And given the same input, it will always produce the same result. Besides, it
produces no side effects (any change outside the function's environment).
With these concepts in mind, functional programming encourages programs written mostly with
functions (surprise). It also defends the idea that code modularity and the absence of side effects
makes it easier to identify and separate responsibilities within the codebase. This therefore improves
the code maintainability.

Going back to the array filtering example, we can see that with the imperative paradigm we might use
an external variable to store the function's result, which can be considered a side effect.

const nums = [1,4,3,6,7,8,9,2]


const result = [] // External variable

for (let i = 0; i < nums.length; i++) {


if (nums[i] > 5) result.push(nums[i])
}

console.log(result) // Output: [ 6, 7, 8, 9 ]

To transform this into functional programming, we could do it like this:

const nums = [1,4,3,6,7,8,9,2]


function filterNums() {
const result = [] // Internal variable

for (let i = 0; i < nums.length; i++) {


if (nums[i] > 5) result.push(nums[i])
}
return result
}

console.log(filterNums()) // Output: [ 6, 7, 8, 9 ]
It's almost the same code, but we wrap our iteration within a function, in which we also store
the result array. In this way, we can assure the function doesn't modify anything outside its
scope. It only creates a variable to process its own information, and once the execution is
finished, the variable is gone too.

Declarative Programming
Declarative programming is all about hiding away complexity and bringing programming
languages closer to human language and thinking. It's the direct opposite of imperative
programming in the sense that the programmer doesn't give instructions about how the
computer should execute the task, but rather on what result is needed.
This will be much clearer with an example. Following the same array filtering story, a
declarative approach might be:

const nums = [1,4,3,6,7,8,9,2]


console.log(nums.filter(num => num > 5)) // Output: [ 6, 7, 8, 9 ]

See that with the filter function, we're not explicitly telling the computer to iterate over the
array or store the values in a separate array. We just say what we want ("filter") and the
condition to be met ("num > 5").

What's nice about this is that it's easier to read and comprehend, and often shorter to write.
JavaScript's filter, map, reduce and sort functions are good examples of declarative
code.
Another good example is modern JS frameworks/libraries like React. Take this code for
example:

<button onClick={() => console.log('You clicked me!')}>Click me</button>


Here we have a button element, with an event listener that fires a console.log function when
the button is clicked.

JSX syntax (what React uses) mixes HTML and JS in the same thing, which makes it easier and
faster to write apps. But that's not what browsers read and execute. React code is later on
transpiled into regular HTML and JS, and that's what browsers run in reality.

JSX is declarative, in the sense that its purpose is to give developers a friendlier and more
efficient interface to work with.
An important thing to notice about declarative programming is that under the hood, the
computer processes this information as imperative code anyway.

Following the array example, the computer still iterates over the array like in a for loop, but
as programmers we don't need to code that directly. What declarative programming does is
to hide away that complexity from the direct view of the programmer.
Object-Oriented Programming
One of the most popular programming paradigms is object-oriented programming (OOP).

The core concept of OOP is to separate concerns into entities which are coded as objects. Each
entity will group a given set of information (properties) and actions (methods) that can be
performed by the entity.

OOP makes heavy usage of classes (which are a way of creating new objects starting out from a
blueprint or boilerplate that the programmer sets). Objects that are created from a class are
called instances.

Following our pseudo-code cooking example, now let's say in our bakery we have a main cook
(called Frank) and an assistant cook (called Anthony) and each of them will have certain
responsibilities in the baking process. If we used OOP, our program might look like this.

// Create the two classes corresponding to each entity


class Cook {
constructor constructor (name) {
this.name = name
}

mixAndBake() {
- Mix the ingredients
- Pour the mix in a mold
- Cook for 35 minutes
}
}

class AssistantCook {
constructor (name) {
this.name = name
}

pourIngredients() {
- Pour flour in a bowl
- Pour a couple eggs in the same bowl
- Pour some milk in the same bowl
}

chillTheCake() {
- Let chill
}
}

// Instantiate an object from each class


const Frank = new Cook('Frank')
const Anthony = new AssistantCook('Anthony')

// Call the corresponding methods from each instance


Anthony.pourIngredients()
Frank.mixAndBake()
Anthony.chillTheCake()

What's nice about OOP is that it facilitates the understanding of a program, by the clear
separation of concerns and responsibilities.

Assignment:

1. Define Programming paradigm in your own term.


2. Describe any 6 programming paradigm you know and state 3 advantages and 3 disadvantages.
3. Give at least 2 programming language in each of the paradigm.
3.0 The first program in PYTHON
Traditionally, the first program you write in a new language is called “Hello, World!”
because all it does is display the words “Hello, World!”. In Python, it looks like this:
>>> print('Hello, World!')

This is an example of a print statement, although it doesn’t actually print anything on paper. It
displays a result on the screen. In this case, the result is the words

Hello, World!

The quotation marks in the program mark the beginning and end of the text to be displayed;
they don’t appear in the result.

The parentheses indicate that print is a function.

In Python 2, the print statement is slightly different; it is not a function, so it doesn’t use
parentheses.

>>> print 'Hello, World!'

This distinction will make more sense soon, but that’s enough to get started.

3.1 Arithmetic operators


After “Hello, World”, the next step is arithmetic. Python provides operators, which are

special symbols that represent computations like addition and multiplication.

The operators +, -, and * perform addition, subtraction, and multiplication, as in the following examples:

>>> 40 + 2

42

>>> 43 - 1

42

>>> 6 * 7

42
The operator / performs division:

>>> 84 / 2

42.0

You might wonder why the result is 42.0 instead of 42. I’ll explain in the next section.

Finally, the operator ** performs exponentiation; that is, it raises a number to a power:

>>> 6**2 + 6

42

3.2 Values and types


A value is one of the basic things a program works with, like a letter or a number. Some values we have seen so
far are 2, 42.0, and 'Hello, World!'.

These values belong to different types: 2 is an integer, 42.0 is a floating-point number, and 'Hello, World!' is a
string, so-called because the letters it contains are strung together.

If you are not sure what type a value has, the interpreter can tell you:

>>> type(2)

<class 'int'>

>>> type(42.0)

<class 'float'>

>>> type('Hello, World!')

<class 'str'>

In these results, the word “class” is used in the sense of a category; a type is a category of
values.

Not surprisingly, integers belong to the type int, strings belong to str and floating-point
numbers belong to float.

What about values like '2' and '42.0'? They look like numbers, but they are in quotation marks
like strings.

>>> type('2')
<class 'str'>

>>> type('42.0')

<class 'str'>

They’re strings.

When you type a large integer, you might be tempted to use commas between groups of

digits, as in 1,000,000. This is not a legal integer in Python, but it is legal:

>>> 1,000,000

(1, 0, 0)

That’s not what we expected at all! Python interprets 1,000,000 as a comma-separated


sequence of integers.

3.3 Data Types


When coding across programming languages, there are many common data types that
software developers can use. These data types can determine how much memory a computer
needs to process the code, how long it might take to load certain features and what functions a
program might perform.

Learning about the basic types of data for coding can help you better understands these
processes. Here, we define common data types in programming and provide examples of each.

What is a data type?


A data type is an attribute of a piece of data that tells a device how the end-user might interact with the data.
You can also think of them as categorizations that different coding programs might combine in order to execute
certain functions. Most programming languages including C++ and Java use the same basic data types.

10 data types

Each programming language uses a different combination of data types. Some of these types
include:

1. Integer
Integer data types often represent whole numbers in programming. An integer's value moves
from one integer to another without acknowledging fractional numbers in between. The
number of digits can vary based on the device, and some programming languages may allow
negative values.

E.g 425

65

2. Character

In coding, alphabet letters denote characters. Programmers might represent these data types
as (CHAR) or (VARGCHAR), and they can be single characters or a string of letters. Characters
are usually fixed-length figures that default to 1 octet—an 8-bit unit of digital information—but
can increase to 65,000 octets. Examples of characters include:

3. Date

This data type stores a calendar date with other programming information. Dates are typically
a combination of integers or numerical figures. Since these are typically integer values, some
programs can store basic mathematical operations like days elapsed since certain events or
days away from an upcoming event. Some examples might be:
2009-09-15

1998-11-30 09:45:87

SYSDATETIME ()

4. Floating point (real)

Floating-point data types represent fractional numbers in programming. There are two main
floating-point data types, which vary depending on the number of allowable values in the
string:
Float: A data type that typically allows up to seven points after a decimal.

Double: A data type that allows up to 15 points after a decimal.

Float data types might look like this:


float num1 = 1.45E2

float num2 = 9.34567

Similar but often longer in length, an example of the floating-point double might be:
double num2 = 1.87358497267482791E+222

double num2 = 3.198728764857268945

The floating-point double type can provide more accurate values, but it also may require additional
memory to process.

5. Long

Long data types are often 32- or 64-bit integers in code. Sometimes, these can represent
integers with 20 digits in either direction, positive or negative. Programmers use an ampersand
to indicate the data type is a long variable. Long data types are whole numbers, both positive
and negative, that have many place values. Examples include:

-398,741,129,664,271

9,000,000,125,356,546

6. Short

Similar to the long data type, a short is a variable integer. Programmers represent these as
whole numbers, and they can be positive or negative. Sometimes a short data type is a single
integer. Short data types can be up to several integers, but they are always less than long data.
Examples include:
-27,400

5,428

17

7. String
A string data type is a combination of characters that can be either constant or variable. This
often incorporates a sequence of character data types that result in specific commands
depending on the programming language. Strings can include upper and lowercase letters,
numbers and punctuation.

String a = "Open"

String b = "The door"

String c = "Say Hello!"

8. Boolean

Boolean data is what programmers use to show logic in code. It's typically one of two values—
true or false—intended to clarify conditional statements. These can be responses to "if/when"
scenarios, where code indicates if a user performs a certain action. When this happens, the
Boolean data directs the program's response, which determines the next code in the sequence.
Here are some examples of how you might use this:
bool baseballIsBest = false;

bool footballIsBest = true;

Depending on the program, the code may direct the end-user to different screens based on
their selection.

9. Nothing

The nothing data type shows that a code has no value. This might indicate that a code is
missing, the programmer started the code incorrectly or that there were values that defy the
intended logic. It's also called the "nullable type." An example of this is:

Dim option = Nothing

Program.WriteWords(x Is Nothing)

10. Void

Similar to the nothing type, the void type contains a value that the code cannot process. Void
data types tell a user that the code can't return a response. Programmers might use or
encounter the void data type in early system testing when there are no responses programmed
yet for future steps. . This might appear as:
int function_name (void)

3.4 Primitive, Derived and Abstract or User-Defined Data Types.

1. Primitive Data Types: These data types are built-in or predefined data types and can be
used directly by the user to declare variables. example: int, char , float, bool etc. Primitive
data types are:
o Integer
o Character
o Boolean
o Floating Point
o Double Floating Point
o Valueless or Void
2. Derived Data Types: The data-types that are derived from the primitive or built-in
datatypes are referred to as Derived Data Types. These can be of four types namely:
o Function
o List
o Tuple
o Dictionary
o Array
o Pointer
o Reference
3. Abstract or User-Defined Data Types: These data types are defined by user itself. Like,
defining a class in C++ or a structure. C++ provides the following user-defined datatypes:
o Class
o Structure
o Union
o Enumeration
o Typedef defined DataType

There are other data types such as set, byte, byte array, range. These are found mostly in
python

At the moment our concentration is going to be on primitive data types.


3.5 VARIABLES

Variables are the names you give to computer memory locations which are used to store
values in a computer program.

For example, assume you want to store two values 10 and 20 in your program and at a later
stage, you want to use these two values. Let's see how you will do it. Here are the following
three simple steps −

 Create variables with appropriate names.


 Store your values in those two variables.
 Retrieve and use the stored values from the variables.

3.6 Creating variables


Creating variables is also called declaring variables in C programming. Different programming languages
have different ways of creating variables inside a program. For example, C programming has the following
simple way of creating variables −

#include <stdio.h>

int main() {
int a;
int b;
}

The above program creates two variables to reserve two memory locations with
names a and b. We created these variables using int keyword to specify variable data
type which means we want to store integer values in these two variables. Similarly, you can
create variables to store long, float, char or any other data type.

For example −
/* variable to store long value */
long a;

/* variable to store float value */


float b;

Python has no command for declaring a variable.

A variable is created the moment you first assign a value to it.


Example
x = 5
y = "John"
print(x)
print(y)

3.7 Variable Casting


If you want to specify the data type of a variable, this can be done with
casting.

Example
x = str(3) # x will be '3'
y = int(3) # y will be 3
z = float(3) # z will be 3.0

3.8 Get the Type


You can get the data type of a variable with the type() function.

Example
x = 10
y = "Mary"
print(type(x))
print(type(y))

The output for the code above is <class 'int'> and <class 'str'> respectively.

You can try it for the code below:

x = 3.73
y = ‘3.72’
z = ‘M’
a = “M”
print(type(x))
print(type(y))
print(type(z))
print(type(a))
3.9 Many Values to Multiple Variables
Python allows you to assign values to multiple variables in one line:

Example
x, y, z = "Orange", "Banana", "Cherry"
print(x)
print(y)
print(z)

3.10 Expressions
An expression is a combination of operators and operands that is interpreted to produce
some other value. In any programming language, an expression is evaluated as per the
precedence of its operators. So that if there is more than one operator in an expression, their
precedence decides which operation will be performed first? We have many different types
of expressions in Python.

1. Constant Expressions: These are the expressions that have constant values only.
Example:
 Python3

# Constant Expressions

x = 15 + 1.3

print(x)

Output
16.3

2. Arithmetic Expressions: An arithmetic expression is a combination of numeric values,


operators, and sometimes parenthesis. The result of this type of expression is also a numeric
value. The operators used in these expressions are arithmetic operators like addition,
subtraction, etc. Here are some arithmetic operators in Python:

Operators Syntax Functioning

+ x + y Addition

– x – y Subtraction

Multiplicati
* x * y
on

/ x / y Division

x //
// Quotient
y

% x % y Remainder

x ** Exponentiati
**
y on

Example:
Let’s see an exemplar code of arithmetic expressions in Python:

 Python3
# Arithmetic Expressions
x = 40
y = 12
add = x + y
sub = x - y
pro = x * y
div = x / y
print(add)
print(sub)
print(pro)
print(div)
Output
52
28
480
3.3333333333333335

3. Integral Expressions: These are the kind of expressions that produce only integer
results after all computations and type conversions.
Example:
 Python3
# Integral Expressions
a = 13
b = 12.0
c = a + int(b)
print(c)

Output
25

4. Floating Expressions: These are the kind of expressions which produce floating point
numbers as result after all computations and type conversions.
Example:
 Python3
# Floating Expressions
a = 13
b =5
c =a /b

print(c)
Output
2.6

5. Relational Expressions: In these types of expressions, arithmetic expressions are written


on both sides of relational operator (> , < , >= , <=). Those arithmetic expressions are
evaluated first, and then compared as per relational operator and produce a boolean output
in the end. These expressions are also called Boolean expressions.
Example:
 Python3
# Relational Expressions
a = 21
b = 13
c = 40
d = 37
p = (a + b) >= (c - d)

print(p)

Output
True
6. Logical Expressions: These are kinds of expressions that result in either True or False. It
basically specifies one or more conditions. For example, (10 == 9) is a condition if 10 is
equal to 9. As we know it is not correct, so it will return False. Studying logical expressions,
we also come across some logical operators which can be seen in logical expressions most
often. Here are some logical operators in Python :

Operator Syntax Functioning

P and
and It returns true if both P and Q are true otherwise returns false
Q

or P or Q It returns true if at least one of P and Q is true

not not P It returns true if condition P is false

Example:
Let’s have a look at an exemplar code :
 Python3

P = (10 == 9)

Q = (7 > 5)

# Logical Expressions

R = P and Q

S = P or Q

T = not P

print(R)

print(S)

print(T)

Output
False
True
True

7. Bitwise Expressions: These are the kind of expressions in which computations are
performed at bit level.
Example:
 Python3

# Bitwise Expressions

a = 12
x = a >> 2

y = a << 1

print(x, y)

Output
3 24

8. Combinational Expressions: We can also use different types of expressions in a single


expression, and that will be termed as combinational expressions.
Example:
 Python3

# Combinational Expressions

a = 16

b = 12

c = a + (b >> 1)

print(c)

Output
22
But when we combine different types of expressions or use multiple operators in a single
expression, operator precedence comes into play.

Multiple operators in expression (Operator Precedence)

It’s a quite simple process to get the result of an expression if there is only one operator in an
expression. But if there is more than one operator in an expression, it may give different
results on basis of the order of operators executed. To sort out these confusions,
the operator precedence is defined. Operator Precedence simply defines the priority of
operators that which operator is to be executed first. Here we see the operator precedence
in Python, where the operator higher in the list has more precedence or priority:
Precedence Name Operator

1 Parenthesis ()[]{}

2 Exponentiation **

3 Unary plus or minus, complement -a , +a , ~a

4 Multiply, Divide, Modulo / * // %

5 Addition & Subtraction + –

6 Shift Operators >> <<

7 Bitwise AND &

8 Bitwise XOR ^

9 Bitwise OR |

10 Comparison Operators >= <= > <

11 Equality Operators == !=

12 Assignment Operators = += -= /= *=

13 Identity and membership operators is, is not, in, not in

14 Logical Operators and, or, not

So, if we have more than one operator in an expression, it is evaluated as per operator
precedence. For example, if we have the expression “10 + 3 * 4”. Going without precedence
it could have given two different outputs 22 or 52. But now looking at operator precedence,
it must yield 22. Let’s discuss this with the help of a Python program:
 Python3
# Multi-operator expression
a = 10 + 3 * 4
print(a)
b = (10 + 3) * 4
print(b)
c = 10 + (3 * 4)
print(c)
Output
22
52
22
Hence, operator precedence plays an important role in the evaluation of a Python
expression.
4.0 BASIC OBJECT-ORIENTED
CONCEPTS
4.1 Python OOPs Concepts
Object Oriented Programming is a fundamental concept in Python, empowering developers
to build modular, maintainable, and scalable applications. By understanding the core OOP
principles—classes, objects, inheritance, encapsulation, polymorphism, and abstraction—
programmers can leverage the full potential of Python’s OOP capabilities to design elegant
and efficient solutions to complex problems.

4.2 What is Object-Oriented Programming in


Python?
In Python object-oriented Programming (OOPs) is a programming paradigm that uses objects
and classes in programming. It aims to implement real-world entities like inheritance,
polymorphisms, encapsulation, etc. in the programming. The main concept of object-
oriented Programming (OOPs) or oops concepts in Python is to bind the data and the
functions that work together as a single unit so that no other part of the code can access this
data.

4.3 OOPs Concepts in Python


 Class in Python
 Objects in Python
 Polymorphism in Python
 Encapsulation in Python
 Inheritance in Python
 Data Abstraction in Python
Python OOPs Concepts

4.3.1 Python Class


A class is a collection of objects. A class contains the blueprints or the prototype from which
the objects are being created. It is a logical entity that contains some attributes and
methods.
To understand the need for creating a class let’s consider an example, let’s say you wanted to
track the number of dogs that may have different attributes like breed, and age. If a list is
used, the first element could be the dog’s breed while the second element could represent
its age. Let’s suppose there are 100 different dogs, then how would you know which element
is supposed to be which? What if you wanted to add other properties to these dogs? This
lacks organization and it’s the exact need for classes.

Some points on Python class:


 Classes are created by keyword class.
 Attributes are the variables that belong to a class.
 Attributes are always public and can be accessed using the dot (.) operator. Eg.:
Myclass.Myattribute

Class Definition Syntax:


class ClassName:
# Statement-1
.
.
.
# Statement-N
Creating an Empty Class in Python
In the above example, we have created a class named Dog using the class keyword.
Python

# Python3 program to

# demonstrate defining

# a class

class Dog:

pass

Output:

4.3.2 Python Objects


In object oriented programming Python, The object is an entity that has a state and behavior
associated with it. It may be any real-world object like a mouse, keyboard, chair, table, pen,
etc. Integers, strings, floating-point numbers, even arrays, and dictionaries, are all objects.
More specifically, any single integer or any single string is an object. The number 12 is an
object, the string “Hello, world” is an object, a list is an object that can hold other objects,
and so on. You’ve been using objects all along and may not even realize it.
An object consists of:
 State: It is represented by the attributes of an object. It also reflects the properties of an
object.
 Behavior: It is represented by the methods of an object. It also reflects the response of an
object to other objects.
 Identity: It gives a unique name to an object and enables one object to interact with other
objects.

To understand the state, behavior, and identity let us take the example of the class dog
(explained above).
 The identity can be considered as the name of the dog.
 State or Attributes can be considered as the breed, age, or color of the dog.
 The behavior can be considered as to whether the dog is eating or sleeping.

Creating an Object
This will create an object named obj of the class Dog defined above. Before diving deep into
objects and classes let us understand some basic keywords that will be used while working
with objects and classes.

Python
obj = Dog()
The Python self
1. Class methods must have an extra first parameter in the method definition. We do not
give a value for this parameter when we call the method, Python provides it
2. If we have a method that takes no arguments, then we still have to have one argument.
3. This is similar to this pointer in C++ and this reference in Java.
When we call a method of this object as myobject.method(arg1, arg2), this is automatically
converted by Python into MyClass.method(myobject, arg1, arg2) – this is all the special self is
about.

class Dog:

# class attribute

attr1 = "mammal"

# Instance attribute

def __init__(self, name):

self.name = name

# Driver code

# Object instantiation

Rodger = Dog("Rodger")

Tommy = Dog("Tommy")

# Accessing class attributes

print("Rodger is a {}".format(Rodger.__class__.attr1))

print("Tommy is also a {}".format(Tommy.__class__.attr1))

# Accessing instance attributes

print("My name is {}".format(Rodger.name))

print("My name is {}".format(Tommy.name))


Output
Rodger is a mammal
Tommy is also a mammal
My name is Rodger
My name is Tommy

Creating Classes and objects with methods


Here, The Dog class is defined with two attributes:
 attr1 is a class attribute set to the value “mammal“. Class attributes are shared by
all instances of the class.
 __init__ is a special method (constructor) that initializes an instance of the Dog
class. It takes two parameters: self (referring to the instance being created) and
name (representing the name of the dog). The name parameter is used to assign a
name attribute to each instance of Dog.
The speak method is defined within the Dog class. This method prints a string that
includes the name of the dog instance.
The driver code starts by creating two instances of the Dog class: Rodger and
Tommy. The __init__ method is called for each instance to initialize their name
attributes with the provided names. The speak method is called in both instances
(Rodger.speak() and Tommy.speak()), causing each dog to print a statement
with its name.

class Dog:

# class attribute

attr1 = "mammal"

# Instance attribute

def __init__(self, name):

self.name = name

def speak(self):

print("My name is {}".format(self.name))

# Driver code

# Object instantiation
Rodger = Dog("Rodger")

Tommy = Dog("Tommy")

# Accessing class methods

Rodger.speak()

Tommy.speak()

Output
My name is Rodger
My name is Tommy
4.3.3 Inheritance (Inheritance in Python)
In Python Object Oriented Programming, Inheritance is the capability of one class to derive or
inherit the properties from another class. The class that derives properties is called the
derived class or child class and the class from which the properties are being derived is called
the base class or parent class.
The benefits of inheritance are:
 It represents real-world relationships well.
 It provides the reusability of a code. We don’t have to write the same code again and
again. Also, it allows us to add more features to a class without modifying it.
 It is transitive in nature, which means that if class B inherits from another class A, then all
the subclasses of B would automatically inherit from class A.

Types of Inheritance
 Single Inheritance: Single-level inheritance enables a derived class to inherit
characteristics from a single-parent class.
 Multilevel Inheritance: Multi-level inheritance enables a derived class to inherit
properties from an immediate parent class which in turn inherits properties from his
parent class.
 Hierarchical Inheritance: Hierarchical-level inheritance enables more than one derived
class to inherit properties from a parent class.
 Multiple Inheritance: Multiple-level inheritance enables one derived class to inherit
properties from more than one base class.

Inheritance in Python
We have created two classes i.e. Person (parent class) and Employee (Child Class). The
Employee class inherits from the Person class. We can use the methods of the person class
through the employee class as seen in the display function in the above code. A child class
can also modify the behavior of the parent class as seen through the details() method.

# Python code to demonstrate how parent constructors


# are called.

# parent class
class Person(object):

# __init__ is known as the constructor


def __init__(self, name, idnumber):
self.name = name
self.idnumber = idnumber

def display(self):
print(self.name)
print(self.idnumber)
def details(self):
print("My name is {}".format(self.name))
print("IdNumber: {}".format(self.idnumber))

# child class
class Employee(Person):
def __ _( init_self, name, idnumber, salary, post):
self.salary = salary
self.post = post

# invoking the __init__ of the parent class


Person.__init__(self, name, idnumber)

def details(self):
print("My name is {}".format(self.name))
print("IdNumber: {}".format(self.idnumber))
print("Post: {}".format(self.post))
# creation of an object variable or an instance
a = Employee('Rahul', 886012, 200000, "Intern")

# calling a function of the class Person using


# its instance
a.display()
a.details()

Output
Rahul
886012
My name is Rahul
IdNumber: 886012
Post: Intern

4.3.4 Polymorphism
In object oriented Programming Python, Polymorphism simply means having many forms. For
example, we need to determine if the given species of birds fly or not, using polymorphism
we can do this using a single function.

Polymorphism in Python
This code demonstrates the concept of Python oops inheritance and method overriding in
Python classes. It shows how subclasses can override methods defined in their parent class to
provide specific behavior while still inheriting other methods from the parent class.
class Bird:
def intro(self):
print("There are many types of birds.")

def flight(self):
print("Most of the birds can fly but some cannot.")

class sparrow(Bird):
def flight(self):
print("Sparrows can fly.")

class ostrich(Bird):
def flight(self):
print("Ostriches cannot fly.")

obj_bird = Bird()
obj_spr = sparrow()
obj_ost = ostrich()

obj_bird.intro()
obj_bird.flight()

obj_spr.intro()
obj_spr.flight()

obj_ost.intro()
obj_ost.flight()

Output
There are many types of birds.
Most of the birds can fly but some cannot.
There are many types of birds.
Sparrows can fly.
There are many types of birds.
Ostriches cannot fly.

3.3.5 Encapsulation
In Python object oriented programming, Encapsulation is one of the fundamental concepts in
object-oriented programming (OOP). It describes the idea of wrapping data and the methods
that work on data within one unit. This puts restrictions on accessing variables and methods
directly and can prevent the accidental modification of data. To prevent accidental change,
an object’s variable can only be changed by an object’s method. Those types of variables are
known as private variables.
A class is an example of encapsulation as it encapsulates all the data that is member
functions, variables, etc.

Encapsulation in Python
In the above example, we have created the c variable as the private attribute. We cannot even
access this attribute directly and can’t even change its value.

# Python program to
# demonstrate private members
# "__" double underscore represents private attribute.
# Private attributes start with "__".

# Creating a Base class


class Base:
def __init__(self):
self.a = "GeeksforGeeks"
self.__c = "GeeksforGeeks"

# Creating a derived class


class Derived(Base):
def __init__(self):

# Calling constructor of
# Base class
Base.__init__(self)
print("Calling private member of base class: ")
print(self.__c)

# Driver code
obj1 = Base()
print(obj1.a)
# Uncommenting print(obj1.c) will
# raise an AttributeError

# Uncommenting obj2 = Derived() will


# also raise an AtrributeError as
# private member of base class
# is called inside derived class

Output
GeeksforGeeks

3.3.6 Data Abstraction


It hides unnecessary code details from the user. Also, when we do not want to give out sensitive
parts of our code implementation and this is where data abstraction came.
Data Abstraction in Python can be achieved by creating abstract classes.

class Rectangle:
def __init__(self, length, width):
self.__length = length # Private attribute
self.__width = width # Private attribute

def area(self):
return self.__length * self.__width

def perimeter(self):
return 2 * (self.__length + self.__width)

rect = Rectangle(5, 3)
print(f"Area: {rect.area()}") # Output: Area: 15
print(f"Perimeter: {rect.perimeter()}") # Output: Perimeter: 16

# print(rect.__length) # This will raise an AttributeError as length and


width are private attributes

Output
Area: 15
Perimeter: 16
4.0 Iterators/Enumerator
Usually, when someone iterates through an iterable using the conventional loops (for and
while), at times it becomes cumbersome to keep track of the count and the relative positions
of the elements in the iterable. When using for loops, there is no need to assign a variable to
keep the count of the elements; however, there is sometimes a need for a variable that
changes inside the loop based on some conditions.

It is common to use the enumerate method in Python to map the counter’s value along with
the iterable items. It can serve both as a counter and as a way to maintain the indices of the
elements in the iterable.

In simpler words, the enumerate function takes as input, an iterable and adds a counter to
each iterable element, and returns an enumerate object. The counter can also act as indices to
each element which can be used to reference these elements at a later stage when required.

4.1 How it works


Enumerate() is a built-in function of Python. This function allows us to loop over something and
have an automatic counter. And this function works by adding a counter to an iterable and
returning it in the form of an enumerate object. The enumerate object can be used directly for
loops or converted into a list of tuples using the list() method.
This enumerate object contains a count (from the start, which always defaults to 0) and a value
obtained from iterating over the iterable object.

The syntax for enumerate is: enumerate (iterable, start=0).

4.2 How to enumerate a list in Python


Here’s how the enumerate function works with a list as the iterable and a start value
of 0 (the default):
enumerate() takes a list called "fruits" as an argument and returns an enumerate object, which
contains pairs of indices and corresponding items from the list. The for loop unpacks each
pair into i and fruit variables, where i is the index and fruit is the corresponding item.
5.0 Lists Data Structure
In Python, a list is a built-in data structure that is used to store an ordered collection of
items. Lists are mutable, meaning that their contents can be changed after the list has been
created. They can hold a several of data types, including integers, floats, strings, and even
other lists.
Let’s take a quick example for Python list:

a = [1, 'apple', 3.14, [5, 6]]

print(a)

Output
[1, 'apple', 3.14, [5, 6]]

5.1 Creating a List


We can create a list in Python using square brackets [ ] or by using the list() constructor.
Here are some common methods to create a list:

Using Square Brackets


We can directly create a list by enclosing elements in square brackets.
# List of integers

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

# List of strings

b = ['apple', 'banana', 'cherry']

# Mixed data types

c = [1, 'hello', 3.14, True]


print(a)
print(b)
print(c)

Output
[1, 2, 3, 4, 5]
['apple', 'banana', 'cherry']
[1, 'hello', 3.14, True]
Using the list() Constructor
We can also create a list by passing an iterable (like a string, tuple, or another list) to
the list() function.

Python

# From a tuple
a = list((1, 2, 3, 'apple', 4.5))

print(a)

Output
[1, 2, 3, 'apple', 4.5]

5.2 Creating a List with Repeated Elements


We can create a list with repeated elements using the multiplication operator.
Python

# Create a list [2, 2, 2, 2, 2]


a = [2] * 5

# Create a list [0, 0, 0, 0, 0, 0, 0]


b = [0] * 7

print(a)
print(b)

Output
[2, 2, 2, 2, 2]
[0, 0, 0, 0, 0, 0, 0]

5.3 Accessing List Elements


Elements in a list can be accessed using indexing. Python indexes start at 0,
so a[0] will access the first element, while negative indexing allows us to access
elements from the end of the list. Like index -1 represents the last elements of list.
Python
a = [10, 20, 30, 40, 50]

# Access first element


print(a[0])

# Access last element


print(a[-1])

Output
10
50

5.4 Adding Elements into List


We can add elements to a list using the following methods:
 append(): Adds an element at the end of the list.
 extend(): Adds multiple elements to the end of the list.
 insert(): Adds an element at a specific position.

Python
# Initialize an empty list
a = []

# Adding 10 to end of list


a.append(10)
print("After append(10):", a)

# Inserting 5 at index 0
a.insert(0, 5)
print("After insert(0, 5):", a)

# Adding multiple elements [15, 20, 25] at the end


a.extend([15, 20, 25])
print("After extend([15, 20, 25]):", a)

Output
After append(10): [10]
After insert(0, 5): [5, 10]
After extend([15, 20, 25]): [5, 10, 15, 20, 25]
5.5 Updating Elements into List
We can change the value of an element by accessing it using its index.
Python

a = [10, 20, 30, 40, 50]

# Change the second element


a[1] = 25

print(a)

Output
[10, 25, 30, 40, 50]

5.6 Removing Elements from List


We can remove elements from a list using:
 remove(): Removes the first occurrence of an element.
 pop(): Removes the element at a specific index or the last element if no index is
specified.
 del statement: Deletes an element at a specified index.

Python
a = [10, 20, 30, 40, 50]

# Removes the first occurrence of 30


a.remove(30)
print("After remove(30):", a)

# Removes the element at index 1 (20)


popped_val = a.pop(1)
print("Popped element:", popped_val)
print("After pop(1):", a)

# Deletes the first element (10)


del a[0]
print("After del a[0]:", a)

Output
After remove(30): [10, 20, 40, 50]
Popped element: 20
After pop(1): [10, 40, 50]
After del a[0]: [40, 50]

5.7 Iterating Over Lists


We can iterate the Lists easily by using a for loop or other iteration methods. Iterating over
lists is useful when we want to do some operation on each item or access specific items
based on certain conditions. Let’s take an example to iterate over the list using for loop.

Using for Loop


Python

a = ['apple', 'banana', 'cherry']

# Iterating over the list


for item in a:
print(item)

Output
apple
banana
cherry

5.8 Nested Lists and Multidimensional Lists


A nested list is a list within another list, which is useful for representing matrices or
tables. We can access nested elements by chaining indexes.

Python

matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

# Access element at row 2, column 3


print(matrix[1][2])

Output
6
6.0 Stack Data Structure
A stack is a linear data structure that follows the principle of Last In First Out (LIFO). This
means the last element inserted inside the stack is removed first.
You can think of the stack data structure as the pile of plates on top of another.

Stack representation similar to a pile of plate

Here, you can:

 Put a new plate on top

 Remove the top plate

And, if you want the plate at the bottom, you must first remove all the plates on top. This is
exactly how the stack data structure works.

6.1 LIFO Principle of Stack


In programming terms, putting an item on top of the stack is called push and removing an item
is called pop.
Stack Push and Pop Operations

In the above image, although item 3 was kept last, it was removed first. This is exactly how
the LIFO (Last In First Out) Principle works.
We can implement a stack in any programming language like C, C++, Java, Python or C#, but
the specification is pretty much the same.

6.2 Basic Operations of Stack


There are some basic operations that allow us to perform different actions on a stack.

 Push: Add an element to the top of a stack


 Pop: Remove an element from the top of a stack
 IsEmpty: Check if the stack is empty
 IsFull: Check if the stack is full
 Peek: Get the value of the top element without removing it

6.3 Working of Stack Data Structure


The operations work as follows:
1. A pointer called TOP is used to keep track of the top element in
the stack.
2. When initializing the stack, we set its value to -1 so that we
can check if the stack is empty by comparing TOP == -1.
3. On pushing an element, we increase the value of TOP and place
the new element in the position pointed to by TOP.
4. On popping an element, we return the element pointed to
by TOP and reduce its value.
5. Before pushing, we check if the stack is already full

6. Before popping, we check if the stack is already empty

Working of Stack Data Structure

6.4 Stack Implementations in Python


The most common stack implementation is using arrays, but it can also be
implemented using lists.

# Stack implementation in python


# Creating a stack
def create_stack():
stack = []
return stack

# Creating an empty stack


def check_empty(stack):
return len(stack) == 0

# Adding items into the stack


def push(stack, item):
stack.append(item)
print("pushed item: " + item)

# Removing an element from the stack


def pop(stack):
if (check_empty(stack)):
return "stack is empty"

return stack.pop()

stack = create_stack()
push(stack, str(1))
push(stack, str(2))
push(stack, str(3))
push(stack, str(4))
print("popped item: " + pop(stack))
print("stack after popping an element: " + str(stack))
7.0 Queue Data Structure
A queue is a useful data structure in programming. It is similar to the ticket queue outside a
cinema hall, where the first person entering the queue is the first person who gets the ticket.

Queue follows the First In First Out (FIFO) rule - the item that goes in first is the item that
comes out first.

FIFO Representation of Queue

In the above image, since 1 was kept in the queue before 2, it is the first to be removed from
the queue as well. It follows the FIFO rule.
In programming terms, putting items in the queue is called enqueue, and removing items from
the queue is called dequeue.
We can implement the queue in any programming language like C, C++, Java, Python or C#, but
the specification is pretty much the same.

7.1 Types of Queues


There are four different types of queues:

 Simple Queue
 Circular Queue
 Priority Queue
 Double Ended Queue
7.2 Basic Operations of Queue
A queue is an object (an abstract data structure - ADT) that allows the following operations:

 Enqueue: Add an element to the end of the queue


 Dequeue: Remove an element from the front of the queue
 IsEmpty: Check if the queue is empty
 IsFull: Check if the queue is full
 Peek: Get the value of the front of the queue without removing it

7.3 Working of Queue


Queue operations work as follows:

 two pointers FRONT and REAR


 FRONT track the first element of the queue
 REAR track the last element of the queue
 initially, set value of FRONT and REAR to -1
Enqueue Operation
 check if the queue is full

 for the first element, set the value of FRONT to 0


 increase the REAR index by 1
 add the new element in the position pointed to by REAR

Dequeue Operation
 check if the queue is empty

 return the value pointed by FRONT


 increase the FRONT index by 1
 for the last element, reset the values of FRONT and REAR to -1

Enqueue and Dequeue Operations

7.4 Queue Implementations in Python


We usually use arrays to implement queues in Java and C/++. In the case of Python, we use
lists.

# Queue implementation in Python

class Queue():
def __init__(self, k):
self.k = k
self.queue = [None] * k
self.head = self.tail = -1

# Insert an element into the queue


def enqueue(self, data):

if (self.tail == self.k - 1):


print("The queue is full\n")

elif (self.head == -1):


self.head = 0
self.tail = 0
self.queue[self.tail] = data
else:
self.tail = self.tail + 1
self.queue[self.tail] = data

# Delete an element from the queue


def dequeue(self):
if (self.head == -1):
print("The queue is empty\n")

elif (self.head == self.tail):


temp = self.queue[self.head]
self.head = -1
self.tail = -1
return temp
else:
temp = self.queue[self.head]
self.head = self.head + 1
return temp

def printQueue(self):
if(self.head == -1):
print("No element in the queue")

else:
for i in range(self.head, self.tail + 1):
print(self.queue[i], end=" ")
print()

# Your Queue object will be instantiated and called as such:


obj = Queue(5)
obj.enqueue(1)
obj.enqueue(2)
obj.enqueue(3)
obj.enqueue(4)
obj.enqueue(5)
print("Initial queue")
obj.printQueue()

obj.dequeue()
print("After removing an element from the queue")
obj.printQueue()

7.5 Limitations of Queue


As you can see in the image below, after a bit of enqueuing and dequeuing, the size of the
queue has been reduced.

Limitation of a queue

And we can only add indexes 0 and 1 only when the queue is reset (when all the elements have
been dequeued).
After REAR reaches the last index, if we can store extra elements in the empty spaces (0 and
1), we can make use of the empty spaces. This is implemented by a modified queue called
the circular queue.

7.6 Applications of Queue


 CPU scheduling, Disk Scheduling

 When data is transferred asynchronously between two processes.The queue is used


for synchronization. For example: IO Buffers, pipes, file IO, etc

 Handling of interrupts in real-time systems.

 Call Center phone systems use Queues to hold people calling them in order.
8.0 Searching
8.1 Searching Algorithms and its implementation in Python.
Searching algorithms are fundamental techniques used to find an element or a value within a
collection of data. This collection of data can take various forms, such as arrays, lists, trees, or
other structured representations. The primary objective of searching is to determine whether
the desired element exists within the data, and if so, to identify its precise location or
retrieve it. It plays an important role in various computational tasks and real-world
applications, including information retrieval, data analysis, decision-making processes, and
more.

Importance of Searching in DSA


 Efficiency: Efficient searching algorithms improve program performance.
 Data Retrieval: Quickly find and retrieve specific data from large datasets.
 Database Systems: Enables fast querying of databases.
 Problem Solving: Used in a wide range of problem-solving tasks

There are many types of searching algorithms but for this course, we'll explore some of the
most commonly used searching algorithms in Python which are the Linear Search and Binary
Search.

1. Linear Search:
Linear Search, also known as Sequential Search, is one of the simplest and most
straightforward searching algorithms. It works by sequentially examining each element in
a collection of data (array or list) until a match is found or the entire collection has been
traversed.

Linear Search
8.2 Algorithm of Linear Search:
 The Algorithm examines each element, one by one, in the
collection, treating each element as a potential match for
the key you’re searching for.
 If it finds any element that is exactly the same as the key
you’re looking for, the search is successful, and it
returns the index of key.
 If it goes through all the elements and none of them
matches the key, then that means “No match is Found”.

Illustration of Linear Search:


Consider the array arr[] = {10, 50, 30, 70, 80, 20, 90, 40}
and key = 30
Start from the first element (index 0) and compare key with
each element (arr[i]). Comparing key with first element
arr[0]. Since not equal, the iterator moves to the next
element as a potential match.

Comparing key with next element arr[1]. Since not equal, the iterator moves to the next
element as a potential match.
Now when comparing arr[2] with key, the value matches. So the Linear Search Algorithm
will yield a successful message and return the index of the element when key is found.

Pseudo Code for Linear Search:


LinearSearch(collection, key):
for each element in collection:
if element is equal to key:
return the index of the element
return “Not found”

Python Implementation
def linear_search(arr, target):
"""
Perform linear search to find the target value in the given list.

Parameters:
arr (list): The list to be searched.
target: The value to be searched for.

Returns:
int: The index of the target value if found, otherwise -1.
"""
for i in range(len(arr)):
if arr[i] == target:
return i
return -1

# Example usage:
arr = [2, 3, 4, 10, 40]
target = 10
result = linear_search(arr, target)
if result != -1:
print(f"Linear Search: Element found at index {result}")
else:
print("Linear Search: Element not found")

Output
Linear Search: Element found at index 3

When to use Linear Search:


 When there is small collection of data.
 When data is unordered.

2. Binary Search
Binary Search is defined as a searching algorithm used in a sorted array by
repeatedly dividing the search interval in half. Binary search is a more efficient
searching algorithm suitable for sorted lists. It repeatedly divides the search
interval in half until the target value is found.
The idea of binary search is to use the information that the array is sorted and
reduce the time complexity to O(log N).
Algorithm of Binary Search:
 Divide the search space into two halves by finding the middle index “mid”.
 Compare the middle element of the search space with the key.
 If the key is found at middle element, the process is terminated.
 If the key is not found at middle element, choose which half will be used as the
next search space.
o If the key is smaller than the middle element, then the left side is used for
next search.
o If the key is larger than the middle element, then the right side is used for
next search.
 This process is continued until the key is found or the total search space is
exhausted.

Illustration of Binary Search:


Consider an array arr[] = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91}, and the target = 23.
 Calculate the mid and compare the mid element with the key. If the key is less
than mid element, move to left and if it is greater than the mid then move search
space to the right.
 Key (i.e., 23) is greater than current mid element (i.e., 16). The search space
moves to the right.
 Key is less than the current mid 56. The search space moves to the left.

 If the key matches the value of the mid element, the element is found and stop
search.

Pseudo Code for Binary Search:


Below is the pseudo code for implementing binary search:
binarySearch(collection, key):
left = 0
right = length(collection) – 1
while left <= right:
mid = (left + right) // 2
if collection[mid] == key:
return mid
elif collection[mid] < key:
left = mid + 1
else:
right = mid – 1
return “Not found”

Python Implementation of Binary Search


def binary_search(arr, target, low, high):
"""
Perform binary search recursively to find the target value in the given
sorted list.

Parameters:
arr (list): The sorted list to be searched.
target: The value to be searched for.
low (int): The lower index of the search interval.
high (int): The upper index of the search interval.

Returns:
int: The index of the target value if found, otherwise -1.
"""
if low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search(arr, target, mid + 1, high)
else:
return binary_search(arr, target, low, mid - 1)
else:
return -1

# Example usage:
arr = [2, 3, 4, 10, 40]
target = 10
result = binary_search(sorted(arr), target, 0, len(arr) - 1)
if result != -1:
print(f"Binary Search: Element found at index {result}")
else:
print("Binary Search: Element not found")

Output
Binary Search: Element found at index 3

When to use Binary Search:


 When the data collection is monotonic (essential condition) in nature.
 When efficiency is required, especially in case of large datasets.
9.0 SORTING ALGORITHM
9.1 Sorting Algorithms in Python
Sorting is defined as an arrangement of data in a certain order. Sorting techniques are used to
arrange data(mostly numerical) in an ascending or descending order. It is a method used for
the representation of data in a more comprehensible format. It is an important area of
Computer Science. Sorting a large amount of data can take a substantial amount of computing
resources if the methods we use to sort the data are inefficient. The efficiency of the
algorithm is proportional to the number of items it is traversing. For a small amount of data, a
complex sorting method may be more trouble than it is worth. On the other hand, for larger
amounts of data, we want to increase the efficiency and speed as far as possible. We will now
discuss the several sorting techniques and compare them with respect to their time
complexity.

Some of the real-life examples of sorting are:


 Telephone Directory: It is a book that contains telephone numbers and addresses of
people in alphabetical order.
 Dictionary: It is a huge collection of words along with their meanings in alphabetical
order.
 Contact List: It is a list of contact numbers of people in alphabetical order on a mobile
phone.

Sorting Techniques
The different implementations of sorting techniques in Python are:
 Bubble Sort
 Selection Sort
 Insertion Sort

Bubble Sort
Bubble Sort is a simple sorting algorithm. This sorting algorithm repeatedly compares two
adjacent elements and swaps them if they are in the wrong order. It is also known as the
sinking sort. It has a time complexity of O(n2) in the average and worst cases scenarios and
O(n) in the best-case scenario. Bubble sort can be visualized as a queue where people arrange
themselves by swapping with each other so that they all can stand in ascending order of their
heights. Or in other words, we compare two adjacent elements and see if their order is wrong,
if the order is wrong we swap them. (i.e arr[i] > arr[j] for 1 <= i < j <=
s; where s is the size of the array, if array is to be in ascending order, and vice-versa).

Example
Here we sort the following sequence using bubble sort
Sequence: 2, 23, 10, 1

First Iteration

(2, 23, 10, 1) –> (2, 23, 10, 1), Here the first 2 elements are compared and remain the same
because they are already in ascending order.

(2, 23, 10, 1) –> (2, 10, 23, 1), Here 2nd and 3rd elements are compared and swapped(10 is
less than 23) according to ascending order.

(2, 10, 23, 1) –> (2, 10, 1, 23), Here 3rd and 4th elements are compared and swapped(1 is less
than 23) according to ascending order

At the end of the first iteration, the largest element is at the rightmost position which is sorted
correctly.

Second Iteration

(2, 10, 1, 23) –> (2, 10, 1, 23), Here again, the first 2 elements are compared and remain the
same because they are already in ascending order.

(2, 10, 1, 23) –> (2, 1, 10, 23), Here 2nd and 3rd elements are compared and swapped(1 is less
than 10) in ascending order.
At the end of the second iteration, the second largest element is at the adjacent position to the
largest element.

Third Iteration

(2, 1, 10, 23) –> (1, 2, 10, 23), Here the first 2 elements are compared and swap according to
ascending order.

The remaining elements are already sorted in the first and second Iterations. After the three
iterations, the given array is sorted in ascending order. So the final result is 1, 2, 10, 23.
# Python3 program for Bubble Sort Algorithm Implementation
def bubbleSort(arr):
n = len(arr)
# For loop to traverse through all
# element in an array
for i in range(n):
for j in range(0, n - i - 1):

# Range of the array is from 0 to n-i-1


# Swap the elements if the element found
#is greater than the adjacent element
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
# Driver code
# Example to test the above code
arr = [ 2, 1, 10, 23 ]

bubbleSort(arr)

print("Sorted array is:")


for i in range(len(arr)):
print("%d" % arr[i])
Output

Sorted array is:


1
2
10
23
Time Complexity: O(n2)
Auxiliary Space: O(1)

Selection Sort
This sorting technique repeatedly finds the minimum element and sort it in order. Bubble Sort
does not occupy any extra memory space. During the execution of this algorithm, two
subarrays are maintained, the subarray which is already sorted, and the remaining subarray
which is unsorted. During the execution of Selection Sort for every iteration, the minimum
element of the unsorted subarray is arranged in the sorted subarray. Selection Sort is a more
efficient algorithm than bubble sort. Sort has a Time-Complexity of O(n2) in the average,
worst, and in the best cases.

Example

Here we sort the following sequence using the selection sort

Sequence: 7, 2, 1, 6

(7, 2, 1, 6) –> (1, 7, 2, 6), In the first traverse it finds the minimum element(i.e., 1) and it is
placed at 1st position.

(1, 7, 2, 6) –> (1, 2, 7, 6), In the second traverse it finds the 2nd minimum element(i.e., 2) and it
is placed at 2nd position.

(1, 2, 7, 6) –> (1, 2, 6, 7), In the third traverse it finds the next minimum element(i.e., 6) and it
is placed at 3rd position.

After the above iterations, the final array is in sorted order, i.e., 1, 2, 6, 7.
# Selection Sort algorithm in Python
def selectionSort(array, size):

for s in range(size):
min_idx = s
for i in range(s + 1, size):
# For sorting in descending order
# for minimum element in each loop
if array[i] < array[min_idx]:
min_idx = i
# Arranging min at the correct position
(array[s], array[min_idx]) = (array[min_idx], array[s])

# Driver code
data = [ 7, 2, 1, 6 ]
size = len(data)
selectionSort(data, size)

print('Sorted Array in Ascending Order is :')


print(data)
Output
Sorted Array in Ascending Order is :
[1, 2, 6, 7]
Time Complexity: O(n2)
Auxiliary Space: O(1)

Insertion Sort
This sorting algorithm maintains a sub-array that is always sorted. Values from the unsorted
part of the array are placed at the correct position in the sorted part. It is more efficient in
practice than other algorithms such as selection sort or bubble sort. Insertion Sort has a Time-
Complexity of O(n2) in the average and worst case, and O(n) in the best case.

Example

Here we sort the following sequence using the insertion sort

Sequence: 7, 2, 1, 6

(7, 2, 1, 6) –> (2, 7, 1, 6), In the first iteration, the first 2 elements are compared, here 2 is less
than 7 so insert 2 before 7.

(2, 7, 1, 6) –> (2, 1, 7, 6), In the second iteration the 2nd and 3rd elements are compared, here
1 is less than 7 so insert 1 before 7.

(2, 1, 7, 6) –> (1, 2, 7, 6), After the second iteration (1, 7) elements are not in ascending order
so first these two elements are arranged. So, insert 1 before 2.

(1, 2, 7, 6) –> (1, 2, 6, 7), During this iteration the last 2 elements are compared and swapped
after all the previous elements are swapped.
# Creating a function for insertion sort algorithm
def insertion_sort(list1):

# Outer loop to traverse on len(list1)


for i in range(1, len(list1)):

a = list1[i]
# Move elements of list1[0 to i-1],
# which are greater to one position
# ahead of their current position
j = i - 1
while j >= 0 and a < list1[j]:
list1[j + 1] = list1[j]
j -= 1

list1[j + 1] = a
return list1
# Driver code
list1 = [ 7, 2, 1, 6 ]
print("The unsorted list is:", list1)
print("The sorted new list is:", insertion_sort(list1))

Output
The unsorted list is: [7, 2, 1, 6]
The sorted new list is: [1, 2, 6, 7]
Time Complexity: O(n2)
Auxiliary Space: O(1)
RECURSIVE ALGORITHM

Recursion in Python
Recursion is the process of defining something in terms of itself.

A physical world example would be to place two parallel mirrors facing each other.
Any object in between them would be reflected recursively.

Python Recursive Function


In Python, we know that a function can call other functions. It is even possible for the function
to call itself. These types of construct are termed as recursive functions.
The following image shows the working of a recursive function called recurse .

Following is an example of a recursive function to find the factorial of an integer.


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

Example of a recursive function


def factorial(x):
"""This is a recursive function
to find the factorial of an integer"""

if x == 1:
return 1
else:
return (x * factorial(x-1))

num = 3
print("The factorial of", num, "is", factorial(num))

Output

The factorial of 3 is 6

In the above example, factorial() is a recursive function as it calls itself.


When we call this function with a positive integer, it will recursively call itself by decreasing the
number.

Each function multiplies the number with the factorial of the number below it until it is equal
to one. This recursive call can be explained in the following steps.

factorial(3) # 1st call with 3

3 * factorial(2) # 2nd call with 2

3 * 2 * factorial(1) # 3rd call with 1

3 * 2 * 1 # return from 3rd call as number=1

3 * 2 # return from 2nd call

6 # return from 1st call

Let's look at an image that shows a step-by-step process of what is going on:
Our recursion ends when the number reduces to 1. This is called the base condition.

Every recursive function must have a base condition that stops the recursion or else the
function calls itself infinitely.

The Python interpreter limits the depths of recursion to help avoid infinite recursions,
resulting in stack overflows.

By default, the maximum depth of recursion is 1000. If the limit is crossed, it results
in RecursionError. Let's look at one such condition.

def recursor():
recursor()
recursor()

Output
Traceback (most recent call last):
File "<string>", line 3, in <module>
File "<string>", line 2, in a
File "<string>", line 2, in a
File "<string>", line 2, in a
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

Advantages of Recursion

1. Recursive functions make the code look clean and elegant.

2. A complex task can be broken down into simpler sub-problems using recursion.

3. Sequence generation is easier with recursion than using some nested iteration.

Disadvantages of Recursion

1. Sometimes the logic behind recursion is hard to follow through.


2. Recursive calls are expensive (inefficient) as they take up a lot of memory and time.
3. Recursive functions are hard to debug.
EVENT-DRIVEN PROGRAMMING
Event-driven programming focuses on events. Eventually, the flow of program depends upon
events. Until now, we were dealing with either sequential or parallel execution model but the
model having the concept of event-driven programming is called asynchronous model. Event-
driven programming depends upon an event loop that is always listening for the new incoming
events. The working of event-driven programming is dependent upon events. Once an event
loops, then events decide what to execute and in what order.

Event-driven programming is a paradigm where the execution of a program is determined by


events such as user actions or messages. Programs respond to events with predefined
actions, allowing for asynchronous and responsive behavior, often seen in GUI applications
and distributed systems.

Most programs and devices like a cellphone respond to events — things that happen. For
example, you might move your mouse, and the computer responds. Or you click a button, and
the program does something interesting.

These events can be triggered by key-press (keypress events), mouse click/movement (mouse
event) and timer (automatic event from a timer).

Here we will concentrate on Event Handling Methods, Event Propagation and Exception
Handling.

Event Handler in Python


What it is?
An Event Handler is a class, part of events, which simply is responsible for managing all
callbacks which are to be executed when invoked. An Event is simply an action, like clicking a
button, which then leads to another event, which the developer already assigns. The core of
Python Event Handler is to manage these events and organize and make them work as
intended in an intended manner. It is a known fact that programs that follow proper event
handling are flexible and easy to manage. Debugging such programs is easy. Another
advantage is the ability to change the program at any given point, according to needs.
How Does Work?
Event Handler class in python works similarly as in other programming languages. We have
understood that the working of events is basically like raising a flag for an event. And a class
responsible for handling and monitoring these events is known as an event handler. A very
simple example to understand the working of events and event handlers is a user form. After
the user is done filling out the information, the user has to click on the submit button, sending
the details and processing it. In Python, where we mentioned events, there are two ends.

One is the class that raises the event, which is called a publisher, and the other class
responsible for receiving the raised events is known as subscribers. Similar to other
programming languages, Events in Python can call for multiple numbers of subscribers, and at
the same time, these subscribers can call for multiple numbers of publishers. This is one of the
great features related to event handling. We have also understood that multiple functions with
callback can be used for a single same event. So when the event is fired, every other event
handler, which is attached to the event, is invoked in a sequential manner.

How to Create and Handle Events in Python


Events are useful for creating dynamic and interactive applications that can react to user input,
system changes, or external stimuli. However, handling events can be challenging, especially
when there are multiple sources and listeners of events, and when the events are
asynchronous or concurrent. To simplify the event handling process, Python provides a built-
in event module that allows you to create and manage event objects that can be set, cleared,
and waited for by different threads or processes.
Another way to handle events in Python is to use the observer pattern, which is a behavioral
design pattern that defines a one-to-many relationship between a subject and multiple
observers. The subject is an object that holds some state and can notify the observers of any
changes in that state. The observers are objects that can register themselves to the subject and
define how to respond to the notifications. The observer pattern decouples the subject and the
observers, making the code more modular and flexible.

Example 1: Using Key Press


import turtle

turtle.setup(400,500) # Determine the window size


wn = turtle.Screen() # Get a reference to the window
wn.title("Handling keypresses!") # Change the window title
wn.bgcolor("lightgreen") # Set the background color
tess = turtle.Turtle() # Create our favorite turtle

# The next four functions are our "event handlers".


def h1():
tess.forward(30)

def h2():
tess.left(45)

def h3():
tess.right(45)

def h4():
wn.bye() # Close down the turtle window

# These lines "wire up" keypresses to the handlers we've defined.


wn.onkey(h1, "Up")
wn.onkey(h2, "Left")
wn.onkey(h3, "Right")
wn.onkey(h4, "q")

# Now we need to tell the window to start listening for events,


# If any of the keys that we're monitoring is pressed, its
# handler will be called.
wn.listen()
wn.mainloop()

Example 2: Using Mouse Click


import turtle

turtle.setup(400,500)
wn = turtle.Screen()
wn.title("How to handle mouse clicks on the window!")
wn.bgcolor("lightgreen")

tess = turtle.Turtle()
tess.color("purple")
tess.pensize(3)
tess.shape("circle")

def h1(x, y):


tess.goto(x, y)

wn.onclick(h1) # Wire up a click on the window.


wn.mainloop()

EXCEPTION in Programming
Python Exceptions
An exception is an unexpected event that occurs during program execution. For example,
division by zero will throw an error.
divide_by_zero = 7 / 0

The above code causes an exception as it is not possible to divide a number by 0.

Python Logical Errors (Exceptions)


Errors that occur at runtime (after passing the syntax test) are called exceptions or logical
errors.
For instance, they occur when we
try to open a file(for reading) that does not exist (FileNotFoundError)

 try to divide a number by zero (ZeroDivisionError)
 try to import a module that does not exist (ImportError) and so on.
Whenever these types of runtime errors occur, Python creates an exception object.
If not handled properly, it prints a traceback to that error along with some details about
why that error occurred.
Let's look at how Python treats these errors:
divide_numbers = 7 / 0
print(divide_numbers)
Run Code

Output
Traceback (most recent call last):
File "<string>", line 1, in <module>
ZeroDivisionError: division by zero

Here, while trying to divide 7 / 0, the program throws a system


exception ZeroDivisionError

Python Error and Exception


Errors represent conditions such as compilation error, syntax error, error in the logical part of
the code, library incompatibility, infinite recursion, etc.
Errors are usually beyond the control of the programmer and we should not try to handle
errors.
Exceptions can be caught and handled by the program.
Python Exception Handling
We already know that exceptions abnormally terminate the execution of a program.
Since exceptions abnormally terminate the execution of a program, it is important to
handle exceptions. In Python, we use the try...except block to handle exceptions.
Python try...except Block
The try...except block is used to handle exceptions in Python.
Here's the syntax of try...except block:
try:
# code that may cause exception
except:
# code to run when exception occurs

Here, we have placed the code that might generate an exception inside
the try block. Every try block is followed by an except block.
When an exception occurs, it is caught by the except block. The except block
cannot be used without the try block.

Example: Exception Handling Using try...except


try:
numerator = 10
denominator = 0

result = numerator/denominator

print(result)
except:
print("Error: Denominator cannot be 0.")

# Output: Error: Denominator cannot be 0.


In the example above, we are trying to divide a number by 0. Here, this code generates
an exception.
To handle the exception, we have put the code, result =
numerator/denominator inside the try block. Now when an exception occurs, the
rest of the code inside the try block is skipped.
The except block catches the exception and statements inside the except block are
executed.
If none of the statements in the try block generates an exception, the except block is
skipped.

Catching Specific Exceptions in Python


For each try block, there can be zero or more except blocks.
Multiple except blocks allow us to handle each exception differently.
The argument type of each except block indicates the type of exception that
can be handled by it.
For example,
try:
even_numbers = [2,4,6,8]
print(even_numbers[5])

except ZeroDivisionError:
print("Denominator cannot be 0.")

except IndexError:
print("Index Out of Bound.")

# Output: Index Out of Bound


In this example, we have created a list named even_numbers.
Since the list index starts from 0, the last element of the list is at index 3. Notice the
statement,
print(even_numbers[5])

Here, we are trying to access a value to the index 5. Hence, IndexError exception
occurs.
When the IndexError exception occurs in the try block,
 The ZeroDivisionError exception is skipped.
 The set of code inside the IndexError exception is executed.

Python try with else clause


In some situations, we might want to run a certain block of code if the code block
inside try runs without any errors.
For these cases, you can use the optional else keyword with the try statement.
Let's look at an example:
# program to print the reciprocal of even numbers

try:
num = int(input("Enter a number: "))
assert num % 2 == 0
except:
print("Not an even number!")
else:
reciprocal = 1/num
print(reciprocal)
Output
If we pass an odd number:

Enter a number: 1
Not an even number!

If we pass an even number, the reciprocal is computed and displayed.


Enter a number: 4
0.25
However, if we pass 0, we get ZeroDivisionError as the code block inside else is
not handled by preceding except.
Enter a number: 0
Traceback (most recent call last):
File "<string>", line 7, in <module>
reciprocal = 1/num
ZeroDivisionError: division by zero

Here, the assert statement in the code checks that num is an even number; if num is
odd, it raises an AssertionError, triggering the except block.
Note: Exceptions in the else clause are not handled by the preceding except clauses.

Python try...finally
In Python, the finally block is always executed no matter whether there is an
exception or not.
The finally block is optional. And, for each try block, there can be only
one finally block.
Let's see an example,
try:
numerator = 10
denominator = 0

result = numerator/denominator

print(result)
except:
print("Error: Denominator cannot be 0.")

finally:
print("This is finally block.")

Output
Error: Denominator cannot be 0.
This is finally block.
In the above example, we are dividing a number by 0 inside the try block. Here, this code generates an
exception.
The exception is caught by the except block. And, then the finally block is executed.

INTRODUCTION TO STRING AND STRING


PROCESSING
In Python, strings are used for representing textual data. A string is a sequence of characters
enclosed in either single quotes (‘’) or double quotes (“”). The Python language provides
various built-in methods and functionalities to work with strings efficiently. We will explore
some of the commonly used string operations and capabilities in Python.

Creating a String
To create a string in Python, you can simply enclose a sequence of
characters in quotes. For example:

my_string = "Hello, World!"

You can also use single quotes to create a string:

my_string = 'Hello, World!'

Both single and double quotes can be used interchangeably, as long as they are used
consistently within the same string.

Accessing Characters in a String


You can access individual characters in a string by using indexing. In Python, indexing starts from
0, so the first character of a string is at index 0, the second character is at index 1, and so on. For
example:
my_string = "Hello, World!"
print(my_string[0]) # Output: H
print(my_string[7]) # Output: W

You can also use negative indexing to access characters from the end of the string. For
example, `-1` represents the last character, `-2` represents the second last character, and so
on.
String Slicing
String slicing allows you to extract a substring from a string. It is done by specifying the start and
end indices of the substring you want to extract. The start index is inclusive, while the end index
is exclusive. For example:
my_string = "Hello, World!"
print(my_string[0:5]) # Output: Hello
print(my_string[7:]) # Output: World!
print(my_string[:5]) # Output: Hello
print(my_string[-6:]) # Output: World!
Concatenating Strings
You can concatenate or combine strings using the `+` operator. For example:
string1 = "Hello"
string2 = "World"
concatenated_string = string1 + ' ' + string2
print(concatenated_string) # Output: Hello World

String Length
To determine the length of a string, you can use the `len()` function. It returns the number of
characters in the string. For example:
my_string = "Hello, World!"
length = len(my_string)
print(length) # Output: 13

String Methods
Python provides various built-in methods to perform operations and manipulations on strings, making it
easy to handle text data efficiently. Here are some commonly used string methods:
 lower(): Converts all characters in a string to lowercase. This is useful for case-insensitive
comparisons or normalizing text data.

text = "Hello World"


print(text.lower()) # Output: "hello world"

 upper(): Converts all characters in a string to uppercase. This can be useful for making
text stand out or for case-insensitive comparisons.
text = "Hello World"
print(text.upper()) # Output: "HELLO WORLD"

 strip(): Removes leading and trailing whitespace from a string. This is often used to clean up
user input or data read from files.
text = " Hello World "
print(text.strip()) # Output: "Hello World"

 split(): Splits a string into a list of substrings based on a delimiter. By default, the delimiter is
any whitespace, but you can specify a different delimiter if needed.
text = "Hello World"
print(text.split()) # Output: ["Hello", "World"]
text = "apple,banana,cherry"
print(text.split(",")) # Output: ["apple", "banana", "cherry"]

 replace(): Replaces occurrences of a specified substring with another substring. This is useful
for text substitution or cleaning up data.
text = "Hello World"
print(text.replace("World", "Python")) # Output: "Hello Python"

 find(): Returns the index of the first occurrence of a substring in a string, or -1 if the substring
is not found. This method is useful for searching within strings.
text = "Hello World"
print(text.find("World")) # Output: 6
print(text.find("Python")) # Output: -1

These methods help streamline various text processing tasks, from cleaning and formatting
to searching and modifying strings, making Python a powerful tool for handling textual data.
These are just a few examples of string methods available in Python. There are many more
methods that you can explore and use depending on your specific needs.

String Formatting
String formatting allows you to create dynamic strings by inserting variables or values into a
string. There are several ways to format strings in Python, including using the `%` operator or
using the `format()` method.
Here’s an example using the `%` operator:
name = "Alice"
age = 25
formatted_string = "My name is %s and I am %d years old." % (name, age)
print(formatted_string) # Output: My name is Alice and I am 25 years old.

And here’s an example using the `format()` method:


name = "Alice"
age = 25
formatted_string = "My name is {} and I am {} years old.".format(name, age)
print(formatted_string) # Output: My name is Alice and I am 25 years old.
Format using the f-string:
The f-string is a feature introduced in Python 3.6 that provides a concise and convenient way to
embed expressions inside string literals, using curly braces “{}” as placeholders. The values of
these expressions are then formatted and replaced inside the string.
Here’s a basic example:
name = "John"
age = 25
message = f"Hello, my name is {name} and I am {age} years old."
print(message) # Hello, my name is John and I am 25 years old.
Hello, my name is John and I am 25 years old.

In this example, the f-string is created by prefixing the string literal with the ‘f’ character. Inside
the string, we can use curly braces to insert expressions. In this case, `{name}` will be
replaced with the value of the `name` variable, and `{age}` will be replaced with the value of
the `age` variable. The resulting string will be printed as “Hello, my name is John and
I am 25 years old.”
We can also perform operations and include expressions inside the curly braces. For example:
num = 42
result = f"The answer is {num * 2}"
print(result)

Here, the expression `{num * 2}` is evaluated to `84` and replaced inside the string. The
output will be “The answer is 84”.
The f-string method is very powerful and flexible. It allows us to include any valid Python
expression inside the curly braces, making it easy to format and interpolate values within
strings.

Iterating through a string


Iterating through a string in Python is simple and can be done in several ways. One common
method is to use a for loop.
Here is an example:
```python
s = “Hello, World!”
for char in s:
print(char)
```
In this example, `char` will take on the value of each character in the string `s` for every
iteration of the loop.
Another method is to use a while loop, although this is less common:
```python
s = “Hello, World!”
i = 0
while i < len(s):
print(s[i])
i += 1
```
In this example, each iteration of the loop prints the character at index `i`
and then increments `i` by 1.

Lastly, if you need the index while iterating, you can use `enumerate()`,
which provides the index and the character at the same time:
```python
s = “Hello, World!”
for i, char in enumerate(s):
print(f”Character at index {i} is {char}”)
```
In this example, for each iteration of the loop, `i` is the index and `char` is
the character at that index in the string `s`. The `f-string` is used to
print a formatted string with the index and character.

You might also like