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

Python

The document provides an overview of Python programming concepts, including tokens, keywords, identifiers, literals, operators, variables, and constants. It explains the rules for naming variables, the importance of case sensitivity, and best practices for avoiding name errors. Additionally, it covers data types in Python, specifically strings, and their properties such as immutability and indexing.

Uploaded by

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

Python

The document provides an overview of Python programming concepts, including tokens, keywords, identifiers, literals, operators, variables, and constants. It explains the rules for naming variables, the importance of case sensitivity, and best practices for avoiding name errors. Additionally, it covers data types in Python, specifically strings, and their properties such as immutability and indexing.

Uploaded by

gguy3911
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 291

Token, Keywords and Operators

Token
In Python, a token is the smallest meaningful unit of code. Just like words make up
sentences, tokens come together to form Python statements and instructions. These
tokens can be categorized into different types, each serving a specific purpose:
Keywords: These are reserved words with special meanings in Python.You cannot
use them for variable names or other purposes. Examples include:

and as assert async continue


else if not while def
except import or with del
finally in pass yield elif
for is raise await false
from lambda return break none
global nonlocal try class true
Identifier
 A Python identifier is a name used to identify a variable, function, class,
module or other object.
 An identifier starts with a letter A to Z or a to z or an underscore (_)
followed by zero or more letters, underscores and digits (0 to 9).
 Python does not allow punctuation characters such as @, $, and % within
identifiers.
 Python is a case sensitive programming language. Thus, Hari and hari are
two different identifiers in Python.
Literals: Represent constant values directly included in the code. These can be
strings enclosed in quotes, numbers (integers, floats), Boolean values (True or
False), and special literals like None.
 Strings
Strings are one of the most common data value types you will work with in Python, and there are
many ways to format strings, and literals support all of them.
 Numeric
Numeric values are another value you will find yourself working with often.
 Booleans
Boolean values are beneficial, especially in the source code of your software, as they are frequently
used to set operating parameters.
 Collections
Collections are also helpful, and the fact is you will likely need them to store collections of data in your
source code.
 Special
Special literal is used to signify a null value, and the None keyword can be used in a literal when you
need a value to be null or — no value.
Operators: The operator is a symbol that performs a specific
operation between two operands, according to one definition.
 Arithmetic operators
 Comparison operators
 Assignment Operators
 Logical Operators
 Bitwise Operators
 Membership Operators
 Identity Operators
 Arithmetic Operators
Arithmetic operators used between two operands for a particular operation. There are many arithmetic
operators. It includes the exponent (**) operator as well as the + (addition), - (subtraction), *
(multiplication), / (divide), % (reminder), and // (floor division) operators.
Operator Description

+ (Addition) It is used to add two operands. For example, if a = 10, b = 10 => a+b = 20

- (Subtraction) It is used to subtract the second operand from the first operand. If the first operand is less than
the second operand, the value results negative. For example, if a = 20, b = 5 => a - b = 15

/ (divide) It returns the quotient after dividing the first operand by the second operand. For example, if a =
20, b = 10 => a/b = 2.0

* (Multiplication) It is used to multiply one operand with the other. For example, if a = 20, b = 4 => a * b = 80

% (reminder) It returns the reminder after dividing the first operand by the second operand. For example, if a
= 20, b = 10 => a%b = 0
** (Exponent) As it calculates the first operand's power to the second operand, it is an exponent operator.

// (Floor division) It provides the quotient's floor value, which is obtained by dividing the two operands.
 Comparison operator
Comparison operators mainly use for comparison purposes. Comparison operators compare the values of
the two operands and return a true or false Boolean value in accordance.

Operator Description

== If the value of two operands is equal, then the condition becomes true.

!= If the value of two operands is not equal, then the condition becomes true.

<= The condition is met if the first operand is smaller than or equal to the second operand.

>= The condition is met if the first operand is greater than or equal to the second operand.

> If the first operand is greater than the second operand, then the condition becomes true.

< If the first operand is less than the second operand, then the condition becomes true.
 Assignment Operators
Using the assignment operators, the right expression's value is assigned to the left operand.

Operator Description

= It assigns the value of the right expression to the left operand.

+= By multiplying the value of the right operand by the value of the left operand, the left operand receives a changed
value. For example, if a = 10, b = 20 => a+ = b will be equal to a = a+ b and therefore, a = 30.

-= It decreases the value of the left operand by the value of the right operand and assigns the modified value back to left
operand. For example, if a = 20, b = 10 => a- = b will be equal to a = a- b and therefore, a = 10.

*= It multiplies the value of the left operand by the value of the right operand and assigns the modified value back to then
the left operand. For example, if a = 10, b = 20 => a* = b will be equal to a = a* b and therefore, a = 200.

%= It divides the value of the left operand by the value of the right operand and assigns the reminder back to the left
operand. For example, if a = 20, b = 10 => a % = b will be equal to a = a % b and therefore, a = 0.

**= a**=b will be equal to a=a**b, for example, if a = 4, b =2, a**=b will assign 4**2 = 16 to a.

//= A//=b will be equal to a = a// b, for example, if a = 4, b = 3, a//=b will assign 4//3 = 1 to a.
 Bitwise Operators
The two operands' values are processed bit by bit by the bitwise operators. The examples of Bitwise
operators are bitwise OR (|), bitwise AND (&), bitwise XOR (^), negation (~), Left shift (<<), and Right
shift (>>).

Operator Description

& (binary and) A 1 is copied to the result if both bits in two operands at the same location are 1. If not, 0 is
copied.

| (binary or) The resulting bit will be 0 if both the bits are zero; otherwise, the resulting bit will be 1.

^ (binary xor) If the two bits are different, the outcome bit will be 1, else it will be 0.

~ (negation) The operand's bits are calculated as their negations, so if one bit is 0, the next bit will be 1, and
vice versa.

<< (left shift) The number of bits in the right operand is multiplied by the leftward shift of the value of the left
operand.

>> (right shift) The left operand is moved right by the number of bits present in the right operand.
 Logical Operators
The assessment of expressions to make decisions typically uses logical operators. The examples of logical
operators are and, or, and not. In the case of logical AND, if the first one is 0, it does not depend upon the
second one. In the case of logical OR, if the first one is 1, it does not depend on the second one.

Operator Description

and The condition will also be true if the expression is true. If the two expressions a and
b are the same, then a and b must both be true.

or The condition will be true if one of the phrases is true. If a and b are the two
expressions, then an or b must be true if and is true and b is false.

not If an expression a is true, then not (a) will be false and vice versa.
 Membership Operators
The membership of a value inside a Python data structure can be verified using Python
membership operators. The result is true if the value is in the data structure; otherwise, it returns
false.

Operator Description

in If the first operand cannot be found in the second operand, it is evaluated to


be true (list, tuple, or dictionary).

not in If the first operand is not present in the second operand, the evaluation is true
(list, tuple, or dictionary).
 Identity Operators:
 It is used to check reference variable pointing same or different object in
memory location.
Operator Description

is If the references on both sides point to the same


object, it is determined to be true.

is not If the references on both sides do not point at


the same object, it is determined to be true.
 Punctuators: Special characters used for structure and separation.
Common punctuators include parentheses (), brackets [], curly braces {},
comma ,, colon :, semicolon ;, and others.
 Variables and Constants:
A variable is a named location in memory where data is stored. Variables are
mutable, i.e., their values can be changed and updated.
A constant is a variable whose value cannot be modified. Constants are
immutable, i.e. their values cannot be changed or updated.
Python programming language incorporates certain rules which should be
followed while declaring a Variable or a Constant in the program. They are
listed as follows :
 Constant and variable names should contain a combination of lowercase (a-z)
or capital (A-Z) characters, numbers (0-9), or an underscore ( ).
 If you want to use underscore to separate two words in a variable name, do
so.
 To declare a constant, use all capital letters as feasible.
 Never use special characters such as !, @, #, $, %, and so on.
 A variable/constant name should never begin with a number.
Id() function
->In Python, id() function is a built-in function that returns the unique identifier of an
object. The identifier is an integer, which represents the memory address of the object.
The id() function is commonly used to check if two variables or objects refer to the same
memory location.
 Syntax: id(object)
 Return: a unique integer for a given object
Example:
x = ('apple', 'banana', 'cherry')
y = id(x)
print(y)
Output: 65182856
Introduction to Variables and Constants: Constants are variables
Constants whose values are intended to remain
 Variables: In Python, a variable is a unchanged throughout the execution of
symbolic name that is a reference or a program. Python doesn’t have built-in
pointer to an object. Once an object is constant types; however, by convention,
assigned to a variable, you can refer to constants are typically written in all
that object by the variable name. uppercase letters.
Variables do not have a fixed type,
meaning the same variable can hold PI = 3.14159
different types of data throughout the GRAVITY = 9.8
program's execution.
x = 10 # x is an integer variable
x = "Hello" # Now, x is a string variable
Naming and Using Variables
Rules for Naming Variables (e.g., snake_case)
 Case Sensitivity: Variable names are case-sensitive in Python. For
example, var and Var would be considered two different variables.
 Allowed Characters: Variable names must start with a letter (a-z, A-Z)
or an underscore (_), followed by letters, numbers (0-9), or
underscores.
 Keywords: Avoid using Python's reserved keywords like if, else, for,
while, etc., as variable names.
valid_variable = 10
_underscore_start = "Valid"
var123 = 123 # Valid
123var = 456 # Invalid, starts with a number
Best Practices for Naming Variables
 Descriptive Names: Use meaningful and descriptive names that clearly
indicate the purpose of the variable.
For example, use total_score instead of ts.
 Use of Snake Case: In Python, the preferred naming convention for variables
is snake_case, where words are separated by underscores (_).
 Consistency: Stick to a consistent naming convention throughout your code
to improve readability.

user_name = "Alice"
account_balance = 1000.50
Avoiding Name Errors When Using Variables
Common Name Errors (Case Sensitivity, Reserved Keywords)
 Case Sensitivity: As Python is case-sensitive, referencing a variable with the wrong case can
lead to NameError.
userAge = 25
print(userage) # NameError: name 'userage' is not defined

 Reserved Keywords: Using Python's reserved keywords as variable names will result in a
SyntaxError.
Example:
if = 5 # SyntaxError: invalid syntax

How to Troubleshoot and Avoid These Errors


 Double-Check Variable Names: Ensure that variable names are correctly spelled and cased.
 Avoid Reserved Keywords: Choose variable names that are not reserved keywords.
 IDE Assistance: Use an Integrated Development Environment (IDE) that highlights keywords
and helps catch these errors early.
Variable as a Label
Understanding Variables as Labels or References
 Reference Concept: In Python, variables are like labels attached to
objects stored in memory. When you assign a value to a variable, you are
essentially attaching a label to that value.
a = [1, 2, 3] # a is a reference to the list [1, 2, 3]
b = a # b is now also a reference to the same list
b.append(4) # Changes the list that both a and b refer to
print(a) # Output: [1, 2, 3, 4]
How Python Manages Variables in Memory
 Memory Allocation: When a variable is assigned a value, Python creates an
object in memory to represent that value and the variable name acts as a
reference to that object.
 Garbage Collection: Python automatically handles memory management
and removes objects from memory when they are no longer referenced by any
variables.
x = 10 # x points to an integer object with value 10
x = 20 # x now points to a new integer object with value 20, the previous object
with value 10 is discarded if no other references exist
Data Types in Python
 In Python, data types specify the type of value a variable can hold.
Understanding data types is crucial for effective programming. This section
will cover two fundamental data types: Strings and Numbers.
1. Strings
Creating and Using Strings
What is a String?
 A string in Python is a sequence of characters enclosed in single quotes ('...'),
double quotes ("..."), triple single quotes ('''...'''), or triple double quotes ("""...""").
 Strings are immutable, meaning once a string is created, it cannot be modified.
single_quote_str = 'Hello'
double_quote_str = "World"
triple_single_quote_str = '''This is a multi-line
string.'''
triple_double_quote_str = """This is another
multi-line string."""
 You can assign a string to a variable, concatenate strings, and repeat strings.
greeting = "Hello"
name = "Alice"
# Concatenation
message = greeting + " " + name # "Hello Alice"
# Repetition
repeated_message = greeting * 3 # "HelloHelloHello"
 String Indexing and Slicing
 Indexing
 Strings are indexed, meaning each character in a string has a position. Indexing starts
from 0 for the first character and goes up to n-1 where n is the length of the string.
 Negative indexing allows you to access characters from the end of the string, starting
from -1.
String Indexing and Slicing
 Indexing
 Strings are indexed, meaning each character in a string has a position. Indexing starts
from 0 for the first character and goes up to n-1 where n is the length of the string.
 Negative indexing allows you to access characters from the end of the string, starting
from -1.
word = "Python"
# Positive indexing
first_char = word[0] # 'P'
second_char = word[1] # 'y'
# Negative indexing
last_char = word[-1] # 'n'
second_last_char = word[-2] # 'o'
Slicing
 Slicing allows you to extract a portion of a string using the start:stop:step
syntax. The start index is inclusive, and the stop index is exclusive.
text = "Hello, World!"
# Slice from index 0 to 4 (exclusive)
slice1 = text[0:5] # "Hello"
# Slice from the start to index 4
slice2 = text[:5] # "Hello"
# Slice from index 7 to the end
slice3 = text[7:] # "World!"
# Slice with step
slice4 = text[::2] # "Hlo ol!"
String Methods
 Common String Methods
 .upper(): Converts all characters in the string to uppercase.
 .lower(): Converts all characters in the string to lowercase.
 .replace(old, new): Replaces all occurrences of a substring old with new.
 .strip(): Removes leading and trailing whitespace from the string.
 .find(sub): Returns the lowest index in the string where substring sub is found.
text = "Hello, World!"
# Uppercase
upper_text = text.upper() # "HELLO, WORLD!"
# Lowercase
lower_text = text.lower() # "hello, world!"
# Replace
replaced_text = text.replace("World", "Python") # "Hello, Python!"
# Strip
text_with_whitespace = " Hello "
stripped_text = text_with_whitespace.strip() # "Hello"
# Find
index_of_comma = text.find(",") # 5
2. Numbers
Overview of Numeric Data Types
 Integers (int)
 Integers are whole numbers, positive or negative, without decimals.
 This value is represented by int class. It contains positive or negative whole numbers
(without fractions or decimals). In Python, there is no limit to how long an integer
value can be.
Examples:
positive_int = 10
negative_int = -5
large_int = 1000000
Floating-Point Numbers (float)
 Floats represent real numbers with decimal points.
 This value is represented by the float class. It is a real number with a
floating-point representation. It is specified by a decimal point
positive_float = 3.14
negative_float = -2.71
scientific_float = 1.2e3 # 1200.0
Complex Numbers (complex):
 A complex number is represented by a complex class. It is specified as (real
part) + (imaginary part)j.
 For example – 2+3j
Type Conversion
Converting Between Data Types
 int(x): Converts x to an integer. If x is a float, it truncates the decimal part.
 float(x): Converts x to a float.
num_str = "10"
num_int = int(num_str) # Converts string to integer
float_num = 5.75
int_num = int(float_num) # Converts float to integer (5)
int_num = 5
float_num = float(int_num) # Converts integer to float (5.0)
1. The Style Guide (PEP 8)
 PEP 8 (Python Enhancement Proposal) is the official Python style guide
that provides guidelines and best practices on how to write Python code.
 It covers aspects like indentation, line length, spacing, comments, and
naming conventions.
2. Indentation
 Use 4 spaces per indentation level.
 Indentation is crucial in Python because it defines the structure of the code
blocks (e.g., loops, functions, conditionals).
 Avoid using tabs or mixing tabs and spaces.
 Example:
def greet(name):
if name:
print(f"Hello, {name}!")
else:
print("Hello, World!")
Maximum Line Length
 Limit all lines to a maximum of 79 characters.
 For docstrings or comments, the line length should be limited to 72
characters.
 Use parentheses for line continuation when necessary.
# Good:
with open('/path/to/some/file/you/want/to/read') as file_:
content = file_.read()
# Bad:
with open('/path/to/some/file/you/want/to/read', 'r') as file_: content = file_.read()
3. Blank Lines
 Surround top-level function and class definitions with two blank lines.
 Method definitions inside a class should be surrounded by a single blank line.
4. Imports
 Imports should be on separate lines.
 Import statements should be placed at the top of the file.
 Imports should be grouped in the following order:
 Standard library imports.
 Related third-party imports.
 Local application/library-specific imports.
import os
import sys
from third_party_library import SomeClass
from my_module import MyClass
5. Whitespace in Expressions and Statements
Avoid extraneous whitespace in the following situations:
 Immediately inside parentheses, brackets, or braces
# Correct:
my_list = [1, 2, 3]
# Incorrect:
my_list = [ 1, 2, 3 ]
------------------------
 Immediately before a comma, semicolon, or colon
