Intro Python-Combined
Intro Python-Combined
Why Python?
1. Easy to Use: Python is comparatively an easier-to-use language as compared to
other programming languages.
2. Expressive Language: The syntax of Python is closer to how you would write
pseudocode. Which makes it capable of expressing the code’s purpose better than
many other languages.
Python Download
The very first step towards Python Programming would be to download the tools required
to run the Python language. We will be using Python 3 for the course. You can download
the latest version of Python 3 from https://www.python.org/downloads/
Note:- If you are using Windows OS, then while installing Python make sure that “Add
Python to PATH“ is checked.
Getting an IDE for writing programs:
You can use any IDE of your choice, however, you are recommended to use Jupyter
Notebook. You can download it from https://jupyter.org/install
1
Working in Python
Once you have Python installed on your system, you are ready to work on it. You can work
in Python in two different modes:-
a) Interactive Mode: In this mode, you type one command at a time and Python
executes the same. Python’s interactive interpreter is also called Python Shell.
b) Script Mode: In this mode, we save all our commands in the form of a program file
and later run the entire script. After running the script, the whole program gets
compiled and you’ll see the overall output.
As we are just getting started with Python, we will start with the most fundamental
program which would involve printing a standard output to the console. The print()
function is a way to print to the standard output. The syntax to use print() function is as
follows:-
In[] : print(<Objects>)
Example: If we want to print “Hello, World!” in our code, we will write it in the following
way:-
2
Python executed the first line by calling the print() function. The string value of Hello,
World! was passed to the function.
Note:- The quotes that are on either side of Hello, World! were not printed to the screen
because they are used to tell Python that they contain a string. The quotation marks delineate
where the string begins and ends.
Variables in Python
What are Variables?
A variable in Python represents a named location that refers to value and whose values can
be used and processed during the program run. In other words, variables are labels/names
to which we can assign value and use them as a reference to that value throughout the
code.
● Variables give values context: For example, The number 56 could mean lots of
different things, such as the number of students in a class, or the average weight of
all students in the class. Assigning the number 56 to a variable with a name like
num_students would make more sense, to distinguish it from another variable
average_weight, which would refer to the average weight of the students. This way
we can have different variables pointing to different values.
3
operator and one to the right, and adds them together. Likewise, the “=” operator takes a
value to the right of the operator and assigns it to the name/label/variable on the left of the
operator.
For Example: Now let us create a variable namely Student to hold a student’s name and a
variable Age to hold a student’s age.
Python will internally create labels referring to these values as shown below:
Here, the Python program assigned the value of the string to a variable greeting, and
then when we call print(greeting), it prints the value that the variable, greeting, points
to i.e. "Hello, World!"
We get the output as:-
Hello, World!
Naming a Variable
You must keep the following points in your mind while naming a variable:-
4
● Variable names are case sensitive. For example:- The variable names Temp and
temp are different.
● While writing a program, creating self-explanatory variable names help a lot in
increasing the readability of the code. However, too long names can clutter up the
program and make it difficult to read.
Age = 20
Age = 30 # Re-assigning a different value to the same variable
5
In the above script, when we declare a new variable Age, a container box/ Memory Location
is named Age and the value 20 is stored in the memory address 1000245 with name/label,
Age. Now, on reassigning the value 30 to Age, the value 30 is stored in the same memory
location. This is how the variables behave in Traditional programming languages.
Python preloads some commonly used values in an area of memory. This memory space
has values/literals at defined memory locations and all these locations have different
addresses.
When we give the command, Age = 20, the variable Age is created as a label pointing to a
memory location where 20 is already stored. If 20 is not present in any of the memory
locations, then 20 is stored in an empty memory location with a unique address and then
the Age is made to point to that memory location.
6
Now, when we give the second command, Age = 30, the label Age will not have the same
location as earlier. Now it will point to a memory location where 30 is stored. So this time
the memory location for the label Age is changed.
Data Types
Introduction
Data types are the classification or categorization of data items. Data types
represent a kind of value that determines what operations can be performed on
that data. Numeric, non-numeric, and Boolean (true/false) data are the most used
data types. However, each programming language has its classification largely
reflecting its programming philosophy. Python offers the following built-in data
types:
7
● Numbers
○ Integers
○ Floating Point Numbers
○ Complex Numbers
● Strings
● Boolean Values
● List, Tuple, and Dictionary ( To be covered later in the course )
int Integers 4
Note:- If a variable has been assigned a value of some data type. It can be reassigned a
value belonging to some other Data Type in the future.
Python Numbers
Introduction
Number data types store numerical values. Python supports Integers, floating-point
numbers, and complex numbers. They are defined as int, float, and complex classes.
● Integers can be of any length (Only limited by the memory available). They do not
have a decimal point and can be positive or negative.
8
● A floating-point number is a number having a fractional part. The presence of a
decimal point indicates a floating-point number. They have a precision of up to 15
digits.
● 1 is an integer, 1.0 is a floating-point number.
● Complex numbers are of the form, x + yj, where x is the real part and y is the
imaginary part.
We can use the type() function to know which class a variable or a value belongs to.
Similarly, the isinstance() function is used to check if an object belongs to a particular
class.
b = 5
print(b, "is of type", type(b))
b = 2.0
print(b, "is of type", type(b))
b = 1+2j
print(b, "is complex number?", isinstance(b,complex))
The Arithmetic Operators are used in Python in the same way as they are used in
Mathematics.
OPERATOR DESCRIPTION
9
* Multiplies two operands
** Exponent Operator- The first operand raised to the power of the second
operand
10
To get the input from the user interactively, we can use the built-in function, input(). This
function is used in the following manner:
For example:
Note:- input() function always returns a value of the String type. Notice that in the
above script the output for both name and age, Python has enclosed the output in quotes,
like 'Rishabh' and '19', which implies that it is of String type. This is just because,
whatever the user inputs in the input() function, it is treated as a String. This would
mean that even if we input an integer value like 20, it will be treated like a string '19' and
not an integer. Now, we will see how to read Numbers in the next section.
Reading Numbers
Python offers two functions int() and float() to be used with the input() function to
convert the values received through input() into the respective numeric types integer and
floating-point numbers. The steps will be:-
1. Use the input() function to read the user input.
11
2. Use the int() and float() function to convert the value read into integers and
floating-point numbers, respectively. This process is called Type Casting.
Here, variableRead is a String type that was read from the user. This string value will then
be converted to Integer using the int() function and assigned to updatedVariable.
This can even be shortened to a single line of code as shown below:-
Here, the output will be 19 and not '19', i.e. the output is an Integer and not a String.
12
A boolean expression (or logical expression) evaluates to one of the two states - True or
False. Several functions and operations in Python return boolean objects.
The assignment of boolean datatype to some variable can be done similar to other data
types. This is shown as follows:-
>>> a = True
>>> type(a)
<class 'bool'>
>>> b = False
>>> type(b)
<class 'bool'>
Note:- Here True and False are Reserved keywords. ie They are not written as "True" or
"False", as then they will be taken as strings and not boolean values.
C = "True"
D = " False"
Here, C and D are of type String.
Also, note the keywords True and False must have an Upper Case first letter. Using a
lowercase true or f alse will return an error.
>>> e = true
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'true' is not defined
1
Relational Operators
The operators which compare the values of their operands are called comparison/
relational operators. Python has 6 most common relational operators. Let X and Y be the
two operands and let X = 5 and Y = 10.
==
If the values of two operands are equal, then the (X == Y) is f alse
condition is true, otherwise, it is f alse.
Common Mistake:- Do not confuse it with the Assignment
Operator(=).
!=
If the values of the two operands are not equal, then the (X != Y) is true.
condition is true.
>
If the value of the left operand is greater than the value of (X > Y) is false
the right operand, then the condition is true.
<
If the value of the left operand is less than the value of (X < Y) is true.
the right operand, then the condition is true.
>=
If the value of the left operand is greater than or equal to (X >= Y) is f alse.
the value of the right operand, then the condition is t rue.
<=
If the value of the left operand is less than or equal to the (X <= Y) is t rue.
value of the right operand, then the condition is true.
2
Logical Operators
The operators which act on one or two boolean values and return another boolean value
are called logical operators. There are 3 key logical operators. Let X and Y be the two
operands and let X
= True and Y = False.
and Logical AND: If both the operands are true then (X and Y) is false
the condition is true.
or Logical OR: If any of the two operands are then (X or Y) is true
the condition is true.
not Logical NOT: Used to reverse the logical state of Not(X) is f alse
its operand.
T T T T F F
T F F T F T
F T F T T F
F F F F T T
3
x = 9
y = 1 3
x = True
y = F alse
4
Introduction to If-Else
There are certain points in our code when we need to make some decisions and then
based on the outcome of those decisions we execute the next block of code. Such
conditional statements in programming languages control the flow of program execution.
Most commonly used conditional statements in Python are:
● Simple If statements
● If-Else statements
● If-Elif s tatements
● Nested C
onditionals
Simple If statements
These are the most simple decision-making/conditional statements. It is used to decide
whether a certain statement or block of statements will be executed or not.
● The most important part of any conditional statement is a condition or a boolean.
● And the second important thing is the code block to be executed.
if <Boolean/Condition>:
<Code Block to be executed in case the Boolean is T
rue>
<Code Block to be executed in case the Boolean is False>
Val = False
if Val == True:
print("Value is True") # Statement 1
print("Value is False") # Statement 2
5
To indicate a block of code and separate it from other blocks in Python, you must indent
each line of the block by the same amount. The two statements in our example of Simple
if-statements are both indented four spaces, which is a typical amount of indentation used
in the case of Python.
In most other programming languages, indentation is used only to improve the readability
of the code. But in Python, it is required for indicating what block of code, a statement
belongs to. For instance, S
tatement 1 which is indented by 4 spaces is a part of the i
f
statement block. On the other hand, Statement 2 is not indented, and hence it is not a part
of the if block. This way, indentation indicates which statements from the code belong
together.
Any deviation from the ideal level of indentation for any statement would produce an
indentation error. F
or example: On running the given script:
Val = False
if Val == True:
print("Value is True") # Statement 1
print("Value is False") # Statement 2
We get the output as:
This error is because s tatement 1 is not in the indentation line for the if statement.
6
Else-If statements
The simple i
f statement, tells us that if a condition is true it will execute a block of
statements, and if the condition is false it won’t. But what if we want some other block of
code to be executed if the condition is false. Here comes the e lse statement. We can use
the else statement with i
f statement to execute a block of code when the condition is
false. The general Syntax for the If-Else statement is:
if (Condition/Boolean):
<Code block to be executed in case the condition is True>
else:
<Code block to be executed in case the condition is False>
*** Keep in mind the indentation levels for various code blocks. Let us now take an
Problem Statement: G
iven a number, print whether it is odd or even.
Approach: In order fora number to be even, it must be divisible by 2. Which means that the
remainder upon dividing the number by 2 must be 0. Thus, in order to distinguish between
odd and even numbers, we can use this condition. The numbers which leave a remainder 0
on division with 2 will be categorized as even, else the number is odd. This can be written in
Python as follows:-
num = 23
If num%2 == 0:
print("Even Number")
else:
print("Odd Number")
The output of this code will be:-
Odd Number
7
If-Elif-Else statements
So far we have looked at Simple If and a single If-Else statement. However, imagine a
executed, and if some other condition is fulfilled we want some other block of code to run.
However, if none of the conditions is fulfilled, we want some third block of code to be
In this, the program decides among multiple conditionals. The if statements are executed
from the top down. As soon as one of the conditions controlling the if is true, the
none of the conditions is true, then the final else statement will be executed.
*** Keep in mind the indentation levels for various code blocks.
Note:- We can have as many elif s tatements as we want, between the if and the e
lse
statements. This means we can consider as many conditions as we want. It should be
noted that once an if or elif condition is executed, the remaining e
lif and else
statements will not be executed.
8
Problem Statement: Given three numbers A, B and C, find the largest among the three
and print it.
A = 10
B = 20
C = 30
if A>=B and A>= C:
print(A)
elif B>=C and B>=A:
print(B)
else:
Print(C)
● Here since 10 is not greater than 20 and 30, the first if the condition is not
satisfied. The code goes on to the e
lif condition.
● Now, 20 is also not greater than both 10 and 30, thus even the elif condition is not
true. Thus, the else code block will now be executed.
● Thus the output will be 30, as it is the largest among the three. The else conditional
block is executed.
The output of the above code will be:
30
9
Nested Conditionals
A nested i
f is an i
f statement that is present in the code block of another if statement.
In other words, it means- an if statement inside another if statement. Yes, Python allows
such a framework for us to nest i
f statements. Just like nested if statements, we can
have all types of nested conditionals. A nested conditional will be executed only when the
parent conditional is true.
The general syntax for a very basic nested if statement will be:
else:
# If Condition 1 is False then execute this code block>
if <Condition 3>:
< If Condition 3 is True then execute this code block>
else:
< If Condition 3 is False then execute this code block>
Note:- The conditions used in all of these conditional statements can be comprised of
relational or logical operators. For example:-
A = T rue
B = F alse
if( A and B ): # True and False = False
print("Hello")
else:
print("Hi") # This code block will be executed
The output of the above code will be:
10
The while loop is somewhat similar to an if statement, it executes the code block inside if
the expression/condition is T
rue. However, as opposed to the if statement, the while loop
continues to execute the code repeatedly, as long as the expression is T
rue. In other words,
a while loop iterates over a block of code.
In Python, the body of a while loop is determined by the indentation. It starts with
indentation and ends at the first unindented line.
The most important part of a while loop is the looping variable. This looping variable
controls the flow of iterations. An increment or decrement in this looping variable is
important for the loop to function. It determines the next iteration level. In case of the
absence of such increment/decrement, the loop gets stuck at the current iteration and
continues forever until the process is manually terminated.
while(Expression/Condition/Boolean):
<Execute this code block till the Expression is True>
#Increment/Decrement in looping variable
Example:
Problem Statement: Given an Integer n, Find the Sum of first n Natural numbers.
n = 4
sum = 0
i = 1 # Initialising the looping variable to 1
while (i<=n): #The loop will continue till the value of i<number
sum = sum + i
i = i+1 #Value of i is updated at the end of every iteration
print(sum)
We get the output as:
10
11
Problem Statement: G
iven any Integer, check whether it is Prime or Not.
Approach to be followed: A prime number is always positive so we are checking that at
the beginning of the program. Next, we are dividing the input number by all the numbers in
the range of 2 to (number - 1) to see whether there are any positive divisors other than
1 and the number itself (Condition for Primality). If any divisor is found then we display, “Is
Prime”, else we display, “ Is Not Prime”.
Note:- We are using the break statement in the loop to come out of the loop as soon as
any positive divisor is found as there is no further check required. The purpose of a break
statement is to break out of the current iteration of the loop so that the loop stops. This
condition is useful, as once we have found a positive divisor, we need not check for more
divisors and hence we can break out of the loop. You will study about the break statement
in more detail in the latter part of this course.
12
Nested Loops
Python programming language allows the usage of one loop inside another loop. The loops
can be nested the same way, the conditional statements are. The general syntax of such
an arrangement is:
while(Expression1):
<Execute this code block till the Expression1 is True>
while(Expression2):
<Execute this code block till the Expression2 is True>
#Increment/Decrement in looping variable
#Increment/Decrement in looping variable
Problem Statement: G iven an Integer, Print all the Prime Numbers between 0 and that
Integer.
Approach to be followed: Run a loop from 2 - n, in order to check which all numbers in
this range are prime. Let the value of the looping variable for this loop in some iteration be
i. Run another loop inside this loop which will check if i is prime or not. This loop will run
from 2 to i
(Similar to the Check Prime Problem). This way we have a loop nested inside
another.
13
14
Patterns
Introduction
Patterns are a handy application of loops and will provide you with better clarity
and understanding of the implementation of loops.
Before printing any pattern, you must consider the following three things:
● The first step in printing any pattern is to figure out the number of rows that
the pattern requires.
● Next, you should know how many columns are there in the ith row.
● Once, you have figured out the number of rows and columns, then focus on
the pattern to print.
For eg. We want to print the following pattern for N rows: (Pattern 1.1)
#For N=4:
****
****
****
****
Approach:
From the above pattern, we can observe:
➔ Number of Rows: The pattern has 4 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 4 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: We have to print * 4 times in all the 4 rows. Thus, in a pattern
of N rows, we will have to print * N times in all the rows.
1
Python Implementation for Patterns
We generally need two loops to print patterns. The outer loop iterates over the rows,
while the inner nested loop is responsible for traversing the columns. The algorithm to
print any pattern can be described as follows:
● Accept the number of rows or size of the pattern from a user using the
input() function.
● Iterate the rows using the outer loop.
● Use the nested inner loop to handle the column contents. The internal loop
iteration depends on the values of the outer loop.
● Print the required pattern contents using the print() function.
● Add a new line after each row.
Step 1: Let us first use a loop to traverse the rows. This loop will start at the first
row and go on till the Nth row. Below is the implementation of this loop:
Printing a New Line: Since we need to print the pattern in multiple lines, we will
have to add a new line after each row. Thus for this purpose, we use an empty
print() statement. The print() function in Python, by default, ends in a new line.
2
Step 2: Now, we need another loop to traverse the row during each iteration and
print the pattern; this can be done as follows:
The print() function in Python, by default, ends in a new line. This means that
print("*"), would print * and a new line character. Now if anything is printed after
this, it will be printed in a new line. However, If we have to print something in the
same line, we will have to pass another argument (end=) in the print() statement.
Thus, when we write the command print("*", end=""), Python prints a * and it
ends in an empty string instead of a new line; this means that, when the next thing
is printed, it will be printed in the same line as *.
There are two popular types of patterns-related questions that are usually posed:
3
Square Patterns
Pattern 1.2
# N = 5
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 5 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: All the entries in any row, are the same as the corresponding
row numbers. Thus in a pattern of N rows, all the entries of the ith row are i
(1st row has all 1’s, 2nd row has all 2’s, and so on).
Python Implementation:
4
print() #Add a new Line after each row
Pattern 1.3
# N = 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 5 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: All the entries in any row, are the same as the corresponding
column numbers. Thus in a pattern of N rows, all the entries of the ith
column are i (1st column has all 1’s, 2nd column has all 2’s, and so on).
Python Implementation:
5
Pattern 1.4
# N = 5
5 4 3 2 1
5 4 3 2 1
5 4 3 2 1
5 4 3 2 1
5 4 3 2 1
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 5 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: All the entries in any row, are N-columnNumber+1. Thus in a
pattern of N rows, all the entries of the ith column are N-i+1 (1st column has
all 5’s (5-1+1), 2nd column has all 4’s (5-2+1), and so on).
Python Implementation:
6
This way there can be several other square patterns and you can easily print them using
this approach- By finding the number of Rows, Columns and What to print.
Pattern 1.5
# N = 5
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 5 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: The first entry in the 1st row is 1, the first entry in the 2nd row
is 2, and so on. Further, these values are incremented continuously by 1 in
the remaining entries of any particular row. Thus in a pattern of N rows, the
first entry of the ith row is i. The remaining entries in the ith row are
i+1,i+2, and so on. It can be observed that any entry in this pattern can be
written as row+col-1.
7
print() #Add a new Line after each row is printed
Triangular Patterns
Pattern 1.6
# N = 5
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: The number of columns in any row is the same as the
corresponding row number.1st row has 1 column, 2nd row has 2 columns, and
so on. Thus, in a pattern of N rows, the ith row will have i columns.
➔ What to print: All the entries in any row, are the same as the corresponding
row numbers. Thus in a pattern of N rows, all the entries of the ith row are i
(1st row has all 1’s, 2nd row has all 2’s, and so on).
Python Implementation:
8
row=row+1 #Increment the current row (Outer Loop)
print() #Add a new Line after each row
Pattern 1.7
# N = 5
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: The number of columns in any row is the same as the
corresponding row number.1st row has 1 column, 2nd row has 2 columns, and
so on. Thus, in a pattern of N rows, the ith row will have i columns.
➔ What to print: All the entries in any row, are the same as the corresponding
column numbers. Thus in a pattern of N rows, all the entries of the ith
column are i (1st column has all 1’s, 2nd column has all 2’s, and so on).
Python Implementation:
9
print() #Add a new Line after each row
Pattern 1.8
# N = 5
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 5 rows. We have to print the pattern for N
rows.
➔ Number of Columns: The number of columns in any row is the same as the
corresponding row number.1st row has 1 column, 2nd row has 2 columns, and
so on. Thus, in a pattern of N rows, the ith row will have i columns.
➔ What to print: The pattern starts with 1 and then each column entry is
incremented by 1. Thus, we will initialize a variable temp=1. We will keep
printing the value of temp in the successive columns and upon printing, we
will increment the value of temp by 1.
Python Implementation:
10
row=row+1 #Increment the current row (Outer Loop)
print() #Add a new Line after each row is printed
Character Patterns
Pattern 1.9
# N = 4
ABCD
ABCD
ABCD
ABCD
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 4 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 4 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: The 1st column has all A’s, 2nd column has all B’s, and so on.
The ASCII value of A is 65. In the 1st column, the character corresponds to the
ASCII value 65 (64+1). In the 2nd column, the character corresponds to the
ASCII value 66 (64+2). Thus, all the entries in the ith column are equal to the
character corresponding to the ASCII value 64+i. The chr() function gives
the character associated with the integral ASCII value within the parentheses.
Python Implementation:
11
col=col+1 #Increment the current column (Inner Loop)
row=row+1 #Increment the current row (Outer Loop)
print() #Add a new Line after each row is printed
Pattern 1.10
# N = 4
ABCD
BCDE
CDEF
DEFG
Approach:
From the above pattern we can observe:
➔ Number of Rows: The pattern has 4 rows. We have to print the pattern for N
rows.
➔ Number of Columns: All the rows have 4 columns. Thus, in a pattern of N
rows, all the rows will have N columns.
➔ What to print: This pattern is very similar to Pattern 1.5. We can implement
this using a similar code with a minor change. Instead of integers, we need
capital letters of the same order. Instead of 1, we need A, instead of 2, we
need B and so on. ASCII value of A is 65. Thus if we add 64 to all the entries
in Pattern 1.5 and find their ASCII values, we will get our result. The
chr() function gives the character associated with the integral ASCII value
within the parentheses.
Python Implementation:
12
col=col+1 #Increment the current column (Inner Loop)
row=row+1 #Increment the current row (Outer Loop)
print() #Add a new Line after each row is printed
Practice Problems
Here are a few similar patterns problems for your practice. All the patterns have been
drawn for N=4.
A
AB
ABC
ABCD
12344321
123**321
12****21
1******1
ABCD
ABC
AB
A
4555
3455
2345
1234
1
11
202
3003
13
A
BB
CCC
DDDD
14
Patterns
# N = 3
* * *
* *
*
Approach:
From the above pattern, we can observe:
➔ Number of Rows: The pattern has 3 rows. We have to print the pattern for N
rows.
➔ Number of Columns: The number of columns in any row is equal to
N-rowNumber+1.1st row has 3 columns (
3-1+1), 2nd row has 2 columns
(3-2+1), and so on. Thus, in a pattern of N rows, the i
th
row will have N
-i+1
columns.
➔ What to print: All the entries in any row are "*".
Python Implementation:
1
# N = 3
*
* *
* * *
Approach:
From the above pattern, we can observe:
➔ Number of Rows: The pattern has 3 rows. We have to print the pattern for N
rows.
➔ Number of Columns: The number of columns in any row is equal to N
.
➔ What to print: In the 1st row, while columnNumber <= 2(3-1), we print a "
"
in every column. Beyond the 2nd column, we print a "
*". Similarly, in the 2nd
row, we print a " " till c
olumnNumber <=1(3-2) and beyond the 1st column,
we print a "*". We can easily notice that if col <= N-rowNumber, we are
printing a "
" (Space). And if c
ol > N-rowNumber, we are printing a "
*".
Python Implementation:
2
# N = 4
1
121
12321
1234321
Approach:
From the above pattern w
e can observe:
➔ Number of Rows: The pattern has 3 rows. We have to print the pattern for N
rows.
➔ Number of Columns: Similar to Pattern 2.2, we first have N
-rowNumber
columns of spaces. Following this, we have 2
*rowNumber-1 c olumns of
numbers.
➔ What to print: We can notice that if c
ol <= N-rowNumber, we are printing a
" " (Space). Further, the pattern has two parts. First is the increasing part
and second is the decreasing part. For the increasing part, we will initialise a
variable n
um=1. In each row we will keep printing n
um till its value becomes
equal to the rowNumber . We will increment num by 1 after printing it; ;this will
account for the first part of the pattern. We have num = rowNumber at this
stage. Now, for the decreasing part, we will again start printing num till
num>=1. After printing n
um we will decrement it by 1.
3
Python Implementation:
4
Practice Problems
Here are a few similar patterns problems for your practice. All the patterns have been
drawn for N=4.
*
***
*****
*******
1
121
12321
1234321
12321
121
1
1 1
2 2
3 3
4
3 3
2 2
1 1
*
***
*****
*******
*****
***
*
5
More On Loops
range() Function
>>> range(0,5)
[0,1,2,3,4] #Output of the range() function
Note: T
he default step value is +1, i.e. the difference in the consecutive values of
the sequence generated will be +1.
If you want to create a list with a step value other than 1, you can use the following
syntax:
>>> range(0,5,2)
[0,2,4] #Output of the range() function
1
in Operator
The in operator tests if a given value is contained in a sequence or not and returns
True or False accordingly. For eg.,
3 in [1,2,3,4]
will return T
rue as value 3 is contained in the list.
will return F
alse as "
A" is not contained in the String "BCD".
for Loop
The for loop of Python is designed to process the items of any sequence, such as a
list or a string, one by one. The syntax of a for loop is:
2
Approach to be followed:
● A prime number is always positive so we are checking that at the beginning
of the program.
● Next, we are dividing the input number by all the numbers in the range of 2
to (number - 1) to see whether there are any positive divisors other than 1
and the number itself (Condition for Primality).
● If any divisor is found then we display, “Is Prime”, else we display, “Is Not
Prime”.
isPrime= True
if number > 1: # prime number is always greater than 1
for i in range(2, number):
if (number % i) == 0: # Checking for positive divisors
isPrime= False
break
3
Jump Statements: b
reak and continue
Python offers two jump statements (within loops) to jump out of the loop iterations.
These are b
reak and continue statements. Let us see how these statements work.
break Statement
The break statement enables a program to skip over a part of the code. A b
reak
statement terminates the very loop it lies within.
while <Expression/Condition/Statement>:
#Statement1
if <condition1>:
break #If “condition” is true, then code breaks out
#Statement2
#Statement3
#Statement4: This statement is executed if it breaks out of the loop
#Statement5
Note: T
his loop can terminate in 2 ways:
1. Throughout the iterations of the loop, if condition1 remains false, the loop
will go through its normal course of execution and stops when its
condition/expression b
ecomes false.
2. If during any iteration, c
ondition1 becomes true, the flow of execution will
break out of the loop and the loop will terminate.
4
s
t
r
continue Statement
The continue statement jumps out of the current iteration and forces the next
iteration of the loop to take place.
while <Expression/Condition/Statement>:
#Statement1
if <condition1>:
continue
#Statement2
#Statement3
#Statement4: This statement is executed if it breaks out of the loop
#Statement5
5
s
t
r
n
g
The end
Here, the iteration with val = "i", gets skipped and hence "i" is not printed.
pass Statement
The pass statement is a null statement.
● It is generally used as a placeholder for future code i.e. in cases where you
want to implement some part of your code in the future but you cannot
leave the space blank as it will give a compilation error.
● Sometimes, pass is used when the user does not want any code to execute.
● Using the pass statement in loops, functions, class definitions, and i
f
statements, is very useful as empty code blocks are not allowed in these.
pass
n=2
if n==2:
pass #Pass statement: Nothing will happen
else:
print ("Executed”)
6
n=1
if n==2:
print ("Executed")
else:
pass #Pass statement: Nothing will happen
In the above code, the if statement condition is not satisfied because n
==2 is
False. Thus there will be no output for the above code because it enters the else
statement block and encounters the pass statement.
7
Functions
What Is A Function?
● Reusability: Once a function is defined, it can be used over and over again.
You can call the function as many times as it is needed. Suppose you are
required to find out the area of a circle for 10 different radii. Now, you can
either write the formula πr2 10 times or you can simply create a function that
takes the value of the radius as an input and returns the area corresponding
to that radius. This way you would not have to write the same code (formula)
10 times. You can simply invoke the function every time.
1
Defining Functions In Python
A function, once defined, can be invoked as many times as needed by using its
name, without having to rewrite its code.
A function in Python is defined as per the following syntax:
def <function-name>(<parameters>):
""" Function's docstring """
<Expressions/Statements/Instructions>
● Function blocks begin with the keyword def followed by the function name
and parentheses ( ( ) ).
● The input parameters or arguments should be placed within these
parentheses. You can also define parameters inside these parentheses.
● The first statement of a function is optional - the documentation string of the
function or docstring. The docstring describes the functionality of a
function.
● The code block within every function starts with a colon (:) and is indented.
All statements within the same code block are at the same indentation level.
● The return statement exits a function, optionally passing back an
expression/value to the function caller.
def add(a,b):
return a+b
2
The return Statement
A return statement is used to end the execution of the function call and it “returns”
the result (value of the expression following the return keyword) to the caller. The
statements after the return statements are not executed. If the return statement is
without any expression, then the special value None is returned.
Note: In Python, you need not specify the return type i.e. the data type of returned
value.
Calling/Invoking A Function
Once you have defined a function, you can call it from another function, program,
or even the Python prompt. To use a function that has been defined earlier, you
need to write a function call.
<function-name> (<value-to-be-passed-as-argument>)
The function definition does not execute the function body. The function gets
executed only when it is called or invoked. To call the above function we can write:
add(5,7)
3
Arguments And Parameters
As you know that you can pass values to functions. For this, you define variables to
receive values in the function definition and you send values via a function call
statement. For example, in the add() function, we have variables a and b to receive
the values and while calling the function we pass the values 5 and 7. We can define
these two types of values:
● Arguments: The values being passed to the function from the function call
statement are called arguments. Eg. 5 and 7 are arguments to the add()
function.
● Parameters: The values received by the function as inputs are called
parameters. Eg. a and b are the parameters of the add() function.
Types Of Functions
1. User-defined functions: Functions that are defined by the users. Eg. The
add() function we created.
2. Inbuilt Functions: Functions that are inbuilt in python. Eg. The print()
function.
4
Scope Of Variables
All variables in a program may not be accessible at all locations in that program.
Part(s) of the program within which the variable name is legal and accessible, is
called the scope of the variable. A variable will only be visible to and accessible by
the code blocks in its scope.
● Global scope
● Local scope
Global Scope
Local Scope
Variables that are defined inside a function body have a local scope. This means
that local variables can be accessed only inside the function in which they are
declared.
The lifetime of a variable is the time for which the variable exists in the memory.
● The lifetime of a Global variable is the entire program run (i.e. they live in the
memory as long as the program is being executed).
● The lifetime of a Local variable is their function’s run (i.e. as long as their
function is being executed).
5
Creating a Global Variable
x = "Global Variable"
def foo():
print("Value of x: ", x)
foo()
Global Variable
Thus we can conclude that we can access a global variable from inside any function.
What if you want to change the value of a Global Variable from inside a
function?
x = "Global Variable"
def foo():
x = x -1
print(x)
foo()
In this code block, we tried to update the value of the global variable x. We get an
output as:
This happens because, when the command x=x-1, is interpreted, Python treats this
x as a local variable and we have not defined any local variable x inside the function
foo().
6
Creating a Local Variable
We declare a local variable inside a function. Consider the given function definition:
def foo():
y = "Local Variable"
print(y)
foo()
Local Variable
def foo():
y = "local"
foo()
print(y)
In the above code, we declared a local variable y inside the function foo(), and
then we tried to access it from outside the function. We get the output as:
We get an error because the lifetime of a local variable is the function it is defined
in. Outside the function, the variable does not exist and cannot be accessed. In
other words, a variable cannot be accessed outside its scope.
7
Global Variable And Local Variable With The Same Name
x = 5
def foo():
x = 10
print("Local:", x)
foo()
print("Global:", x)
In this, we have declared a global variable x = 5 outside the function foo(). Now,
inside the function foo(), we re-declared a local variable with the same name, x.
Now, we try to print the values of x, inside, and outside the function. We observe
the following output:
Local: 10
Global: 5
In the above code, we used the same name x for both global and local variables.
We get a different result when we print the value of x because the variables have
been declared in different scopes, i.e. the local scope inside foo() and global scope
outside foo().
When we print the value of the variable inside foo() it outputs Local: 10. This is
called the local scope of the variable. In the local scope, it prints the value that it has
been assigned inside the function.
Similarly, when we print the variable outside foo(), it outputs global Global: 5.
This is called the global scope of the variable and the value of the global variable x
is printed.
8
Python Default Parameters
Function parameters can have default values in Python. We can provide a default
value to a parameter by using the assignment operator (=). Here is an example.
"""This function wishes the person with the provided message. If the
message is not provided, it defaults to "Happy Birthday" """
greet("Rohan")
greet("Hardik", "Happy New Year")
Output
In this function, the parameter name does not have a default value and is required
(mandatory) during a call.
On the other hand, the parameter wish has a default value of "Happy Birthday".
So, it is optional during a call. If an argument is passed corresponding to the
parameter, it will overwrite the default value, otherwise it will use the default value.
9
For example, if we had defined the function header as:
Thus to summarise, in a function header, any parameter can have a default value
unless all the parameters to its right have their default values.
10
Lists
Introduction
A list is a standard data type of Python that can store a sequence of values
belonging to any type. The Lists are contained within square brackets ( [ ] ).
Following are some examples of lists in Python:
[ ] #Empty list
[1, 2, 3] #List of integers
[1, 2, 5.6, 9.8] #List of numbers (Floating point and Integers)
['a', 'b', 'c'] #List of characters
['a', 1, 4.3, "Zero"] #List of mixed data types
["One", "Two", "Three"] #List of strings
Creating Lists
In Python programming, a list is created by placing all the items (elements) inside
square brackets [ ], separated by commas.
It can have any number of items and they may be of different types (integer, float,
string etc.).
A list can also have another list as an element. Such a list is called a Nested List.
1
Operations On Lists
Accessing Elements in a List
List indices start at 0 and go on till 1 less than the length of the list. We can use the
index operator [ ] to access a particular item in a list. Eg.
Index: 0 1 2 3 4
1 10 34 23 90
Note: Trying to access indexes out of the range (0 ,lengthOfList-1), will raise an
IndexError. Also, the index must be an integer. We can't use float or other types,
this will result in TypeError.
Negative Indexing
Python allows negative indexing for its sequences. The index of -1 refers to the last
item, -2 to the second last item, and so on. The negative indexing starts from the
last element in the list.
2
Positive Indexing: 0 1 2 3 4 →
1 10 34 23 90
Negative Indexing: -5 -4 -3 -2 -1 ←
Output:
Concatenation of Lists
Joining or concatenating two list in Python is very easy. The concatenation operator (+), can
be used to join two lists. Consider the example given below:
3
l3= l1+l2 #Concatenating both to get a new list
print(l3)
Output:
[1,2,3,3,4,5]
Note: The + operator when used with lists requires that both the operands are of
list types. You cannot add a number or any other value to a list.
Repeating/Replicating Lists
Like strings, you can use * operator to replicate a list specified number of times.
Consider the example given below:
Notice that the above output has the same list l1 repeated 3 times within a single
list.
List Slicing
List slicing refers to accessing a specific portion or a subset of a list while the
original list remains unaffected. You can use indexes of list elements to create list
slices as per the following syntax:
● The StartIndex represents the index from where the list slicing is supposed
to begin. Its default value is 0, i.e. the list begins from index 0 if no
StartIndex is specified.
● The StopIndex represents the last index up to which the list slicing will go on.
4
Its default value is (length(list)-1) or the index of the last element in the
list.
● The list slices created, include elements falling between the indexes
StartIndex and StopIndex, including StartIndex and not including
StopIndex.
As, you can see from the figure given above, we get the output as:
5
below.
6
The output will be:
['c','e','g']
You can even specify a negative step size:
['g','e','c']
Output
7
Whereas, omitting the StopIndex extends the slice to the end of the list. Meaning,
L[start:] is equivalent to L[start:len(L)].
Output
Reversing a List
You can reverse a list by omitting both StartIndex and StopIndex and specifying
steps as -1.
Output:
['e', 'd', 'c', 'b', 'a'] #Reversed List
List Methods
append(): Used for appending/adding elements at the end of a list.
Syntax: <ListName>.append(element)
Example:
>>> li=[1,2,3,4]
>>> li.append(5) #Append 5 to the end of the list
>>> li
[1,2,3,4,5]
8
extend(): Adds the contents of List2 to the end of List1.
Syntax: <ListName1>.extend(<ListName2)
Example:
>>> l1=[1,2,3,4]
>>> l2=[5,6,7,8]
>>> l1.extend(l2) #Adds contents of l2 to l1 at the end
>>> l1
[1,2,3,4,5,6,7,8]
**.append() vs .extend():
The only difference between .append() and .extend() is that, the .append()
method adds an element at the back of a given list (appends an element at the end of
a list). On the other hand, the .extend() method adds the contents of another list
at the end of the given list i.e. it merges two lists (extends the given list). See the
examples given above for better clarity.
>>> li=[1,2,3,4]
>>> li.insert(2,5) #Insert 5 at the index no. 2
>>> li
[1,2,5,3,4]
9
sum() : Returns the sum of all the elements of a List. (Used only for lists containing
numerical values)
Syntax: sum(<ListName>)
Example:
>>> l1=[1,2,3,4]
>>> sum1= sum(l1) #Finds the sum of all elements in l1
>>> sum1
10
count(): Returns the total number of times a given element occurs in a List.
Syntax: <ListName>.count(element)
Example:
>>> l1=[1,2,3,4,4,3,5,4,4,2]
>>> c= l1.count(4) #Number of times 4 occurs in the list
>>> c
4
>>> l1=[1,2,3,4,5]
>>> len(l1)
5
10
index(): Returns the index of first occurrence of an element in a list. If element is
not present, it returns -1.
Syntax: <ListName>.index(element)
Example:
>>> l1=[1,2,3,4]
>>> l1.index(3)
2
>>> l1=[1,2,3,4]
>>> min(l1)
1
>>> l1=[1,2,3,4]
>>> max(l1)
4
pop(): It deletes and returns the element at the specified index. If we don't mention
the index, it by default pops the last element in the list.
Syntax: <ListName>.pop([index])
Example:
>>> l1=[1,2,3,4]
11
>>> poppedElement= l1.pop(2)
>>> poppedElement #Element popped
3
>>> l1 #List after popping the element
[1,2,4]
Note: Index must be in range of the List, otherwise IndexError occurs.
>>> l1=[1,1,12,3]
>>> del l1[2]
>>> l1
[1,1,3]
Example:
>>> l1=[1,1,12,3]
>>> l1.remove(12)
>>> l1
[1,1,3]
Looping On Lists
There are multiple ways to iterate over a list in Python.
12
li = [1, 3, 5, 7, 9]
# Using for loop
for i in li:
print(i) #Print the element in the list
Output:
1
3
5
7
9
list = [1, 3, 5, 7, 9]
length = len(list) #Getting the length of the list
for i in range(length): #Iterations from 0 to (length-1)
print(i)
Output:
1
3
5
7
9
You can even use while() loops. Try using the while() loops on your own.
13
Taking Lists as User Inputs
There are two common ways to take lists as user inputs. These are:
14
print(li) #Print the list
The above code will prompt the user to input 5 integers in 5 lines. These 5 integers
will be appended to a list and the list will be printed.
Example :
In[]: a= input().split()
In[]: print(a)
User[]: 1 2 3 4 5 #User inputs the data (space separated input)
Out[]: ['1','2','3','4','5']
Now, say you want to take comma separated inputs, then you will use "," as the
separator. This will be done as follows:
In[]: a= input().split(",")
In[]: print(a)
15
User[]: 1,2,3,4,5 #User inputs the data (space separated input)
Out[]: ['1','2','3','4','5']
Note: Observe that the elements were considered as characters and not integers in
the list created using the split() function. (What if you want a list of integers?- Think)
Example :
Here, In[1] typecasts x in the list input().split() to an integer and then makes
Linear Search
Linear search is the simplest searching algorithm that searches for an element in a
list in sequential order.
16
Linear Search Algorithm
We have been given a list and a targetValue. We aim to check whether the given
targetValue is present in the given list or not. If the element is present we are
required to print the index of the element in the list and if the element is not
present we print -1.
(First, let us implement this using a simple loop, then later we will see how to implement
linear search using functions.)
Pseudo-Code
Python Code
17
found = False #Boolean value to check if we found the targetValue
for i in li:
if (i==targetValue): #If we found the targetValue
print(li.index(i)) #Print the index
found = True #Set found as True as we found the targetValue
break #Since we found the targetValue, we break out of loop
if found is False:#If we did not find the targetValue
print(-1)
We have:
User[1]: 1 2 4 67 23 12 #User input for list
User[2]: 4 #User input= targetValue
Out[]: 2 #Index of 4
We will create a function linearSearch, which will have the following properties:
● Take list and targetValue as parameters.
● Run a loop to check the presence of targetValue in list.
● If it is present then it returns the index of the targetValue.
● If it is not present, then it returns -1.
We will call this function and then print the return value of the function.
Python Code
def linearSearch(li,targetValue):
18
for i in li:
if (i==targetValue): #If we found the targetValue
return li.index(i) #Return the index
return -1 #If not found, return -1
li= [int(x) for x in input().split()] #Taking list as user input
targetValue= int(input()) #User input for targetValue
print(linearSearch(li,targetValue)) #Print the return value
The Python data types can be broadly categorized into two - Mutable and
Immutable types. Let us now discuss these two types in detail.
Note: Objects of built-in types like (int, float, bool, str, tuple, Unicode) are immutable.
Objects of built-in types like (list, set, dict) are mutable. A list is a mutable as we can
insert/delete/reassign values in a list.
19
Searching
Searching means to find out whether a particular element is present in a given sequence or
not. There are commonly two types of searching techniques:
Binary Search
Binary Search is a searching algorithm for finding an element's position in a sorted array. In
a nutshell, this search algorithm takes advantage of a collection of elements of being
already sorted by ignoring half of the elements after just one comparison.
Prerequisite: Binary search has one pre-requisite; unlike the linear search where elements
could be any order, the array in binary search must be sorted,
1
Example Run
2
Python Code
#Function to implement Binary Search Algorithm
def binarySearch(array, x, low, high):
#Repeat until the pointers low and high meet each other
while low <= high:
mid = low + (high - low) #Middle Index
if array[mid] == x: #Element Found
return mid
elif array[mid] < x: #x is on the right side
low = mid + 1
else: #x is on the left side
high = mid - 1
return -1 #Element is not found
3
number of operations that are performed by that algorithm i.e. time complexity is
directly proportional to the number of operations in the program).
Sorting
Sorting is a permutation of a list of elements of such that the elements are either i n
increasing ( ascending) order or decreasing (descending) order.
There are many different sorting techniques. The major difference is the amount of space
and t ime they consume while being performed in the program.
● Selection sort
● Bubble sort
● Insertion sort
Selection Sort
Selection sort is an algorithm that selects the smallest element from an unsorted list in
each iteration and places that element at the beginning of the unsorted list. The detailed
algorithm is given below.
4
● For each iteration, indexing starts from the first unsorted element. These steps are
repeated until all the elements are placed at their correct positions.
First Iteration
5
Second Iteration:
Third Iteration
6
Fourth Iteration
Python Code
# Selection sort in Python
def selectionSort(arr, size):
# Swap
(arr[step], arr[minimum]) = (arr[minimum], arr[step])
Sorted Array in Ascending Order: [2, 10, 12, 15, 20]
7
Bubble Sort
Bubble sort is an algorithm that compares the adjacent elements and swaps their positions
if they are not in the intended order. The order can be ascending or descending.
● Starting from the first index, compare the first and the second elements. If the first
element is greater than the second element, they are swapped.
● Now, compare the second and third elements. Swap them if they are not in order.
● The above process goes on until the last element.
● The same process goes on for the remaining iterations. After each iteration, the
largest element among the unsorted elements is placed at the end.
● In each iteration, the comparison takes place up to the last unsorted element.
● The array is sorted when all the unsorted elements are placed at their correct
positions.
8
Python Code
# Bubble sort in Python
def bubbleSort(arr):
# run loops two times: one for walking through the array
# and the other for comparison
9
Sorted Array in Ascending Order: [-9, -2, 0, 11, 45]
Insertion Sort
● Insertion sort works similarly as we sort cards in our hand in a card game.
● We assume that the first card is already sorted
● Then, we select an unsorted card.
● If the unsorted card is greater than the card in hand, it is placed on the right
otherwise, to the left.
● In the same way, other unsorted cards are taken and put in the right place. A similar
approach is used by insertion sort.
● Insertion sort is a sorting algorithm that places an unsorted element at its suitable
place in each iteration
Algorithm
10
● The first element in the array is assumed to be sorted. Take the second element and
store it separately in key.
● Compare key with the first element. If the first element is greater than k
ey, then k
ey
is placed in front of the first element.
● If the first element is greater than key, then key is placed in front of the first
element.
● Now, the first two elements are sorted.
● Take the third element and compare it with the elements on the left of it. Placed it
just behind the element smaller than it. If there is no element smaller than it, then
place it at the beginning of the array.
● Similarly, place every unsorted element at its correct position.
11
Python Code
# Insertion sort in Python
def insertionSort(arr):
# Compare key with each element on the left of it until an element smaller
than it is found
# For descending order, change key<array[j] to key>array[j].
while j >= 0 and key < arr[j]:
arr[j + 1] = arr[j]
12
j = j - 1
# Place the key at after the element just smaller than it.
arr[j + 1] = key
Sorted Array in Ascending Order: [1, 3, 4, 5, 9]
Suppose your sorted array has duplicate numbers. For example, if the array is as follows:
[1, 2, 2, 3, 3, 3, 4, 8, 9, 19, 19, 19].
Let’s see how we can modify the code to find the first occurrence of the element x
to be
found.
In the current code, we exit when any of the following two conditions are satisfied
The modification we need is quite simple. Instead of exiting the code when arr[mid] == x,
we shall assign high a
nd index as m
id a
s follows:
index = mid
high = mid
13
Python Code
#Function to implement Binary Search Algorithm
def binarySearch(array, x, low, high):
low = 0;
high = n
mid = low
index = -1
return index
14
Strings
Introduction
● A character is simply a symbol. For example, the English language has 26 characters;
while a string is a contiguous sequence of characters.
● In Python, a string is a sequence of Unicode characters.
● Python strings are immutable, which means they cannot be altered after they are
created.
Note: Unicode was introduced to include every character in all languages and bring
uniformity in encoding. You can learn more about Unicode from Python Unicode. Given
below are some examples of Unicode Encoding:
string ='pythön!' → Default U
TF-8 Encoding: b'pyth\xc3\xb6n!'
string ='python!'→ Default U 'python!'
TF-8 Encoding: b
Output:
Hello
Hello
Note:
1
s3 = '''Hello
World'''
print(s3) #Multiline string
Output
Hello
World
If you wish to print a string in a new line you can use the new line character '\n'. This is
used within the strings. For e
xample:
First Line
Second Line
I ndex: 0 1 2 3 4
String "
hello": h"
" e"
" l"
" l"
" o"
"
s= "hello"
>>> print(s[0]) #Output: h
>>> print(s[2]) #Output: l
>>> print(s[4]) #Output: o
2
Negative Indexing
Python allows negative indexing for strings. The index of - 1 refers to the last
character, -2 to the second last character, and so on. The negative indexing starts
from the last character in the string.
Positive Indexing: 0 1 2 3 4
String "
hello": h"
" e"
" l"
" l"
" o"
"
Negative Indexing: -5 -4 -3 -2 -1
s= "hello"
>>> print(s[-1]) #Output: o
>>> print(s[-2]) #Output: l
>>> print(s[-3]) #Output: l
Concatenation Of Strings
Joining of two or more strings into a single string is called string concatenation. The
+ operator does this in Python.
3
Note: Y
ou cannot combine numbers and strings using the + operator. If you do so,
you will get an error:
Repeating/Replicating Strings
You can use * operator to replicate a string specified number of times. Consider the
example given below:
String Slicing
String slicing refers to accessing a specific portion or a subset of a string with the
original string remaining unaffected. Y
ou can use the indexes of string characters to
create string slices as per the following syntax:
● The StartIndex r epresents the index from where the string slicing is
supposed to begin. Its default value is 0, i.e. the string begins from index 0 if
4
no S
tartIndex is specified.
● The StopIndex represents the last index up to which the string slicing will go
on. Its default value is (
length(string)-1) or the index of the last character
in the string.
● steps represent the number of steps. It is an optional parameter. s
teps, i f
defined, specifies the number of characters to jump over while counting
from StartIndex to StopIndex. By default, it is 1.
● The string slices created, include characters falling between the indexes
StartIndex and StopIndex, including StartIndex and not including
StopIndex.
s = "abcdefghi"
print(s[2:7])
As you can see from the figure given above, we get the output as:
cdefg
5
Slice Using Negative Indices
You can also specify negative indices while slicing a string. Consider the example
given below.
s = "abcdefghi"
print(s[-7:-2])
cdefg
Specify Step of the Slicing
You can specify the step of the slicing using the steps parameter. The steps
parameter is optional and by default 1.
6
s = "abcdefghi"
print(s[2:7:2])
ceg
You can even specify a negative step size:
gec
7
Output
abc
Whereas, omitting the S
topIndex extends the slice to the end of the string.
Meaning, S
[start:] is equivalent to S
[start:len(S)].
Output
ghi
Comparing Strings
1. In string comparison, we aim to identify whether two strings are equivalent
2. String comparison in Python takes place character by character. That is,
characters in the same positions are compared from both the strings.
3. If the characters fulfill the given comparison condition, it moves to the
● If two characters are different, then their Unicode value is compared; the
8
● <: This checks if the string on its left is smaller than that on its right
● <=: This checks if the string on its left is smaller than or equal to that on its
right
● >: This checks if the string on its left is greater than that on its right
● >=: This checks if the string on its left is greater than or equal to that on its
right
Iterating On Strings
There are multiple ways to iterate over a string in Python.
Using f
or loop
s="13579"
# Using for loop
for i in li:
print(i) #Print the character in the string
Output:
1
3
5
7
9
Using f
or loop and range()
s="13579"
length = len(s) #Getting the length of the string
for i in range(length): #Iterations from 0 to (length-1)
print(i)
9
Output:
1
3
5
7
9
You can even use while() loops. Try using the while() loops on your own.
10
Introduction
T = [[11, 12, 5, 2], [15, 6, 10, 6], [10, 8, 12, 5], [12, 15, 8, 6]]
The data elements in two-dimensional lists can be accessed using two indices. One
index referring to the main or parent list (inner list) and another index referring to
the position of the data element in the inner list. If we mention only one index then
the entire inner list is printed for that index position.
T = [[11, 12, 5, 2], [15, 6, 10, 6], [10, 8, 12, 5], [12,15,8,6]]
print(T[0]) #List at index 0 in T
print(T[1][2]) #Element at index 2 in list at index 1 in T
1
T = [[11, 12, 5, 2], [15, 6, 10, 6], [10, 8, 12, 5], [12, 15, 8, 6]]
This can be done the same way as in 1D lists. Consider the examples given below:
T[0][1]= 1
#Update the element at index 1 of list at index 0 of T to 1
T[1][1]= 7
T= [[11, 1, 5, 2], [15, 7, 10, 6], [10, 8, 12, 5], [12, 15, 8, 6]]
In the below example a new data element is inserted at index position 2.
T = [[11,12,5,2],[15,6,10,6],[10,8,12,5],[12,15,8,6]]
T.insert(2, [0,5,11,13])
T = [[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
2
List Comprehension
List comprehensions are used for creating new lists from other iterable sequences.
As list comprehensions return lists, they consist of brackets containing the
expression, which is executed for each element along with the for loop to iterate
over each element.
3
Jagged Lists
Till now we have seen lists with an equal number of columns in all rows. Jagged lists
are the two-dimensional lists with a variable number of columns in various rows.
Various operations can be performed on such lists, the same way as in 2D lists with
the same number of columns throughout. Some examples of jagged lists are shown
below:
T1 = [[11,12,5,2],[10,6],[10,8,12],[12]]
T2 = [[1,2,3], 1, 3, [1,2]]
T3 = [[1],[],[1,2,1],0]
The elements in a jagged list can be accessed the same way as shown:
>>> T1[3]
[12]
>>> T1[0][2]
5
Note: Keep in mind the range of columns for various rows. Indexes out of the
range can produce indexOutOfRange error.
There are many ways to print a 2D List. Some of them are discussed below:
T= [[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
print(T)
4
[[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
T= [[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
for row in T: #Every row in T is a list
for col in row: #Every col is an element of the list row
print(col, end=" ") #Print col
print() #New Line
.join(): T
he .
join() string method returns a string by joining all the elements of
an iterable sequence, separated by a string separator. The working is shown below:
>>> "-".join("abcd")
a-b-c-d
>>> "-".join(['a','b','c','d'])
a-b-c-d
5
T= [[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
for row in T: #Every row in T is a list
output = " ".join([str(col) for col in row])
print(output)
n = int(input())
input= [[int(col) for col in input.split()] for row in range n]
print(input)
User Input:
5
11 12 5 2
15 6 10 6
0 5 11 13
10 8 12 5
12 15 8 6
6
Output:
[[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
User Input:
4
5
11 12 5 2 15 6 10 6 0 5 11 13 10 8 12 5 12 15 8 6
Output:
[[11,12,5,2],[15,6,10,6],[0,5,11,13],[10,8,12,5],[12,15,8,6]]
7
Tuples
● A tuple is an ordered collection of elements/entries.
● Objects in a Tuple are immutable i.e. they cannot be altered once created.
● In a tuple, elements are placed within parentheses, separated by commas.
● The elements in a tuple can be of different data types like integer, list, etc.
>>> a=(1,2)
>>> b=("eat","dinner","man","boy")
>>> print(a)
(1,2)
>>> print(type(a))
<class 'tuple'>
1
>>> c= 1,2,3,4,5
>>> print(c)
(1,2,3,4,5)
>>> print(type(c))
<class 'tuple'>
Note: If we assign a set of comma separated elements (or objects) to a set of comma
separated variables, then these variables are assigned the corresponding values. F
or
Example:
a=()
b=()
#Here 'a' and 'b' are empty tuples.
>>> a=("Hamburger")
>>> print(type(a))
<class 'str'>
>>> tuple("Hamburger")
('H', 'a', 'm', 'b', 'u', 'r', 'g', 'e', 'r')
2
● To create such a tuple, along with a single element inside parentheses, we need a
trailing comma. This would tell the system that it is in fact, a tuple.
>>> a=("Hamburger",)
>>> print(type(a))
<class 'tuple>
#Here a is indeed a tuple. Thus, the trailing comma is important in such an
assignment.
Tuple List
We cannot change the elements of We can change the elements of a list
a Tuple once it is created once it is created
Indexing in a Tuple
● Indexing in a Tuple starts from index 0
.
● The highest index is the N
umberOfElementsInTheTuple-1.
● So a tuple having 10 elements would have indexing from 0-9.
● This system is just like the one followed in Lists.
Negative Indexing
● Python language allows negative indexing for its tuple elements.
● The last element in the tuple has an index -1, the second last element has index - 2,
and so on.
3
Index 0 1 2 3 4 5 6 7 8 9
Negative -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
indexing
>>> print(myTemp[0])
1
>>> print(myTemp[8])
2
>>> print(myTemp[-1])
3
If any index out of this range is tried to be accessed, then it would give the following error.
>>> print(myTemp[10])
IndexError: tuple index out of range
>>> print(myTemp[20])
IndexError: tuple index out of range
>>> print(myTemp[-100])
IndexError: tuple index out of range
Slicing of a Tuple
● We can slice a Tuple and then access any required range of elements. Slicing is done
by the means of a slicing operator which is “:”.
● The basic format of slicing is:
>>> print(myTemp[1:4])
(15,13,18)
>>> print(myTemp[7:])
(5,2,3)
4
● Though, you can change items from any mutable object in the tuple.
>>> del(myTemp)
>>> print(myTemp)
NameError: name 'myTemp' is not defined
# The name error shows that the tuple 'myTemp' has been deleted
5
Tuples Functions
● We can use loops to iterate through a tuple: For example, if we want to print all
the elements in the tuple. We can run the following loop.
myTemp=(1,2,3)
for t in myTemp:
print(t)
Output:
1
2
3
● Checking whether the tuple contains a particular element: The keyword used is
in. We can easily get a boolean output using this keyword. It returns T
rue if the
tuple contains the given element, else the output is False.
● Finding the length of a tuple: We can easily find the number of elements that any
tuple contains. The keyword used is l
en.
>>> print(len(myTemp))
6
● Concatenation: We can add elements from two different tuples and form a single
tuple out of them. This process is concatenation and is similar to data types like
string and list. We can use the “ + ” operator to combine two tuples.
a = (1,2,3,4)
b = (5,6,7,8)
d = a+b
print(d)
Out[]: (1,2,3,4,5,6,7,8)
6
We can also combine two tuples into another tuple in order to form a nested tuple. This is
done as follows:
a = (1,2,3,4)
b = (5,6,7,8)
d = (a, b)
print(d)
--> ((1,2,3,4),(5,6,7,8))
# Here d is a nested tuple which is formed from 2 different tuples.
● Repetition of a Tuple: W
e can repeat the elements from a given tuple into a
different tuple. The operator used is “ * ”, the multiplication operator. In other
words, by using this operator, we can repeat the elements of a tuple as many times
as we want.
>>> a = (1,2,3,4)
>>> print(a*4)
(1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4)
# The same tuple elements are repeated 4 times in the form of another
tuple.
>>> a = (1,2,3,4)
>>> print(min(a))
1
>>> print(max(a))
4
Note: We can find the minimum and maximum of only those tuples, which have
comparable entries. We cannot compare two different data types like a string and a tuple.
Such comparisons would throw an error.
For example:
>>> s= (1,2,"string",4)
>>> print(min(s))
TypeError: '<' not supported between instances of 'string' and 'int'
7
Task 1: G
iving a variable number of inputs and printing them:
1
2
(3,4,5,5)
8
Task 2: Finding the sum of a variable number of inputs:
Consider an example in which we have to calculate the sum of a variable number of inputs.
In such a situation we cannot practically have multiple parameters in the function. This can
be done as follows:
9
Dictionaries
● A Dictionary is a Python’s implementation of a data structure that is more generally
known as an associative array.
● A dictionary is an unordered collection of key-value pairs.
● Indexing in a dictionary is done using these “ keys”.
● Each pair maps the key to its value.
● Literals of the type dictionary are enclosed within curly brackets.
● Within these brackets, each entry is written as a key followed by a colon ” : ”, which is
further followed by a value. This is the value that corresponds to the given key.
● These keys must be unique and cannot be any immutable data type. Eg- string,
integer, tuples, etc. They are always mutable.
● The values need not be unique. They can be repetitive and can be of any data type
(Both mutable and immutable)
● Dictionaries are mutable, which means that the key-value pairs can be changed.
myDictionary = {
<key>: <value>,
<key>: <value>,
.
.
<key>: <value>
}
10
Creating A Dictionary
myDict= {"red":"boy", 6
: 4, "name":"boy"}
months= {1:"January", 2 :"February", 3: "March"}
11
This method is particularly useful if we want to create a dictionary with variable keys and all
the keys must have the same value. The values corresponding to all the keys is exactly the
same. This is done as follows:
# We can initialise all the values to a custom value too. This is done by
providing the second argument as the desired value.
>>> d2= dict.fromkeys(["abc",1,"two"],6)
>>> print(d2)
["abc":6 ,1:6, "two":6]
Similar to the list and tuples, this can be done by the square bracket operator [ ].
foo= {"a":1,"b":2,"c":3}
print(foo["a"])
--> 1
print(foo["c"])
--> 3
12
If we want the value corresponding to any key , we can even use an inbuilt dictionary
method called get.
A very unique feature about this method is that , incase the desired key is not present in
the dictionary , it won’t throw an error or an exception. It would simple return N
one.
We can make use of this feature in another way. Say we want the method to do the
following action: If the key is present in the dictionary then return the value corresponding
to the key. In case the key is not present, return a custom desired value ( say 0 ).
13
14
n bar:
for t i
print(t, bar[t])
Out[]:
2 1
3 2
4 3
# Here along with the keys, the values which are bar[t] are printed. In
this loop, the values are accessed using the keys.
Now if we want to add a new key-value pair to our dictionary, then we can make a similar
assignment. If we have to add a key-value pair as "
man":"boy", then we can make the
assignment as:
>>> bar["man"]="boy"
>>> print(bar)
{2:1,3:2,4:3,"man":"boy"}
15
a= {1:2,2:3,3:4}
b= {7:2,10:3,6:4}
a.update(b)
print(a)
--> {1:2,2:3,3:4,7:2,10:3,6:4}
In this process, the second dictionary is unchanged and the contents of the second
dictionary are copied into the first dictionary. The uncommon keys from the second
dictionary are added to the first with their corresponding values. However, if these
dictionaries have any common key, then the value of the common key present in the first
dictionary is updated to the new value from the second.
Deleting an entry:
In order to delete an entry corresponding to any key in a dictionary , we can simple pop the
key from the dictionary. The method used here is .pop() . This method removes the
key-value pair corresponding to any particular key and then returns the value of the
removed key-value pair.
>>> c={1:2,2:(3,23,3),3:4}
>>> c.pop(2)
(3,23,3)
>>> c={1:2,2:(3,23,3),3:4}
>>> c.clear()
>>> print(c)
{}
16
Now we have a dictionary with unique keys and their respective frequencies. Now we run
another loop to print the keys with the frequency 'k'.
17
Sets
Mathematically a set is a collection of items (not in any particular order). A Python set is
similar to this mathematical definition with below additional conditions.
● The elements in a set cannot be repeated i.e. an element can occur only once.
● The elements in the set are immutable(cannot be modified) but the set as a whole is
mutable.
● There is no index attached to any element in a python set. So they do not support
any indexing or slicing operation.
Set Operations
The sets in python are typically used for mathematical operations like union, intersection,
difference, and complement, etc. We can create a set, access its elements, and carry out
these mathematical operations as shown below.
Creating a set
A set is created by using the s
et() function or placing all the elements within a pair of curly
braces, separated by commas.
Days=set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
Months={"Jan","Feb","Mar"}
Dates={21,22,17}
print(Days)
print(Months)
print(Dates)
18
Days=set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
for d in Days:
print(d)
Wed
Sun
Fri
Tue
Mon
Thu
Sat
>>> Days=set(["Mon","Tue","Wed","Thu","Fri","Sat"])
>>> Days.add("Sun")
>>> print(Days)
set(['Wed', 'Sun', 'Fri', 'Tue', 'Mon', 'Thu', 'Sat'])
>>> Days=set(["Mon","Tue","Wed","Thu","Fri","Sat"])
>>> Days.discard("Sun")
>>> print(Days)
set(['Wed', 'Fri', 'Tue', 'Mon', 'Thu', 'Sat'])
19
Union of Sets
The union operation on two sets produces a new set containing all the distinct elements
from both the sets. In the below example the element "Wed" is present in both the sets.
The union operator is ‘ |’.
DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Wed","Thu","Fri","Sat","Sun"])
AllDays = DaysA|DaysB #Union of Sets
print(AllDays)
When the above code is executed, it produces the following result. Please note the result
has only one "
wed".
Intersection of Sets
The intersection operation on two sets produces a new set containing only the common
elements from both the sets. In the below example the element "Wed" is present in both
the sets. The intersection operator is “&”.
DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Wed","Thu","Fri","Sat","Sun"])
AllDays = DaysA & DaysB #Intersection of Sets
print(AllDays)
When the above code is executed, it produces the following result. Please note the result
has only one "
wed".
set(['Wed'])
Difference of Sets
The difference operation on two sets produces a new set containing only the elements
from the first set and none from the second set. In the below example the element "Wed"
is present in both the sets so it will not be found in the result set. The operator used is “ -”.
DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Wed","Thu","Fri","Sat","Sun"])
AllDays = DaysA - DaysB #Difference of Sets
print(AllDays)
20
When the above code is executed, it produces the following result. Please note the result
has only one "
wed".
set(['Mon', 'Tue'])
Compare Sets
We can check if a given set is a subset or superset of another set. The result is True or False
depending on the elements present in the sets.
DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
SubsetRes = DaysA <= DaysB #Check Subset
SupersetRes = DaysB >= DaysA #Check Superset
print(SubsetRes)
print(SupersetRes)
True
True
21
Recursion-1
Introduction
The process in which a function calls itself is called recursion and the
corresponding function is called a recursive function.
In general, we all are aware of the concept of functions. In a nutshell, functions are
mathematical equations that produce an output on providing input. For example:
Suppose the function F(x) is a function defined by:
F(x) = x2 + 4
Now, we can pass different values of x to this function and receive our output
accordingly.
Before moving onto the recursion, let's try to understand another mathematical
concept known as the Principle of Mathematical Induction (PMI).
1. Step of the trivial case: In this step, we will prove the desired statement for
a base case like n = 0 or n = 1.
1
2. Step of assumption: In this step, we will assume that the desired statement
is valid for n = k.
3. To prove step: From the results of the assumption step, we will prove that,
n = k + 1 is also true for the desired equation whenever n = k is true.
For Example: Let’s prove using the Principle of Mathematical Induction that:
Proof:
1 + 2 + 3 + .... + k = (k * (k + 1))/2
Proof:
Adding (k+1) to both LHS and RHS in the result obtained on step 2:
1 + 2 + 3 + ... + (k+1) = (k*(k+1))/2 + (k+1)
Hence proved.
2
One can think, why are we discussing these over here. To answer this question, we
need to know that these three steps of PMI are related to the three steps of
recursion, which are as follows:
1. Induction Step and Induction Hypothesis: Here, the Induction Step is the
main problem which we are trying to solve using recursion, whereas the
Induction Hypothesis is the sub-problem, using which we’ll solve the
induction step. Let’s define the Induction Step and Induction Hypothesis for
our running example:
Induction Step: Sum of first n natural numbers - F(n)
Induction Hypothesis: This gives us the sum of the first n-1 natural
numbers - F(n-1)
2. Express F(n) in terms of F(n-1) and write code:
F(N) = F(N-1)+ N
3. The code is still not complete. The missing part is the base case. Now we will
dry run to find the case where the recursion needs to stop.
3
4. After the dry run, we can conclude that for N equals 1, the answer is 1, which
we already know. So we'll use this as our base case. Hence the final code
becomes:
def f(N):
if(N == 1): #Base Case
return 1
ans = f(N-1)
return ans + N
This is the main idea to solve recursive problems. To summarize, we will always
focus on finding the solution to our starting problem and tell the function to
compute the rest for us using the particular hypothesis. This idea will be studied in
detail in further sections with more examples.
4
Now, we’ll learn more about recursion by solving problems which contain smaller
subproblems of the same kind. Recursion in computer science is a method where
the solution to the question depends on solutions to smaller instances of the same
problem. By the exact nature, it means that the approach that we use to solve the
original problem can be used to solve smaller problems as well. So, in other words,
in recursion, a function calls itself to solve smaller problems. Recursion is a popular
approach for solving problems because recursive solutions are generally easier to
think than their iterative counterparts, and the code is also shorter and easier to
understand.
Working of recursion
We can define the steps of the recursive approach by summarizing the above three
steps:
● Base case: A recursive function must have a terminating condition at which
the process will stop calling itself. Such a case is known as the base case. In
the absence of a base case, it will keep calling itself and get stuck in an
infinite loop. Soon, the recursion depth* will be exceeded and it will throw
an error.
● Recursive call: The recursive function will invoke itself on a smaller version
of the main problem. We need to be careful while writing this step as it is
crucial to correctly figure out what your smaller problem is.
● Small calculation: Generally, we perform a calculation step in each recursive
call. We can achieve this calculation step before or after the recursive call
depending upon the nature of the problem.
Note*: Recursion uses an in-built stack which stores recursive calls. Hence, the
number of recursive calls must be as small as possible to avoid memory-overflow. If
the number of recursion calls exceeded the maximum permissible amount, the
recursion depth* will be exceeded.
5
Now, let us see how to solve a few common problems using Recursion.
Approach: Figuring out the three steps of PMI and then relating the same using
recursion.
def fact(n):
ans = fact(n-1) #Assumption step
return ans * n; #Solving problem from assumption step
3. The code is still not complete. The missing part is the base case. Now we will
dry run to find the case where the recursion needs to stop. Consider n = 5:
6
As we can see above, we already know the answer of n = 0, which is 1. So we will
keep this as our base case. Hence, the code now becomes:
def factorial(n):
if n == 0: #base case
return 1
else:
return n*factorial(n-1) # recursive case
Approach: Figuring out the three steps of PMI and then relating the same using
recursion.
1. Induction Step: Calculating the nth Fibonacci number n.
Induction Hypothesis: We have already obtained the (n-1)th and (n-2)th
Fibonacci numbers.
def f(n):
ans = f(n-1) + f(n-2) #Assumption step
return ans #Solving problem from assumption step
3. Let’s dry run the code for achieving the base case: (Consider n= 6)
7
From here we can see that every recursive call either ends at 0 or 1 for which we
already know the answer: F(0) = 0 and F(1) = 1. Hence using this as our base case in
the code below:
def fib(n):
if n <= 1:
return (n)
else:
return (fib(n-1) + fib(n-2))
8
We have to tell whether the given array is sorted or not using recursion.
For example:
● If the array is {2, 4, 8, 9, 9, 15}, then the output should be YES.
● If the array is {5, 8, 2, 9, 3}, then the output should be NO.
Approach: Figuring out the three steps of PMI and then relating the same using
recursion.
3. We can see that in the case when there is only a single element left or no
element left in our array, the array is always sorted. Let’s check the final code
now:
9
isSmallerSorted = isSorted(a + 1, size - 1) #Recursive call
return isSmallerSorted
Given an array of length N and an integer x, you need to find and return the first
index of integer x present in the array. Return -1 if it is not present in the array. The
first index means that if x is present multiple times in the given array, you have to
return the index at which x comes first in the array.
To get a better understanding of the problem statement, consider the given cases:
Case 1: Array = {1,4,5,7,2}, Integer = 4
Output: 1
Explanation: 4 is present at 1st position in the array.
10
Explanation: 4 is not present in the array
Approach:
Now, to solve the question, we have to figure out the following three elements of
the solution:
1. Base case
2. Recursive call
3. Small calculation
if(arr[0] == x):
return 0
f(arr+1, size-1, x)
11
● In the recursive call, we are incrementing the pointer and decrementing the
size of the array.
● We have to assume that the answer will come from the recursive call. The
answer will come in the form of an integer.
● If the answer is -1, this denotes that the element is not present in the
remaining array.
● If the answer is any other integer (other than -1), then this denotes that the
element is present in the remaining array.
● If the element is present at the ith index in the remaining array, then it will be
present at (i+1)th index in the main array. For instance, in the running
example, 6 is present at index 1 in the remaining array and at index 2 in the
array.
Note: The code written from the above insights can be accessed in the solution tab
in the question itself.
12
Given an array of length N and an integer x, you need to find and return the first
index of integer x present in the array. Return -1 if it is not present in the array. The
last index means that if x is present multiple times in the given array, you have to
return the index at which x comes last in the array.
Approach:
Now, to solve the question, we have to figure out the following three elements of
the solution.
1. Base case
2. Recursive call
3. Small calculation
Let the array be: [5, 5, 6, 2, 5] and x = 6. Now, if we want to find 6 in the array, then
first we have to check with the first index. This is the small calculation part.
Code:
if(arr[0] == x):
return 0
13
Since, in the running example, the 0th index element is not equal to 6, so we will
have to make a recursive call for the remaining array: [5, 6, 2, 5] and x = 6. This is
the recursive call step.
f(arr+1, size-1, x)
● In the recursive call, we are incrementing the pointer and decrementing the
size of the array.
● We have to assume that the answer will come for a recursive call. The answer
will come in the form of an integer.
● If the answer is -1, this denotes that the element is not present in the
remaining array; otherwise, we need to add 1 to our answer as for recursion,
it might be the 0th index, but for the previous recursive call, it was the first
position.
● For instance: In the running example, 6 is present at index 1 in the
remaining array and at index 2 in the array.
Base Case:
● The base case for this question can be identified by dry running the case
when you are trying to find an element that is not present in the array.
● For example: [5, 5, 6, 2, 5] and x = 10. On dry running, we can conclude that
the base case will be the one when the size of the array becomes zero.
● When the size of the array becomes zero, then we will return -1.
● This is because if the size of the array becomes zero, then this means that we
have traversed the entire array and we were not able to find the target
element.
14
Note: The code written from the above insights can be accessed in the solution tab
in the question itself.
Approach:
Now, to solve the question, we have to figure out the following three elements of
the solution:
1. Base case
2. Recursive call
3. Small calculation
Let us assume the given array is: [5, 6, 5, 5, 6] and the target element is 5, then the
output array should be [0, 2, 3] and for the same array, let’s suppose the target
element is 6, then the output array should be [1, 4].
15
To solve this question, the base case should be the case when the size of the input
array becomes zero. In this case, we should simply return 0, since there are no
elements.
The next two components of the solution are Recursive call and Small calculation.
Let us try to figure them out using the following images:
So, the following are the recursive call and small calculation components of the
solution:
Recursive Call
Small Calculation:
1. Update the elements of the output array by adding one to them.
16
2. If the equality exists, then shift the elements and add 0 at the first index of
the output array. Moreover, increment the size, as we have added one
element to the output array.
Note: The code written from the above insights can be accessed in the solution tab
in the question itself.
Using the same concept, other problems can be solved using recursion, just
remember to apply PMI and three steps of recursion intelligently.
17