Python Introduction
Understand Python, its features, applications and basic program structure.
Python is a high-level, general-purpose programming language designed with an emphasis on readability and developer productivity. Its syntax is relatively easy to understand, which makes Python a popular choice for beginners as well as experienced developers.
Python is an interpreted language. In a typical development workflow, Python code is executed by the Python interpreter rather than being compiled into a traditional standalone executable in the same way as languages such as C or C++.
Why Is Python Popular?
Simple Syntax
Python syntax is designed to be readable, allowing developers to focus more on solving problems than on complex language syntax.
Large Ecosystem
Python has a large collection of libraries and frameworks for web development, data, automation and artificial intelligence.
Web Development
Frameworks such as Django and Flask can be used to build web applications and APIs.
Data & AI
Python is widely used for data analysis,machine learning and artificial intelligence.
Your First Python Program
The print() function is commonly used to display
information in the console.
print("Hello, Python!")
Python Installation & IDLE Setup
Install Python, open IDLE, create your first Python program, and run it step by step.
Before learning Python programming, you need an environment where you can write and execute Python programs. The easiest option for beginners is IDLE, which is included with the standard Python installation.
IDLE stands for Integrated Development and Learning Environment. It provides a simple interface for writing, editing, and executing Python programs without requiring a separate code editor.
What You Will Learn
Step 1 Check Whether Python Is Already Installed
Before installing Python, first check whether Python is already available on your computer.
On Windows, open Command Prompt.
- Press Windows + R.
- Type
cmd. - Press Enter.
Now execute:
python --version
If Python is installed, you may see output similar to:
Python 3.x.x
If Python is not installed, Windows may display a message indicating that the command cannot be found.
Step 2 Download Python
If Python is not installed, download it from the official Python website.
Choose the latest supported Python 3 release available for your operating system.
Step 3 Start the Python Installation
After downloading the Python installer:
- Open your Downloads folder.
- Find the downloaded Python installer.
- Double-click the installer.
- Wait for the Python Setup window to open.
Step 4 Enable "Add Python to PATH"
On the Python installation screen, you will find an option similar to:
Enable this option before continuing with the installation.
PATH allows Windows to find Python when you type commands such as
python in Command Prompt.
Step 5 Install Python
After enabling the PATH option:
- Click Install Now.
- Allow the installer to copy the required Python files.
- Wait until the installation is completed.
- Click Close.
Step 6 Verify the Installation
Open a new Command Prompt window and execute:
python --version
You should see a Python version:
Python 3.x.x
You can also start Python directly from the Command Prompt:
python
If Python is working correctly, you will see the Python interactive
shell with the >>> prompt.
>>> print("Hello Python")
Hello Python
Exit the Python shell using:
exit()
Step 7 Open Python IDLE
IDLE is installed along with Python, so you normally do not need to install it separately.
To open IDLE in Windows:
- Open the Start Menu.
- Search for IDLE.
- You should see an entry similar to IDLE (Python 3.x).
- Click it to open IDLE.
Step 8 Understand the IDLE Shell
When IDLE opens, you will normally see a window containing the Python Shell.
The Shell allows you to execute Python statements immediately without creating a Python file.
For example, type:
>>> 10 + 20
30
You can also execute:
>>> print("Welcome to Python")
Welcome to Python
Step 9 Create a Python Program in IDLE
The Shell is useful for testing small pieces of code, but complete programs should normally be saved in a Python file.
To create a Python file:
- Open IDLE.
- Click File.
- Select New File.
A new editor window will appear.
Step 10 Write Your First Python Program
In the new IDLE editor window, type the following program:
name = "Python"
print("Welcome to", name)
This program creates a variable named name and stores the
value "Python" in it.
The print() function then displays the value on the screen.
Step 11 Save the Python Program
Python programs should be saved with the .py file extension.
- Click File.
- Select Save As.
- Choose a folder where you want to store your programs.
- Enter the file name
hello.py. - Click Save.
.py extension.
Python uses this extension to identify Python source files.
Step 12 Run the Program in IDLE
After saving the program, you can execute it directly from IDLE.
- Make sure
hello.pyis open in the IDLE editor. - Click Run from the menu.
- Select Run Module.
You can also use the keyboard shortcut:
F5
IDLE will execute the program and display the output in the Python Shell.
Welcome to Python
Step 13 Modify and Run the Program Again
One advantage of using IDLE is that you can quickly modify your program and run it again.
Change the program to:
name = "Python Programming"
print("Welcome to", name)
print("Let's start learning!")
Save the file and press F5.
The Shell will display:
Welcome to Python Programming
Let's start learning!
Step 14 Understand the Difference Between Shell and Editor
| Python Shell | Python Editor |
|---|---|
| Executes statements immediately | Used to write complete programs |
| Useful for quick experiments | Useful for larger programs |
Usually uses the >>> prompt |
Contains saved .py files |
| Results appear immediately | Program is executed using Run Module |
Step 15 Run a Python File from Command Prompt
Although IDLE is convenient for beginners, it is also important to understand how Python programs are executed from a terminal.
Open Command Prompt and navigate to the folder containing
hello.py.
Then run:
python hello.py
The output will be:
Welcome to Python Programming
Let's start learning!
Common Problems
IDLE is normally installed with the standard Python installation. If it is missing, check whether Python was installed correctly and whether the installation included IDLE.
You can also search the Start Menu for:
IDLE
This generally means Python is not available through PATH.
- Check that Python is installed.
- Close and reopen Command Prompt.
- Try
python --versionagain. - Check your Python installation and PATH configuration.
First save the Python file and make sure it has a
.py extension.
Then press F5 again or select:
Run → Run Module
Python Setup Checklist
.py file
Datatypes, Variables & Operators
Learn how Python stores data, creates variables, works with different data types, converts values, and performs operations.
Every Python program works with data. A program may need to store a person's name, calculate a salary, compare two numbers, store multiple values, or perform mathematical calculations.
Python provides variables to store or refer to values, data types to describe the kind of data being used, and operators to perform operations on that data.
Variables
A variable is a name used to refer to a value stored during program execution.
For example:
name = "Arun"
age = 22
salary = 25000.50
In this example:
namerefers to the string"Arun".agerefers to the integer22.salaryrefers to the floating-point value25000.50.
The = symbol is called the assignment operator.
It assigns a value to a variable.
= operator does not mean "equal to" in the mathematical
sense. It means that the value on the right is assigned to the variable
on the left.
Example: Using Variables
name = "Arun"
age = 22
salary = 25000.50
print(name)
print(age)
print(salary)
Arun
22
25000.5
Changing the Value of a Variable
A variable can be assigned a new value at any time.
age = 22
print(age)
age = 23
print(age)
22
23
The variable age first refers to 22 and later
refers to 23.
Multiple Assignment
Python allows multiple variables to be assigned in a single statement.
name, age, city = "Arun", 22, "Chennai"
print(name)
print(age)
print(city)
Variable Naming Rules
Python has rules that must be followed when creating variable names.
| Rule | Example |
|---|---|
| Can contain letters | studentName |
| Can contain numbers | student1 |
| Can use underscore | student_name |
| Cannot start with a number | 1student ❌ |
| Cannot contain spaces | student name ❌ |
| Cannot use Python keywords | class ❌ |
Good Variable Names
student_name = "Arun"
student_age = 22
total_salary = 35000
Python's Dynamic Typing
Python is a dynamically typed language. This means you do not need to explicitly specify the data type when creating a variable.
For example:
value = 10
value = "Python"
value = 25.5
The same variable can refer to values of different types at different points during program execution.
Python Data Types
A data type defines the kind of value that Python is working with. Different types support different operations.
Some of the most commonly used built-in Python data types are:
| Data Type | Example | Description |
|---|---|---|
int |
25 |
Whole numbers |
float |
25.50 |
Decimal numbers |
complex |
3 + 4j |
Complex numbers |
str |
"Python" |
Text or sequence of characters |
bool |
True |
Boolean values |
list |
[10, 20, 30] |
Ordered and mutable collection |
tuple |
(10, 20, 30) |
Ordered and immutable collection |
set |
{10, 20, 30} |
Collection of unique values |
dict |
{"name": "Arun"} |
Key-value collection |
NoneType |
None |
Represents the absence of a value |
Numeric Data Types
Python provides several numeric types. The most commonly used are
int, float, and complex.
Integer
The int type represents whole numbers without a decimal
component.
age = 22
quantity = 100
temperature = -5
Float
The float type represents numbers containing a decimal
component.
price = 99.50
height = 5.8
percentage = 82.75
Complex
Complex numbers contain a real part and an imaginary part.
Python uses j to represent the imaginary component.
number = 3 + 4j
print(number)
String Data Type
A str represents text. Strings can be created using single
quotes, double quotes, or triple quotes.
name = "Arun"
city = 'Chennai'
message = """Welcome to
Python Programming"""
Strings can contain letters, numbers, spaces, and special characters.
course = "Python Full Stack"
code = "PY101"
message = "Hello, Python!"
Boolean Data Type
The bool data type has only two possible values:
True and False.
is_logged_in = True
is_admin = False
print(is_logged_in)
print(is_admin)
Boolean values are commonly used with conditions and comparison operations.
Collection Data Types
Python provides several built-in collection types for storing multiple values.
| Type | Example | Mutable? | Duplicates? |
|---|---|---|---|
list |
[10, 20, 30] |
Yes | Yes |
tuple |
(10, 20, 30) |
No | Yes |
set |
{10, 20, 30} |
Yes | No |
dict |
{"name": "Arun"} |
Yes | Keys must be unique |
Checking the Data Type
Python provides the built-in type() function to determine
the type of a value or variable.
age = 22
price = 99.50
name = "Arun"
print(type(age))
print(type(price))
print(type(name))
<class 'int'>
<class 'float'>
<class 'str'>
The type() function is especially useful when debugging
programs or understanding what type of value a variable currently
contains.
Type Conversion
Sometimes a program receives a value in one data type but needs to use it as another type. Python provides built-in functions for converting compatible values.
| Function | Converts To | Example |
|---|---|---|
int() |
Integer | int("25") |
float() |
Float | float("25.5") |
str() |
String | str(25) |
bool() |
Boolean | bool(1) |
Example: String to Integer
age = "22"
age = int(age)
print(age + 5)
Without conversion, "22" is a string rather than a number.
Converting it to int allows numerical operations.
Example: Integer to String
age = 22
message = "My age is " + str(age)
print(message)
Mutable and Immutable Data
Python objects can broadly be classified as mutable or immutable.
A mutable object can be changed after it is created, while an immutable object cannot be changed after creation.
| Category | Examples | Meaning |
|---|---|---|
| Mutable | list, dict, set |
Contents can be changed |
| Immutable | int, float, str, tuple |
Object cannot be changed after creation |
This concept becomes particularly important when working with lists, functions, and object references.
Operators
Operators are symbols or keywords used to perform operations on values and variables.
Python provides several categories of operators.
| Category | Operators | Purpose |
|---|---|---|
| Arithmetic | + - * / // % ** |
Mathematical operations |
| Comparison | == != > < >= <= |
Compare values |
| Assignment | = += -= *= /= |
Assign and update values |
| Logical | and or not |
Combine logical conditions |
| Membership | in not in |
Check membership |
| Identity | is is not |
Check object identity |
| Bitwise | & | ^ ~ << >> |
Perform bit-level operations |
Arithmetic Operators
Arithmetic operators are used to perform mathematical calculations.
| Operator | Name | Example | Result |
|---|---|---|---|
+ |
Addition | 10 + 3 |
13 |
- |
Subtraction | 10 - 3 |
7 |
* |
Multiplication | 10 * 3 |
30 |
/ |
Division | 10 / 3 |
3.333... |
// |
Floor division | 10 // 3 |
3 |
% |
Modulus | 10 % 3 |
1 |
** |
Exponentiation | 2 ** 3 |
8 |
Arithmetic Example
a = 10
b = 3
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a // b)
print(a % b)
print(a ** b)
/performs normal division and returns a floating-point result.//performs floor division.%returns the remainder.**is used for exponentiation.
Comparison Operators
Comparison operators compare two values and return either
True or False.
| Operator | Meaning | Example |
|---|---|---|
== |
Equal to | 10 == 10 |
!= |
Not equal to | 10 != 5 |
> |
Greater than | 10 > 5 |
< |
Less than | 5 < 10 |
>= |
Greater than or equal to | 10 >= 10 |
<= |
Less than or equal to | 5 <= 10 |
a = 10
b = 3
print(a > b)
print(a == b)
print(a != b)
True
False
True
Assignment Operators
Assignment operators are used to assign values to variables and update their existing values.
| Operator | Example | Equivalent To |
|---|---|---|
= |
x = 10 |
Assign 10 to x |
+= |
x += 5 |
x = x + 5 |
-= |
x -= 5 |
x = x - 5 |
*= |
x *= 5 |
x = x * 5 |
/= |
x /= 5 |
x = x / 5 |
score = 100
score += 20
print(score)
Logical Operators
Logical operators are used to combine or modify Boolean expressions.
| Operator | Description |
|---|---|
and |
Returns a truthy result only when both conditions are true. |
or |
Returns a truthy result when at least one condition is true. |
not |
Reverses the Boolean truth value. |
age = 22
has_id = True
print(age >= 18 and has_id)
print(age < 18 or has_id)
print(not has_id)
Membership Operators
Membership operators check whether a value exists inside a collection such as a string, list, tuple, or set.
Python provides:
innot in
languages = ["Python", "Java", "C++"]
print("Python" in languages)
print("PHP" not in languages)
True
True
Operator Precedence
When an expression contains multiple operators, Python follows a specific order to determine which operation should be performed first.
For example:
result = 10 + 5 * 2
print(result)
Multiplication is performed before addition, so the expression is evaluated as:
10 + (5 * 2)
10 + 10
20
Parentheses can be used when you want to explicitly control the order of evaluation.
result = (10 + 5) * 2
print(result)
Common Beginner Mistakes
= assigns a value, while == compares
two values.
age = 22
print(age == 22)
A value such as "100" is a string, not an integer.
age = "22"
age = int(age)
print(age + 5)
Convert the value to the required data type before performing numerical calculations.
For example, this is invalid:
2name = "Arun"
Variable names cannot begin with a number.
Use:
name2 = "Arun"
Conditional Statements & Loops
Control the flow of your Python programs using decisions and repetition.
A Python program normally executes statements from top to bottom. However, real-world programs often need to make decisions or repeat certain operations multiple times.
For example, a program may need to check whether a student has passed, determine whether a person is eligible to vote, display different messages based on a user's age, or process every item in a list.
Python provides conditional statements for decision-making and loops for repeated execution.
if, elif, else,
nested conditions, for loops, while loops,
range(), nested loops, break,
continue, and pass.
Conditional Statements
Conditional statements allow a program to make decisions based on
whether a condition is True or False.
Python commonly uses:
ifif ... elseif ... elif ... else- Nested
ifstatements
Conditions usually contain comparison or logical operators.
The if Statement
The if statement executes a block of code only when its
condition evaluates to True.
Basic syntax:
if condition:
statement
For example:
age = 20
if age >= 18:
print("You are eligible to vote")
Since age >= 18 evaluates to True,
Python executes the indented print() statement.
Indentation in Python
Python uses indentation to define a block of code. Unlike languages that
use curly braces such as { }, Python uses whitespace to
determine which statements belong to a conditional or loop.
age = 20
if age >= 18:
print("Eligible")
print("Age requirement satisfied")
Both print() statements belong to the if block
because they are indented.
The if...else Statement
The else block is executed when the if
condition is False.
age = 16
if age >= 18:
print("You are eligible to vote")
else:
print("You are not eligible to vote")
Only one of the two blocks is executed.
The if...elif...else Statement
When there are multiple possible conditions, Python provides
elif, which means "else if".
marks = 75
if marks >= 90:
grade = "A"
elif marks >= 60:
grade = "B"
else:
grade = "C"
print(grade)
Python checks the conditions from top to bottom. Once it finds a
condition that is True, its corresponding block executes
and the remaining conditions are skipped.
Using Multiple elif Conditions
You can use multiple elif blocks when a program needs to
handle several possible outcomes.
marks = 82
if marks >= 90:
grade = "A+"
elif marks >= 80:
grade = "A"
elif marks >= 70:
grade = "B"
elif marks >= 60:
grade = "C"
else:
grade = "F"
print(grade)
Using Comparison Operators in Conditions
Conditions commonly use comparison operators such as:
| Operator | Meaning | Example |
|---|---|---|
== |
Equal to | age == 18 |
!= |
Not equal to | age != 18 |
> |
Greater than | marks > 50 |
< |
Less than | marks < 50 |
>= |
Greater than or equal to | age >= 18 |
<= |
Less than or equal to | age <= 18 |
Using Logical Operators in Conditions
Logical operators allow multiple conditions to be combined.
age = 25
has_id = True
if age >= 18 and has_id:
print("Entry allowed")
else:
print("Entry denied")
Here, both conditions must be true because the and operator
is being used.
Nested if Statements
An if statement can be placed inside another
if statement. This is called a nested if.
age = 22
has_id = True
if age >= 18:
if has_id:
print("Entry allowed")
else:
print("ID is required")
else:
print("You are underage")
The inner condition is checked only when the outer condition is true.
Practical Example: Login Validation
Conditional statements are frequently used when validating information.
username = "admin"
password = "python123"
if username == "admin" and password == "python123":
print("Login successful")
else:
print("Invalid username or password")
Loops
A loop allows a block of code to execute repeatedly.
Instead of writing the same statement many times, you can use a loop to perform the operation automatically.
Python provides two main types of loops:
forloopwhileloop
The for Loop
A for loop is used to iterate over the items of an
iterable such as a list, tuple, string, set, or range.
For example:
for number in range(1, 6):
print(number)
1
2
3
4
5
During each iteration, the variable number receives the
next value produced by range(1, 6).
Understanding range()
The range() function is commonly used with
for loops to generate a sequence of numbers.
When using two arguments, range(start, stop) begins at
start and stops before stop.
for number in range(1, 6):
print(number)
The values are:
1
2
3
4
5
range(1, 6) produces numbers from 1 through 5.
Using a Step with range()
A third argument can be used to specify how much the value should change during each iteration.
for number in range(2, 11, 2):
print(number)
2
4
6
8
10
Using for with a String
A string is iterable, so a for loop can process one
character at a time.
name = "Python"
for character in name:
print(character)
P
y
t
h
o
n
Using for with a List
A for loop can also process each item in a list.
languages = ["Python", "Java", "C++"]
for language in languages:
print(language)
Python
Java
C++
Nested for Loops
A loop can be placed inside another loop. This is called a nested loop.
for row in range(1, 4):
for column in range(1, 4):
print(row, column)
The inner loop completes all of its iterations for every iteration of the outer loop.
The while Loop
A while loop repeatedly executes a block of code as long
as its condition remains True.
Example:
count = 1
while count <= 5:
print(count)
count += 1
1
2
3
4
5
The variable count changes during every iteration.
Once the condition count <= 5 becomes false, the loop stops.
Avoiding Infinite Loops
A while loop must eventually reach a condition that becomes
false. Otherwise, it can continue running indefinitely.
For example:
count = 1
while count <= 5:
print(count)
count += 1
Here, count += 1 changes the value used by the condition.
Without an appropriate update, the condition might never become false.
while loop
can create an infinite loop.
for Loop vs while Loop
| for Loop | while Loop |
|---|---|
| Commonly used to iterate over an iterable. | Runs while a condition remains true. |
| Useful when processing a known sequence. | Useful when repetition depends on a condition. |
Often used with range(). |
Requires a condition that eventually becomes false. |
| Loop progression is usually handled by the iterator. | The programmer often needs to update a control variable. |
The break Statement
The break statement immediately terminates the current loop.
Python continues execution with the statement after the loop.
for number in range(1, 10):
if number == 5:
break
print(number)
1
2
3
4
When number becomes 5, break stops the loop.
The continue Statement
The continue statement skips the remaining statements in
the current iteration and moves to the next iteration.
for number in range(1, 6):
if number == 3:
continue
print(number)
1
2
4
5
When number becomes 3, Python skips the
print() statement for that iteration and continues with
the next value.
break vs continue
| Statement | What it does |
|---|---|
break |
Completely stops the current loop. |
continue |
Skips the current iteration and continues the loop. |
The pass Statement
The pass statement does nothing. It is used as a placeholder
when Python requires a statement but you do not want to execute any code
yet.
age = 20
if age >= 18:
pass
else:
print("Underage")
pass is useful while developing a program when a block is
planned but its implementation has not been written yet.
else with Loops
Python also allows an else block to be associated with a
loop. The else block executes when the loop finishes
normally without encountering break.
for number in range(1, 4):
print(number)
else:
print("Loop completed")
1
2
3
Loop completed
break, the loop's
else block does not execute.
Practical Example: Student Result
Conditional statements and loops are often combined to solve practical problems.
The following example checks the result of multiple students:
marks = [85, 72, 45, 91, 38]
for mark in marks:
if mark >= 50:
print(mark, "Pass")
else:
print(mark, "Fail")
85 Pass
72 Pass
45 Fail
91 Pass
38 Fail
Here, the for loop processes every mark, while the
if...else statement determines whether each student
has passed or failed.
Practical Example: Finding Even Numbers
The modulus operator can be combined with a loop and a condition to identify even numbers.
for number in range(1, 11):
if number % 2 == 0:
print(number)
2
4
6
8
10
Common Beginner Mistakes
Python requires a colon after conditions and loop statements.
if age >= 18:
print("Eligible")
Statements belonging to a block must have consistent indentation.
if age >= 18:
print("Eligible")
print("You can continue")
Make sure the condition of a while loop can
eventually become false.
count = 1
while count <= 5:
print(count)
count += 1
Updating count allows the condition to eventually
become false.
breakstops the entire loop.continueskips only the current iteration.
Python Functions
Create reusable, organized, and maintainable blocks of code.
A function is a reusable block of code designed to perform a specific task. Instead of writing the same logic repeatedly, you can place it inside a function and call that function whenever you need it.
Functions are one of the most important concepts in Python because they help break a large program into smaller and more manageable parts.
For example, an application may contain separate functions for calculating salary, validating a user, calculating an order total, sending a message, or processing data.
- Reduce code repetition
- Divide a large program into smaller tasks
- Improve code readability
- Make code easier to test and debug
- Allow the same logic to be reused multiple times
- Make programs easier to maintain
Understanding a Function
A Python function is created using the def keyword.
The function has a name, optional parameters, and a block of statements.
def function_name(parameters):
statements
return value
| Part | Purpose |
|---|---|
def |
Keyword used to define a function. |
| Function name | Name used to identify and call the function. |
| Parameters | Input values accepted by the function. |
: |
Marks the beginning of the function block. |
| Function body | Contains the statements that perform the task. |
return |
Optionally sends a value back to the caller. |
Creating a Function
The following function displays a welcome message:
def greet():
print("Welcome to Python")
greet()
The function is defined using def greet():.
The statement inside the function is executed only when
greet() is called.
Defining and Calling a Function
There is an important difference between defining a function and calling a function.
Defining
Defining a function means creating the function and specifying what it should do.
def greet():
print("Hello")
Calling
Calling a function means executing the function.
greet()
Parameters and Arguments
Functions can accept values from the code that calls them. These values are commonly referred to as arguments.
A parameter is the variable defined inside the function definition, while an argument is the actual value passed when the function is called.
def greet(name):
print("Hello", name)
greet("Arun")
greet("Priya")
Hello Arun
Hello Priya
Here, name is the parameter, while
"Arun" and "Priya" are arguments.
Multiple Parameters
A function can accept multiple parameters. Each parameter can represent a different piece of information required by the function.
def student(name, age, course):
print("Name:", name)
print("Age:", age)
print("Course:", course)
student("Arun", 22, "Python")
Name: Arun
Age: 22
Course: Python
Returning a Value
A function can perform a calculation and send the result back to the
part of the program that called it. The return statement
is used for this purpose.
def add(a, b):
return a + b
result = add(10, 20)
print(result)
The value returned by add() is stored in the
result variable.
print() vs return
Beginners often confuse print() and return.
They serve different purposes.
print() |
return |
|---|---|
| Displays a value on the screen. | Sends a value back to the caller. |
| Mainly used for displaying information. | Used when another part of the program needs the result. |
| Does not normally provide the displayed value to another operation. | The returned value can be stored, calculated, or passed elsewhere. |
For reusable logic, return is often more useful than simply
printing the result.
Returning Multiple Values
Python allows a function to return multiple values. Internally, Python packages the returned values together, and they can be assigned to multiple variables.
def calculate(a, b):
total = a + b
difference = a - b
return total, difference
result, difference = calculate(20, 5)
print(result)
print(difference)
25
15
Default Arguments
A parameter can have a default value. If the caller does not provide a value for that parameter, Python uses the default value.
def greet(name="Student"):
print("Hello", name)
greet()
greet("Arun")
Hello Student
Hello Arun
In the first call, no value is supplied, so Python uses
"Student".
Keyword Arguments
Keyword arguments allow you to pass values by explicitly specifying the parameter name.
def student(name, age):
print("Name:", name)
print("Age:", age)
student(age=22, name="Arun")
Name: Arun
Age: 22
Notice that the arguments are supplied in a different order from the function definition. Because the parameter names are specified, Python knows which value belongs to which parameter.
Positional Arguments
Positional arguments are assigned to parameters according to their position.
def student(name, age):
print(name)
print(age)
student("Arun", 22)
The first argument is assigned to name and the second
argument is assigned to age.
Positional vs Keyword Arguments
| Type | Example | How values are assigned |
|---|---|---|
| Positional | student("Arun", 22) |
Based on position. |
| Keyword | student(age=22, name="Arun") |
Based on parameter name. |
Variable Scope in Functions
The scope of a variable determines where that variable can be accessed. Variables created inside a function are generally local to that function.
def calculate():
result = 100
print(result)
calculate()
The variable result belongs to the function's local scope.
It is available inside the function where it was created.
Local and Global Variables
A variable created outside a function is generally considered a global variable, while a variable created inside a function is local to that function.
course = "Python"
def display():
name = "Arun"
print(course)
print(name)
display()
The function can access the global course variable and its
own local name variable.
Calling One Function from Another
Functions can call other functions. This makes it possible to divide a larger task into smaller reusable operations.
def calculate_total(price, quantity):
return price * quantity
def display_bill():
total = calculate_total(500, 3)
print("Total:", total)
display_bill()
Here, display_bill() calls
calculate_total() to perform the calculation.
Common Beginner Mistakes
Defining a function does not automatically execute it. You must call it when you want its code to run.
def greet():
print("Hello")
greet()
If another part of the program needs the result of a calculation, the function should normally return that value.
def add(a, b):
return a + b
The number of required positional arguments should normally match the parameters defined by the function.
def add(a, b):
return a + b
add(10, 20)
Parameters are defined in the function declaration, while arguments are the actual values supplied during the function call.
Function Best Practices
Keep Functions Focused
A function should ideally perform one clear responsibility rather than trying to handle many unrelated tasks.
Use Meaningful Names
Names such as calculate_total() and
validate_user() make the purpose of a function clear.
Avoid Unnecessary Repetition
If the same logic appears in multiple places, consider moving it into a reusable function.
Return Results When Appropriate
Returning values allows the calling code to decide how the result should be displayed or processed.
Modules & Packages
Organize Python programs into reusable components.
As applications become larger, keeping every function and class in a single file becomes difficult. Python modules and packages provide a way to organize code into reusable components.
Using a Built-in Module
import math
print(math.sqrt(25))
print(math.pi)
Importing Specific Functions
from math import sqrt
print(sqrt(36))
Module Alias
import math as m
print(m.sqrt(49))
Custom Modules
Suppose we create a file named
calculator.py:
def add(a, b):
return a + b
Another Python file can import and use that function:
import calculator
print(calculator.add(10, 20))
Python Data Structures
Store, organize and manipulate collections of data efficiently.
A data structure determines how multiple values are stored, organized, accessed and modified inside a program. Choosing the correct data structure can make a program easier to understand and more efficient.
Python provides several built-in data structures. The four most commonly
used collection types are list, tuple,
set and dictionary.
Python's Built-in Collection Types
| Data Structure | Ordered | Mutable | Allows Duplicates | Access Method |
|---|---|---|---|---|
list |
Yes | Yes | Yes | Index |
tuple |
Yes | No | Yes | Index |
set |
No* | Yes | No | Membership |
dict |
Yes** | Yes | Keys must be unique | Key |
* Sets are unordered collections and should not be used when positional
order is required.
** Dictionaries preserve insertion order in modern Python versions.
Lists
A list is an ordered and mutable collection. It can contain multiple values and those values can be changed after the list is created.
Lists can contain values of the same type or different types.
students = ["Arun", "Priya", "Kumar"]
print(students)
List Indexing
Every element in a list has a position called an index. Python uses
zero-based indexing, so the first element has index 0.
| Value | Arun | Priya | Kumar | Meena |
|---|---|---|---|---|
| Positive Index | 0 | 1 | 2 | 3 |
| Negative Index | -4 | -3 | -2 | -1 |
students = ["Arun", "Priya", "Kumar", "Meena"]
print(students[0])
print(students[2])
print(students[-1])
Arun
Kumar
Meena
Modifying List Elements
Lists are mutable, so individual elements can be changed using their index.
students = ["Arun", "Priya", "Kumar"]
students[1] = "Meena"
print(students)
Common List Methods
| Method | Purpose | Example |
|---|---|---|
append() |
Adds an element to the end. | items.append(50) |
insert() |
Inserts an element at a specific position. | items.insert(1, 20) |
extend() |
Adds multiple elements. | items.extend([60, 70]) |
remove() |
Removes the first matching value. | items.remove(20) |
pop() |
Removes and returns an element. | items.pop() |
sort() |
Sorts the list. | items.sort() |
reverse() |
Reverses the list. | items.reverse() |
count() |
Counts occurrences of a value. | items.count(20) |
index() |
Returns the position of a value. | items.index(20) |
clear() |
Removes all elements. | items.clear() |
Tuples
A tuple is an ordered and immutable collection. Like lists, tuples support indexing and slicing, but their elements cannot normally be changed after creation.
coordinates = (10, 20, 30)
print(coordinates[0])
print(coordinates[-1])
10
30
Tuple Immutability
Because tuples are immutable, an existing element cannot simply be replaced.
coordinates = (10, 20, 30)
# coordinates[0] = 50
Tuple Methods
Since tuples cannot be modified, they have fewer methods than lists.
Two commonly used methods are count() and
index().
numbers = (10, 20, 20, 30)
print(numbers.count(20))
print(numbers.index(30))
2
3
Sets
A set is a mutable collection that stores unique values. Duplicate elements are automatically removed.
numbers = {10, 20, 20, 30, 30}
print(numbers)
Adding Elements to a Set
numbers = {10, 20, 30}
numbers.add(40)
print(numbers)
Removing Elements from a Set
Sets provide methods such as remove() and
discard().
numbers = {10, 20, 30}
numbers.remove(20)
print(numbers)
remove() raises an error if the element does not exist,
while discard() does not.
Dictionaries
A dictionary stores data as key-value pairs. Each key identifies a corresponding value.
student = {
"name": "Arun",
"age": 22,
"course": "Python"
}
print(student["name"])
print(student["course"])
Arun
Python
Dictionary Keys and Values
A dictionary consists of keys and values. Keys must be unique, while values can be duplicated.
student = {
"name": "Arun",
"age": 22,
"course": "Python"
}
print(student.keys())
print(student.values())
print(student.items())
Adding and Updating Dictionary Data
Dictionaries are mutable. A new key-value pair can be added, and an existing value can be updated using its key.
student = {
"name": "Arun",
"age": 22
}
student["course"] = "Python"
student["age"] = 23
print(student)
Common Dictionary Methods
| Method | Purpose |
|---|---|
get() |
Returns the value associated with a key. |
keys() |
Returns dictionary keys. |
values() |
Returns dictionary values. |
items() |
Returns key-value pairs. |
update() |
Adds or updates multiple key-value pairs. |
pop() |
Removes a key and returns its value. |
popitem() |
Removes and returns the last inserted key-value pair. |
clear() |
Removes all key-value pairs. |
Nested Data Structures
Python data structures can contain other data structures. This is useful when representing real-world data.
students = [
{
"name": "Arun",
"age": 22,
"course": "Python"
},
{
"name": "Priya",
"age": 21,
"course": "Java"
}
]
print(students[0]["name"])
print(students[1]["course"])
Arun
Java
This type of structure is commonly encountered when working with JSON data, APIs and database records.
List of Lists
A list can also contain other lists. This is useful for representing table-like or matrix-style data.
marks = [
[80, 75, 90],
[70, 85, 88],
[90, 92, 95]
]
print(marks[0][1])
Mutable vs Immutable
One of the most important concepts when working with Python data structures is mutability.
A mutable object can be changed after it is created. An immutable object cannot normally be changed after creation.
| Data Type | Mutable? |
|---|---|
| List | Yes |
| Tuple | No |
| Set | Yes |
| Dictionary | Yes |
| String | No |
Which Data Structure Should You Use?
| Requirement | Recommended Structure | Reason |
|---|---|---|
| Ordered collection that changes | list |
Ordered and mutable. |
| Fixed collection of values | tuple |
Ordered and immutable. |
| Unique values | set |
Automatically eliminates duplicates. |
| Key-value information | dict |
Values can be accessed using meaningful keys. |
| Student records | list + dict |
Multiple records can be stored as dictionaries inside a list. |
| Unique user roles | set |
Duplicate roles are automatically avoided. |
| Coordinates | tuple |
Coordinates normally represent fixed values. |
Common Mistakes
OOP Concepts: Classes, Objects, Inheritance & Polymorphism
Understand how Python uses objects to organize data and behavior.
Object-Oriented Programming, commonly called OOP, is a programming approach where data and the operations performed on that data are organized into objects.
Instead of writing an entire program as a collection of unrelated functions, OOP allows us to model real-world entities such as students, employees, customers, products and vehicles as objects.
Python supports several important OOP concepts including classes, objects, attributes, methods, constructors, inheritance and polymorphism.
Classes and Objects
A class defines the properties and behaviors that its objects will have. It acts like a blueprint for creating objects.
An object is an actual instance of a class. Multiple objects can be created from the same class, and each object can contain different data.
Example:
- Class: Student
- Objects: Arun, Priya, Kumar
- Attributes: name, age, course
- Methods: study(), attend_class()
class Student:
def greet(self):
print("Hello Student")
student1 = Student()
student1.greet()
Here, Student is the class and
student1 is an object created from that class.
The greet() method defines a behavior that the object can
perform.
Understanding self
The self parameter refers to the current object. It allows
methods inside a class to access the attributes and other methods
belonging to that particular object.
class Student:
def greet(self):
print("Hello", self)
student1 = Student()
student2 = Student()
student1.greet()
student2.greet()
When student1.greet() is called,
self refers to student1. When
student2.greet() is called, self refers to
student2.
self is not a separate object. It is a reference to the
current object on which the method is being called.
Attributes and Methods
An object generally contains two important types of information: attributes and methods.
| Term | Meaning | Example |
|---|---|---|
| Attribute | Data or property belonging to an object. | student.name |
| Method | Function defined inside a class. | student.greet() |
Constructor: __init__()
The __init__() method is commonly used to initialize the
attributes of an object when it is created.
It is automatically called when a new object is created from the class. This allows each object to start with its own initial data.
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student = Student("Arun", 22)
print(student.name)
print(student.age)
Arun
22
In this example, name and age are attributes of
the object. The values "Arun" and 22 are passed
when the object is created.
Creating Multiple Objects
A single class can be used to create multiple objects. Each object can contain different attribute values.
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student1 = Student("Arun", 22)
student2 = Student("Priya", 21)
print(student1.name)
print(student2.name)
Arun
Priya
Both objects belong to the same Student class, but they
contain different data.
Inheritance
Inheritance allows one class to acquire properties and methods from another class.
The existing class is called the parent class or base class. The class that inherits from it is called the child class or derived class.
Inheritance is useful when different classes share common functionality. Instead of writing the same code repeatedly, the common functionality can be placed in a parent class.
class Animal:
def speak(self):
print("Animal makes a sound")
class Dog(Animal):
def bark(self):
print("Dog barks")
dog = Dog()
dog.speak()
dog.bark()
Animal makes a sound
Dog barks
Dog inherits from Animal. Therefore, the
Dog object can use the speak() method inherited
from Animal, in addition to its own bark()
method.
Common Types of Inheritance
Python supports different inheritance relationships depending on how classes are connected.
| Type | Description |
|---|---|
| Single Inheritance | One child class inherits from one parent class. |
| Multilevel Inheritance | A class inherits from a class that already inherits from another class. |
| Multiple Inheritance | A child class inherits from more than one parent class. |
| Hierarchical Inheritance | Multiple child classes inherit from the same parent class. |
Method Overriding
Method overriding occurs when a child class provides its own implementation of a method that already exists in the parent class.
This allows the child class to change or specialize the behavior inherited from the parent.
class Animal:
def sound(self):
print("Animal sound")
class Dog(Animal):
def sound(self):
print("Bark")
dog = Dog()
dog.sound()
Although Animal contains a sound() method,
Dog provides its own version. Therefore, when
dog.sound() is called, the implementation in
Dog is executed.
Using super()
The super() function can be used to access methods or
functionality from the parent class.
class Animal:
def sound(self):
print("Animal sound")
class Dog(Animal):
def sound(self):
super().sound()
print("Bark")
dog = Dog()
dog.sound()
Animal sound
Bark
Here, super().sound() calls the parent class implementation
before the child class adds its own behavior.
Polymorphism
Polymorphism means "many forms". In OOP, it allows the same method or operation to produce different behavior depending on the object that is using it.
This is useful when different classes provide the same method name but implement that method differently.
class Dog:
def sound(self):
print("Bark")
class Cat:
def sound(self):
print("Meow")
animals = [Dog(), Cat()]
for animal in animals:
animal.sound()
Bark
Meow
The loop does not need to know whether the object is a
Dog or a Cat. It simply calls
sound(). Python automatically uses the implementation
belonging to the current object.
Encapsulation
Encapsulation means keeping data and the methods that operate on that data together inside a class. It also helps control how an object's internal data is accessed or modified.
Python uses naming conventions such as a single underscore
(_name) and double underscore (__name) to
indicate protected or private-like attributes.
class BankAccount:
def __init__(self, balance):
self.__balance = balance
def show_balance(self):
print(self.__balance)
account = BankAccount(5000)
account.show_balance()
The double underscore makes __balance name-mangled by
Python, which helps prevent direct accidental access from outside the
class.
Abstraction
Abstraction means exposing only the necessary details while hiding unnecessary implementation details.
For example, when using a car, a driver uses the steering wheel, accelerator and brakes without needing to understand every internal operation of the engine.
Python provides the abc module for creating abstract
classes and abstract methods.
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
print("Bark")
dog = Dog()
dog.sound()
Four Major Principles of OOP
| Principle | Purpose | Python Example |
|---|---|---|
| Encapsulation | Organizes and controls access to data and behavior. | Classes and private-like attributes |
| Inheritance | Allows classes to reuse functionality from other classes. | class Dog(Animal) |
| Polymorphism | Allows the same interface to have different implementations. | animal.sound() |
| Abstraction | Hides implementation details and exposes essential behavior. | Abstract classes |
Exception Handling in Python
Handle runtime errors safely and prevent applications from stopping unexpectedly.
An exception is an event that occurs while a program is running and interrupts the normal flow of execution. Exceptions commonly occur when a program receives invalid input, performs an invalid operation, or tries to access something that does not exist.
For example, dividing a number by zero, converting invalid text into an integer, or opening a file that does not exist can cause exceptions.
Python provides try, except,
else, finally and raise to
handle and control exceptions.
Errors and Exceptions
During Python programming, you may encounter different types of problems. Some problems occur before the program can execute, while others occur during execution.
| Type | When It Occurs | Example |
|---|---|---|
| Syntax Error | When Python syntax is written incorrectly. | Missing colon after an if statement |
| Exception | During program execution. | Dividing a number by zero |
Exception handling mainly deals with problems that occur while the program is running.
Basic try-except
The try block contains code that may produce an exception.
If an exception occurs, Python stops executing the remaining statements
inside the try block and looks for a matching
except block.
try:
number = int(input("Enter a number: "))
print(10 / number)
except ZeroDivisionError:
print("Cannot divide by zero")
Enter a number: 0
Cannot divide by zero
If the user enters 0, Python raises a
ZeroDivisionError. The except block catches
that exception and displays a meaningful message instead of allowing
the program to terminate with an unhandled exception.
How try-except Works
try block.
try block.
except block that matches the
exception.
Common Python Exceptions
Python provides many built-in exception types. Each exception represents a particular type of runtime problem.
| Exception | Meaning | Example Situation |
|---|---|---|
ValueError |
Value has an inappropriate format. | Converting "abc" to an integer |
TypeError |
Operation is performed on an incompatible type. | Adding a string and an integer |
ZeroDivisionError |
Division or modulo operation uses zero. | 10 / 0 |
IndexError |
Sequence index does not exist. | Accessing an unavailable list index |
KeyError |
Dictionary key does not exist. | Accessing a missing dictionary key |
FileNotFoundError |
Requested file cannot be found. | Opening a file that does not exist |
Handling Multiple Exceptions
A single block of code may produce different types of exceptions.
Python allows multiple except blocks so that each exception
can be handled appropriately.
try:
number = int(input("Enter a number: "))
result = 10 / number
print(result)
except ValueError:
print("Please enter a valid number")
except ZeroDivisionError:
print("Number cannot be zero")
- If the user enters
abc, aValueErroroccurs. - If the user enters
0, aZeroDivisionErroroccurs. - If the user enters
5, the calculation executes normally.
Using separate except blocks makes it possible to provide
a different response for each type of problem.
Accessing the Exception Message
The as keyword can be used to store the exception object in
a variable. This allows the program to inspect or display information
about the error.
try:
number = int("abc")
except ValueError as error:
print("Error:", error)
This technique is useful when you need more information about the exception while debugging or logging an application.
else and finally
Python also provides else and finally blocks
to give more control over exception handling.
-
elseexecutes only when no exception occurs. -
finallyexecutes whether an exception occurs or not.
try:
number = int(input("Enter number: "))
except ValueError:
print("Invalid input")
else:
print("You entered:", number)
finally:
print("Program completed")
Enter number: 25
You entered: 25
Program completed
Understanding the Execution Flow
| Situation | try | except | else | finally |
|---|---|---|---|---|
| No exception | Executed | Skipped | Executed | Executed |
| Exception occurs | Stops at exception | Executed if matched | Skipped | Executed |
finally block is commonly used for cleanup operations
that should happen regardless of whether the operation succeeded or
failed.
Why Use finally?
The finally block is useful when some operation must be
performed regardless of the result. For example, a program may need to
close a file, release a resource, or disconnect from a service.
try:
print("Processing data")
except Exception:
print("Something went wrong")
finally:
print("Cleanup completed")
Raising an Exception
Normally, Python raises exceptions when it detects a problem during execution. However, sometimes the programmer needs to deliberately generate an exception when a specific condition is not acceptable.
The raise statement is used to explicitly raise an
exception.
age = -5
if age < 0:
raise ValueError("Age cannot be negative")
ValueError: Age cannot be negative
This is useful when a program has a business rule or validation rule. For example, an application may reject a negative age, an invalid salary, or an empty username.
Using raise with try-except
An exception raised using raise can also be handled using
try-except.
try:
age = -5
if age < 0:
raise ValueError("Age cannot be negative")
except ValueError as error:
print(error)
Custom Exceptions
Python also allows developers to create their own exception classes. Custom exceptions are useful when an application contains specific business rules that are not clearly represented by Python's built-in exceptions.
class InvalidAgeError(Exception):
pass
age = -2
if age < 0:
raise InvalidAgeError("Age cannot be negative")
Here, InvalidAgeError is a custom exception created by
inheriting from Python's built-in Exception class.
Catching a General Exception
A general except Exception can catch many common runtime
exceptions. However, specific exceptions are usually preferred because
they make the program easier to understand and debug.
try:
result = 10 / 0
except Exception as error:
print("An error occurred:", error)
Exception Handling Best Practices
ValueError, TypeError,
FileNotFoundError, etc., when you know what can occur.
except blocks because they can make debugging
difficult.
finally when an operation must happen regardless of
success or failure.
raise when your application needs to reject invalid
data or business conditions.
File Handling in Python
Read, write, update and manage files using Python.
File handling is used when a Python program needs to store or retrieve information from files. Unlike variables, which hold data temporarily while a program is running, files allow information to be stored permanently on a storage device.
For example, a program can use files to store student records, employee information, application logs, configuration data, reports and other information.
Python provides the built-in open() function for opening
files. After opening a file, we can read from it, write to it, append
data to it, and finally close it.
Basic File Handling Process
Working with a file generally involves a few important steps:
open() function.
Opening a File
Python uses the open() function to open a file.
The function returns a file object that can be used to perform operations
on the file.
file = open("message.txt", "r")
Here, message.txt is the file name and
"r" specifies that the file should be opened in
read mode.
File Modes
The second argument of open() determines what operation
Python should perform on the file.
| Mode | Purpose | Important Behavior |
|---|---|---|
r |
Read | File must already exist. |
w |
Write | Creates a file or replaces existing content. |
a |
Append | Adds new content to the end of the file. |
x |
Create | Creates a new file and fails if the file already exists. |
r+ |
Read and write | Allows both reading and writing. |
b |
Binary mode | Used for binary data such as images or other binary files. |
w mode:
Opening an existing file in write mode removes its previous content
before writing new data.
Writing to a File
The write() method is used to store text inside a file.
When a file is opened using w mode, Python creates the file
if it does not already exist.
file = open("message.txt", "w")
file.write("Welcome to Python")
file.close()
After executing this program, a file named
message.txt will contain:
Writing Multiple Lines
Multiple lines can be written by including newline characters
(\n) between the lines.
file = open("students.txt", "w")
file.write("Arun\n")
file.write("Priya\n")
file.write("Kumar\n")
file.close()
The \n character moves the next text to a new line.
Arun
Priya
Kumar
Reading a File
The read() method reads the contents of a file. The file
must normally be opened in r mode for reading.
file = open("message.txt", "r")
content = file.read()
print(content)
file.close()
Different Ways to Read a File
Python provides several methods for reading file contents. The method you choose depends on how much data you need to process at a time.
| Method | Purpose |
|---|---|
read() |
Reads the entire file or a specified number of characters. |
readline() |
Reads one line at a time. |
readlines() |
Reads all lines and returns them as a list. |
Appending Data to a File
The a mode is used when you want to add new content without
removing the existing content.
file = open("students.txt", "a")
file.write("Meena\n")
file.close()
If the file already contains:
Arun
Priya
Kumar
After appending Meena, the file becomes:
Arun
Priya
Kumar
Meena
w replaces existing content, while a
preserves existing content and adds new data at the end.
File Paths
Python can work with files located in the same folder as the Python program or in another directory.
When only the file name is provided, Python looks for the file relative to the program's current working directory.
with open("data.txt", "r") as file:
content = file.read()
You can also specify a path to a file located inside another folder.
with open("data/students.txt", "r") as file:
content = file.read()
r"C:\Users\Student\data.txt" can help avoid problems
caused by backslashes being interpreted as escape characters.
Text Files and Binary Files
Python can work with both text files and binary files.
| Type | Examples | Mode |
|---|---|---|
| Text | .txt, .csv, .json |
r, w, a |
| Binary | Images, PDFs and other binary data | rb, wb |
Binary mode is useful when the file contains data that should not be interpreted as ordinary text.
File Handling Best Practices
with open():
It automatically closes the file after the operation.
r for reading, w for replacing content
and a for adding content.
w:
It can overwrite existing file contents.
encoding="utf-8" when appropriate for text files.
List Comprehension
Create lists using concise expressions.
List comprehension provides a short and readable way to create a new list
from an existing iterable such as a list, tuple, range, or string.
Instead of writing a separate for loop and using
append(), the expression and loop can be written in a
single line.
Traditional Approach
Normally, we create an empty list and use a for loop to add
each calculated value to it.
numbers = [1, 2, 3, 4, 5]
squares = []
for number in numbers:
squares.append(number * number)
print(squares)
Using List Comprehension
The same operation can be written more compactly using list comprehension.
The expression number * number is applied to every item in
numbers.
numbers = [1, 2, 3, 4, 5]
squares = [number * number for number in numbers]
print(squares)
List Comprehension with Condition
A condition can also be added to a list comprehension. This allows us to include only the items that satisfy a particular condition.
numbers = range(1, 11)
even_numbers = [
number for number in numbers
if number % 2 == 0
]
print(even_numbers)
for loop may make the code easier to read.
Lambda Functions
Work with small anonymous functions.
A lambda function is a small anonymous function that can perform a simple
operation without defining a function using def.
It is generally used when a function is needed for a short operation,
especially when working with functions such as sorted(),
map(), and filter().
Basic Lambda Function
A lambda function can accept parameters and return the result of an
expression. In the example below, the function receives x
and returns its square.
square = lambda x: x * x
print(square(5))
Lambda with Multiple Parameters
A lambda function can accept more than one parameter. Here,
a and b are passed to the function and their
values are added together.
add = lambda a, b: a + b
print(add(10, 20))
Lambda with sorted()
Lambda functions are commonly used with sorted() when the
sorting should be based on a particular value inside each item.
In this example, students are sorted according to their marks.
students = [
("Arun", 80),
("Priya", 95),
("Kumar", 70)
]
students.sort(key=lambda student: student[1])
print(students)
def is usually clearer.
Decorators in Python
Add extra functionality to functions without modifying their original code.
Decorators are used to modify or extend the behavior of an existing function without changing its original implementation. They are commonly used when the same additional functionality needs to be applied to multiple functions.
Python treats functions as objects, which means a function can be passed as an argument to another function and can also be returned from a function. Decorators use this feature to wrap an existing function with additional behavior.
Basic Structure of a Decorator
A decorator normally contains another function inside it. The inner function is responsible for adding the extra behavior and then calling the original function.
def decorator_function(original_function):
def wrapper():
# Additional behavior
original_function()
return wrapper
Here, original_function represents the function that we want
to modify, while wrapper() contains the additional behavior.
Creating a Simple Decorator
Consider a situation where several functions need to display a welcome message before they execute. Instead of repeating the same statement in every function, we can place it inside a decorator.
def welcome(func):
def wrapper():
print("Welcome")
func()
return wrapper
def message():
print("Python Tutorial")
message = welcome(message)
message()
Python Tutorial
The welcome() function receives message as an
argument. It creates a wrapper function that prints
Welcome and then calls the original message()
function.
Using the @ Decorator Syntax
Python provides a shorter syntax for applying a decorator. Instead of
assigning the decorated function manually, we can place the decorator
name above the function using the @ symbol.
def welcome(func):
def wrapper():
print("Welcome")
func()
return wrapper
@welcome
def message():
print("Python Tutorial")
message()
Python Tutorial
The statement @welcome tells Python to apply the
welcome decorator to the message() function.
Internally, Python performs the equivalent of:
message = welcome(message)
Decorator with Function Arguments
Decorators can also be used with functions that accept arguments. In this case, the wrapper should accept the required arguments and pass them to the original function.
def display(func):
def wrapper(name):
print("Student Information")
func(name)
return wrapper
@display
def student(name):
print("Student:", name)
student("Arun")
Student: Arun
Practical Uses of Decorators
Decorators are widely used in Python applications and frameworks because they allow common functionality to be added without repeating code.
Decorator Best Practices
functools.wraps():
Preserve the original function's name and documentation.
Generators & Iterators
Understand iteration and memory-efficient value generation.
Iterators and generators are used in Python to process values one at a time. They are especially useful when working with collections, sequences and large amounts of data.
An iterator keeps track of its current position and provides the next
value when requested. A generator is a simple way to create an iterator
using the yield keyword.
What Is an Iterable?
An iterable is an object whose elements can be accessed one at a time. Python provides many built-in iterable objects such as lists, tuples, strings, sets and dictionaries.
A for loop can be used to automatically iterate through the
values of an iterable.
numbers = [10, 20, 30]
for number in numbers:
print(number)
20
30
The list numbers is an iterable because Python can access
each of its elements one by one.
Iterator
An iterator is an object that keeps track of its current
position while going through a collection. The iter()
function can be used to create an iterator from an iterable.
numbers = [10, 20, 30]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
20
30
The next() function requests the next value from the
iterator. Each time it is called, the iterator moves to the next
element.
next() is called after all values have been consumed,
Python raises a StopIteration exception.
Using an Iterator with a for Loop
Although next() can be used manually, Python's
for loop automatically handles the iteration process.
numbers = [10, 20, 30]
iterator = iter(numbers)
for number in iterator:
print(number)
20
30
Generator
A generator is a special type of iterator that produces
values one at a time. Generators are created using a function containing
the yield keyword.
Unlike return, which ends a function completely,
yield pauses the function and remembers its current state.
When the next value is requested, the function continues from where it
stopped.
def numbers():
yield 1
yield 2
yield 3
for number in numbers():
print(number)
2
3
Using next() with a Generator
Since a generator is an iterator, we can also use next()
to request each value individually.
def numbers():
yield 10
yield 20
yield 30
values = numbers()
print(next(values))
print(next(values))
print(next(values))
20
30
yield vs return
Both yield and return can produce a value from a
function, but they behave differently.
| Feature | return |
yield |
|---|---|---|
| Purpose | Returns a result and ends the function. | Produces a value and pauses the function. |
| Execution | Function stops immediately. | Function can continue from where it stopped. |
| Values | Normally returns a result at a time. | Can produce multiple values one at a time. |
| Memory | May require storing a complete collection if multiple values are created. | Produces values only when required. |
Generator Expression
Python also provides generator expressions, which have a syntax similar to list comprehensions. The main difference is that a generator expression produces values one at a time instead of creating the complete list immediately.
numbers = (number * number for number in range(1, 6))
for number in numbers:
print(number)
4
9
16
25
[] create a list comprehension, while
parentheses () create a generator expression.
Why Use Generators?
Generators are useful when a program needs to process a large amount of data. Instead of creating and storing every value at once, a generator produces each value only when it is needed.
yield keyword makes it easier to create custom
iterators.
Iterable vs Iterator vs Generator
| Concept | Description | Example |
|---|---|---|
| Iterable | An object whose elements can be accessed one at a time. | List, tuple, string |
| Iterator | An object that produces the next value using next(). |
iter(list) |
| Generator | A convenient way to create an iterator using yield. |
Generator function |
Generator & Iterator Best Practices
yield for sequences:
It is useful when a function needs to produce multiple values gradually.
for loops when possible:
Python automatically handles the iterator process and
StopIteration.
Virtual Environments
Isolate project dependencies and Python packages.
A virtual environment is an isolated environment used to install Python packages for a specific project. It helps prevent package conflicts between different Python projects.
For example, one project may require a particular version of a library, while another project may require a different version. Virtual environments allow both projects to maintain their own packages.
Creating a Virtual Environment
Python provides the venv module to create a virtual
environment.
python -m venv myenv
Here, myenv is the name of the virtual environment.
You can choose a different name if required.
Activating on Windows
After creating the environment, activate it using the following command:
myenv\Scripts\activate
Once activated, packages installed using pip will be
installed inside this virtual environment.
Activating on Linux / macOS
source myenv/bin/activate
Installing a Package
After activating the environment, you can install packages using
pip.
pip install requests
The requests package will be installed in the active
virtual environment rather than globally.
Saving Project Dependencies
The installed packages can be saved in a
requirements.txt file. This makes it easier to recreate
the same environment on another computer.
pip freeze > requirements.txt
Another developer can install all the packages listed in the file using:
pip install -r requirements.txt
Deactivating the Environment
When you finish working on the project, you can leave the virtual
environment using the deactivate command.
deactivate
Basic Virtual Environment Workflow
python -m venv myenv.
pip install.