Python Programming Handout
Python Programming Handout
Dear Students,
Welcome to Python Programming Course! We are thrilled to have you join us on this exciting journey
into the world of Python Programming. Over the coming weeks, you will explore key concepts,
develop practical skills, and engage in hands-on projects that will enhance your understanding and
expertise.
The modules that we will cover in this course are outlined as follows:
Module Topics
Python interpreter and interactive mode,debugging; values and types: int, float,
boolean, string , and list; variables, expressions, statements, tuple assignment,
II
precedence of operators, comments; Illustrative programs: exchange the values of
two variables, distance between two points.
Lists: list operations, list slices, list methods, list loop, mutability, aliasing, cloning lists,
list parameters; Tuples: tuple assignment, tuple as return value; Dictionaries:
IV
operations and methods; advanced list processing - list comprehension; Illustrative
programs: simple sorting, Students marks statement, Retail bill preparation.
Files and exceptions: text files, reading and writing files, format operator; command
line arguments, errors and exceptions, handling exceptions, modules, packages;
V
Illustrative programs: word count, copy file, Voter‘s age validation, Marks range
validation (0-100).
Please note that our training process includes periodic assessments (Internal and External
Assessments)that will be crucial parts of your learning journey. We encourage you to approach these
assessments with enthusiasm and a positive mindset.
In addition, the assessment rubrics given below will be integral to your overall grading:
Category Number of Marks Pattern Syllabus
instances
Assignment 1 5 - Module 2
Attendance 1 5 75% -
Total 100 - -
We encourage you to actively participate, ask questions, and collaborate with your peers to
maximize your learning experience.
For any questions or clarifications, feel free to visit our expert trainers at Room CLC06 (Library Block -
Reading Hall) between 9:00 AM and 4:30 PM, Monday through Friday. Alternatively, you can reach
out to us via email at helpdesk@[Link].
We are thrilled to have you with us and look forward to seeing you thrive in these training sessions.
Let’s embark on this journey together, and make the most of every opportunity to grow and excel.
S. No Topic [Link]
1 Fundamentals of Computing
1.1 Algorithms 01
1.2 Iterations and Functions 03
Module 1: Fundamentals of Computing
Chapter 1: Algorithms and flowchart
Algorithms are a way of specifying a multi-step task, and are especially useful when we wish to
explain to a third party (be it human or machine) how to carry out steps with extreme precision.
A series of clear and efficient steps that a computer executes to solve problems, perform calculations,
process data, or make decisions to produce a result is called an algorithm.
Algorithm is a sequence of clearly defined steps that describe a process to follow a finite set of
unambiguous instructions with clear start and end points.
Properties of algorithm:
1.Collection of individual steps: The first thing to note is that an algorithm is a series of individual
steps. This is similar to a recipe, which includes steps like "preheat the oven to 180 degrees Celsius"
or "add two tablespoons of sugar to the bowl."
2.Definiteness: The next property is definiteness, which means every step must be clearly defined.
Each step in an algorithm should have only one meaning to avoid confusion. Similarly, chefs use
precise measurements in recipes, like "two tablespoons of sugar" or "bake for 20 minutes," instead
of vague instructions like "some sugar" or "cook it for a while."
3.Sequential: Algorithms are also sequential, meaning the steps must be followed in the exact order
specified. Doing them out of order can lead to incorrect results. For example, in a recipe, dicing an
onion before frying it gives a different outcome than frying it first. Similarly, in math, doubling a
number and then adding 5 gives a different result than adding 5 first and then doubling it. Like a
recipe, an algorithm must be executed in the correct sequence to produce meaningful results.
State in algorithms:
The current configuration of all information kept track of by a program at any one instant in time.
As a computer follows an algorithm, much like how you follow a recipe, the state of the system can
evolve. Clearly defining the sequence of steps in an algorithm ensures that the state changes
consistently each time the algorithm is executed.
There is no "global view" in algorithms. At any given moment, the environment in which the
algorithm is running is in a specific state. However, by the time the next step is executed, things
might have changed. The recipe analogy illustrates this well. At the start, you might have butter,
flour, milk, eggs, and sugar. After each step, you take a snapshot of the kitchen, capturing how the
ingredients change bit by bit. First, the flour goes into a bowl, then the eggs join, the butter goes into
the pan, and so on.
For algorithms, this means that individual steps are executed sequentially, with only one step being
considered at any given moment. Once a step has been executed, the computer discards any
reference to it and proceeds to the next step.
Problem Statement 1: Write an algorithm for finding the minimum number in a given list of
numbers.
Solution:
Step 1: Start.
Step 2: Initialize a list of elements.
Flowchart Symbols:
Iteration:
Variables can be used to control the execution of an algorithm. At a basic level, they can be used in
two ways. One of those is iteration, also known as looping. Iteration allows you to repeat a series of
steps over and over, without the need to write out each individual step manually.
To save yourself from writing the same thing repeatedly, you could write one sentence with
instructions to repeat it.
For example: X represents the number of steps in a staircase.
At the start, X is 0.
Repeat the sentence: You are on step X of the staircase.
Take one step up. Now you are on step X+1.
Add 1 to X.
Repeat the sentence if X is less than 10, otherwise you’ve reached the top.
This brings us to the second method used for controlling the execution of an algorithm that is
selection.
Selection:
In a loop, one way to control how many times the steps are repeated is to simply specify the number,
like ‘take 10 steps up’. But notice that the example above doesn’t do that. Instead, it uses selection
(also known as a conditional), which checks the current value of the variable and makes a decision
based on it.
In the staircase example, a condition helps decide whether to keep repeating the steps or stop. For
instance, let's say you're starting at the bottom of the staircase and need to climb up to the 10th
step. The condition might be: "Repeat taking steps as long as you haven't reached the 10th step."
At the start, you're on step 0, and the condition is true because you're not yet at step 10. So, the
computer keeps instructing you to take one step up. After each step, the number of steps remaining
decreases. Each time you take a step, the condition is checked: "Are you still on a step less than 10?"
As long as the answer is yes, the loop continues.
When you reach step 10, the condition becomes false because you've reached the top of the
staircase. Now, the computer knows that no more steps need to be taken, so it stops giving
instructions and ends the process.
In this way, the condition controls when the loop ends. As long as you're still below the 10th step,
the condition is true, and the process repeats. Once you reach the 10th step, the condition becomes
false, and the loop stops.
Conditions can be used at any point in an algorithm, not just to control loops. Wherever they are,
they help the computer decide whether to do something or not. For example, in the staircase, the
condition could be whether you've reached the top or not, and this helps decide if you keep going or
stopping
Conditions can be used at any point in an algorithm, not just to control loops. Wherever they are,
they help the computer decide whether to do something or not. For example, in the staircase, the
condition could be whether you've reached the top or not, and this helps decide if you keep going or
stopping.
Problem statement 2: Write an algorithm and draw a flowchart to determine the number of
iterations it takes for a given number to reach 1 using the Collatz sequence.
Solution:
Step 1: Start
Step 2: Initialize an input number ‘n’ . Initialize count as ‘0’.
Step 3: Check if ‘n’ is greater than one. (or check if ‘n’ is not equal to one)
Step 3A: if true, check if ‘n’ is even. i.e., n%2==0
Step 3A1: if true, update ‘n’ as n/2
Step 3A2: if false, update ‘n’ as (3Xn)+1
Step 3A3: Increment count by 1 and go back to step 3.
Step 3B: if false, print count.
Step 4: Stop.
Problem statement 3: Write an algorithm and draw a flowchart to determine whether the given
number is a prime number or not.
Prime number: A prime number is a natural number greater than 1 that has no positive divisors other
than 1 and itself (only 2 divisors). In other words, a prime number can only be divided by 1 and the
number itself without leaving a remainder.
Solution:
Step 1: Start.
Step 2: Initialize variables ‘count’ as zero, ‘i’ as one and an input ‘n’ from the user.
Step 3: Check if ‘i’ is less than and equal to ‘n’.
Step 4: If true, check if ‘n’ is divisible by ‘i’ (or ‘i’ divides ‘n’).
Step 4A: If true, increase count value by one.
Step 4B: Increase the value of ‘i’ by one and go back to step 3.
Step 5: If false, check if count is equal to two.
Step 5A: If true, print the output as “Prime”.
Step 5B: If false, print the output as “Not Prime”.
Step 6: Stop.
Functions:
A subroutine is like a small, self-contained set of instructions or actions within a larger program. It's a
specific task or operation that can be used over and over without repeating the same lines of code
each time. Subroutines are also known as functions or procedures in some programming languages.
Think of a subroutine like a recipe in a cookbook. The recipe is a set of instructions for making a dish,
but it’s not followed until someone decides to cook that dish. Similarly, the lines of code inside a
subroutine aren’t executed until the programmer tells the program to "call" or "run" that subroutine.
Scenario:
Imagine you're writing a program that calculates the area of different shapes like squares, circles,
and triangles. Instead of rewriting the formula for each shape every time, you could create a
subroutine for each shape's area calculation. Each subroutine would just contain the steps to
calculate the area for that specific shape.
For example:
The Square Area Subroutine: This subroutine takes the side length of a square and returns the area
(side * side).
The Circle Area Subroutine: This subroutine takes the radius of a circle and returns the area (π *
radius * radius).
Now, if you need to calculate the area of a square or circle in multiple parts of your program, you
don’t need to rewrite the area formula every time. Instead, you simply call the subroutine, and the
program will go to that subroutine, run the instructions, and then come back to where it left off once
the subroutine finishes.
How It Works:
Subroutine Declaration: First, the subroutine is defined with its specific set of instructions. It doesn’t
run at this point.
Subroutine Call: When the program reaches a point where it needs to calculate, for example, the
area of a square, it calls the Square Area Subroutine.
Execution: The program temporarily "jumps" to the subroutine, runs its instructions (like calculating
the area), and then returns to where it left off in the main program once the subroutine is done.
Benefits:
Reuse: You only need to write the code for a specific task once, and you can call the subroutine
anytime you need that task to be done.
Organization: It makes your code easier to organize, manage, and debug because you can break it
down into smaller, more manageable parts.
In short, a subroutine allows you to organize and reuse code efficiently, ensuring that the program
only does the work when it's needed.
Problem statement 4: Write an algorithm and draw a flowchart to determine whether the given
number is present in an unordered list or not.
Solution without functions(without subroutines):
Step 1: Start.
Step 2: Initialize a list, variable ‘n’ for size of list, ‘i’ as zero and a variable ‘e’ that will be used for
searching within the list.
Step 3: Check if ‘i’ is less than ‘n’.
Step 4: If true, check if ‘i’th number on the list is equal to ‘e’.
Step 4A: if true, print “number is present” and go to step 6.
Step 4B: if false, Increase the variable ‘i’ by 1 and go back to step 3.
Step 5: If false, print “number is not present”.
Step 6: Stop.
Assignment:
Similarly, consider writing an algorithm for checking whether a given number is a prime number or
not using functions (given flowchart).
History:
Python was created by a programmer named Guido van Rossum and was first released on February
20, 1991. Even though "python" is also the name of a big snake, the Python programming language
actually got its name from a funny TV show called Monty Python’s Flying Circus.
One special thing about Python is that it was originally made by just one person, which is unusual.
Most programming languages are created by big companies with many experts, and we rarely know
the names of the people who worked on them. But Python is different.
Of course, Guido van Rossum didn’t build everything in Python by himself. Over time, thousands of
programmers, testers, and users (many of whom aren’t even computer experts) helped make Python
better and more popular. However, the original idea for Python came from Guido.
Today, Python is taken care of by the Python Software Foundation, a group of people who work to
improve and spread the use of Python around the world.
Python goals:
In 1999, Guido van Rossum set goals for Python. He wanted it to be:
● Easy to learn and use, while still being as powerful as other popular languages.
● Open source, so anyone could help improve it.
● Readable, so the code would be as easy to understand as plain English.
● Useful for everyday tasks, allowing programmers to write code quickly.
More than 20 years later, Python has achieved all these goals! Some rankings say it is the most
popular programming language in the world, while others place it in the top three.
Python consistently ranks at the top of the TIOBE Index and PYPL Popularity of Programming
Language Index (as of February 2022).
Areas of use:
● Web development – Used to create websites and web applications with frameworks like
Django, Flask, and Pyramid.
● Scientific and numeric computing – Helpful for math, science, and engineering with tools
like SciPy (a collection of science-related packages) and IPython (an advanced interactive
shell).
● Education – A great language for beginners learning to code.
● Desktop applications – Used to build software with tools like wxWidgets, Kivy, and Qt.
● Software development – Helps manage and test software using Scons, Buildbot, Apache
Gump, Roundup, and Trac.
● Business applications – Used in ERP (Enterprise Resource Planning) and e-commerce with
tools like Odoo and Tryton.
● Games – Python was used in popular games like Battlefield series and Sid Meier’s
Civilization IV.
● Websites and services – Major platforms like Dropbox, Uber, Pinterest, and BuzzFeed use
Python.
Google collab:
Google Colab (Colaboratory) is a free online tool that allows you to write and run Python code in a
web browser. Here’s why it’s so useful:
1. No Installation Needed – You don’t have to install Python or any software on your computer.
Just open Collab in your browser and start coding.
2. Free Access to Powerful Computers – Google Colab provides free access to GPUs and TPUs,
which are useful for machine learning and deep learning.
3. Cloud Storage – Your notebooks are stored in Google Drive, so you can access them from
anywhere and share them easily.
4. Built-in Libraries – Popular Python libraries like NumPy, Pandas, TensorFlow, and Matplotlib
are pre-installed, saving you time.
5. Collaboration – Multiple people can work on the same notebook in real time, just like in
Google Docs.
6. Supports Machine Learning and AI – It’s widely used for AI, data science, and deep learning
projects because of its easy integration with TensorFlow and PyTorch.
7. Free to Use – You get all these features without any cost (though there’s a paid version,
Colab Pro, with even more power).
Google Colab is an excellent choice for beginners, students, and professionals working on Python
projects.
Interpreter Vs Compiler:
Compiler Interpreter
1. Creates an object file (e.g., .exe), which is 1. No object file is needed; source code is
converted to machine code for output. directly converted to machine code.
2. Executes the entire source code at once. 2. Executes the source code line by line.
4. Debugging is harder since the whole code 4. Debugging is easier due to line-by-line
runs at once. execution.
6. Source code is not needed after the first 6. Source code is needed every time the
execution. program runs.
Variables:
In python, variables are named locations which are used to store data/value.
Example: a=10 or b=20 or c= “A”
Data Types:
If variables are like containers which are used to hold a value/physical entity then the data type
represents the kind of value which is stored in that container.
In python, there are majorly 5 basic data types namely, Numeric, Boolean, set, dictionary, Sequence.
Input:
There are majorly 2 types of inputs in any programming language: 1. User input.
2. File input.
For user input we can use the inbuilt function present in python: input()
Example: a = input()
Note: the default data type of input() function is string. I.e., whatever the value entered using input()
function will be in data type string only.
Type casting:
The process of converting from one kind of datatype to another kind is called type casting. We will
study more about this in upcoming chapters.
Now if we want to store the data from a user as a specific kind we need to typecast the value from
string to desired form. Refer the example given below:
Output:
For printing any output either string or variable values we use python built-in called print().
print("Hello World!")
For printing the data we use any one of the 3 formats available. But in python print() is not only
limited to printing values and texts. Further features are given below.
Notice we are getting an error because as mentioned print(“”) is limited to a single line.
If we want to print in multiple lines using a single print statement we can use 3 double quotes. Or we
can also use escape sequences like ‘\n’ or ‘\t’ like these.
4. Printing Emojis:
In python we can also print emoji’s other than plain texts using print() function. For doing so we have
basic 3 approaches.
i. Using Unicodes:
ii. Using CLDR:
This is just an example, try out different emojis using the sample commands given in the below table.
Unicodes for emoji
Color Code
S. No Code Color
1 “\33[0m” Default
2 “\33[30m” Black
3 “\33[31m” Red
4 “\33[32m” Green
5 “\33[33m” Yellow
6 “\33[34m” Blue
7 “\33[35m” Magenta
8 “\33[36m” Cyan
9 “\33[37m” White
NOTE: Once you start printing in a specific color the interpreter will keep on printing in the chosen
one only. We need to reset to default again to avoid errors.
In .format if we are using multiple variable values, the order of variables inside the .format function
will appear as the same inside our curly brackets. Refer to the below example.
Note: Programmers be aware this formatted printing method is not available in every version of
python. In competitive coding or in interviews this format may not be supportive. Use .format
extensively.
Operators:
In Python programming language, there are 7 types of operators their details are given below:
1 Arithmetic + (Addition)
- (Subtraction)
* (Multiplication)
/ (Division-quotient:with decimal)
% (Modulus-remainder)
// (Floor division- quotient: without decimal)
** (Exponentiation)
2 Assignment =
Shorthand operators
:= {print(x:=3)}
6 Membership in not in
7 Identity is is not
Precedence:
Conditional statements in Python are used to make decisions in a program by executing specific
blocks of code based on certain conditions. They control the flow of execution, allowing the program
to respond differently in different situations.
For example, consider a traffic signal system. If the light is green, cars are allowed to move; if it's
yellow, drivers should slow down; and if it's red, vehicles must stop. Similarly, in Python, conditional
statements help a program decide what action to take based on given conditions.
1. if statement:
Syntax:
if condition:
Statement
We use the if condition when we need to execute a specific block of code only if a particular
condition is met. If the condition is True, the code inside the if block runs; otherwise, it is completely
skipped. This type of conditional statement is used when there is only one possibility—either the
condition is satisfied, and the code executes, or nothing happens.
Imagine you set an alarm to wake up in the morning. If the alarm rings, you wake up; otherwise, you
continue sleeping. There is no alternative action in this case—it’s either waking up or doing nothing.
Example:
Notice in the above two examples the print statement which is inside if-condition is being executed
only when condition evaluates to be true. The second program even when being executed without
errors doesn’t print anything because the condition part is false.
2. If-else statement:
Syntax:
if condition:
Statement 1
else:
Statement 2
We use the if-else condition when we have exactly two possible outcomes—one if the condition is
True and another if it is False. It helps in decision-making when there are only two choices, such as
left or right, heads or tails, pass or fail.
Imagine you're flipping a coin. The result can either be heads or tails, and there are no other
possibilities.
3. if-elif-else statement:
Syntax:
if condition1:
Statement 1
elif condition2:
Statement 2
elif condition3:
Statement 3
else:
Statement 4
We use the if-elif-else condition when there are multiple choices to consider, and only one condition
can be true at a time. This is useful in situations where we have more than two options, such as
choosing an engineering branch based on interest.
In the below example only the third condition is true so only the third statement will be printed. If
none of the given conditions evaluates to be true then as default statement else block will be
executed.
4. Nested if statements:
A nested if statement is when an if condition is placed inside another if statement. This is useful
when multiple conditions must be checked in a hierarchical manner.
Now in this stage if we enter correct college name it will enter through another page or it will throw
an error message:
Notice in the below image the website is displaying an error message as “Domain not found!”
because we are entering the college name as “Alliance” but the correct domain is “alliance”.
When we enter the proper domain it will then ask for username and password for login. Now here
only if both username and password are matching it will successfully login for the candidate. Else
error message will be displayed. (Refer to the images below and code on next page to understand
properly)
Code:
Now imagine the below mentioned two test cases one where domain is wrong and one where
username/password goes wrong and observe how our output statement differs.
In such cases we check for both uppercase alphabet range A->Z and lowercase range a->z. Here the
character input needs to satisfy only one of the two conditions either range A->Z or range a->z not
both.
Observing these scenarios we can conclude that we use logical and operator if we need all the
conditions to be satisfied and logical or if we need any one condition to be satisfied to execute a
block of code.
Iteration in Python refers to the process of repeatedly executing a block of code. It is commonly used
to loop through elements in a sequence (like lists, tuples, dictionaries, or strings) or run a block of
code multiple times until a condition is met.
The process of repeatedly executing a block of code or statement with little or no modification is
called a loop. Loops are used to automate repetitive tasks and reduce manual effort.
[Link] Loop:
Syntax:
while condition:
Statements
A while loop is used in Python to execute a block of code repeatedly as long as a given condition
remains True. It is particularly useful when the number of iterations is unknown beforehand and
depends on modification/upation of variables or dynamic conditions.
Imagine a scenario where you have 5 rupees in a savings account, and every year your money grows
5 times due to an exceptional investment opportunity. You want to track your balance until it reaches
or exceeds 100 rupees.
If we observe the above scenario, we know our initial investment, but we don't know how long it will
take to reach 100 rupees (here the number of iterations is unknown). However, we do know the end
condition, which is reaching 100 rupees. Therefore, we print the values until we reach 100, using the
condition while i < 100:
Another example for the same can be to print Collatz sequence. Starting from a number until it
reaches one.
Here we already know that for odd numbers updation is: 3n+1 and for even: n//2 and we need to
keep doing this until we reach 1. Observe we know the end condition but not the number of iteration
so we use the reverse of the end condition as our loop condition. And the main task is to find the
number of steps that is the number of iterations the loop executes.
2. For loop:
A for loop in Python is used to iterate over a sequence (like a list, tuple, or range) and execute a block
of code a fixed number of times. It is particularly useful when the number of iterations is known
beforehand.
Syntax:
for i in range(start,end,step):
Statement
In the given three syntaxes, the first one is the most elaborate. Here, we have the keyword ‘for’, and
the character ‘i’ represents the iterator, which is used to check whether the value of ‘i’ falls within
the specified range of start and end values using the membership operator ‘in’. Additionally, it
includes a step value that determines the increment or decrement after each iteration.
The second syntax is not having start or step value. In such scenarios default value for start will be
considered as 0 and step value as +1.
Finally in the third syntax jump value is not given where it will be considered as +1 as before.
Note: In for loop the start value will always be inclusive and the end value specified will always be
exclusive.
Scenario:
Imagine you have 5 rupees in a savings account, and instead of growing dynamically, the bank
provides a fixed interest rate that multiplies your money by 5 each year. You want to track your
balance over a fixed period of 5 years.
If we understand this concept, we are counting the number of divisors for a given input number. We
know that the divisors of a number will always range from 1 to the number itself (n). This means that
the number of iterations required to check for divisibility is exactly ‘n’ times, which is a
predetermined (known) quantity.
Since the number of iterations is fixed and does not depend on dynamic conditions, a for loop is the
ideal choice in this scenario. The for loop allows us to systematically iterate through all numbers from
1 to n, checking whether each number is a divisor of n. If it is, we can count it as a valid divisor.
Further we have one more implementation type that is nested for loop, which we discuss in the next
chapter.
Pattern printing in programming utilizes loops and control structures to generate visual
patterns—such as stars, numbers, or symbols—on the console. It serves as an effective way to
practice iteration and logic building.
Patterns:
[Link] pattern:
n=4
J=n i j
0 4
1 4
2 4
3 4
[Link] pyramid:
J = i+1 n=4
i j
0 1
1 2
2 3
3 4
1 3
2 2
3 1
[Link] Pyramid:
i j(Space) j(*)
0 3 1
1 2 2
2 1 3
3 0 4
1 1 3
2 2 2
3 3 1
[Link] triangle:
[Link] pattern:
[Link] pattern:
[Link] pattern 1:
[Link] pattern 2:
Example:
name = "Alice"
greeting = 'Hello, world!'
sentence = "Python is fun! 123 :)"
Properties of strings:
1. Strings are immutable.
2. Strings are indexed.
3. Strings are iterable.
4. Strings can be tested using membership operators for character presence.
5. String supports slicing.
6. Strings can contain any character.
text = "Python"
P y t h o n
0 1 2 3 4 5
Code: print(text[0:3])
Output: Pyt
Just like lists, strings will also have negative indices starting from -1.
P y t h o n
-6 -5 -4 -3 -2 -1
print(s[7:12])
print(s[-6:-1])
print(s[::3])
print(s[::-2])
name = "Alice"
print(name[0]) #A
print(name[-1]) #e
print(name[1]) #l
print(name[-3]) #i
You can also use loops to go through each character in a string, one by one.
Method1: using an iterator variable:
Code:
text = "Python"
for char in text:
print(char)
Output:
P
y
t
h
o
n
Method2: Using normal variables and length of string to iterate every index from 0 to length of
string.
Code:
text = "Python"
for i in range(len(text)):
print(f"Index {i} = {text[i]}")
Output:
(printing both index and character value)
Index 0 = P
Index 1 = y
Index 2 = t
Index 3 = h
Index 4 = o
Index 5 = n
3. Concatenation of strings.
String concatenation means joining two or more strings together to form one continuous string.
We can use the ‘+’ operator to join two different strings.
Code:
first_name = "John"
last_name = "Doe"
full_name = first_name + " " + last_name
print(full_name)
Output:
John Doe
We can also use ‘+=’ to join a string at the end of an already existing string
Code:
greeting = "Hello"
greeting += ", world!"
print(greeting)
Output:
Hello, world!
4. Replace:
Replaces all occurrences of a specified substring with another.
Can be used to replace a specific indexed character or a substring.
Code:
text = "I love Java"
result = [Link]("Java", "Python")
print(result)
Output:
I love Python
5. Split:
Splits the string into a list of words, using a separator (default is space).
Code:
text = "apple,banana,cherry"
result = [Link](",")
print(result)
Output:
['apple', 'banana', 'cherry']
6. Title:
Capitalizes the first letter of each word in the string.
Code:
text = "python is awesome"
result = [Link]()
print(result)
Output:
Python Is Awesome
A function is a block of reusable code that performs a specific task. It helps make code organized,
modular, and easier to manage.
A function is a set of instructions that executes only when it is invoked. It can accept input values,
called parameters. Functions can also produce and return a result.
Example:
def add_numbers(a, b):
result = a + b
return result
Output:
The sum is: 15
Explanation:
●The function add_numbers takes two integer parameters: a and b.
●It adds them and stores the result.
●The return statement sends the result back.
●We then print the returned value.
Parameters:
Variables a and b are parameters.
They are defined inside the function definition: def add_numbers(a, b):
Parameters are like variables that the function expects when it is called.
Arguments:
10 and 5 are arguments.
They are the actual values passed to the function in the call: add_numbers(10, 5)
These values are assigned to the parameters a and b during execution.
Function Types:
Type Description
# Example array
numbers = [5, 10, 15, 20, 25]
Output:
The sum of array elements is: 75
Explanation:
●Function name: sum_of_array
●Parameter: arr – takes a list (array) as input.
●Logic: Loops through each number in the array and adds it to total.
●Return: Returns the final sum.
●Function call: We pass numbers (the array) as an argument.
Recursion:
Recursion is a programming technique where a function calls itself to solve smaller instances of a
problem until it reaches a condition that stops the recursion (called the base case).
In Python, recursive functions are used to solve problems that can be broken down into smaller,
similar sub-problems, such as computing factorials, Fibonacci numbers, or traversing data structures
like trees.
Note:
Every recursion must have a base case to avoid infinite loops.
Python has a recursion depth limit (by default it's around 1000). You can check it with:
Too many recursive calls without a base case can result in a RecursionError.
GCD:
def gcd(a,b):
if b==0:
return a
else:
return gcd(b,a%b)
print(gcd(24,36))
FACTORIAL:
def factorial(n):
if n == 0 or n == 1: # Base case
return 1
else:
return n * factorial(n - 1) # Recursive call
FIBONACCI:
def fibonacci(n):
"""Prints the first n Fibonacci numbers."""
If n==1 or n==2:
return n-1
else:
return fibonacci(n-1)+fibonacci(n-2)
print(fibonacci(5))
Chapter 1: Lists
A list is a heterogeneous, sequential data type in python which can store heterogeneous elements.
A list in Python is an ordered, mutable, and indexed collection of items. Lists can hold elements of
different data types like integers, strings, floats, or even other lists.
Example: list = [1, 2, 3, "apple", 4.5]
Properties of lists:
1. Lists are ordered.
2. Lists are mutable.
3. Lists can contain duplicate elements.
4. Lists can store elements of different data types.
5. Lists Dynamic in size.
6. Lists are iterable.
Types of lists:
1D list: A simple list where elements are stored in a single row (like a single line of data).
Ex: [ item1, item2, item3, ..., itemN ]
2D list: A list of lists — useful for representing tables, matrices, grids, etc.
Ex: [
[row1_item1, row1_item2],
[row2_item1, row2_item2],
...
]
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
Accessing lists:
[Link] both string and list belong to sequence data type accessing is possible through indecis.
Ex: fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # Output: apple
print(fruits[2]) # Output: cherry
print(fruits[-1]) # Output: cherry
print(fruits[-2]) # Output: banana
2. String slicing:
numbers = [10, 20, 30, 40, 50]
print(numbers[1:4]) # Output: [20, 30, 40]
print(numbers[:3]) # Output: [10, 20, 30]
print(numbers[::2]) # Output: [10, 30, 50] (step by 2)
2D lists:
matrix = [
[1, 2, 3],
[4, 5, 6]
]
print(matrix[1][2]) # Output: 6 (2nd row, 3rd column)
Input format:
6 #number of elements
1 3 4 9 7 5 #list elements
Code:
# Read number of elements (n)
n = int(input("Enter the number of elements: "))
# Read list elements in a single line
elements = list(map(int, input("Enter the list elements: ").split()))
Input format:
33
123
456
789
Code:
# Read number of rows and columns
m, n = map(int, input("Enter rows and columns: ").split())
# Read 2D list (matrix) using map in a loop
matrix = []
print("Enter the matrix row by row:")
for _ in range(m):
row = list(map(int, input().split()))
[Link](row)
One important thing to understand is that append() only takes one item. So if you append a list,
that entire list becomes a single element inside the original list, not a merged set of values. For
instance:
nums = [1, 2]
[Link]([3, 4])
print(nums) # Output: [1, 2, [3, 4]]
2. remove():
The remove() function lets you delete an element from a list — not by its position, but by its
value. It searches from the beginning of the list, finds the first occurrence of the item, and
removes it. If the value appears more than once, only the first one is removed. If it doesn't exist
at all, Python will raise a ValueError, which means you’ll need to be cautious and possibly check
first if the item is in the list.
colors = ['red', 'blue', 'green', 'blue']
[Link]('blue')
print(colors) # Output: ['red', 'green', 'blue']
NOTE: As you can see, even though "blue" appears twice, only the first one was removed. Also,
remove() doesn’t return anything; it just changes the list directly.
3. insert():
Sometimes, you don’t want to just stick something on the end — you want to place it at a
specific spot in the list. That’s where insert() comes in. This method takes two arguments: the
position (index) where you want the item to go, and the item itself. The element at that position
(and all following ones) will shift to the right to make space.
numbers = [10, 20, 30]
[Link](1, 15)
print(numbers) # Output: [10, 15, 20, 30]
Here, 15 gets inserted right at index 1. If the index is greater than the list’s length, the item just
gets added to the end. If the index is negative, it counts from the back of the list
4. pop():
This is a really useful method when you not only want to remove an item from a list but also
want to use it afterward. pop() removes an item at a specific index and returns it. If you don’t
pass any index, it just removes and returns the last item in the list. This makes it handy when
treating a list like a stack or queue.
For example:
tasks = ['code', 'test', 'deploy']
last_task = [Link]()
print(last_task) # Output: 'deploy'
print(tasks) # Output: ['code', 'test']
If you do pop(1), you’ll remove the item at index 1 instead. If the index is out of range, Python
raises an IndexError. So, like with remove(), you might need to handle that with error checking.
5. len():
This one isn’t a list method but a built-in function that works on all kinds of collections —
strings, tuples, dictionaries, and of course, lists. When you use len(my_list), Python returns the
number of items inside that list. This is often used in loops, conditionals, or when checking if a
list is empty.
names = ['Alice', 'Bob', 'Charlie']
print(len(names)) # Output: 3
It’s worth remembering that len() doesn’t count nested elements as individual ones — so a list
inside a list still counts as one item.
6. sort():
If you want to arrange the items in your list in ascending order (or descending), sort() is your
tool. It changes the original list itself — it doesn't return a new sorted version. By default, it
sorts items in ascending order, whether they're numbers or strings. If you want descending
order, you can pass reverse=True.
scores = [88, 95, 70, 100]
[Link]()
print(scores) # Output: [70, 88, 95, 100]
You can also sort based on custom rules using a key function. For example, if you have a list of
strings and want to sort them by length:
words = ['banana', 'apple', 'fig', 'cherry']
[Link](key=len)
print(words) # Output: ['fig', 'apple', 'banana', 'cherry']
Keep in mind that if you don’t want to alter the original list, but want a sorted version, you can
use the sorted() function instead.
Definition:
In Python, a tuple is a built-in ordered collection of elements, similar to a list, but with one key
difference: tuples are immutable, meaning their contents cannot be changed once they’re created.
You can think of a tuple as a fixed-size container that stores a sequence of items — numbers, strings,
or even other tuples and lists — but once it’s created, you can't add, remove, or modify elements in
it.
You define a tuple using parentheses (), with the elements separated by commas:
my_tuple = (1, 2, 3)
Properties of tuple:
●Ordered: Tuples maintain the order of elements. You can access elements by index.
●Immutable: Once defined, you cannot change a tuple’s content — no adding, removing, or altering
items.
●Allow duplicates: Just like lists, tuples can contain duplicate values.
●Can hold mixed data types: Integers, strings, lists, other tuples — all can be elements inside a tuple.
●Hashable (if elements are immutable): Tuples can be used as keys in dictionaries or elements in
sets, unlike lists.
Importance of tuples:
●Data integrity: Since tuples can't be changed, they're great for data that shouldn't be modified —
like dates, coordinates, or fixed settings.
●Performance: Tuples are slightly faster than lists for iteration and access, since their immutability
allows certain internal optimizations.
●Safety: By using a tuple, you signal to other developers that “this data should not change.”
●Can be dictionary keys: Because they're immutable and hashable, tuples can be used where lists
can’t — like as keys in a dictionary.
Example:
location = {(40.7128, -74.0060): "New York City"}
print(location[(40.7128, -74.0060)]) # Output: New York City
Accessing tuples:
1. Accessing tuples is possible just like lists, through index, using loop for individual elements or
slicing method for sequence within a tuple.
If you try to unpack with a different number of variables than tuple elements, Python will
raise a ValueError. But Python also supports extended unpacking, which allows you to collect
remaining values using *.
For example:
values = (1, 2, 3, 4, 5)
a, b, *rest = values
print(a) # 1
print(b) # 2
print(rest) # [3, 4, 5]
Here, the first two values are unpacked into a and b, and the remaining are collected into a
list called rest.
OR
values = (1, 2, 3, 4)
*start, end = values
print(start) # [1, 2, 3]
print(end) # 4
Unpacking is commonly used in scenarios like returning multiple values from a function,
iterating with enumerate() or zip(), or when destructuring values from complex structures.
Here, Python simply places the contents of tuple2 right after tuple1, and stores the result in
a new tuple called result.
t1 = ('a', 'b')
t2 = ('c', 'd')
t3 = ('e', 'f')
combined = t1 + t2 + t3
print(combined) # Output: ('a', 'b', 'c', 'd', 'e', 'f')
In Python, a dictionary is an unordered, mutable, and indexed collection of key-value pairs. Think of it
as a real-life dictionary where you look up a word (key) and get its meaning (value). In Python, you
can store all kinds of values (strings, numbers, lists, even other dictionaries) under unique keys.
You define a dictionary using curly braces {}, with each item consisting of a key: value pair.
student = {
"name": "Alice",
"age": 21,
"course": "Computer Science"
}
Here:
●"name" is a key with the value "Alice"
●"age" is a key with the value 21
●"course" is a key with the value "Computer Science"
Keys are unique and must be of an immutable type (like strings, numbers, or tuples). Values can be
anything — even lists or other dictionaries.
Properties:
●Unordered (prior to Python 3.7), insertion ordered from Python 3.7+
●Mutable – can change, add, or remove elements
●Indexed using keys (not numeric positions)
●Keys must be unique and immutable
●Values can be of any data type
●Dynamic in size – can grow or shrink as needed
●Supports built-in methods like .keys(), .values(), .items(), .get(), .update(), etc.
Accessing elements:
You use the key inside square brackets [] to get its value:
student = {
"name": "Alice",
"age": 21,
"course": "Computer Science"
}
student["age"] = 22
print(student) # {"name": "Alice", "age": 22, "course": "Computer Science"}
You can also add new key-value pairs just by assigning them:
student["grade"] = "A"
print(student)
Removing elements:
You can remove keys in multiple ways:
[Link] del:
del student["course"]
Nested Dictionaries:
A dictionary can contain other dictionaries. This is called nesting:
students = {
"101": {"name": "Alice", "grade": "A"},
"102": {"name": "Bob", "grade": "B"}
}
print(students["101"]["name"]) # Output: Alice
Properties of sets:
●Unordered collection (no index or position)
●Mutable – can add or remove elements
●No duplicate elements – each item is unique
●Elements must be immutable (like numbers, strings, tuples)
●Can perform set operations like union, intersection, difference
●Created using {} or set() constructor
my_set = {1, 2, 3, 2, 4}
for item in my_set:
print(item)
This loop will print each element in the set, but the order in which the elements appear may vary
every time you run the code, because sets do not maintain order. Looping through a set is a common
way to process or display all of its items, especially when the specific order does not matter.
will be removed. However, if you try to remove something like [Link]("orange"), which isn’t in
the set, Python will raise an error. To avoid that, you can use the discard() method, which works
similarly but does not raise an error if the element is missing. There’s also a method called pop(),
which removes and returns an arbitrary element from the set, but since sets are unordered, you
can’t predict which element will be removed.
Chapter 1: Introduction
File handling is widely used in real-life projects across various industries and applications. It allows
programs to store, retrieve, and manipulate data efficiently.
A school or university needs to maintain student records, including names, roll numbers, grades,
attendance, and other details.
How File Handling is Used:
●Text Files (CSV, TXT): Store student details in a structured format for easy retrieval.
●Binary Files: Store student photos or digital signatures.
●Reading & Writing: When a teacher updates attendance, the program reads the file, modifies the
records, and writes it back.
●Data Backup: At the end of the academic year, all student data is backed up to a file for future
reference.
●Complexity – Managing files, especially large ones, requires careful handling of file paths, formats,
and permissions.
●Risk of Data Corruption – If files are not properly closed or if there is a system crash, data may be lost
or corrupted.
●Storage Space – Large files consume significant disk space, which can become an issue if storage is
limited.
●Security Vulnerabilities – Files can be accessed by unauthorized users if not properly protected,
leading to potential data breaches.
Mode Usage
‘x’ Creates a new file for writing. Fails if the file exists.
‘r’ Opens an existing file for reading. Fails if the file does not exist.
‘w’ Opens a file for writing. Creates a new file if it does not exist, or truncates an existing
file.
‘a’ Opens a file for appending. Creates a new file if it does not exist.
‘r+’ Opens a file for both reading and writing. Fails if the file does not exist.
‘w+’ Opens a file for both reading and writing. Creates a new file if it does not exist, or
truncates an existing file.
‘a+’ Opens a file for both reading and appending. Creates a new file if it does not exist.
However, if a file with the same name already exists, it will raise a FileExistsError and stop
the program. This behavior makes 'x' mode especially useful when you want to avoid
accidentally overwriting an existing file.
For example, if you write open('[Link]', 'x') and there is no file named [Link] in
the current directory, Python will create it. You can then write data to the file as usual using
write(). But if you try the same line again and the file [Link] already exists, Python will
not open it and instead throw an error.
This mode is helpful in scenarios where the integrity of existing data is critical, and you want
to make sure you're creating something entirely new without affecting what’s already there.
Unlike 'w' mode which can overwrite existing files, 'x' mode prioritizes safety by avoiding
overwriting files.
This means that using 'w' mode is destructive to existing content — anything that was in the
file before will be lost. Therefore, it should be used with caution when working with existing
files.
This mode allows you to read the content of the file, but you cannot modify or write to the
file while it is open in 'r' mode. It is typically used when you just want to view or process data
stored in an existing file.
This makes 'a' mode especially useful when you want to add information to a file without
deleting or overwriting what's already in it. Unlike 'w' mode, 'a' mode ensures that the
original data remains intact.
After opening the file, you can perform both read and write operations. However, one
important point is that the file pointer is positioned at the beginning, and reading
immediately after writing (or vice versa) requires repositioning the file pointer using seek().
After opening the file in 'r+' mode, the file pointer starts at the beginning, meaning you can
read from or overwrite existing content right away. However, similar to 'w+', switching
between reading and writing (or vice versa) requires using seek() to reposition the file
pointer.
When you open a file in 'a+' mode, the file pointer is initially placed at the end, so if you
want to read the contents, you’ll need to manually move the pointer to the beginning using
seek(0).
In Python, a module is simply a file containing Python code — it can include functions, classes,
variables, and even runnable code. Modules help you organize your code by breaking it into smaller,
reusable parts. Instead of writing all code in one file, you can keep related code in a separate file
(module) and use it when needed.
Python comes with many built-in modules (like math, random, os) that you can use to perform
various tasks. You can also create your own custom modules.
Types of Modules:
●Built-in Modules – Already available in Python (e.g., math, datetime, os)
●User-defined Modules – Python files you create to reuse code (e.g., my_utils.py)
●External Modules – Installed using tools like pip (e.g., numpy, pandas)
# [Link]
def fibonacci(n):
"""Prints the first n Fibonacci numbers."""
If n==1 or n==2:
return n-1
else:
return fibonacci(n-1)+fibonacci(n-2)
def factorial(n):
"""Returns the factorial of n."""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
Now you can use the functions directly without the module prefix.