# Correct:
if x == 4:
# Incorrect:
if x == 4 :
----------------------
 Around the = operator used for keyword arguments or default parameter values
# Correct:
def func(a=1, b=2):
# Incorrect:
def func(a = 1, b = 2):
6. Comments
 Use comments to explain why something is done, not what is done.
 Use block comments to explain code logic, and inline comments to clarify
single lines of code.
 Keep comments up to date with code changes.
7. Naming Conventions
 Use lower_case_with_underscores for function and variable names.
 Use UpperCamelCase for class names.
 Use ALL_CAPS for constants.
 Avoid using single-character variable names except for counters or iterators.
8. String Quotes
Use consistent quotes for strings (' or ").
Triple quotes (""" or ''') should be used for multi-line strings.
9. Docstrings
Use docstrings to describe the purpose and usage of functions,
classes, and methods.
The first line should be a short description, followed by more
detailed explanations if necessary.
Naming Conventions:
 Use descriptive names for variables, functions, and classes.
 Variables/Functions: Use lower_case_with_underscores.
 Classes: Use CamelCase.
 Constants: Use ALL_CAPS.

variable_name = "value"
def my_function():
pass
class MyClass:
pass
MAX_RETRIES = 5
1. Input Statement
 The input() function is used to take input from the user. It reads a line from
input, converts it into a string, and returns it.
name = input("Enter your name: ")
print(f"Hello, {name}!")
 input("Enter your name: ") prompts the user to enter their name.
 The entered value is stored in the name variable.
 The print() statement then outputs a greeting.
Output Statement
 The print() function is used to display output on the screen.
 Basic Syntax:
print(object(s), sep=' ', end='\n', file=sys.stdout, flush=False)

 object(s): The value(s) to be printed.


 sep: Separator between objects (default is a space).
 end: String appended after the last value (default is a newline).
 file: Object where the values are printed (default is sys.stdout).
 flush: Whether to forcibly flush the stream.

print("Hello", "World", sep="-")


print("Hello", end="!")
print("World")
1. Debugging
 Debugging is the process of identifying and fixing bugs or errors in your code.
Here are some common methods and tools used for debugging in Python:
a. Print Statements
 Usage: Adding print() statements at various points in your code can help you
understand the flow and identify where things might be going wrong.
a=10
b=5
print(f"Values received: a={a}, b={b}")
result = a / b
print(f"Result: {result}")
b. Logging
Usage: The logging module provides a more flexible way to output debugging
information without cluttering the code with print() statements.
import logging
logging.basicConfig(level=logging.DEBUG)
def divide(a, b):
logging.debug(f"Values received: a={a}, b={b}")
try:
result = a / b
except ZeroDivisionError:
logging.error("Division by zero!")
return None
logging.debug(f"Result: {result}")
return result
divide(10, 0)
c. The pdb Module
 Usage: Python’s built-in debugger, pdb, allows you to step through your code,
inspect variables, and evaluate expressions.
How to Use:
 Start the debugger with import pdb; pdb.set_trace() at the point in the code where
you want to start debugging.
 You can then use commands like n (next), s (step into), c (continue), and q (quit).
def divide(a, b):
import pdb; pdb.set_trace()
result = a / b
return result
divide(10, 2)
2. Testing
 Testing involves writing code to check if your functions and modules behave as expected. There
are different types of testing in Python:
a. Unit Testing
Purpose: Unit tests are designed to test individual units of code (like functions or methods) in
isolation.
Tool: The unittest module is part of Python’s standard library and is commonly used for writing unit
tests.
import unittest
def add(a, b):
return a + b
class TestMathFunctions(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(-1, 1), 0)
self.assertEqual(add(0, 0), 0)
if __name__ == '__main__':
unittest.main()
b. Test-Driven Development (TDD)
Concept: TDD is a development process where you write the tests first and then write the code
to pass the tests.
Benefits: Ensures that your code is always covered by tests and helps in maintaining high code
quality.

import pytest
# Step 1: Write the test (initially will fail)
def test_is_even():
assert is_even(2) == True
assert is_even(3) == False
assert is_even(0) == True
# Step 3: Write the code
def is_even(n):
return n % 2 == 0
# Running the tests
if __name__ == "__main__":
pytest.main()
c. Integration Testing
Purpose: Integration tests check how different modules or components of your
application work together.
Tool: You can use unittest or more advanced tools like pytest for integration testing.
d. pytest
Usage: pytest is a popular testing framework that simplifies writing small tests and
scales to support complex functional testing.
Features: It has more advanced features like fixtures, parameterized testing, and
powerful assertions.
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
# To run, simply execute `pytest` in the terminal
e. Continuous Integration (CI)
 Purpose: CI tools automatically run your tests whenever changes are made to the
codebase.
 Tools: Popular CI services like Travis CI, Jenkins, or GitHub Actions can be
integrated with your project to ensure that your tests are always run and the
codebase is stable.
 #WAP in python to print first 20 natural numbers.
 #WAP in python to print first 10 even numbers.
Introduction
 Conditional statements (if, else, and elif) are fundamental programming
constructs that allow you to control the flow of your program based on
conditions that you specify.
 They provide a way to make decisions in your program and execute different
code based on those decisions.
 The main ones are if/else for making choices, loops like for/while for
repeating tasks, and keywords like break/continue to control the flow.
1. if Statement:
The `if` statement executes a block of code only if a specified condition is
true. If the condition evaluates to false, the code block is not executed. It has
the following
 syntax:
if condition:
# statement to be executed if the condition is true
Example:
age = 10
if age >= 18:
print("You are an adult")
Write a program in python to check you are eligible for
voting .
Write a program in python to check your name is matched .
Write a program in python show message meow meow if
you enter Cat or CAT or cat.
Write a program in python to find factorial of input number.
2. if…else Statement:
The `if…else` statement allows you to execute the instructions if one block of
code condition is true, and another block runs when if the condition is false.
 syntax:
if condition:
# statement to be executed if condition is true
else:
# statement to be executed if condition is false
Eg: name = "Alice"
if name == "Bob":
print("Hello Bob")
else:
print("Hello", name)
 Write a program in python to a=int(input("Enter any number:"))
check you are eligible for voting or Is_perfect_Square=False
not . for i in range(1,a):
 Write a program in python to if i==math.sqrt(a):
check your name is matched or not
Is_perfect_Square=True
 Write a program in python show
message meow meow if you enter break
Cat or CAT or cat and show if Is_perfect_Square:
message Vau Vau for other case. print(f"{a} is perfect square")
 Write a program in python to else:
check input number is perfect print(f"{a} is not perfect square")
square or not.
3. if…elif…else Statement: else:
The `if…elif…else` statement # code to be executed if all
allows you to check multiple
conditions and execute different conditions are false
blocks of code based on which Eg: score = 75
condition is true. if score >= 90:
 syntax: print("Excellent!")
if condition1: elif score >= 80:
# code to be executed if condition1 print("Great job!")
is true else:
print("Keep practicing!")
elif condition2:
# code to be executed if condition2
is true
Write a program in python to print largest number among
three numbers.
Write a program in python to enter five subject marks and
calculate percentage, division and result.
Write a program in python to calculate Grade if you enter
Grade point.
Write a program in python to smallest number among three
numbers.
Write a program in python to check positive and negative
number or zero.
4. Nested if Statement: Example:
A nested `if` statement is an `if` age = int(input("Enter your age: "))
statement that is placed inside another citizen = input("Are you a citizen?
`if` statement. It allows you to check for (yes/no): ")
additional conditions based on the if age >= 18:
result of the outer `if` statement.
if citizen == "yes":
 syntax:
print("You are eligible to vote.")
if condition1:
else:
if condition2:
print("You are not eligible to vote
# code to be executed if both because you are not a citizen.")
condition1 and condition2 are true
else:
print("You are not eligible to vote
because you are under 18.")
Match- Case option = int(input("Enter an
 In Python, starting with version option (1, 2, or 3): "))
3.10, the match-case statement match option:
was introduced, providing a case 1:
structured way to handle print("You selected option 1.")
multiple conditions, similar to
case 2:
the switch-case construct found
in other programming print("You selected option 2.")
languages. case 3:
print("You selected option 3.")
case _:
print("Invalid option.")
Unit -4
Control Statements
Introduction
 Control statements are like instructions that tell Python how to navigate through the code. They
help in making decisions and looping over tasks.
 Control statements in Python are used to control the flow of execution in a program based on
certain conditions.
 Loops are employed in Python to iterate over a section of code continually.
 Control statements are designed to serve the purpose of modifying a loop's execution from its
default behaviour.
 Based on a condition, control statements are applied to alter how the loop executes.
 The if/else for making choices, loops like for/while for repeating tasks, and keywords like
break/continue to control the flow.
Looping Statement :
 In Python, Looping are vital structures that enable the repetition of code execution,
either for a specific count or until a certain condition is fulfilled.
1. for loop:
 Used to iterate over a sequence of elements, like lists, strings, tuples, or dictionaries.
 Executes a block of code for each element in the sequence.
Syntax:
for element in sequence:
# code to execute for each element
Example:
for a in range(11):
print(a)
 Write a program in python using for loop to print alphabets of word
“PYTHON”.
 Write a program to count numbers of vowel in input string.
2. while loop:
 Executes a block of code repeatedly as long as a specified condition is true.
 Well-suited for situations where you don't know the exact number of iterations
beforehand.
 Syntax:
while condition:
# code to execute as long as the condition is true
Example:
count = 0
while count < 5:
print(count)
count += 1
 Write a program in python using while loop to print multiplication
table of input number.
 Write a program in python to find reverse number of input number.
 Write a program in python to check input number is palindrome or
not.
Assignment
 Write a program in python to find reverse number of input string.
 Write a program in python to check input string is palindrome or
not.
 Write a program in python to check input number is Armstrong or
not?
Unconditional Statements: Continue Statement:
In Python, there exist three kinds of control The continue statement skips the rest of the code
statements: Break, Continue, and Pass. inside the loop for the current iteration and proceeds
to the next iteration of the loop.
 These are control flow statements in Python that
allow you to modify the behaviour of loops and Example:
conditional statements. for i in range(10):
Break Statement: if i == 5:
The break statement in Python is used to exit a loop continue
i.e. it immediately terminates the loop when it is print(i)
encountered. This can be useful when you want to
stop the loop's execution based on a certain
condition.
Example:
for i in range(10):
if i == 5:
break
print(i)
Pass Statement:
The pass statement is a null operation; nothing happens when it is
executed. It is used as a placeholder when a statement is syntactically
required but you have no need for any code to execute.
 Example:
for i in range(5):
if i == 3:
pass
else:
print(i)
1. Write a Python program that iterates through numbers 1 to 10. If a number is
divisible by 3, skip the rest of the loop's code using the continue statement. Stop the
loop entirely if a number is greater than or equal to 8 using the break statement.
2. Write a Python program that iterates through numbers from 1 to 10. If a number is
less than 6, print it. If a number equals 7, use the break statement to exit the loop.
Use the pass statement for numbers greater than 7 and print "Skipped" for those
numbers.
3. Write a Python program that uses a while loop to count from 1 to 20. If the current
count is divisible by 4, use the continue statement to skip the rest of the loop body
and move to the next iteration. Print the count value on each iteration.
1. for num in range(1, 11): elif num > 7:
if num % 3 == 0: print("Skipped“)
continue ………………………..
if num >= 8: 3. count = 1
break while count <= 20:
print(num) if count % 4 == 0:
………………………. continue
2. for num in range(1, 11): count += 1
if num < 6: print(count)
print(num) count += 1
elif num == 7:
break
Using if else as ternary:
The ternary operator in Python is a compact way of writing an if-else
statement. It’s used when you want to return two different values
based on the truth value of a condition.
Syntax:
value_if_true if condition else value_if_false
Example:
x = 10
y = 20
result = "x is greater" if x > y else "y is greater“
Print (result)
The else clause after a for or while loop:
In Python, the else clause after a for or while loop is an optional construct that provides a
way to execute a block of code after the loop completes normally, i.e., without
encountering a break statement.
 for loops:
 The else block will execute after the loop iterates over all the items in the iterable or
sequence.
# Syntax for 'for' loop with 'else' clause
for item in iterable:
# Code block inside the loop
else:
# Code block inside the loop
# Example with for loop
for i in range(5):
print(i)
else:
print("Loop completed successfully")
While loops:
The else block will execute after the loop exits normally (when the condition becomes false)
without encountering a break statement.
# Syntax for 'while' loop with 'else' clause
while condition:
# Code block inside the loop
else:
# Code block to execute after the loop completes
Example:
x=0
while x < 5:
print(x)
x += 1
else:
print("Loop completed successfully")
1. Write a program using a for loop to calculate the sum of the first 20 natural numbers.
2. Write a program that prints numbers from 10 down to 1 using a for loop.
3. Write a program that finds the sum of all even numbers between 1 and 50 using a for
loop.
4. Write a program that iterates through a list of numbers and prints the square of each
number using a for-in loop.
5. Write a program that iterates through a list of words and finds the longest word using a
for-in loop.
6. Write a program that checks if a particular element exists in a list using a for-in loop.
7. Write a program that iterates through a list of strings and concatenates them into a
single string using a for-in loop.
numbers = [1, 2, 3, 4, 5] if item == search_item:
for num in numbers: found = True
print(f"Square of {num} is {num ** 2}") break
----------------------------------- if found:
words = ["apple", "banana", "cherry", print("Item found!")
"watermelon"] else:
longest = "" print("Item not found.")
for word in words: -----------------------------------------------
if len(word) > len(longest): strings = ["Hello", "world", "Python", "is",
longest = word "great"]
print("The longest word is:", longest) result = ""
----------------------------------------- for s in strings:
items = [10, 20, 30, 40, 50] result += s + " "
search_item = int(input("Enter the item to print("Concatenated string:", result)
search: "))
found = False
for item in items:
 Write a program that uses nested loops to print a pyramid pattern of stars.
 Write a program that uses nested loops to print an inverted right triangle of numbers.
 Write a program that prints multiplication tables for numbers 1 to 5 using nested loops.
 Write a program that asks the user to enter a password and breaks the loop if the correct
password is entered.
 While a program to print the following pattern.
1
12
123
1234
12345
rows = 5 else:
for i in range(1, rows + 1): print("Incorrect password, try again.")
print(' ' * (rows - i) + '*' * (2 * i - 1)) -----------------------------------------------------------
-------------------------------------------
rows = 5
for i in range(rows, 0, -1):
for j in range(1, i + 1):
print(j, end=" ")
print()
---------------------
correct_password = "secret"
while True:
password = input("Enter the password: ")
if password == correct_password:
print("Access granted")
break
 While a program to print the following pattern.
1
22
333
4444
55555
 While a program to print the following pattern.
*
**
***
****
*****

 While a program to print the following pattern.


A
AB
ABC
ABCD
ABCDE
#Write a program in python using while else statement to print numbers 3 upto 50 which are
incremented by 3.
a=3
while a<=50:
print(a)
a+=3
else:
print("Loop completed")
#Write a program in python to check input number is palindrome or not?
n = int(input("Enter any number: "))
a=n
p=0
while n != 0:
r = n % 10
p = p * 10 + r
n = n // 10
if a == p:
print(a, "is a palindrome number")
else:
print(a, "is not a palindrome number")
#Write a program in python to print Fibonacci series of 10 numbers.
a=0
b=1
print(a)
print(b)
for i in range(8):
c=a+b
print(c)
a=b
b=c
#Write a program in python to find reverse of input number.
n=int(input("Enter any number"))
rev=0
while n!=0:
r = n % 10
rev=rev*10+r
n=n//10
print("Reverse Number is:",rev)
#Write a program in python to find reverse of input string.
str = input("Enter any string: ")
rev = " "
for char in str:
rev = char +rev
print("Reversed string:", rev)
#Write a program in python to check positive and negative number.
a=int(input("Enter any number:"))
if a>0:
print("Input number is positive")
elif a<0:
print("Input number is Negative number")
else:
print("Input number is zero(0)")
#Write a program in python to input check #While a program to print the following
input number is Armstrong number or not. pattern.
n=int(input("Enter any number:")) 1
d=len(str(n)) 12
a=n 123
m=0 1234
while n!=0: 12345
r=n%10
m=m+r**d for i in range(1,6):
n=n//10 for j in range(1,i+1):
if a==m: print(j, end=" ")
print("Is Armstrong number") print()
else:
print("Is not a Armstrong number")
#While a program to print the following pattern.
1
22
333
4444
55555
for i in range(1,6):
for j in range(1,i+1):
print(i, end=" ")
print()
#While a program to print the following pattern.
*
**
***
****
*****
for i in range(1,6):
for j in range(1,i+1):
print("*", end=" ")
print()
#While a program to print the following pattern.
A
AB
ABC
ABCD
ABCDE
n=5
a = 65
for i in range(0, n):
for j in range(0, i+1):
print(chr(a), end=" ")
a += 1
a = 65
print()
#Write a program to print following pattern
A
AB
ABC
ABCD
ABCDE
n=5
a = 65
for i in range(0, n):
print(" " * (n-i), end=" ")
for j in range(0, i+1):
print(chr(a), end=" ")
a += 1
a = 65
print()
Unit-5
List and Tuples
List Data Type
Lists are just like arrays, declared in other languages which is an ordered collection
of data. It is very flexible as the items in a list do not need to be of the same type.
Lists in Python can be created by just placing the sequence inside the square
brackets[].
In Python, the list data type is one of the built-in data structures, commonly used to
store a collection of items.
Lists are mutable, meaning their elements can be changed after the list is created.
They are ordered and allow duplicate elements.
Characteristics of Lists
 The lists are in order.
 The list element can be accessed via the index.
 The list is mutable type.
 The rundowns are changeable sorts.
 The number of various elements can be stored in a list.
Python List Operations
 The concatenation (+) and repetition (*) operators work in the same way as they were
working with the strings. The different operations of list are
 Repetition
 Concatenation
 Length
 Iteration
 Membership
1. Repetition
 The redundancy administrator empowers the rundown components to be rehashed on
different occasions.
# repetition of list
list1 = [12, 14, 16, 18, 20]
# repetition operator *
li = list1 * 2
print(li)
2. Concatenation
 It concatenates the list mentioned on either side of the operator.
# concatenation of two lists
list1 = [12, 14, 16, 18, 20]
list2 = [9, 10, 32, 54, 86]
# concatenation operator +
li = list1 + list2
print(li)
3. Length
 It is used to get the length of the list
# size of the list
list1 = [12, 14, 16, 18, 20, 23, 27, 39, 40]
# finding length of the list
len(list1)
4. Iteration 5. Membership
 The for loop is used to iterate over the  It returns true if a particular item exists
list elements. in a particular list otherwise false.

list1 = [12, 14, 16, 39, 40] list1 = [100, 200, 300, 400, 500]
# iterating print(600 in list1)
for i in list1: print(700 in list1)
print(i) print(1040 in list1)
print(300 in list1)
print(100 in list1)
print(500 in list1)
Adding Elements to the List
The append() function in Python can add a new item to the List.
my_list = []
my_list.append(1)
my_list.append(2)
my_list.append(3)
print(my_list)
Removing Elements from the List
 The remove() function in Python can remove an element from the List.
list = [0,1,2,3,4]
print("printing original list: ");
for i in list:
print(i,end=" ")
list.remove(2)
print("\nprinting the list after the removal of first element...“,list)
popped_element = list.pop(3) #Remove value at position 3 from the list
del list[0] #Delete element at position 0 or first position.
for i in list:
print(i,end=" ")
Updating List Values
 Due to their mutability and the slice and assignment operator's ability to update their values, lists are
Python's most adaptable data structure.
 Python's append() and insert() methods can also add values to a list.
list = [1, 2, 3, 4, 5, 6]
print(list)
list[2] = 10
print(list)
# Adding multiple-element
list[1:3] = [89, 78]
print(list)
# It will add value at the end of the list
list[-1] = 25
print(list)
Python List Built-in Functions Max( )
 Python provides the following built-in  It returns the maximum element of the list
functions, which can be used with the lists. # maximum of the list
 len() list1 = [103, 675, 321, 782, 200]
 max() # large element in the list
 min() print(max(list1))
len( ) Min( )
 It is used to calculate the length of the list.  It returns the minimum element of the list
# size of the list # minimum of the list
list1 = [12, 16, 18, 20, 39, 40] list1 = [103, 675, 321, 782, 200]
# finding length of the list # smallest element in the list
len(list1) print(min(list1))
sort() Method
 In Python, you can sort a list permanently using the sort() method.
 This modifies the list in place, meaning the original list is sorted and the changes are permanent.
Syntax:
list.sort(reverse=False)
Example1:
my_list = [3, 1, 4, 1, 5, 9]
my_list.sort()
print("List after sorting in ascending order:", my_list)
Example 2:
my_list = [3, 1, 4, 1, 5, 9]
# Sort the list in descending order
my_list.sort(reverse=True)
print("List after sorting in descending order:", my_list)
sorted() Function
 The sorted() function in Python Example1:
allows you to sort a list temporarily, my_list = [3, 1, 4, 1, 5, 9]
meaning it returns a new sorted list but # Sort the list temporarily in ascending order
does not modify the original list. sorted_list = sorted(my_list)
 This is useful when you want to keep print("Original list:", my_list)
the original list unchanged while still print("Temporarily sorted list:", sorted_list)
getting a sorted version of it.
Syntax: Example2:
my_list = [3, 1, 4, 1, 5, 9]
sorted(iterable, reverse=False)
sorted_list_desc = sorted(my_list, reverse=True)
print("Original list:", my_list)
print("Temporarily sorted list in descending order:",
sorted_list_desc)
List in Reverse Order
 In Python, you can print a list in reverse order in several ways, depending on whether
you want to reverse the list temporarily or permanently.
# Permanently reverse the list
my_list = [1, 2, 3, 4, 5]
my_list.reverse()
print("List after permanent reversal:", my_list)

# Temporarily reverse the list using slicing


my_list = [1, 2, 3, 4, 5]
reversed_list = my_list[::-1]
print("Original list:", my_list)
print("Temporarily reversed list:", reversed_list)
Avoiding Index Errors When Working with Lists
 In Python, the IndexError is a common exception that occurs when trying to access an
element in a list, tuple, or any other sequence using an index that is outside the valid range of
indices for that sequence.
 List Index Out of Range Occur in Python when an item from a list is tried to be accessed
that is outside the range of the list.
j = [1, 2, 4]
print(j[4])
------------------
Error
print(j[4])
~^^^
IndexError: list index out of range
How to Fix IndexError in Python
 Check List Length: It’s important to check if an index is within the valid range of a list before
accessing an element.
 To do so, you can use the function to determine the length of the list and make sure the index falls
within the range of 0 to length-1.
 Use Conditional Statements:To handle potential errors, conditional statements like “if ” or “else”
blocks can be used.
 For example, an “if ” statement can be used to verify if the index is valid before accessing the element.
 if or try-except blocks to handle the potential IndexError. For instance, you can use a if statement to
check if the index is valid before accessing the element.
my_list = [10, 20, 30, 40, 50]
index = 6
if index < len(my_list):
print(f"The element at index {index} is: {my_list[index]}")
else:
print("Error: Index is out of bounds.")
How to Fix List Index Out of Range in Python
 Using Python range()
 Using Python Index()
 Using Try Except Block
Python Fix List Index Out of Range using Range()
 The range is used to give a specific range, and the Python range() function returns the sequence
of the given number between the given range.

names = ["blue," "red," "green"]


for name in range(len(names)):
print(names[name])
Python Fix List Index Out of Range using Index()
 Here we are going to create a list and then try to iterate the list using the constant values in for loops.
li = [1, 2, 3, 4, 5]
for i in range(6):
print(li[i])

Python Fix List Index Out of Range using Try Except Block
 If we expect that an index might be out of range, we can use a try-except block to handle the error
gracefully.
my_list = [1, 2, 3]
try:
print(my_list[3])
except IndexError:
print("Index is out of range")
Using the range() Function
 The range() function in Python generates a sequence of numbers, but it doesn’t directly
produce a list.
 To create a list of numbers from a range, you can pass the result of range() to the list() function.
Syntax:
range(start, stop, step)
Example 1:
# Create a list of numbers from 0 to 9
numbers = list(range(10))
print(numbers)
Example 2:
numbers = list(range(0, 10, 2))
print(numbers)
Indexing and Slicing:
Indexing
 In Python, a list is an ordered collection of elements, and indexing refers to accessing
elements based on their position in the list.
 Python uses zero-based indexing, meaning the first element is at index 0, the second
element is at index 1, and so on.
 We can access element in a list in Two ways :
Accessing element by Positive Index Number
Accessing element by Negative Index Number
1. Accessing element by Positive Index Number
 In this type of Indexing, we pass a Positive index(which we want to access)
in square brackets.
 The index number starts from index number 0 (which denotes the first
element of a list).

list = [1,2,5,6,8,9,10,15]
print(list[0])
print(list[6])
2. Accessing element by Negative Index Number
 In this type of Indexing, we pass the Negative index(which we want to access) in square
brackets.
 Here the index number starts from index number -1 (which denotes the last element of
a list).

list = [1,2,5,6,8,9,10,15]
print(list[-1])
print(list[-5])
Slicing
 Slicing in Python lists allows you to access a subsection (or "slice") of a list by specifying a range of
indices.
 The general syntax for slicing is:
list[start : stop: step]
Where:
 start (optional): The index at which the slice starts (inclusive).
 stop: The index at which the slice stops (exclusive).
 step (optional): The interval between elements in the slice.

my_list = [10, 20, 30, 40, 50, 60]


print(my_list [: 3])
print(my_list [1 : 5 : 2])
print(my_list [-1 : -6 : -2])
Examples:
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']
# Loop through the first three items
for fruit in fruits[:3]:
print(fruit)

fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']


# Get the first three elements
print(fruits[0:3])
# Get elements from index 2 to the end
print(fruits[2:])
Copying a List
 To make a copy of a list, you can use slicing or the list() function.
 Directly assigning one list to another (i.e., new_list = old_list) does not create a copy but
makes both names point to the same list in memory.
fruits = ['apple', 'banana', 'cherry']
# Using slicing to copy
fruits_copy = fruits[:]
print(fruits_copy)
# Using list() to copy
fruits_copy2 = list(fruits)
print(fruits_copy2)
List Comprehension:
List comprehensions provide a concise way to create lists.
squared = [x**2 for x in range(5)]
print(squared) # Outputs: [0, 1, 4, 9, 16]
Other List Methods:
 extend(): Adds elements from another list to the end of the list.
Syntax:
list.extend(iterable)
Example:
fruits = ['apple', 'banana', 'cherry']
more_fruits = ['date', 'elderberry', 'fig']
# Extend the original list by adding elements from another list
fruits.extend(more_fruits)
print(fruits)
 count(): The count() method in Python is used to count the number of
occurrences of a specific element in a list. It returns the number of times the
specified element appears in the list.
Syntax:
list.count(element)
Example:
fruits = ['apple', 'banana', 'cherry', 'apple', 'apple', 'banana']
# Count the number of times 'apple' appears
apple_count = fruits.count('apple')
print(apple_count)
# Count the number of times 'banana' appears
banana_count = fruits.count('banana')
print(banana_count)
clear(): Removes all elements from the list.
 The clear() method in Python is used to remove all elements from a list, making the
list empty.
 After calling this method, the list will still exist, but it will have no items.
Syntax:
list.clear()
Example 1:
fruits = ['apple', 'banana', 'cherry', 'date']
# Clear all elements from the list
fruits.clear()
print(fruits)
 index(): Returns the index of the first occurrence of a value.
Syntax:
list.index(element, start, end)
Example 1:
fruits = ['apple', 'banana', 'cherry', 'date', 'banana']
# Find the index of the first 'banana'
index_of_banana = fruits.index('banana')
print(index_of_banana)

Example 2:
fruits = ['apple', 'banana', 'cherry']
# Extend the list with characters from a string
fruits.extend('date')
print(fruits)
Questions For Practice:
1. Write a program that takes a list of numbers and finds both the largest and the smallest
elements in the list.
2. Given a list with potential duplicate values, write a program to remove the duplicates
while preserving the original order of the elements.
3. Write a program that checks if a given list is a palindrome (i.e., it reads the same
backward as forward).
4. Write a program to count how many even and odd numbers are in a list of integers.
5. Write a program to reverse a list and print the reversed list.
6. Write a program that calculates and prints the average of all the numbers in a list.
7. Write a program that asks the user for a number and checks if the number exists in a
predefined list.
Example 1: Example 2:
numbers = [3, 8, 2, 7, 4] numbers = [1, 2, 3, 2, 4, 1, 5]
largest = numbers[0] result = []
smallest = numbers[0] seen = set()
for num in numbers:
if num > largest: for num in numbers:
largest = num if num not in seen:
if num < smallest: result.append(num)
smallest = num seen.add(num)
print(f"Largest: {largest}, Smallest: {smallest}")
print("List without duplicates:", result)
Example 3 Example 4
numbers = [1, 2, 3, 2, 1] numbers = [1, 2, 3, 4, 5, 6]
is_palindrome = True even_count = 0
for i in range(len(numbers) // 2): odd_count = 0
if numbers[i] != numbers[-i-1]: for num in numbers:
is_palindrome = False if num % 2 == 0:
break even_count += 1
if is_palindrome: else:
print("The list is a palindrome") odd_count += 1
else: print(f"Even numbers: {even_count}, Odd
print("The list is not a palindrome") numbers: {odd_count}")
# Program to reverse a list and print #Program that asks the user for a
the reversed list: number and checks if the number
my_list = [1, 2, 3, 4, 5] exists in a predefined list:
# Using slicing to reverse the list predefined_list = [5, 10, 15, 20, 25]
reversed_list = my_list[::-1] user_input = int(input("Enter a number: "))
print("Original List:", my_list) if user_input in predefined_list:
print("Reversed List:", reversed_list) print(f"{user_input} exists in the list.")
#Program that calculates and prints the else:
average of all the numbers in a list: print(f"{user_input} does not exist in the list.")
numbers = [10, 20, 30, 40, 50]
average = sum(numbers) / len(numbers)
print("List of Numbers:", numbers)
print("Average of Numbers:", average)
9. Write a program to insert an element into a list at a specific index provided by the
user.
10. Write a program to remove a specific element from a list. The element to be removed
should be provided by the user.
11. Write a program that takes a list of numbers and prints the list sorted in ascending
order without using any built-in sort function.
12. Write a program that prints all elements in a list that are greater than a number
specified by the user.
13. Write a program to concatenate two lists and print the result.
14. Write a program to multiply every element in a list by a number (constant) provided
by the user.
Tuple
 A tuple is a collection in Python that is ordered and immutable (i.e., once defined, you cannot
change its elements).
 Tuples are similar to lists, but they use parentheses () instead of square brackets [].

# Defining a tuple with multiple values


dimensions = (200, 50)
print(dimensions)
Looping in a Tuple
 Even though tuples are immutable, you can still loop through all the values in a tuple just like you would
with a list.
dimensions = (200, 50, 75)
# Looping through a tuple
for dimension in dimensions:
print(dimension)
Writing over a Tuple
 You cannot modify (change, add, or remove elements from) a tuple once it is defined
because tuples are immutable.
 However, you can redefine the entire tuple by assigning new values to the variable.

dimensions = (200, 50)


# Redefining the entire tuple (reassignment)
dimensions = (400, 100)
print(dimensions)
Tuple Packing and Unpacking:
Packing:You can assign multiple values to a tuple in a single step.
Unpacking:You can assign the values of a tuple to multiple variables.

Tuple packing
packed_tuple = (1, "apple", 3.14)
Tuple unpacking
a, b, c = packed_tuple
print(a, b, c)
Tuple Operations: 2. Slicing
 Tuples in Python support various operations,  You can extract a sub-part of a tuple using the
even though they are immutable. These slicing operation.
operations allow you to manipulate or query my_tuple = (1, 2, 3, 4, 5, 6)
tuples without modifying their structure slice_tuple = my_tuple[1:4]
1. Indexing print(slice_tuple)
 You can access individual elements of a tuple 3. Concatenation:You can concatenate tuples
using their index. using the + operator.
my_tuple = (10, 20, 30, 40) new_tuple = my_tuple + (4, 5)
print(my_tuple[0]) print(new_tuple) # Output: (1, 2, 3, 4, 5)
print(my_tuple[-1]) 4. Repetition:You can repeat a tuple using the *
operator.
repeated_tuple = my_tuple * 2
print(repeated_tuple) # Output: (1, 2, 3, 1, 2, 3)
5. Membership (in, not in) my_tuple = (1, 2, 3, 4)
 You can check if an item exists in a tuple using print(max(my_tuple)) # Output: 4
the in and not in operators. print(min(my_tuple)) # Output: 1
my_tuple = (1, 2, 3, 4) 8. Sum (sum())
print(2 in my_tuple)  You can calculate the sum of all numeric
print(5 not in my_tuple) elements in a tuple using the sum() function.
6. Length (len()) my_tuple = (1, 2, 3, 4)
 You can get the number of elements in a tuple print(sum(my_tuple))
using the len() function. 9. Nested Tuples
my_tuple = (1, 2, 3, 4)  Tuples can contain other tuples as elements,
print(len(my_tuple)) # Output: 4 which is known as nesting.
7. Max (max()) and Min (min()) nested_tuple = (1, 2, (3, 4, 5), 6)
 You can find the maximum and minimum values print(nested_tuple[2])
in a tuple of comparable elements (like numbers print(nested_tuple[2][1])
or strings).
10. Conversion (tuple())
 You can convert other iterables like lists or strings into tuples using the tuple() function.
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
print(my_tuple) # Output: (1, 2, 3)

my_string = "hello"
string_tuple = tuple(my_string)
print(string_tuple) # Output: ('h', 'e', 'l', 'l', 'o')
Tuple Methods: 2. index()
 Tuples in Python have only two built-in  The index() method returns the index of the
methods, as they are immutable and cannot be first occurrence of a specified value. If the
modified after creation. Here are the two value is not found, it raises a ValueError.
methods available for tuples: tuple.index(value)
1. count() Example:
 The count() method returns the number of my_tuple = (1, 2, 3, 4, 5)
times a specified value appears in the tuple. index_of_three = my_tuple.index(3)
tuple.count(value) print(index_of_three) # Output: 2
Example:
my_t = (1, 2, 3, 2, 4, 2)
count_of_twos = my_t.count(2)
print(count_of_twos)
Unit-6
Dictionaries
 Dictionaries are useful data structure for storing data in Python because they are capable of
imitating real-world data arrangements where a certain value exists for a given key.
 The data is stored as key-value pairs using a Python dictionary.
 This data structure is mutable
 The components of dictionary were made using keys and values.
 Keys must only have one component.
 Values can be of any type, including integer, list, and tuple.
A dictionary is, in other words, a group of key-value pairs, where the values can be any Python
object. The keys, in contrast, are immutable Python objects, such as strings, tuples, or numbers.
Creating the Dictionary Example:
 Curly brackets are the simplest way to Employee = {"Name": "Johnny", "Age": 32, "salar
generate a Python dictionary, although there y":26000,"Company":“BIT"}
are other approaches as well. print(type(Employee))
 With many key-value pairs surrounded in print("printing Employee data .... ")
curly brackets and a colon separating each print(Employee)
key from its value, the dictionary can be
built. (:).
Syntax:
Dict = {"Name":“Ram", "Age": 25}
 In the above dictionary Dict,The
keys Name and Age are the strings which comes
under the category of an immutable object.
Example 2:
# Creating an empty Dictionary # Creating a Dictionary with each item as a Pair
Dict = {}
print("Empty Dictionary: ") Dict = dict([(4, 'Rinku'), (2, Singh)])
print(Dict) print("\nDictionary with each item as a pair: "
)
# Creating a Dictionary with dict() method print(Dict)
Dict = dict({1: 'Hcl', 2: 'WIPRO', 3:'Facebook'}
print("\nCreate Dictionary by using dict()
: ")
print(Dict)
Accessing the dictionary values
 To access data contained in lists and tuples, indexing has been studied.
 The keys of the dictionary can be used to obtain the values because they are unique from one
another.
Example:
Employee = {"Name": "Dev", "Age": 20, "salary":45000,"Company":"WIPRO"}
print(type(Employee))
print("printing Employee data .... ")
print("Name : %s" %Employee["Name"])
print("Age : %d" %Employee["Age"])
print("Salary : %d" %Employee["salary"])
print("Company : %s" %Employee["Company"])
Adding Dictionary Values print("\nDictionary after adding 3 elements: ")
 The dictionary is a mutable data type, and
utilising the right keys allows you to change its print(Dict)
values. # Adding set of values with a single Key
 Dict[key] = value and the value can both be Dict['Emp_ages'] = 20, 33, 24
modified. An existing value can also be updated print("\nDictionary after adding 3 elements: ")
using the update() method.
Example:
print(Dict)
# Creating an empty Dictionary # Updating existing Key'sValue
Dict = {} Dict[3] = 'JavaTpoint'
print("Empty Dictionary: ")
print("\nUpdated key value: ")
print(Dict) print(Dict)
# Adding elements to dictionary one at a time
Dict[0] = ‘Pabitra'
Dict[2] = 'John'
Dict[3] = 'Rocky'
Example 2:
Employee = {"Name": "Dev", "Age": 20, "salary":45000,"Company":"WIPRO"}
print(type(Employee))
print("printing Employee data .... ")
print(Employee)
print("Enter the details of the new employee....");
Employee["Name"] = input("Name: ");
Employee["Age"] = int(input("Age: "));
Employee["salary"] = int(input("Salary: "));
Employee["Company"] = input("Company:");
print("printing the new data");
print(Employee)
Deleting Elements using del Keyword
 The items of the dictionary can be deleted by using the del keyword as given below.
Example:
Employee = {"Name": "David", "Age": 30, "salary":55000,"Company":"WIPRO"}
print(type(Employee))
print("printing Employee data .... ")
print(Employee)
print("Deleting some of the employee data")
del Employee["Name"]
del Employee["Company"]
print("printing the modified information ")
print(Employee)
print("Deleting the dictionary: Employee");
del Employee
print("Lets try to print it again ");
print(Employee)
Deleting Elements using pop() Method
 A dictionary is a group of key-value pairs in Python.You can retrieve, insert, and remove
items using this unordered, mutable data type by using their keys.
 The pop() method is one of the ways to get rid of elements from a dictionary.
# Creating a Dictionary
Dict1 = {1: 'JavaTpoint', 2: 'Educational', 3: 'Website'}
# Deleting a key
# using pop() method
pop_key = Dict1.pop(2)
print(Dict1)
Iterating Dictionary: #for loop to print all the values of the dictionary
A dictionary can be iterated using for loop as Employee = {"Name": "John", "Age": 29, "salary"
given below :25000,"Company":"PRO"} for x in Employee:
Example:
# for loop to print all the keys of a dictionary print(Employee[x])
Employee = {"Name": "John", "Age": 29, "salary"
:25000,"Company":"PRO"} #for loop to print the items of the dictionary by usi
for x in Employee: ng items() method
print(x) Employee = {"Name": "John", "Age": 29, "salary"
:25000,"Company":"PRO"}
for x in Employee.items():
print(x)
Properties of Dictionary:  Dynamic Size
 Unordered  Dictionaries are dynamic and can grow or shrink in size as
items are added or removed.
 Dictionaries are unordered collections, meaning that the
order of items is not guaranteed. This means that items are  Nested Dictionaries
not stored in the order you define them.  Dictionaries can contain other dictionaries as values,
 Mutable allowing you to create nested structures for complex data.
 Dictionaries are mutable, which means you can add, remove, employees = {
or change key-value pairs after the dictionary has been "Employee1": {"Name": "Dev", "Age": 20},
created. "Employee2": {"Name": "Alex", "Age": 25}
 Key-value pairs }
 Dictionaries store data in key-value pairs, where each key is
unique within the dictionary. Keys are used as identifiers to
access values.  No Duplicate Keys, but duplicate values allowed
 Unique keys  While each key must be unique, dictionaries allow duplicate
values.
 Each key in a dictionary must be unique. If a duplicate key is
added, the last value assigned to that key will overwrite any  Keys and values can be of different types
previous values. Both keys and values in a dictionary can be of any data type,
 Efficient Data Retrieval and different pairs in the same dictionary can have different
types.
 Dictionaries are implemented using hash tables, making data
retrieval by key very fast on average, regardless of the
dictionary’s size.
Built-in Dictionary Functions:
 A function is a method that can be used on a construct to yield a value. Additionally, the construct is
unaltered. A few of the Python methods can be combined with a Python dictionary.
 The built-in Python dictionary methods are listed below, along with a brief description.
len()
 The dictionary's length is returned via the len() function in Python. The string is lengthened by one for
each key-value pair.
dict = {1:“Ram", 2:“Shyam", 3:“Sita", 4: "Bhim"}
len(dict)
any()
 It is a built-in function that returns True if at least one element in an iterable is truthy; otherwise, it
returns False..
dict = {1: "Ayan", 2: "Bunny", 3: "Ram", 4: "Bheem"}
result=any({'':'','':'','3':''})
print(result)
all() sorting has no effect on the original Python
 The all() function in Python is used to dictionary.
check if all elements in an iterable are dict = {7: "Ayan", 5: "Bunny", 8: "Ram", 1:
truthy. Unlike in any() method, all() only "Bheem"}
returns True if each of the dictionary's keys result = sorted(dict)
contain a True Boolean value. print(result) # Output: [1, 5, 7, 8]
dict = {1: "Ayan", 2: "Bunny", 3: "Ram", 4: #To print values
"Bheem"}
dict = {7: "Ayan", 5: "Bunny", 8: "Ram", 1:
result=all({1: '', 2: '', '': ''}) "Bheem"}
print(result) result = sorted(dict.values())
sorted() print(result) # Output: ['Ayan', 'Bheem', 'Bunny',
 Like it does with lists and tuples, the 'Ram']
sorted() method returns an ordered series
of the dictionary's keys. The ascending
Built-in Dictionary methods Example:
 Python has a set of built-in methods that # dictionary methods
you can use on dictionaries. The built-in dict = {1: "Hcl", 2: "WIPRO", 3: "Facebook",
python dictionary methods along with 4: "Amazon", 5: "Flipkart"}
the description and Code as: # clear() method
clear() dict.clear()
 The clear() method in Python is used
print(dict)
to remove all items from a dictionary,
effectively making it an empty
dictionary.
Syntax:
dict.clear()
copy()
 The copy() method in Python is used to create a shallow copy of a dictionary.
 A shallow copy means that the method creates a new dictionary with the same key-value pairs as
the original dictionary.
 However, if the values in the dictionary are mutable objects (e.g., lists or other dictionaries),
changes to those objects will affect both the original and the copied dictionary.
Syntax:
new_dict = original_dict.copy()
# dictionary methods
dict = {1: "Hcl", 2: "WIPRO", 3: "Facebook", 4: "Amazon", 5: "Flipkart"}
# copy() method
dict_demo = dict.copy()
print(dict_demo)
pop()
 The pop() method in Python is used to remove a key-value pair from a dictionary. It
returns the value associated with the specified key and removes that key-value pair from the
dictionary.
# dictionary methods
dict = {1: "Hcl", 2: "WIPRO", 3: "Facebook", 4: "Amazon", 5: "Flipkart"}
# pop() method
dict_demo = dict.copy()
x = dict_demo.pop(1)
print(x)
popitem() keys()
removes the most recent key-value It returns all the keys of the
pair entered dictionary.
# dictionary methods # dictionary methods
dict = {1: "Hcl", 2: "WIPRO", 3: "F dict = {1: "Hcl", 2: "WIPRO", 3: "Faceb
acebook", 4: "Amazon", 5: "Flipkar ook", 4: "Amazon", 5: "Flipkart"}
t“} # keys() method
# popitem() method print(dict.keys())
dict_demo.popitem()
print(dict_demo)
items() get()
It returns all the key-value pairs as a It is used to get the value specified
tuple. for the passed key.
# dictionary methods # dictionary methods
dict = {1: "Hcl", 2: "WIPRO", 3: "Faceb dict = {1: "Hcl", 2: "WIPRO", 3: "Faceb
ook", 4: "Amazon", 5: "Flipkart"} ook", 4: "Amazon", 5: "Flipkart"}
# items() method # get() method
print(dict_demo.items()) print(dict_demo.get(3))
update()
 It mainly updates all the dictionary by adding the key-value pair of dict2 to this
dictionary.
# dictionary methods
dict = {1: "Hcl", 2: "WIPRO", 3: "Facebook", 4: "Amazon", 5: "Flipkart"}
# update() method
dict_demo.update({ 3: "TCS"})
print(dict_demo)
Nested Dictionary
A dictionary can contains dictionaries, this is called nested dictionaries.
Student={ “name”: “Ram Kumar”,
“Subjects”:{ “DBMS”=65, “Python”=75, “Probability”=54, “Discrete” =88} }
#Access data of DBMS
Print(Student[“Subjects”] [“DBMS”])
Print(list(Student.values())) #Print values in list
Pairs=list(Students.items())
Print(Pairs[0]) # print items
Write a Python script to merge two Python dictionaries.
# Create the first dictionary 'd1' with key-value pairs.
d1 = {'a': 100, 'b': 200}
# Create the second dictionary 'd2' with key-value pairs.
d2 = {'x': 300, 'y': 200}
# Create a new dictionary 'd' and initialize it as a copy of 'd1'.
d = d1.copy()
# Update the dictionary 'd' by adding key-value pairs from 'd2'.
d.update(d2)
# Print the dictionary 'd' after combining the key-value pairs from 'd1' and 'd2.
print(d)
Write a Python program to sum all the items in a dictionary.
# Create a dictionary 'my_dict' with key-value pairs.
my_dict = {'data1': 100, 'data2': -54, 'data3': 247}
# Use the 'sum' function to calculate the sum of all values in the 'my_dict' dictionary.
# 'my_dict.values()' extracts the values from the dictionary, and 'sum' calculates their sum.
result = sum(my_dict.values())
# Print the result, which is the sum of the values.
print(result)
Write a Python program to remove a key from a dictionary.
# Create a dictionary 'myDict' with key-value pairs.
myDict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Print the original dictionary 'myDict'.
print(myDict)
# Check if the key 'a' exists in the 'myDict' dictionary.
if 'a' in myDict:
# If 'a' is in the dictionary, delete the key-value pair with the key 'a'.
del myDict['a']
# Print the updated dictionary 'myDict' after deleting the key 'a' (if it existed).
print(myDict)
Write a Python program to sort a given dictionary by key
# Create a dictionary 'color_dict' with color names as keys and their corresponding color codes in
hexadecimal format as values.
color_dict = {
'red': '#FF0000',
'green': '#008000',
'black': '#000000',
'white': '#FFFFFF'
}
for key in sorted(color_dict):
print("%s: %s" % (key, color_dict[key]))
Write a Python program to print a dictionary in table format.
my_dict = {'C1': [1, 2, 3], 'C2': [5, 6, 7], 'C3': [9, 10, 11]}
for row in zip(*([key] + (value) for key, value in sorted(my_dict.items()))):
print(*row)
Unit-7
Functions
In Python, a function is a block of code that performs a specific task.
It's a reusable piece of code that can be called from anywhere in your
program.
This promotes modularity, readability, and efficiency in your code.
Defining a Function
﴿ To define a function, you use the def keyword followed by the function name
and parentheses:
def function_name():
# Function body
Example: Parameters
def greet(name): They are placeholders for values that
#This function greets the person passed as a will be passed to the function when it's
parameter. called.
return f"Hello, {name}!" Within the function, they represent the
# Calling the function values that are passed in.
print(greet("Manisha")) Used to specify the type and number of
inputs a function expects.
 In Python, information can be passed to
a function through arguments. The Arguments
function receives this information in its They are the actual values that are
parameters and can process or utilize assigned to the parameters.
it within its body. Provide the data that the function will
process.
Example:
def greet(name, age): # name and age are parameters
print("Hello,", name, "!You are", age, "years old.")
greet("Alice", 30) # "Alice" and 30 are arguments

name and age are parameters defined in the greet function.


When the function is called with greet("Alice", 30), "Alice" is passed as
the argument for the name parameter, and 30 is passed as the argument for
the age parameter.
# Function to add two numbers is {result}")
def add_numbers(a, b):  Write a program in python using
return a + b function to calculate area of circle
num1 = float(input("Enter the first
number: "))
num2 = float(input("Enter the second
number: "))
# Calling the function
result = add_numbers(num1, num2)
# Displaying the result
print(f"The sum of {num1} and {num2}
Passing Arguments to functions
1. Positional Arguments:
Arguments are assigned to parameters based on their position in the
function call.
The number and order of arguments must match the number and order of
parameters.
def greet(name, age):
print("Hello,", name, "!You are", age, "years old.")
greet("Alice", 30) # Output: Hello, Alice!You are 30 years old.
2. Keyword Arguments:
Arguments are assigned to parameters by keyword, allowing you to specify
the parameter name explicitly.
Order doesn't matter in this case.
def greet(name, age):
print("Hello,", name, "!You are", age, "years old.")
greet(age=30, name="Alice") # Output: Hello, Alice!You are 30 years old.
3. Default Argument Values:
You can assign default values to parameters, which are used when the
function is called without providing a value for that parameter.
def greet(name, age=30):
print("Hello,", name, "!You are", age, "years old.")
greet("Bob") # Output: Hello, Bob!You are 30 years old.
greet("Charlie", 25) # Output: Hello, Charlie!You are 25 years old.
Example: # Input for keyword arguments
def add_numbers(a, b=0): num3 = float(input("Enter the first number (keyword):
"))
return a + b
num4 = float(input("Enter the second number
# Getting user input
(keyword): "))
print("Enter two numbers to calculate their sum.")
result2 = add_numbers(a=num3, b=num4)
# Input for positional arguments
print(f"Sum using keyword arguments: {result2}")
num1 = float(input("Enter the first number
# Input using default argument
(positional): "))
num5 = float(input("Enter the first number (default
num2 = float(input("Enter the second number
second number is 0): "))
(positional): "))
result3 = add_numbers(num5)
result1 = add_numbers(num1, num2)
print(f"Sum using default argument: {result3}")
print(f"Sum using positional arguments: {result1}")
Equivalent Function Calls # 2. Keyword arguments
 Equivalent function calls occur when a function greet(name="Alice", age=25, city="NewYork")
can be invoked in different ways (using positional # 3. Mixed (positional + keyword) arguments
arguments, keyword arguments, or default
greet("Alice", age=25, city="NewYork")
values) but produces the same result.
# 4. Default arguments (city will use its default value)
 This flexibility allows you to call a function in the
most convenient manner for your specific use greet("Alice", 25)
case. # 5. Unpacking arguments from a tuple
Example: args = ("Alice", 25, "NewYork")
# Define a function greet(*args)
def greet(name, age, city="Unknown"): # 6. Unpacking arguments from a dictionary
print(f"Hello {name}, age {age}, from {city}!") kwargs = {"name": "Alice", "age": 25, "city": "New
# Equivalent function calls York"}
# 1. Positional arguments greet(**kwargs)
greet("Alice", 25, "NewYork")
Avoiding Argument Errors:
Argument errors occur when the arguments passed to a function do not match its parameter
requirements.
Understanding common errors and strategies to avoid them ensures your code runs correctly
and is easy to debug.
To avoid argument errors, follow these tips:
 Match the number of arguments to the number of parameters.
 Ensure the argument types match the parameter types.
 Use keyword arguments to improve code readability and flexibility.
 Consider using default values for optional parameters.
 Leverage type hints to clarify expected argument types.
Write a program in python using function to calculate simple interest.
Write a program in python using function to calculate compound interest.
Write a program in python using function to find first 10 Fibonacci series of
number.
Write a program in python using function to print multiplication table of any
input number.
Write a program in python to calculate TSA amd CSA of cylinder (Hint:
TSA=2πr (r + h), CSA = 2πrh).
Return Types in Python
 Functions in Python can return various types of values based on the task they perform.
 The returned value can be a single data type (e.g., integer, string), a complex data type (e.g.,
dictionary, list), or even nothing (None).
1. Returning a Simple Value
 A function can return a single, simple value like a number, string, or boolean.
def add(a, b):
return a + b
result = add(5, 3)
print(result) # Output: 8
 The return statement exits the function and sends the specified value back to the caller.
 A function without a return statement returns None.
2. Returning Multiple Values age = int(input("Enter your age: "))
Returning a Dictionary city = input("Enter your city: ")
 A function can return a dictionary when return {"name": name, "age": age, "city":
you need to provide multiple related city}
values in a structured format. person = get_person_details()
 A dictionary is a versatile data structure print("Person details as a dictionary:", person)
in Python that stores key-value pairs.
 You can easily return a dictionary from a
function to provide multiple values or
structured data.

def get_person_details():
name = input("Enter your name: ")
Returning a Tuples Returning a Lists
The most common way to return multiple We can also return multiple values in a list.
values is by using tuples. When you return def get_numbers():
multiple values separated by commas, n = int(input("Enter how many numbers you
Python packs them into a tuple. want to input: "))
def get_coordinates(): numbers = []
x = float(input("Enter X coordinate: ")) for _ in range(n):
y = float(input("EnterY coordinate: ")) number = int(input("Enter a number: "))
z = float(input("Enter Z coordinate: ")) numbers.append(number)
return (x, y, z) return numbers
coordinates = get_coordinates() numbers = get_numbers()
print("Coordinates as a tuple:", coordinates) print("List of numbers:", numbers)
Passing a List to a Function Example:
 Lists are mutable, meaning they can be def modify_list(my_list):
changed in place. When you pass a list to a my_list.append(4)
function, the function receives a reference to my_list = [1, 2, 3]
the same list, allowing it to modify the
original list. modify_list(my_list)
 In Python, lists are mutable objects, meaning
print(my_list) # Output: [1, 2, 3, 4]
they can be modified in-place. Example:
 When you pass a list to a function, you're def print_items(items):
actually passing a reference to the same list for item in items:
object. print(item)
 This means any modifications made to the list fruits = ["apple", "banana", "cherry"]
inside the function will be reflected in the print_items(fruits)
original list outside the function.
Modifying a List in a Function Preventing a Function from
 Since lists are mutable, any changes made to a Modifying a List
list inside a function will affect the original list.  If you want to prevent a function from
 The append() operation modifies the original modifying the original list, you can create a
list. copy of the list before passing it to the function.
def add_item(items, new_item): This way, the function will work on a copy of
the list, leaving the original list unchanged.
items.append(new_item)
Using the copy() method
shopping_list = ["milk", "eggs"]
def modify_list(my_list):
add_item(shopping_list, "bread")
my_list.append(4)
print(shopping_list)
my_list = [1, 2, 3]
# Output: ['milk', 'eggs', 'bread']
new_list = my_list.copy()
modify_list(new_list)
print(my_list) # Output: [1, 2, 3]
print(new_list) # Output: [1, 2, 3, 4]
Using the [:] slice
def modify_list(my_list):
my_list.append(4)
my_list = [1, 2, 3]
new_list = my_list[:]
modify_list(new_list)
print(my_list) # Output: [1, 2, 3]
print(new_list) # Output: [1, 2, 3, 4]
Storing Functions in Modules in Example (math_operations.py):
Python def add(a, b):
 Storing functions in modules allows you return a + b
to organize your code, improve def subtract(a, b):
reusability, and make large programs return a - b
more manageable.
def multiply(a, b):
 A module is simply a Python file (.py)
return a * b
that contains definitions like functions,
classes, and variables. def divide(a, b):
Steps to Store Functions in a Module if b != 0:
Create a Python Module: return a / b
 A module is just a file with a .py else:
extension. return "Division by zero is not allowed!"
 Define your functions in the module.
Use the Module in Another Script: Benefits of Storing Functions in Modules
 You can import the module into any other  Reusability:
Python script and use its functions.  Functions stored in a module can be reused
across multiple programs.
Example (main.py):
 Organization:
import math_operations
 Keeping functions in separate modules makes
print(math_operations.add(5, 3)) # Output: 8 your codebase easier to read and manage.
print(math_operations.subtract(5, 3)) # Output: 2  Encapsulation:
print(math_operations.multiply(5, 3)) # Output:  Related functions can be grouped into specific
15 modules for better structure.

print(math_operations.divide(5, 0)) # Output:  Ease of Testing:


 Functions in a module can be tested
Division by zero is not allowed!
independently.
Import An Entire Module Example 2:
 When you import an entire module in import random
Python, you bring all the functions, classes, and # Generate a random integer between 1 and 10
variables defined in that module into your rand_number = random.randint(1, 10)
program.
 You will need to reference the module by its
name when accessing these components. # Choose a random item from a list
Syntax: import module_name choices = ['apple', 'banana', 'cherry']
Example 1: rand_choice = random.choice(choices)
import math
result = math.sqrt(16) print("Random Number:", rand_number)
pi_value = math.pi print("Random Choice:", rand_choice)
print("Square Root:", result)
print("Value of Pi:", pi_value)
Some other modules # Create a specific date
 os module specific_date = datetime.date(2023, 11, 15)
The os module provides a way to interact with the print("Specific Date:", specific_date)
operating system.  time Module
import os The time module provides functions for working
# Get the current working directory with time.
current_dir = os.getcwd() import time
print("Current Directory:", current_dir) # Pause the program for 2 seconds
# List files and directories in the current directory print("Waiting for 2 seconds...")
files = os.listdir(current_dir) time.sleep(2)
print("Files and Directories:", files) print("Done!")
 datetime Module # Get the current time in seconds since the epoch
The datetime module is used to manipulate dates epoch_time = time.time()
and times. print("Seconds since epoch:", epoch_time)
import datetime
# Get the current date and time
current_time = datetime.datetime.now()
print("Current Time:", current_time)
 Statistics Module print("PythonVersion:", sys.version)
The statistics module is used for statistical # Get the list of command-line arguments
calculations.operations. print("Command-line Arguments:", sys.argv)
import statistics  json Module
data = [1, 2, 2, 3, 4, 5] The json module is used for working with JSON
# Calculate the mean, median, and mode data.
mean = statistics.mean(data) import json
median = statistics.median(data) # Convert a dictionary to a JSON string
mode = statistics.mode(data) data = {'name': 'Alice', 'age': 25}
print("Mean:", mean) json_string = json.dumps(data)
print("Median:", median) print("JSON String:", json_string)
print("Mode:", mode) # Convert a JSON string back to a dictionary
 sys Module parsed_data = json.loads(json_string)
The sys module provides access to system-specific print("Parsed Data:", parsed_data)
parameters and functions.
import sys
# Print Python version
 re Module  urllib Module
The re module is used for working The urllib module is used for working
with regular expressions. with URLs.
import re import urllib.request
# Search for a pattern in a string # Fetch data from a URL
text = "Hello, my name is Alice." response =
match = re.search(r'name', text) urllib.request.urlopen("https://www.examp
if match: le.com")
print("Found 'name' at index:", html = response.read().decode('utf-8')
match.start()) print(html)
Importing Specific Functions in Python Example 2
 When you need only a few functions or from random import randint, choice
variables from a module, you can import # Generate a random integer between 1 and 10
them specifically instead of importing the random_number = randint(1, 10)
entire module.
# Choose a random item from a list
Syntax:
options = ['apple', 'banana', 'cherry']
from module_name import function_name1,
function_name2, ... random_item = choice(options)
Example:
from math import sqrt, pow print("Random Number:", random_number)
# Use imported functions directly print("Random Item:", random_item)
square_root = sqrt(25)
power = pow(2, 3)
print("Square Root:", square_root)
print("Power:", power)
Using as to Give a Function an Alias in Example 1:
Python from math import sqrt as square_root
 When you import specific functions, you can use # Using the alias to call the function
the as keyword to give the function an alias. result = square_root(49)
 This is useful for shortening long function names
print("Square Root:", result) # Output: Square Root: 7.0
or improving readability.
 It also allows you to avoid conflicts if your code
has a variable or function with the same name. Example 2:
Syntax: from statistics import mean as average
from module_name import function_name as alias_name # Using the alias for calculating the mean
data = [10, 20, 30, 40, 50]
avg = average(data)
print("Average:", avg) # Output: Average: 30
Using as to Give a Module an Alias in print(df)
Python
 The as keyword in Python allows you to assign Example 2:
an alias to a module when importing it. import matplotlib.pyplot as plt
 This is particularly useful for shortening long
# Create a simple line plot using the alias
module names or standardizing names across
x = [1, 2, 3, 4, 5]
projects for better readability and consistency.
y = [2, 4, 6, 8, 10]
Syntax:
plt.plot(x, y)
import module_name as alias_name
plt.title("Line Plot")
Example 1:
plt.xlabel("X-axis")
import pandas as pd
plt.ylabel("Y-axis")
# Create a DataFrame using the alias
plt.show()
data = {'Name': ['Alice', 'Bob'], 'Age': [25, 30]}
df = pd.DataFrame(data)
Importing All Functions in a Module Example 1:
in Python from math import *
 To import all functions, classes, and # Using the sqrt and pow functions without the
variables from a module, you can use the * `math.` prefix
wildcard. result1 = sqrt(16) # Square root of 16
 This imports everything that the module
result2 = pow(2, 3) # 2 raised to the power of 3
provides into your program's namespace.
print("Square Root:", result1) # Output: Square
Syntax: Root: 4.0
from module_name import * print("Power:", result2) # Output: Power:
8.0
Namespaces in Python throughout the execution.
 A namespace is a container that holds a Example:
collection of identifiers (variable names, print(len("Hello")) # Using the built-in `len`
function names, class names, etc.) and maps function
them to their corresponding objects.
 In simple terms, it's like a dictionary where 2. Global Namespace
names are the keys, and the objects (values)  Contains names defined at the top level of a
they point to are stored in memory. script or module.
Types of Namespaces in Python  Exists until the script/module terminates.
 Python maintains different types of Example:
namespaces based on the scope and lifecycle x = 10 # Global variable
of identifiers:
print(x)
1. Built-in Namespace
 Contains names for all built-in functions and
exceptions (e.g., print(), len(), int()).
 Available as soon as Python is started and lasts
3. Local Namespace names defined in the outer (enclosing)
 Contains names defined inside a function or function.
method.  Accessed using the nonlocal keyword.
 Created when the function is called and def outer_function():
destroyed after the function finishes z = 10 # Enclosing variable
execution. def inner_function():
def my_function(): nonlocal z
y = 5 # Local variable z += 5
print(y) print("Inner z:", z)
my_function() inner_function()
4. Enclosing Namespace (Nonlocal print("Outer z:", z)
Namespace)
outer_function()
 Exists in nested functions and contains
Package in python package.
 Python Packages are a way to organize and » Init File: Include an __init__.py file in the
structure your Python code into reusable package directory. This file can be empty or can
components. contain an initialization code for your package. It
 Think of it like a folder that contains related signals to Python that the directory should be
Python files (modules) that work together to treated as a package.
provide certain functionality. » Subpackages:You can create sub-packages
 Packages help keep your code organized, make it within your package by adding additional
easier to manage and maintain, and allow you to directories containing modules, along with their
share your code with others. own __init__.py files.
» Importing: To use modules from your package,
Create Package in Python import them into your Python scripts using dot
» Create a Directory: Start by creating a notation.
directory (folder) for your package. This » Distribution: If you want to distribute your
directory will serve as the root of your package package for others to use, you can create a
structure. setup.py file using Python’s setuptools library.
» Add Modules: Within the package directory, This file defines metadata about your package and
you can add Python files (modules) containing specifies how it should be installed.
your code. Each module should represent a
distinct functionality or component of your
Example
 Create a directory named mypackage.
 Inside mypackage, create two Python files: module1.py and module2.py.
 Create an __init__.py file inside mypackage (it can be empty).
 Add some code to the modules.
 Finally, demonstrate how to import and use the modules from the package.
# module1.py from mypackage import module1, module2
def greet(name): # Using functions from module1
print(f"Hello, {name}!") module1.greet(“Ram")
# Using functions from module2
# module2.py result = module2.add(3, 5)
def add(a, b): print("The result of addition is:", result)
return a + b
Re-importing Modules and import importlib
Packages import mod2 # Import your module
 When working in a python interpreter, # Make changes to `my_module` source code
there might be instances where you update importlib.reload(mod2) # Re-imports and reloads
a package or module and need the the module
interpreter to recognize these changes
without restarting it.
Using the importlib Module
 Python provides the importlib module,
which includes utilities for importing and
reloading modules. The importlib.reload()
function is particularly useful for re-
importing updated modules.
Unit 8
Classes and Object
Introduction:
In Python object-oriented Programming (OOPs) is a programming
paradigm that uses objects and classes in programming. It aims to implement
real-world entities like inheritance, polymorphisms, encapsulation, etc. in the
programming.
The main concept of object-oriented Programming (OOPs) or oops
concepts in Python is to bind the data and the functions that work together as
a single unit so that no other part of the code can access this data.
OOPs Concepts in Python:
Class in Python
Objects in Python
Polymorphism in Python
Encapsulation in Python
Inheritance in Python
Data Abstraction in Python
Python Class
A class is a collection of objects. A class contains the blueprints or the prototype from
which the objects are being created. It is a logical entity that contains some attributes
and methods.
To understand the need for creating a class let’s consider an example, let’s say you
wanted to track the number of dogs that may have different attributes like breed, and
age. If a list is used, the first element could be the dog’s breed while the second
element could represent its age. Let’s suppose there are 100 different dogs, then how
would you know which element is supposed to be which? What if you wanted to add
other properties to these dogs? This lacks organization and it’s the exact need for
classes.
class ClassName:
# Statement-1
...
# Statement-N
Python Objects:
In object oriented programming Python, The object is an entity that has a state and behavior
associated with it. It may be any real-world object like a mouse, keyboard, chair, table, pen, etc.
Integers, strings, floating-point numbers, even arrays, and dictionaries, are all objects. More
specifically, any single integer or any single string is an object. The number 12 is an object, the
string “Hello, world” is an object, a list is an object that can hold other objects, and so on.You’ve
been using objects all along and may not even realize it.
An object consists of:
 State: It is represented by the attributes of an object. It also reflects the properties of an object.
 Behavior: It is represented by the methods of an object. It also reflects the response of an
object to other objects.
 Identity: It gives a unique name to an object and enables one object to interact with other
objects.
Example: Tommy = Dog("Tommy")
class Dog: print("My name is
# class attribute {}".format(Rodger.name))
attr1 = "mammal" print("My name is
# Instance attribute {}".format(Tommy.name))
def __init__(self, name):
self.name = name
# Driver code
# Object instantiation
Rodger = Dog("Rodger")
Defining a Class:
A class is a blueprint for creating objects. It defines a set of attributes (variables) and
methods (functions) that the objects created from the class can use.
Adding Instance Variables:
Instance variables are attributes that are unique to each instance of a class. They are
defined within a class but outside any methods. Each object created from the class will
have its own copy of these variables.
Example:
class Animal:
def __init__(self, name, species):
self.name = name # instance variable
self.species = species # instance variable
Adding Instance Methods: Adding Class Variables:
Instance methods are functions defined Class variables are attributes that are shared
within a class that operate on instance among all instances of a class. They are
variables. They can modify the state of an defined within a class but outside any
object or perform operations using its methods. All instances of the class share the
instance variables. same value for these variables.
Example: Example:
class Animal: class Animal:
def __init__(self, name, species): kingdom = "Animalia" # class variable
self.name = name def __init__(self, name, species):
self.species = species self.name = name
def describe(self): self.species = species
return f"{self.name} is a {self.species}" def describe(self):
return f"{self.name} is a {self.species}"
Adding Class Methods @classmethod
Class methods are methods that operate on def get_kingdom(cls):
the class itself, rather than on instances of the return cls.kingdom
class. They use a decorator @classmethod and Adding Static Methods
the first parameter is cls, which refers to the
class. Static methods are methods that do not
operate on class or instance variables. They
Example: use the @staticmethod decorator and do not
class Animal: take self or cls as the first parameter.
kingdom = "Animalia"
def __init__(self, name, species):
self.name = name
self.species = species
def describe(self):
return f"{self.name} is a {self.species}"
Example: corresponds to an animal
class Animal: return name.lower() in ["dog", "cat", "bird",
kingdom = "Animalia" "fish"]
def __init__(self, name, species): dog = Animal("Buddy", "Dog")
self.name = name print(dog.describe())
self.species = species print(Animal.get_kingdom())
def describe(self): print(Animal.is_animal("Dog"))
return f"{self.name} is a {self.species}" print(Animal.is_animal("Car"))
@classmethod Note: Decorators allow us to wrap another
def get_kingdom(cls): function in order to extend the behaviour
the wrapping function, without
return cls.kingdom
permanently modifying it.
@staticmethod
def is_animal(name):
Python Inheritance
In Python object oriented Programming, Inheritance is the capability of one class to derive or inherit the
properties from another class. The class that derives properties is called the derived class or child class and
the class from which the properties are being derived is called the base class or parent class. The benefits of
inheritance are:
 It represents real-world relationships well.
 It provides the reusability of a code. We don’t have to write the same code again and again. Also, it allows
us to add more features to a class without modifying it.
 It is transitive in nature, which means that if class B inherits from another class A, then all the subclasses of
B would automatically inherit from class A.
Types of Inheritance
 Single Inheritance: Single-level inheritance enables a derived class to inherit characteristics from a
single-parent class.
 Multilevel Inheritance: Multi-level inheritance enables a derived class to inherit properties from an
immediate parent class which in turn inherits properties from his parent class.
 Hierarchical Inheritance: Hierarchical-level inheritance enables more than one derived class to
inherit properties from a parent class.
 Multiple Inheritance: Multiple-level inheritance enables one derived class to inherit properties from
more than one base class.
Single Inheritance: #child class Dog inherits the base cla
Single inheritance enables a ss Animal
derived class to inherit class Dog(Animal):
properties from a single parent def bark(self):
class, thus enabling code print("dog barking")
reusability and the addition of
d = Dog()
new features to existing code.
d.bark()
class Animal:
d.speak()
def speak(self):
print("Animal Speaking")
Multilevel Inheritance: class Dog(Animal):
When a class can be derived from def bark(self):
more than one base class this type of print("dog barking")
inheritance is called multiple #The child class Dogchild inherits another chil
inheritances. d class Dog
In multiple inheritances, all the class DogChild(Dog):
features of the base classes are def eat(self):
inherited into the derived class. print("Eating bread...")
class Animal: d = DogChild()
def speak(self): d.bark()
print("Animal Speaking") d.speak()
#The child class Dog inherits the base class An d.eat()
imal
Multiple Inheritance: def Multiplication(self,a,b):
When a class can be derived from return a*b;
more than one base class this type of class Derived(Calculation1,Calculation2):
inheritance is called multiple def Divide(self,a,b):
inheritances.
return a/b;
In multiple inheritances, all the
d = Derived()
features of the base classes are
inherited into the derived class. print(d.Summation(10,20))
class Calculation1: print(d.Multiplication(10,20))
def Summation(self,a,b): print(d.Divide(10,20))
return a+b;
class Calculation2:
Hierarchical Inheritance: def __init__(self, a, b):
 When more than one derived class are created super().__init__(a, b)
from a single base this type of inheritance is
called hierarchical inheritance.
print(f"{self.a} can bark")
 In this program, we have a parent (base) class class Cat(Animal):
and two child (derived) classes. def __init__(self, a, b):
class Animal: super().__init__(a, b)
def __init__(self, a, b): print(f"{self.b} can mewaoo")
self.a = a d = Animal("Dog", "Cat")
self.b = b d.walk()
def walk(self): b = Dog("Dog", "Cat")
print(f"{self.a} can walk") c = Cat("Dog", "Cat")
print(f"{self.b} Can walk")
class Dog(Animal):
Hybrid Inheritance: def __init__(self, name):
 Inheritance consisting of multiple types of super().__init__(name)
inheritance is called hybrid inheritance. def hang_upside_down(self):
class Animal: print(f"{self.name} can hang upside down")
def __init__(self, name): animal = Animal("Generic Animal")
self.name = name animal.walk()
def walk(self): mammal = Mammal("Mammal")
print(f"{self.name} can walk") mammal.walk()
class Mammal(Animal): mammal.feed_milk()
def __init__(self, name): bird = Bird("Bird")
super().__init__(name) bird.walk()
def feed_milk(self): bird.fly()
print(f"{self.name} can feed milk")
bat = Bat("Bat")
class Bird(Animal):
bat.walk()
def __init__(self, name):
super().__init__(name)
bat.feed_milk()
def fly(self): bat.fly()
print(f"{self.name} can fly") bat.hang_upside_down()
class Bat(Mammal, Bird): # Bat inherits from both
Mammal and Bird
Python Polymorphism: print("Sparrows can fly.")
In object oriented Programming Python, class ostrich(Bird):
Polymorphism simply means having many def flight(self):
forms. print("Ostriches cannot fly.")
 For example, we need to determine if the obj_bird = Bird()
given species of birds fly or not, using
polymorphism we can do this using a single obj_spr = sparrow()
function. obj_ost = ostrich()
class Bird: obj_bird.intro()
def intro(self): obj_bird.flight()
print("There are many types of birds.") obj_spr.intro()
def flight(self): obj_spr.flight()
print("Most of the birds can fly but obj_ost.intro()
some cannot.") obj_ost.flight()
class sparrow(Bird):
def flight(self):
Python Encapsulation
 In Python object oriented programming, Encapsulation is one of the fundamental concepts
in object-oriented programming (OOP).
 It describes the idea of wrapping data and the methods that work on data within one unit.
 This puts restrictions on accessing variables and methods directly and can prevent the
accidental modification of data.
 To prevent accidental change, an object’s variable can only be changed by an object’s
method. Those types of variables are known as private variables.
 Wrapping data and function into single unit (object).
Protected members class Base:
 Protected members (in C++ and JAVA) are def __init__(self):
those members of the class that cannot be self.a = “Hello"
accessed outside the class but can be self.__c = “Class"
accessed from within the class and its
class Derived(Base):
subclasses.
def __init__(self):
 To accomplish this in Python, just
follow the convention by prefixing the Base.__init__(self)
name of the member by a single print("Calling private member of base
underscore “_”. class: ")
print(self.__c)
obj1 = Base()
print(obj1.a)
# Creating a base class # Modify the protected variable:
class Base: self._a = 3
def __init__(self): print("Calling modified protected member
# Protected member outside class: ",
self._a = 2 self._a)
# Creating a derived class obj1 = Derived()
class Derived(Base):
def __init__(self): obj2 = Base()
Base.__init__(self) print("Accessing protected member of obj1: ",
print("Calling protected member of base class: ", obj1._a)
self._a) # Accessing the protected variable outside
print("Accessing protected member of obj2: ",
obj2._a)
Private members # Creating a derived class
 Private members are similar to protected class Derived(Base):
members, but the difference is that class members def __init__(self):
declared as private cannot be accessed outside the # Calling constructor of
class, nor by any derived class. In other words,
private members are only accessible within the # Base class
class where they are declared. Base.__init__(self)
 To define a private member prefix the member print("Calling private member of base class: ")
name with double underscore “__”. print(self.__c)
# Driver code
obj1 = Base()
class Base: print(obj1.a)
def __init__(self):
self.a = “HWIC"
self.__c = “HWIC"
Data Abstraction
 Data abstraction is one of the most essential concepts of Python OOPs which is
used to hide irrelevant details from the user and show the details that are relevant
to the users.
 A simple example of this can be a car. A car has an accelerator, clutch, and break
and we all know that pressing an accelerator will increase the speed of the car and
applying the brake can stop the car but we don't know the internal mechanism of
the car and how these functionalities can work this detail hiding is known as data
abstraction.
 Data abstraction in Python is a programming concept that hides complex
implementation details while exposing only essential information and
functionalities to users. In Python, we can achieve data abstraction by using
abstract classes and abstract classes can be created using abc (abstract base class)
module and abstractmethod of abc module.
from abc import ABC, abstractmethod class Cat(Animal):
# Abstract base class def sound(self):
class Animal(ABC): print(f"{self.name} says Meow!")
def __init__(self, name): dog = Dog("Dog")
self.name = name cat = Cat("Cat")
@abstractmethod dog.walk()
def sound(self): dog.sound()
pass cat.walk()
def walk(self): cat.sound()
print(f"{self.name} can walk")
class Dog(Animal):
def sound(self):
print(f"{self.name} says Woof!")
#Create Account class with 2 attributes- self.balance+=amount
balance and account no. Create methods for print("Your account no:",self.account_no,"is
debit, credit and printing the balance. Credited by",amount)
class Account: print("Your New balance is:",self.balance)
def __init__(self,bal,acc): a1=Account(10000,23534245)
self.balance=bal print("Your Balance is:",a1.balance,"And Account
self.account_no=acc No. is:",a1.account_no)
def debit(self,amount): a1.debit(2000)
self.balance-=amount a1.credit(5000)
print("Your account no:",self.account_no,"is
debited by",amount)
print("Your New balance is:",self.balance)
def credit(self,amount):
Python Constructor: #Creating class
A constructor is a special type of method Class Student():
(function) which is used to initialize the def __init__(self,fullname):
instance members of the class. self.name=fullname
Constructors can be of four types. #creating object
 Parameterized Constructor
S1=student(“Hari”)
 Non-parameterized Constructor
Print(S1.name)
 Default constructor
 Copy Constructor
__init__() function:
All classes have a function called
__init__(),which is always executed when
the object being imitated.
Creating the constructor in python: self.id = id
In Python, the method self.name = name
the __init__() simulates the constructor of def display(self):
the class. This method is called when the class print("ID: %d \nName: %s" % (self.id, self.n
is instantiated. It accepts the self-keyword as ame))
a first argument which allows accessing the
attributes or method of the class. emp1 = Employee(“Binod", 101)
We can pass any number of arguments at the emp2 = Employee(“Sarita", 102)
time of creating the class object, depending # accessing display() method to print employee 1 info
upon the __init__() definition. It is mostly rmation
used to initialize the class attributes. Every emp1.display()
class must have a constructor, even if it # accessing display() method to print employee 2 inf
simply relies on the default constructor. ormation
Example emp2.display()
class Employee:
def __init__(self, name, id):
#Create student class that takes name and marks of 3 subjects as arguments in constructor.
Then create a method to print the average.
class Student:
def __init__(self,name,marks):
self.name=name
self.marks=marks
def avg(self):
marks=sum(self.marks)/3
print("Average marks is:",marks)
s=Student("Binod",[56,76,45])
s.avg()
Method Overloading:
Two or more methods have the same name but different numbers of parameters or
different types of parameters, or both. These methods are called overloaded methods and
this is called method overloading.
Like other languages (for example, method overloading in C++) do, python does not
support method overloading by default. But there are different ways to achieve method
overloading in Python.
We can use *args and **kwargs to overload methods.
Example 1: Example2:
class calculation: class calc:
def sum(self,*args): def sum(self,a=0,b=0):
total=0 return a+b
for i in args: def sum(self,a=0,b=0,c=0):
total=total+i return a+b+c
return total c=calc()
b=calculation() print(c.sum(5,6))
print(b.sum(5,7)) print(c.sum(5,6,9))
print(b.sum(5,7,8))
print(b.sum(5,7,8,6,4,7))
Method Overriding: class Son(Father):
Method overriding in Python is a feature that def Sleep(self):
allows a subclass to provide a specific print("Sleep at 12:00PM to 7:00 AM")
implementation for a method that is already super().Sleep()
defined in its superclass.
s=Son()
The overridden method in the subclass has the
s.Sleep()
same name, parameters, and return type as
the method in the superclass.
class Father:
def Sleep(self):
print("Sleep from 10:00 PM to 5:00 AM")
def eat(self):
print("Eat food")
#Write difference between method overloading and method overriding in python.
Access Modifiers:
Python supports three types of access modifiers which are public, private and protected. These access
modifiers provide restrictions on the access of member variables and methods of the class from any
object outside the class.
Public Access Modifier
By default the member variables and methods are public which means they can be accessed from
anywhere outside or inside the class. No public keyword is required to make the class or methods and
properties public.
Example:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def display(self):
print("Name:", self.name)
print("Age:", self.age)
s = Student("John", 20)
s.display()
Private Access Modifier:
Class properties and methods with private access modifier can only be accessed within the class where
they are defined and cannot be accessed outside the class.
In Python private properties and methods are declared by adding a prefix with two underscores(‘__’)
before their declaration.
Example:
class BankAccount:
def __init__(self, account_number, balance):
self.__account_number = account_number
self.__balance = balance

# def __display_balance(self):
print("Balance:", self.__balance)
b = BankAccount(1234567890, 5000)
# b.__display_balance()
Protected Access Modifier: print("Name:", self._name)
Class properties and methods with protected print("Age:", self._age)
access modifier can be accessed within the class Student(Person):
class and from the class that inherits the def __init__(self, name, age, roll_number):
protected class.
super().__init__(name, age)
In python, protected members and methods
self._roll_number = roll_number
are declared using single underscore(‘_’) as
prefix before their names. def display(self):
Example: self._display()
class Person: print("Roll Number:", self._roll_number)
def __init__(self, name, age): s = Student("John", 20, 123)
self._name = name s.display()
self._age = age
def _display(self):
Abstract Class:
An abstract class in Python is a class that cannot be instantiated on its own and is
typically used to define a common interface for its subclasses.
Abstract classes can include one or more abstract methods, which are methods
declared in the abstract class that must be implemented by any non-abstract subclass.
 To create an abstract class in Python, you use the abc (Abstract Base Class) module.
Here's how you can define and use an abstract class:
 Import the abc module: You need to import the ABC class and the abstractmethod
decorator from the abc module.
 Define an abstract class: Create a class that inherits from ABC.
 Define abstract methods: Use the @abstractmethod decorator to declare methods
that must be implemented in any subclass.
from abc import ABC,abstractmethod print("Mobile app is secured")
class BankApp(ABC): class WebApp(BankApp):
def Database(self): def Login_web(self):
print("Database successfully print("Sucessfully login")
created.") def Security(self):
@abstractmethod print("Web app is secured")
def Security(self): m=MoblieApp()
pass m.Mobile_login()
class MoblieApp(BankApp): w=WebApp()
def Mobile_login(self): w.Login_web()
print("Login to mobile app
successfully")
def Security(self):
Operator Overloading:
Operator overloading in Python allows you to define or change the behavior of operators (+, -, *, etc.)
for user-defined classes. This is done by defining special methods in your class that Python will call when
those operators are used.
Example:
class Point: p1 = Point(1, 2)
def __init__(self, x, y): p2 = Point(3, 4)
self.x = x
p3 = p1 + p2
self.y = y
def __add__(self, other): print(p3) # Output: Point(4, 6)
return Point(self.x + other.x, self.y + other.y) p4 = p1 - p2
def __sub__(self, other): print(p4) # Output: Point(-2, -2)
return Point(self.x - other.x, self.y - other.y) p5 = p1 * 3
def __mul__(self, scalar):
print(p5) # Output: Point(3, 6)
return Point(self.x * scalar, self.y * scalar)
def __eq__(self, other): print(p1 == p2) # Output: False
return self.x == other.x and self.y == other.y print(p1 == Point(1, 2)) # Output:
def __str__(self): True
return f"Point({self.x}, {self.y})"
Magic Methods:  __sub__(self, other): Subtraction (-).
Magic methods in Python, also known as  __mul__(self, other): Multiplication (*).
dunder (double underscore) methods, are  __truediv__(self, other): True division (/).
special methods with double underscores at the  __floordiv__(self, other): Floor division (//).
beginning and end of their names. These
methods allow you to define the behavior of  __mod__(self, other): Modulus (%).
your objects for built-in operations like  __pow__(self, other): Exponentiation (**).
arithmetic, comparison, string representation,  __eq__(self, other): Equality (==).
and more.  __ne__(self, other): Inequality (!=).
 __init__(self, ...): Object initializer  __lt__(self, other): Less than (<).
(constructor).
 __le__(self, other): Less than or equal to
 __repr__(self): Official string representation (<=).
of the object.
 __gt__(self, other): Greater than (>).
 __str__(self): Informal string representation
 __ge__(self, other): Greater than or equal to
of the object.
(>=).
 __add__(self, other): Addition (+).
 __getattr__(self, name): Called when an attribute is not found.
 __setattr__(self, name, value): Called when setting an attribute.
 __delattr__(self, name): Called when deleting an attribute.
 __len__(self): Called by len().
 __getitem__(self, key): Called to get an item.
 __setitem__(self, key, value): Called to set an item.
 __delitem__(self, key): Called to delete an item.
 __iter__(self): Called to get an iterator.
 __enter__(self): Called when entering a with statement.
 __exit__(self, exc_type, exc_value, traceback): Called when exiting a with statement.
Exception Handling: inside the finally block.
 Exception handling in Python is a mechanism for Example:
responding to and managing errors or other try:
exceptional conditions that arise during the x = int(input("Enter a number: "))
execution of a program. Python uses try, except,
else, and finally blocks to handle exceptions result = 10 / x
gracefully. exceptValueError:
Basic Structure print("Invalid input. Please enter a valid number.")
try block: The code that might raise an exception except ZeroDivisionError:
is placed inside the try block. print("Division by zero is not allowed.")
except block: The code that handles the exception else:
is placed inside the except block. print(f"Result: {result}")
else block: The code that runs if no exception is finally:
raised is placed inside the else block.
print("Execution complete.")
finally block: The code that runs no matter what
(whether an exception is raised or not) is placed
Common types of Exceptions:
AttributeError: Raised when an attribute reference or assignment fails.
ImportError: Raised when an import statement fails to find the module definition or when a
from ... import fails.
IndexError: Raised when a sequence subscript is out of range.
KeyError: Raised when a dictionary key is not found.
NameError: Raised when a local or global name is not found.
TypeError: Raised when an operation or function is applied to an object of inappropriate type.
ZeroDivisionError: Raised when the second argument of a division or modulo operation is
zero.
Modules and Packages:
Modules:
The module is a simple Python file that contains collections of functions and global
variables and with having a .py extension file.
There are two types of modules in python.
 Built in Modules : These modules are ready to import and use and ships with the
python interpreter. There is no need to install such modules explicitly.
 External Modules: These modules are imported from a third party file or can be
installed using a package manager like pip or conda. Since this code is written by
someone else, we can install different versions of a same module with time.
Packages:
The package is a simple directory having collections of modules. This directory
contains Python modules and also having __init__.py file by which the interpreter
interprets it as a Package. The package is simply a namespace. The package also
contains sub-packages inside it.
Enumeration: class Color(Enum):
Enumeration, or enum, in Python is a way to RED = 1
define a set of named values. These values can GREEN = 2
represent a collection of constants and are BLUE = 3
useful for creating self-documenting code print(Color.RED)
with more readable and maintainable
print(Color.GREEN)
constants.
print(Color.BLUE)
 Is a set of symbolic names(members) bound
to unique values. print(Color.RED.name)
The enum module, introduced in Python print(Color.RED.value)
3.4, provides a way to define and use for color in Color:
enumerations. print(color)
Example:
from enum import Enum
UNIT-9
FILE DIRECTORIES AND EXCEPTIONS
Files: File Handling:
Files are named locations on disk to store File handling is an essential aspect of
information. programming, allowing you to read from
They used to store data permanently. and write to files. Python provides built-in
functions and modules to make file
Data is stored in non-volatile memory.
handling easy and efficient.
We can retrieve data whenever required.
Python supports file handling and allows
There are two types of files: users to handle files i.e., to read and write
 Text file : Store data in the form of files, along with many other file handling
characters. It is used to store data and options, to operate on files. The concept of
strings. file handling has stretched over various
 Binary Files: Stores data in the form of other languages, but the implementation is
bytes. Eg. Audio, video, image, pdf etc. either complicated or lengthy, like other
concepts of Python, this concept here is also
easy and short.
Advantages of File Handling in Python:
 Versatility: File handling in Python allows you to perform a wide range of
operations, such as creating, reading, writing, appending, renaming, and
deleting files.
 Flexibility: File handling in Python is highly flexible, as it allows you to work
with different file types (e.g. text files, binary files, CSV files, etc.), and to
perform different operations on files (e.g. read, write, append, etc.).
 User–friendly: Python provides a user-friendly interface for file handling,
making it easy to create, read, and manipulate files.
 Cross-platform: Python file-handling functions work across different
platforms (e.g. Windows, Mac, Linux), allowing for seamless integration and
compatibility.
Disadvantages of File Handling in Python:
 Error-prone: File handling operations in Python can be prone to errors, especially
if the code is not carefully written or if there are issues with the file system (e.g. file
permissions, file locks, etc.).
 Security risks: File handling in Python can also pose security risks, especially if
the program accepts user input that can be used to access or modify sensitive files
on the system.
 Complexity: File handling in Python can be complex, especially when working
with more advanced file formats or operations. Careful attention must be paid to the
code to ensure that files are handled properly and securely.
 Performance: File handling operations in Python can be slower than other
programming languages, especially when dealing with large files or performing
complex operations.
Opening a file
 Python provides inbuilt functions for creating, writing, and reading
files.
 Opening a file refers to getting the file ready either for reading or for
writing. This can be done using the open() function.
 This function returns a file object and takes two arguments, one that
accepts the file name and another that accepts the mode(Access Mode).
Syntax: File_object = open(“File_Name”, “Access_Mode”)
Access_Mode: Access modes govern the type of operations possible in the
opened file. The below table gives the list of all access mode available in
python
Operation Syntax Description

Read Only r Open text file for reading only.

Read and Write r+ Open the file for reading and writing.

Write Only w Open the file for writing.

Open the file for reading and writing. Unlike “r+” is doesn’t
Write and Read w+
raise an I/O error if file doesn’t exist.

Open the file for writing and creates new file if it doesn’t
Append Only a exist. All additions are made at the end of the file and no
existing data can be modified.

Open the file for reading and writing and creates new file if it
Append and Read a+ doesn’t exist. All additions are made at the end of the file and
no existing data can be modified.
Example 1: Open and read a file using Python

# open the file using open() function


file = open("sample.txt")
# Reading from file
print(file.read())
Example 2: Open and write in a file using Python

# open the file using open() function


file = open("sample.txt", 'a')
# Add content in the file
file.write(" This text has been newly appended on the sample file")
Example 3: Open and overwrite a file using Python
# open the file using open() function
file = open("sample.txt", 'w')
# Overwrite the file
file.write(" All content has been overwritten !")
Example 4: Create a file if not exists in Python
 The path.touch() method of the pathlib module creates the file at the
path specified in the path of the path.touch().
from pathlib import Path
my_file = Path('test1/myfile.txt')
my_file.touch(exist_ok=True)
f = open(my__file)
Closing a file in Python
 Python automatically closes a file if the reference object of the file is
allocated to another file, it is a standard practice to close an opened
file as a closed file reduces the risk of being unwarrantedly modified
or read.
 Python has a close() method to close a file.
 The close() method can be called more than once and if any operation
is performed on a closed file it raises a ValueError.
 The below code shows a simple use of close() method to close an
opened file.
What happens when we close a file?
 File object is deleted from memory and file is no more accessible
unless we open it again.
 After program execution, python garbage collector will destroy file
object and closes file automatically.
Example:
# open the file using open() function
file = open("sample.txt")
# Reading from file
print(file.read())
# closing the file
file.close()
Reading line by line inside it, but the readline() method
only reads one line from the file and
 Reading a file line-by-line includes returns it.
iterating over a file object in a loop.
 In doing this we are taking
with open("example.txt") as file:
advantage of a built-in Python
print(file.readline())
function that allows us to iterate
over the file object implicitly using
a for loop in combination with using  You can optionally pass
the iterable object. a size argument to
the readline() method, which specifies
Read a Text File Using
the length of the returned line and the
the readline() Method in Python
maximum number of bytes it will read.
 If you want to read only one single
with open("example.txt") as file:
individual line from a text file, use
the readline() method. print(file.readline(10))
 The text file example.txt has two lines
Read a Text File Using the readlines() Method in Python
 Python readlines() is used to read all the lines at a single go and then return
them as each line a string element in a list.
 This function can be used for small files, as it reads the whole file content to the
memory, then split it into separate lines.
 The readlines() method reads all the lines from a file, going through the file line
by line.

with open("example.txt") as file:


print(file.readlines())

 The readlines() method read all the lines in one go and stored each line from the
text file as a single list item inside a list.
 The readlines() method also added a newline character \n at the end of each line.
Read a Text File Using a for Loop in Python
 An alternative way of reading a file line by line in Python is using
a for loop, which is the most Pythonic approach to reading a file.

with open("example.txt") as file:


for item in file:
print(item)
Reading Big Files in Python 2. Reading in Chunks:
 When dealing with large files in  If you need to process the file in larger
Python, it's crucial to employ efficient chunks, use the read(size) method.
techniques to avoid memory issues with open('large_file.txt', 'r') as file:
and optimize performance. chunk_size = 1024 # Adjust chunk
1. Reading Line by Line size as needed
 This is the most common and while True:
memory-efficient approach. chunk = file.read(chunk_size)
 Use the readline() method to read one
if not chunk:
line at a time
break
with open('large_file.txt', 'r') as file:
# Process the chunk
for line in file:
print(chunk)
# Process the line
print(line.strip())
3. Using fileinput Module
 The fileinput module provides a convenient way to iterate over
multiple files or standard input.
 It's particularly useful for processing files line by line without
loading the entire file into memory.

import fileinput
for line in fileinput.input('large_file.txt'):
# Process the line
print(line.strip())
4. Memory Mapping:
 For very large files, memory mapping can be more efficient.

 It creates a memory map of the file, allowing you to access parts of the
file directly without reading the entire file into memory.

import mmap
with open('large_file.txt', 'r+b') as file:
mm = mmap.mmap(file.fileno(), 0)
# Process the memory map
print(mm[:10]) # Read the first 10 bytes
1. Renaming Files
 To rename a file, use the os.rename() function.

Syntax:
os.rename(source, destination)
 source: The current name/path of the file.

 destination: The new name/path of the file.

Example
import os
# Rename a file
old_name = "example.txt"
new_name = "renamed_example.txt"
os.rename(old_name, new_name)
print("File renamed successfully.")
2. Moving Files
 To move a file, use the shutil.move() function from the shutil module.

Syntax:
shutil.move(source, destination)
 source: The file path you want to move.

 destination: The target directory or path.

Example
import shutil
# Move a file
source = "renamed_example.txt"
destination = "new_folder/renamed_example.txt"
shutil.move(source, destination)
print("File moved successfully.")
3. Copying Files
 To copy files, use the shutil.copy() or shutil.copy2() function.
 shutil.copy() copies the file content and permissions.
Syntax:
shutil.copy(source, destination)
Example
import shutil
# Copy a file
source = "new_folder/renamed_example.txt"
destination = "copy_of_example.txt"
shutil.copy(source, destination)
print("File copied successfully.")
4. Removing Files
 To delete (remove) a file, use the os.remove() function.

Syntax:
os.remove(file_path)
Example:
import os
# Remove a file
file_to_delete = "copy_of_example.txt"
os.remove(file_to_delete)
print("File removed successfully.")
Replace text in a file: # Python program to replace text in a
 Replacing Text could be either file
erasing the entire content of the file with open("Sample.txt", "r+") as f:
and replacing it with new text or it f.truncate(0)
could mean modifying only specific s = input("Enter text to replace the
words or sentences within the existing contents:")
existing text.
f.write(s)
1. Removing all text and write new
print("Text successfully replaced")
text in the same file
 In this method we replacing all the
text stored in the text file, for this, we
will open the file in reading and
writing mode and it will rewrite all
the text.
Using Replace function in for loop
 The simple for loop is a conventional way to traverse through every line in
the given text file and find the line we want to replace. Then, the desired line
can be replaced by using the replace() function. Finally, the file is opened in
the write mode, and the replaced content is written in the given file.

with open("sample.txt","r") as f:
data=f.read()
x=input("Enter text you want to replace:")
y=input("Enter text you want to placed:")
new_data=data.replace(x,y)
print(new_data)
 WAP using function that replace all occurrences of “java” with
“Python” in “sample.txt” file.
def replace():
with open("sample.txt","r") as f:
data=f.read()
x=input("Enter text you want to replace:")
y=input("Enter text you want to placed:")
new_data=data.replace(x,y)
print(new_data)
replace()
Searching text in file: with open("Sample.txt","r") as f:
word=input("Enter word to search:") while data:
with open("sample.txt","r") as f: data=f.readline()
data=f.read() if word in data:
if(data.find(word)!=-1): print(word ,"is found at
print("Found") line",line)
else: return
print("Not found") line +=1
#WAP find the the text you want return "Word is not found"
to search at which line. print(check_for_line())
def check_for_line():
word=input("Enter text you want
search:")
data=True
line=1
Error Handling in Python:
 Exception handling in Python is a mechanism to handle runtime errors in a
program gracefully. Instead of terminating the program abruptly, Python allows
you to manage errors by catching and handling them using a structured
approach.
 Error handling in Python is done using the try, except, else, and finally blocks.
This allows you to handle exceptions (errors) gracefully without crashing the
program.
Basic Syntax:
try:
# Code that might raise an exception
except ExceptionType:
# Code to handle the exception
else:
# Code that runs if no exception occurs (optional)
finally:
# Code that always runs (optional)
1. try and except Example:
 The try block contains code that try:
might raise an exception. file = open(“sample_file.txt", "r")
 The except block handles the error. except FileNotFoundError:
Example: print("Error: File not found.")
try:
x = 10 / 0 # This will raise a
ZeroDivisionError
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
2. Catching Specific Exceptions
 You can catch specific exceptions like
ZeroDivisionError,
FileNotFoundError, etc.
3. Catching Multiple Exceptions 4. Catching All Exceptions
 You can handle multiple exception To catch any type of exception, use the
types in one try block. base Exception class.
try: try:
x = int("abc") # Raises ValueError x = 10 / 0
y = 10 / 0 # Raises except Exception as e: # Catches all
ZeroDivisionError exceptions
except ValueError: print(f"An error occurred: {e}")
print("Error: Invalid conversion to
integer.")
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
5. else Block closing files.
 The else block runs if no exceptions try:
occur. file = open("example.txt", "w")
try: file. write("Hello, World!")
x = 10 / 2 except Exception as e:
except ZeroDivisionError: print(f"Error: {e}")
print("Cannot divide by zero.") finally:
else: file.close()
print("Division successful:", x) print("File closed.")
6. finally Block
 The finally block always executes,
regardless of whether an exception
occurs or not.
 It's useful for cleanup tasks like
Exception Catching Multiple Exceptions
 ArithmeticError try:
 ZeroDivisionError my_list = [1, 2]
 OverflowError
print(my_list[5]) # IndexError
 ImportError x = 10 / 0 # ZeroDivisionError
 IndexError
except (IndexError, ZeroDivisionError)
 KeyError as e:
 ValueError print("Caught an error:", e)
 TypeError

 FileNotFoundError

 RuntimeError
Unit 10:
Machine Learning/Deep Learning Framework
Scikit-learn
 Scikit-learn is a popular and powerful machine learning library in Python that
provides tools for developing, training, and evaluating machine learning models,
including classifiers.
 It is built on foundational libraries such as NumPy, SciPy, and Matplotlib, making it
an essential toolkit for data scientists and machine learning practitioners.
Installation of Scikit- learn
The latest version of Scikit-learn is 1.1 and it requires Python 3.8 or newer.
Scikit-learn requires:
 NumPy
 SciPy as its dependencies.
Steps for Training and Evaluating .fit() method.
Classifiers  Example: classifier.fit(X_train, y_train)
1. Dataset Preparation: 4. Evaluating the Classifier:
 Use datasets from Scikit-learn’s built-in  Predict on the test set using the .predict()
collection (e.g., Iris, digits) or import custom method.
datasets using libraries like Pandas.  Use metrics like accuracy, precision, recall, F1-
 Split the dataset into training and testing sets score, and confusion matrices to evaluate
using the train_test_split function. performance (from sklearn.metrics import
2. Choosing a Classifier: accuracy_score, classification_report).
 Scikit-learn provides a variety of classifiers, 5. Cross-validation:
such as Logistic Regression, Support Vector  Use cross-validation techniques
Machines (SVM), Decision Trees, and Random (cross_val_score) to validate the model across
Forests. multiple splits of the data.
 Example: from sklearn.linear_model import
LogisticRegression
3. Training the Classifier:
 Fit the model to the training data using the
Introduction to TensorFlow and Keras
What is TensorFlow?
 TensorFlow is an open-source framework developed in late 2015 by Google for building
various machine learning and deep learning models. TensorFlow is free and open-source.
 The main objective of using TensorFlow is to reduce the complexity of implementing
computations on large numerical data sets. In practice, these large computations can
manifest as training and inference with machine learning or deep learning models.
 TensorFlow is an open-source, end-to-end machine learning framework developed by
Google.
 It is widely used for building and deploying machine learning models, including deep
learning models like neural networks.
 TensorFlow provides a flexible and efficient platform to perform computations and
manage large-scale machine learning tasks.
There are three main components to deploying models on mobile and IoT devices).
TensorFlow’s structure.  Extensive Community Support:
 preprocessing the data  TensorFlow has an active community,
 building the model comprehensive documentation, and a wealth of
tutorials and pre-built models.
 training and estimating the model
 Integration with Libraries:
Python is the most commonly used language  It integrates well with Python's scientific
for machine learning and deep learning tasks. computing libraries (e.g., NumPy, Pandas),
TensorFlow's Python API provides a simple which simplifies data preprocessing and
and intuitive interface for building, training, analysis.
and deploying models.  Flexibility:
Why Do We Use TensorFlow in Python?  TensorFlow allows both low-level control (for
 Ease of Use: custom operations) and high-level abstractions
 TensorFlow has a Python-friendly syntax, (using Keras for fast prototyping).
making it easy for developers to build and train  Production-Ready:
models.  TensorFlow supports deployment in production
 High Performance: environments, including web servers, mobile
 TensorFlow is optimized for speed and can applications, and the cloud.
perform computations efficiently on CPUs,
GPUs, or TPUs.
 Pre-built Tools:
 TensorFlow includes tools like TensorBoard
(for visualization) and TensorFlow Lite (for
Example: Dense(10, activation='relu', input_shape=(X_train.shape[1],)), # Input layer
# Step 1: Import Libraries Dense(10, activation='relu'), # Hidden layer
from sklearn.datasets import load_iris Dense(3, activation='softmax') # Output layer for 3 classes
from sklearn.model_selection import train_test_split ])
from sklearn.preprocessing import OneHotEncoder
import tensorflow as tf # Step 5: Compile the Model
from tensorflow.keras.models import Sequential model.compile(optimizer='adam',
from tensorflow.keras.layers import Dense loss='categorical_crossentropy',
metrics=['accuracy'])
# Step 2: Load Dataset
iris = load_iris() # Step 6: Train the Model
X = iris.data # Features (sepal/petal length and width) model.fit(X_train, y_train, epochs=20, batch_size=8, verbose=1)
y = iris.target.reshape(-1, 1) # Labels (species)
# Step 7: Evaluate the Model
# Step 3: Preprocess Data loss, accuracy = model.evaluate(X_test, y_test, verbose=0)
# Convert labels to one-hot encoded format print(f"Test Accuracy: {accuracy:.2f}")
encoder = OneHotEncoder()
y = encoder.fit_transform(y).toarray() # Step 8: Make Predictions
predictions = model.predict(X_test)
# Split the dataset into training and testing sets print(f"Predictions (first 5):\n{predictions[:5]}")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=42)

# Step 4: Build the Model


model = Sequential([
What is Keras?
 Keras is the high-level API of the TensorFlow platform.
 It provides an approachable, highly-productive interface for solving machine learning
(ML) problems, with a focus on modern deep learning.
 Keras covers every step of the machine learning workflow, from data processing to
hyperparameter tuning to deployment.
 It was developed with a focus on enabling fast experimentation.
 With Keras, you have full access to the scalability and cross-platform capabilities of
TensorFlow.
 You can run Keras on a TPU(Tensor Processing Units) Pod or large clusters of
GPUs(Graphics Processing Units), and you can export Keras models to run in the
browser or on mobile devices.
 You can also serve Keras models via a web API.
Why Use Keras?
Keras is ideal for:
 Beginners:
 Its simple and readable syntax is perfect for those new to deep learning.
 Rapid Prototyping:
 You can quickly build, test, and iterate over models.
 Advanced Research:
 Supports custom layers and loss functions for more complex use cases.
 Seamless Deployment:
 With TensorFlow integration, models built using Keras can be deployed on mobile, web, or
cloud platforms.
NumPy:
Introduction to NumPy:
NumPy is a powerful numerical computing library in Python. It provides
support for large, multi-dimensional arrays and matrices, along with a large
collection of high-level mathematical functions to operate on these arrays. It is
a fundamental package for scientific computing in Python.
Why use NumPy?
 NumPy provides efficient storage.
 It also provides better ways of handling data for processing.
 It is fast
 It is easy to learn
 NumPy uses relatively less memory to store data.
Array Creating empty, and arange.
There are 5 general mechanisms for import numpy as np
creating arrays:
1. Conversion from other python # Create an array from a list
structures (e.g., lists, tuples) arr = np.array([1, 2, 3, 4, 5])
2. Intrinsic numpy array creation
# Create an array of zeros
objects(eg. Arange, ones,zeros, etc.)
zeros = np.zeros((2, 3))
3. Reading arrays from disk, either
from standard or custom formats. # Create an array of ones
4. Creating arrays from raw bytes ones = np.ones((3, 4))
through the use of strings or butters. # Create an empty array
5. Use of special library functions ( eg. empty = np.empty((2, 2))
Random) # Create an array with a range of values
You can create NumPy arrays using range_arr = np.arange(10)
functions like array, zeros, ones,
Dimensions
NumPy arrays can have any number
of dimensions. You can check the
dimensions of an array using the
‘ndim’ attribute and reshape arrays
using the reshape method.

arr = np.array([[1, 2, 3], [4, 5, 6]])


print(arr.ndim) # Output: 2
reshaped_arr = arr.reshape((3, 2))
Array Attributes
NumPy arrays have several important attributes, such as shape, size, and
dtype.
ndim: Number of array dimensions (axes).
shape: Tuple of array dimensions.
size: Total number of elements in the array.
dtype: Data type of the array's elements.
itemsize: Length of one array element in bytes.
nbytes: Total number of bytes consumed by the elements of the array.
T: Transpose of the array (only for 2-D arrays).

arr = np.array([[1, 2, 3], [4, 5, 6]])


print(arr.shape) # Output: (2, 3)
print(arr.size) # Output: 6
print(arr.dtype) # Output: int64 (depending on your system)
Indexing and Slicing
You can access elements of an array using indexing and slicing.
NumPy allows for more advanced slicing techniques compared to
standard Python lists.
arr = np.array([1, 2, 3, 4, 5])
print(arr[0]) # Output: 1
print(arr[1:4]) # Output: [2 3 4]
multi_arr = np.array([[1, 2, 3], [4, 5, 6]])
print(multi_arr[0, 1]) # Output: 2

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])


print(arr[0, 0]) # Output: 1
print(arr[1, 2]) # Output: 6
print(arr[-1, -1]) # Output: 9
Array Copy and View
In NumPy, you can create a copy or a view of an array. A view is a new
array object that looks at the same data as the original array, while a
copy is a new array with its own data.
arr = np.array([1, 2, 3])
view_arr = arr.view()
copy_arr = arr.copy()
arr[0] = 10
print(view_arr) # Output: [10 2 3]
print(copy_arr) # Output: [1 2 3]
Creating Array from Numerical Range
NumPy provides several functions to create arrays from numerical
ranges: arange, linspace, and logspace.
range_arr = np.arange(0, 10, 2)
linspace_arr = np.linspace(0, 1, 5)
logspace_arr = np.logspace(0, 2, 5)
Array Broadcasting
Broadcasting is a powerful mechanism that allows NumPy to work
with arrays of different shapes during arithmetic operations.

arr1 = np.array([1, 2, 3])


arr2 = np.array([[1], [2], [3]])
result = arr1 + arr2 # Broadcasting
Iterating Over Array
You can iterate over elements of an array using standard Python loops
or NumPy's nditer.

arr = np.array([[1, 2, 3], [4, 5, 6]])


for row in arr:
for element in row:
print(element)
for x in np.nditer(arr):
print(x)
Sorting and Searching
NumPy provides functions for sorting arrays and searching for elements:
sort, argsort, where, and searchsorted.

arr = np.array([3, 1, 2])


sorted_arr = np.sort(arr)
indices = np.argsort(arr)
condition = arr > 1
filtered_arr = arr[np.where(condition)]
position = np.searchsorted(arr, 2)
Statistical Functions
NumPy offers various statistical functions like mean, median, std, and
sum.

arr = np.array([1, 2, 3, 4, 5])


mean = np.mean(arr)
median = np.median(arr)
std_dev = np.std(arr)
total = np.sum(arr)
SciPy
 SciPy is an open-source Python library used for scientific and technical computing. It builds on NumPy
and provides a wide range of tools for numerical integration, optimization, linear algebra, statistics, and
more. It is a part of the SciPy ecosystem, which includes other libraries like NumPy, Matplotlib, and
Pandas.
 The SciPy is an open-source scientific library of Python that is distributed under a BSD license. It is used
to solve the complex scientific and mathematical problems.
 It is built on top of the Numpy extension, which means if we import the SciPy, there is no need to import
Numpy.
 The Scipy is pronounced as Sigh pi, and it depends on the Numpy, including the appropriate and fast N-
dimension array manipulation.
 It provides many user-friendly and effective numerical functions for numerical integration and
optimization.
 The SciPy library supports integration, gradient optimization, special functions, ordinary
differential equation solvers, parallel programming tools, and many more. We can say
that SciPy implementation exists in every complex numerical computation.
 The scipy is a data-processing and system-prototyping environment as similar to MATLAB. It is easy to
use and provides great flexibility to scientists and engineers.
Why use SciPy?
 SciPy contain significant mathematical algorithms that provide easiness to develop sophisticated
and dedicated applications.
 Being an open-source library, it has a large community across the world to the development of
its additional module, and it is much beneficial for scientific application and data scientists.
Numpy vs. SciPy
 Numpy and SciPy both are used for mathematical and numerical analysis.
 Numpy is suitable for basic operations such as sorting, indexing and many more because it
contains array data, whereas SciPy consists of all the numeric data.
Pandas:
Pandas is a powerful, open-source data manipulation and analysis library for
Python. It provides data structures and functions needed to work with
structured data seamlessly and efficiently. The two primary data structures in
Pandas are Series and DataFrame, which allow for the handling of one-
dimensional and two-dimensional data, respectively. Pandas is widely used
in data science, machine learning, and data analysis for its ease of use and
robust functionality.
Series:
A Pandas Series is a one-dimensional array-like object that can hold any
data type.
It has an index, which is a labelled axis for accessing data.
import pandas as pd
# Creating a Series
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(s)
DataFrame:
A Pandas DataFrame is a two-dimensional, size-mutable, and potentially
heterogeneous tabular data structure with labeled axes (rows and
columns).
# Creating a DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David'],
'Age': [24, 27, 22, 32],
'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)
print(df)
Creating DataFrames
DataFrames can be created from various data structures like dictionaries, lists, and
arrays.
data = {
'Product': ['Apples', 'Oranges', 'Grapes'],
'Quantity': [10, 15, 12],
'Price': [0.5, 0.75, 1.0]
}
df = pd.DataFrame(data)
print(df)
The head() and tail() Functions:
These functions are used to view the first and last few rows of the DataFrame.
# Using head() to view the first 5 rows
print(df.head())
# Using tail() to view the last 5 rows
print(df.tail())
Attributes:
Common attributes of DataFrames include:
df.shape: returns a tuple representing the dimensionality of the
DataFrame.
df.columns: returns the column labels of the DataFrame.
df.index: returns the row labels of the DataFrame.
df.dtypes: returns the data types of each column.
print(df.shape)
print(df.columns)
print(df.index)
print(df.dtypes)
Working with Missing Data
Handling missing data is crucial for data cleaning. Pandas provides methods to handle this.

# Creating a DataFrame with missing data


data = {
'A': [1, 2, None, 4],
'B': [5, None, None, 8],
'C': [10, 11, 12, None]
}
df = pd.DataFrame(data)
# Checking for missing data
print(df.isnull())
# Dropping rows with missing data
df_dropped = df.dropna()
print(df_dropped)

# Filling missing data


df_filled = df.fillna(0)
print(df_filled)
Indexing, Slicing, and Subsetting
Indexing and slicing are used to access specific parts of the DataFrame.
# Selecting a single column
print(df['A'])
# Selecting multiple columns
print(df[['A', 'B']])
# Slicing rows
print(df[1:3])
# Using loc for label-based indexing
print(df.loc[1:3, ['A', 'C']])
# Using iloc for integer-based indexing
print(df.iloc[1:3, 0:2])
Merging and Joining DataFrames
DataFrames can be merged or joined using various methods.
df1 = pd.DataFrame({
'Key': ['A', 'B', 'C'],
'Value1': [1, 2, 3]
})
df2 = pd.DataFrame({
'Key': ['A', 'B', 'D'],
'Value2': [4, 5, 6]
})
# Merging DataFrames
df_merged = pd.merge(df1, df2, on='Key', how='inner')
print(df_merged)
# Joining DataFrames
df1.set_index('Key', inplace=True)
df2.set_index('Key', inplace=True)
df_joined = df1.join(df2, how='inner')
print(df_joined)
Working with CSV Files
CSV (Comma-Separated Values) files are simple text files used to store tabular data,
such as a spreadsheet or database. Each line in a CSV file corresponds to a row of data,
and each field in the row is separated by a comma (or another delimiter such as a
semicolon or tab). CSV files are commonly used for data exchange because they are
easy to read and write by both humans and machines
Pandas makes it easy to read from and write to CSV files.
# Reading from a CSV file
df = pd.read_csv('data.csv')
print(df)
#Writing to a CSV file
df.to_csv('output.csv', index=False)
Matplotlib Basemap, Cartopy, etc. buil on
Matplotlib is an open-source plotting Matplotlib for plotting animations,
library developed by John D. Hunter. styles, etc.
Matplotlib is a comprehensive library PyPlot:
for creating static, animated, and The PyPlot is a sub module and a lot of
interactive visualizations in Python. It is Matplotlib functionalities reside in it,
widely used for data visualization in therefore import it as shown below:
scientific computing, machine learning, import matploatlib.pyplot as plt
and data analysis.
 Following are the methods you can use
Features of Matplotlib: to create different plots with Matplotlib
 Free and open-source python library sub module PyPlot.
 Load and plot the data easily.  bar() : For bar plot.
 Easily make interactive figures that can  hist(): Plot a Histogram
zoom, update.  pie(): Plot a pie chart
 Export to various file formats such as
 scatter(): Form a scatter plot.
PNG, PDF, SVG.
 stem(): Form a stem plot.
 Use third-party packages, such as
 step(): Form a step plot.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 7, 11]
plt.plot(x, y)
plt.show()
Markers
Markers are used to emphasize points on a line plot.
plt.plot(x, y, marker='o')
plt.show()
Line
You can customize the line style using different options.
plt.plot(x, y, linestyle='--') # Dashed line
plt.show()
Color
You can change the color of the line or markers.
plt.plot(x, y, color='green', marker='o', linestyle='dashed')
plt.show()
Label
Labels can be added to the axes and the plot itself.
plt.plot(x, y, label='Prime Numbers')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Line Plot')
plt.legend()
plt.show()
Grid Lines
Grid lines can be added to the plot for better readability.
plt.plot(x, y)
plt.grid(True)
plt.show()
Subplot
Subplots allow you to create multiple plots in one figure.
fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(x, y)
axs[0, 0].set_title('First Plot')
axs[0, 1].plot(y, x)
axs[0, 1].set_title('Second Plot')
axs[1, 0].plot(x, [i**2 for i in x])
axs[1, 0].set_title('Third Plot')
axs[1, 1].plot(y, [i/2 for i in y])
axs[1, 1].set_title('Fourth Plot')
plt.tight_layout()
plt.show()
Scatter Plot
Scatter plots are used to display values for two variables.
plt.scatter(x, y)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Scatter Plot')
plt.show()
Bar Graph
Bar graphs are used to compare different groups.
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 1, 8]
plt.bar(categories, values)
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Bar Graph')
plt.show()
Histogram
Histograms are used to show the distribution of a dataset.
data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
plt.hist(data, bins=4)
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Histogram')
plt.show()
Pie Chart
Pie charts are used to show the proportions of a whole.
sizes = [15, 30, 45, 10]
labels = ['A', 'B', 'C', 'D']
plt.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.title('Pie Chart')
plt.show()
Box Plot
Box plots are used to show the distribution of data based on a five-number
summary.
data = [np.random.randn(100), np.random.randn(100) + 1,
np.random.randn(100) - 1]
plt.boxplot(data, vert=True, patch_artist=True)
plt.xlabel('Dataset')
plt.ylabel('Value')
plt.title('Box Plot')
plt.show()

You might also like