Unit -1
Python Interpreter and Interactive Mode
The Python interpreter is an environment that reads Python code and executes it. Interactive
mode (also called the REPL, Read-Eval-Print Loop) allows you to type and execute Python
code one line at a time, which is useful for testing small code snippets and learning.
Data Types
1. int: Represents integers, e.g., 5, -3.
2. float: Represents floating-point numbers (decimals), e.g., 3.14, -0.5.
3. boolean: Represents truth values, True or False.
4. string: Represents sequences of characters, e.g., "hello".
5. list: Represents an ordered, mutable sequence of items, e.g., [1, 2, 3].
Variables, Expressions, and Statements
● Variables are used to store data. You create a variable by assigning a value to it, e.g., x
= 5.
● Expressions are combinations of variables, literals, and operators that Python
evaluates, e.g., 3 + 4 * 2.
● Statements perform actions, e.g., print(x) or x = 10.
Tuple Assignment
Tuple assignment allows assigning multiple variables at once: a, b = 10, 20
Precedence of Operators
The order of operations follows standard mathematics:
1. Parentheses ()
2. Exponents **
3. Multiplication and division *, /, //, %
4. Addition and subtraction +, -
Comments
Comments help document code. In Python, single-line comments start with #, while multi-line
comments can use triple quotes (''' or """).
Modules and Functions
● Modules are files containing Python definitions and statements. You can import modules
to use functions defined in them, e.g., import math.
● Functions are reusable blocks of code that perform a specific task.
Defining Functions
A function is defined using the def keyword:
def greet(name):
print(f"Hello, {name}!")
Flow of Execution
The flow of execution is the order in which Python executes statements. Functions are executed
in the order they are called.
Parameters and Arguments
Parameters are variables in the function definition, while arguments are the actual values
passed to the function.
Illustrative Programs
1. Exchange the Values of Two Variables
x, y = 5, 10
x, y = y, x
print(x, y) # Output: 10 5
2. Circulate the Values of n Variables
This rotates the values in a list of variables.
values = [1, 2, 3, 4]
values = values[-1:] + values[:-1]
print(values) # Output: [4, 1, 2, 3]
3. Distance Between Two Points
The formula for distance is:
distance^2=(x2−x1)^2+(y2−y1)^2
import math
def distance(x1, y1, x2, y2):
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
print(distance(1, 2, 4, 6)) # Example usage
UNIT 2
Conditionals
1. Boolean Values and Operators: Boolean values are True and False. Common
operators include:
○ Logical operators: and, or, not
○ Comparison operators: ==, !=, <, >, <=, >=
2. Conditional Statements:
○ if: Executes a block of code if a condition is True.
○ if-else: Provides an alternative block to execute if the condition is False.
○ if-elif-else: Allows checking multiple conditions in sequence.
x = 10
if x > 0:
print("Positive")
elif x == 0:
print("Zero")
else:
print("Negative")
Iteration
1. while Loop: Repeats a block of code while a condition is True.
n=5
while n > 0:
print(n)
n -= 1
2. for Loop: Iterates over a sequence (like a list, string, or range).
for i in range(5):
print(i)
3. break, continue, pass:
○ break exits a loop.
○ continue skips the current iteration and continues with the next.
○ pass does nothing; it’s a placeholder.
Functions
1. Return Values: Functions can return values using return.
2. Parameters: Arguments provided to functions.
3. Local and Global Scope: Variables created inside a function are local; variables outside
are global.
4. Function Composition: Calling one function inside another.
5. Recursion: A function that calls itself.
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
Strings
1. Slices: You can slice strings with s[start:end].
text = "hello"
print(text[1:4]) # Output: "ell"
2. Immutability: Strings cannot be changed after creation. Any modification creates a new
string.
3. String Functions and Methods:
○ Common methods: .upper(), .lower(), .find(), .replace(), .strip()
○ String module: Provides additional constants and functions (e.g.,
string.ascii_letters).
Lists
● Lists are mutable sequences that can store various data types. They support indexing,
slicing, and common operations like .append(), .remove(), .pop().
Illustrative Programs
1. Square Root (Using the Newton-Raphson Method)
def square_root(n, tolerance=1e-10):
guess = n / 2.0
while abs(guess * guess - n) > tolerance:
guess = (guess + n / guess) / 2
return guess
print(square_root(16)) # Output: 4.0
2. Greatest Common Divisor (GCD) Using Euclid’s Algorithm
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
print(gcd(48, 18)) # Output: 6
3. Exponentiation (Recursive)
def power(base, exp):
if exp == 0:
return 1
elif exp % 2 == 0:
half_power = power(base, exp // 2)
return half_power * half_power
else:
return base * power(base, exp - 1)
print(power(2, 3)) # Output: 8
4. Sum an Array of Numbers
def sum_array(numbers):
return sum(numbers)
print(sum_array([1, 2, 3, 4])) # Output: 10
5. Linear Search
def linear_search(arr, target):
for index, value in enumerate(arr):
if value == target:
return index
return -1
print(linear_search([1, 3, 5, 7], 5)) # Output: 2
6. Binary Search (For Sorted Arrays)
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
print(binary_search([1, 3, 5, 7], 5)) # Output: 2
These examples illustrate key concepts of control flow, functions, strings, and lists in Python.
Each program demonstrates how Python’s control structures can be used to implement efficient
algorithms. Let me know if you need further clarification on any specific part!
UNIT -3
Lists in Python
Lists are mutable, ordered collections that can hold various data types.
1. List Operations
Accessing Elements: Use indexing to access individual elements. Negative indexing starts
from the end of the list.
my_list = [10, 20, 30, 40]
print(my_list[0]) # Output: 10
print(my_list[-1]) # Output: 40
● Concatenation: Combine lists using the + operator.
list1 = [1, 2, 3]
list2 = [4, 5]
combined_list = list1 + list2 # Output: [1, 2, 3, 4, 5]
● Repetition: Repeat elements in a list with the * operator.
repeated_list = list1 * 2 # Output: [1, 2, 3, 1, 2, 3]
● Membership Testing: Check if an item is in a list using in.
print(2 in list1) # Output: True
print(5 not in list1) # Output: True
2. List Slices
Slicing lets you extract a part of a list by specifying a start and end index.
my_list = [1, 2, 3, 4, 5]
print(my_list[1:4]) # Output: [2, 3, 4]
print(my_list[:3]) # Output: [1, 2, 3]
print(my_list[::2]) # Output: [1, 3, 5]
● Negative Step in Slicing: Allows reversing a list.
reversed_list = my_list[::-1] # Output: [5, 4, 3, 2, 1]
3. List Methods
Lists come with several useful methods to manipulate their contents:
my_list = [10, 20, 30]
my_list.append(40) # Adds 40 at the end: [10, 20, 30, 40]
my_list.insert(1, 15) # Inserts 15 at index 1: [10, 15, 20,
30, 40]
my_list.pop() # Removes and returns the last element:
40
my_list.remove(15) # Removes the first occurrence of 15
my_list.sort() # Sorts in place
my_list.reverse() # Reverses the list in place
4. List Loop
Loop through list elements using for loops.
for element in my_list:
print(element)
5. Mutability
Lists are mutable, meaning their elements can be changed in place.
my_list = [1, 2, 3]
my_list[1] = 'changed' # List becomes [1, 'changed', 3]
6. Aliasing
Aliasing happens when you assign one list to another. Both variables will point to the same list,
so changes in one will affect the other.
list1 = [1, 2, 3]
list2 = list1
list2[0] = 100
print(list1) # Output: [100, 2, 3]
●
7. Cloning Lists
To avoid aliasing, you can create a shallow copy of the list using slicing or the copy() method.
list2 = list1[:] # or list1.copy()
8. List Parameters
When a list is passed to a function, it’s passed by reference, meaning the function can modify
the original list.
def modify_list(lst):
lst[0] = 'modified'
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # Output: ['modified', 2, 3]
Tuples in Python
Tuples are similar to lists but are immutable, meaning their elements cannot be changed.
1. Tuple Assignment
Tuples are created using parentheses, and you can access elements by indexing.
my_tuple = (10, 20, 30)
2. Tuple as Return Value
Functions can return multiple values using tuples.
def min_max(lst):
return min(lst), max(lst)
minimum, maximum = min_max([1, 2, 3, 4])
print(minimum, maximum) # Output: 1 4
Dictionaries in Python
Dictionaries store data as key-value pairs and provide methods to add, remove, and modify
entries.
1. Dictionary Operations and Methods
● Dictionaries are created using curly braces {} with key-value pairs.
my_dict = {'name': 'Alice', 'age': 25}
# Accessing values
print(my_dict['name']) # Output: Alice
# Adding and updating keys
my_dict['city'] = 'New York' # Adds a new key-value pair
my_dict['age'] = 26 # Updates the value for 'age'
# Removing keys
my_dict.pop('city') # Removes 'city' key
Common dictionary methods:
print(my_dict.keys()) # Returns all keys
print(my_dict.values()) # Returns all values
print(my_dict.items()) # Returns all key-value pairs as tuples
Advanced List Processing with List Comprehension
List comprehension provides a concise way to create lists.
# Basic list comprehension
squares = [x**2 for x in range(10)] # Output: [0, 1, 4, 9, ..., 81]
# With a condition
even_squares = [x**2 for x in range(10) if x % 2 == 0]
Illustrative Programs for Sorting and Searching
1. Sorting
Python provides sorted() for a sorted copy and sort() to sort in place.
my_list = [3, 1, 4, 2]
sorted_list = sorted(my_list) # Returns a new sorted list: [1, 2,
3, 4]
my_list.sort() # Sorts in place: my_list becomes [1,
2, 3, 4]
●
2. Searching
Use the in operator for simple checks or linear/binary search algorithms for complex cases.
if 3 in my_list:
print("Found 3!")
Binary Search (assuming a sorted list) can be implemented using a loop or the bisect module
for efficiency.
import bisect
my_list = [1, 2, 3, 4, 5]
● index = bisect.bisect_left(my_list, 3)
UNIT -4
Object-Oriented Programming (OOP) is a programming paradigm that revolves around creating
"objects" to model real-world entities. These objects have both data (attributes) and behaviors
(methods). Here, we’ll explore classes, inheritance, and the benefits of OOP.
1. Basics of Object-Oriented Programming (OOP)
In Python, classes are blueprints for creating objects. Classes define the properties (attributes)
and behaviors (methods) that the objects created from them will have.
Example of a Simple Class
class Dog:
def __init__(self, name, breed):
self.name = name # attribute
self.breed = breed # attribute
def bark(self): # method
return f"{self.name} says Woof!"
● Attributes: name and breed store information about each dog.
● Methods: Functions defined within a class that perform actions, like bark().
Creating Instances of a Class
An instance is an individual object of a class. Each instance can have unique attribute values.
dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Luna", "Labrador")
print(dog1.bark()) # Output: Buddy says Woof!
2. Why OOP?
The key benefits of OOP include:
● Code Reusability: Classes and methods can be reused across different parts of an
application.
● Encapsulation: Attributes and methods are bundled together in objects, hiding
unnecessary details.
● Inheritance: New classes can inherit the properties and methods of existing classes.
● Polymorphism: Different classes can be used interchangeably if they implement similar
methods.
3. Inheritance
Inheritance allows a class (subclass) to inherit attributes and methods from another class
(superclass). It enables code reuse and helps in building a hierarchy of classes.
Example of Inheritance
Let’s create a Dog superclass and have a WorkingDog subclass inherit from it.
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
return f"{self.name} says Woof!"
class WorkingDog(Dog): # WorkingDog inherits from Dog
def __init__(self, name, breed, job):
super().__init__(name, breed) # Initialize parent class
attributes
self.job = job # New attribute specific to WorkingDog
def do_job(self):
return f"{self.name} is doing their job as a {self.job}."
● WorkingDog inherits attributes (name, breed) and methods (bark()) from Dog.
● WorkingDog has an additional attribute job and a method do_job().
Using Inherited Methods
service_dog = WorkingDog("Max", "German Shepherd", "service dog")
print(service_dog.bark()) # Inherited method: Max says Woof!
print(service_dog.do_job()) # Output: Max is doing their job as a
service dog.
4. Building a Class: An Extended Example
Let’s build an extended example by creating a class hierarchy of animals.
# Base class
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
def make_sound(self):
return f"{self.name} makes a generic animal sound."
# Subclass - Dog
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name, "Dog") # Calls the initializer of
Animal
self.breed = breed
def make_sound(self):
return f"{self.name} says Woof!"
# Subclass - Cat
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name, "Cat")
self.color = color
def make_sound(self):
return f"{self.name} says Meow!"
● Animal: A base class with basic attributes and a make_sound() method.
● Dog and Cat: Subclasses with specific attributes and customized make_sound()
methods.
Creating Instances and Using Inherited Methods
dog = Dog("Rex", "Bulldog")
cat = Cat("Whiskers", "Gray")
print(dog.make_sound()) # Output: Rex says Woof!
print(cat.make_sound()) # Output: Whiskers says Meow!
5. Visualizing the Hierarchy
In this hierarchy:
● Animal is the superclass.
● Dog and Cat are subclasses of Animal.
● Each subclass inherits common methods but can override or add specific behaviors.
6. Adding Another Class
Let’s add another class, Bird, to the hierarchy.
class Bird(Animal):
def __init__(self, name, wing_span):
super().__init__(name, "Bird")
self.wing_span = wing_span
def make_sound(self):
return f"{self.name} chirps melodiously!"
def fly(self):
return f"{self.name} flies with a wingspan of {self.wing_span}
cm."
● Bird has an additional method, fly(), specific to birds.
● We can use make_sound() to demonstrate polymorphism, where different subclasses
have different implementations of the same method.
Creating a Bird Instance and Using Methods
sparrow = Bird("Jack", 25)
print(sparrow.make_sound()) # Output: Jack chirps melodiously!
print(sparrow.fly()) # Output: Jack flies with a wingspan
of 25 cm.
7. Using Inherited Methods
By calling make_sound() on each instance, we see how each subclass defines its own version
of the method:
animals = [dog, cat, sparrow]
for animal in animals:
print(animal.make_sound())
This loop will output:
Copy code
Rex says Woof!
Whiskers says Meow!
Jack chirps melodiously!
Summary
This example covers the fundamental concepts of OOP:
● Encapsulation: Grouping data and methods in a single class.
● Inheritance: Reusing code from a superclass.
● Polymorphism: Different classes respond differently to the same method call
(make_sound() in this case).
● Hierarchy Visualization: Classes are organized in a structure based on inheritance.
With these foundations, you can create complex and structured applications, improving
readability, reusability, and maintainability.
UNIT -5
1. Working with Files
Python makes file operations straightforward. We commonly work with text files, reading and
writing their contents.
Opening Files
● Use open() to open a file, which returns a file object.
○ 'r': Read mode (default).
○ 'w': Write mode (overwrites existing content).
○ 'a': Append mode (adds content to the end of the file).
○ 'b': Binary mode, e.g., 'rb' for reading binary files.
file = open("example.txt", "r") # Open for reading
content = file.read() # Read the entire file content
file.close() # Close the file after reading
Reading Files
● read(): Reads the entire file.
● readline(): Reads a single line.
● readlines(): Reads all lines into a list.
with open("example.txt", "r") as file:
content = file.read()
# 'with' statement ensures file closes automatically
Writing Files
● write(): Writes text to a file.
● writelines(): Writes a list of strings.
with open("output.txt", "w") as file:
file.write("Hello, World!")
file.writelines(["Line 1\n", "Line 2\n"])
2. Format Operator
The format operator (%) and newer .format() method are used for inserting values into
strings.
name = "Alice"
age = 25
print("Hello, %s. You are %d years old." % (name, age)) # Using %
formatting
print("Hello, {}. You are {} years old.".format(name, age)) # Using
.format()
print(f"Hello, {name}. You are {age} years old.") # Using f-strings
(Python 3.6+)
3. Command Line Arguments
Command-line arguments are parameters passed to the program when it starts. Python’s
sys.argv list stores these arguments.
import sys
# sys.argv[0] is the name of the script
# sys.argv[1:] are additional arguments
if len(sys.argv) > 1:
print("Arguments passed:", sys.argv[1:])
To run a Python script with arguments:
bash
python my_script.py arg1 arg2
4. Errors and Exceptions
Errors occur during runtime and cause a program to stop unless they are handled.
● SyntaxError: Code syntax is incorrect.
● TypeError: An operation is applied to an incompatible type.
● FileNotFoundError: File operations on a non-existent file.
5. Handling Exceptions
Exceptions are handled using try, except, else, and finally.
try:
with open("nonexistent_file.txt", "r") as file:
content = file.read()
except FileNotFoundError:
print("File not found.")
except Exception as e:
print(f"An error occurred: {e}")
else:
print("File read successfully.")
finally:
print("This runs no matter what.")
6. Modules and Packages
● Modules: A module is a Python file with functions and classes. Importing modules is
done with the import statement.
import math
print(math.sqrt(16)) # Using a function from the math module
● Packages: A package is a collection of modules organized in directories with an
__init__.py file.
For example:
# In a directory named `my_package`:
# - `__init__.py` (empty or contains initial setup)
# - `module1.py`
# To use:
from my_package import module1
Illustrative Programs
1. Word Count Program
A word count program counts the number of words in a file.
def word_count(filename):
try:
with open(filename, "r") as file:
content = file.read()
words = content.split() # Split content by whitespace
return len(words)
except FileNotFoundError:
print("File not found.")
return 0
filename = "example.txt"
print(f"Word count in '{filename}':", word_count(filename))
2. Copy File Program
A file copying program reads from a source file and writes to a target file.
def copy_file(source, destination):
try:
with open(source, "r") as src:
content = src.read()
with open(destination, "w") as dest:
dest.write(content)
print(f"File copied from '{source}' to '{destination}'
successfully.")
except FileNotFoundError:
print("Source file not found.")
except Exception as e:
print(f"An error occurred: {e}")
source_file = "example.txt"
destination_file = "copy_of_example.txt"
copy_file(source_file, destination_file)
In this program:
● try/except blocks handle exceptions if the file isn’t found.
● with statements ensure files close automatically after reading/writing.
Summary
This guide covered file operations, exception handling, and using modules and packages in
Python, with illustrative programs for word counting and file copying. These are essential tasks
for building robust, error-resistant programs in Python. Let me know if you'd like more examples
or details on any specific topic!