ASSIGNMENT - 03
Subject: Object Oriented Programming
Subject Code: 24CST-651
Branch: ME-CSE (AIML)
Submitted By: Submitted To:
Name: Simranjeet Singh Er. Kushalpreet Kaur
UID: 24MAI10038 E16395
Simranjeet 24MAI10038
Q1. Explain all the OOPs concepts and data processing in Python with examples.
Ans. OOP revolves around four main principles: Encapsulation, Inheritance, Polymorphism,
and Abstraction. Additionally, concepts like classes, objects, and method overriding are
integral to OOP. Let’s break them down with examples.
1. Class and Object
A class is a blueprint for creating objects, defining properties (attributes) and behaviours
(methods). An object is an instance of a class.
Example:
# Define a class
class Car:
def __init__(self, brand, model): # Constructor
self.brand = brand # Attribute
self.model = model
def drive(self): # Method
return f"{self.brand} {self.model} is driving!"
# Create an object
my_car = Car("Toyota", "Camry")
print(my_car.brand) # Output: Toyota
print(my_car.drive()) # Output: Toyota Camry is driving!
2. Encapsulation
Encapsulation restricts access to an object’s internal data, exposing only what’s necessary
through public methods. In Python, private attributes are denoted with a double
underscore (__).
Example:
class BankAccount:
def __init__(self, account_holder, balance):
self.account_holder = account_holder
self.__balance = balance # Private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return f"New balance: {self.__balance}"
return "Invalid amount"
def get_balance(self): # Public method to access private attribute
return self.__balance
# Create object
Simranjeet 24MAI10038
account = BankAccount("Alice", 1000)
print(account.deposit(500)) # Output: New balance: 1500
print(account.get_balance()) # Output: 1500
# print(account.__balance) # Error: AttributeError (private)
3. Inheritance
Inheritance allows a class (child/subclass) to inherit attributes and methods from another
class (parent/superclass), promoting code reuse.
Example:
# Parent class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
# Child class
class Dog(Animal):
def speak(self): # Override parent method
return f"{self.name} says Woof!"
# Child class
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
# Create objects
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak()) # Output: Buddy says Woof!
print(cat.speak()) # Output: Whiskers says Meow!
4. Polymorphism
Polymorphism allows different classes to be treated as instances of the same class through
a common interface, typically achieved by overriding methods.
Example:
def animal_sound(animal): # Polymorphic function
print(animal.speak())
# Test polymorphism
animal_sound(dog) # Output: Buddy says Woof!
animal_sound(cat) # Output: Whiskers says Meow!
Simranjeet 24MAI10038
5. Abstraction
Abstraction hides complex implementation details and exposes only the necessary parts.
In Python, abstraction is achieved using abstract base classes (ABCs) from the abc
module.
Example:
from abc import ABC, abstractmethod
# Abstract base class
class Shape(ABC):
@abstractmethod
def area(self):
pass
# Concrete class
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
# Concrete class
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
# Create objects
circle = Circle(5)
rectangle = Rectangle(4, 6)
print(circle.area()) # Output: 78.5
print(rectangle.area()) # Output: 24
# shape = Shape() # Error: Can't instantiate abstract class
6. Method Overriding and Overloading
• Method Overriding: A subclass provides a specific implementation of a method
defined in its parent class (shown in the Inheritance example).
• Method Overloading: Python doesn’t support traditional method overloading
(multiple methods with the same name but different parameters). Instead, you can use
default arguments or variable-length arguments.
Simranjeet 24MAI10038
Example:
class Calculator:
def add(self, a, b, c=0): # Default argument for overloading
return a + b + c
calc = Calculator()
print(calc.add(2, 3)) # Output: 5
print(calc.add(2, 3, 4)) # Output: 9
Data Processing in Python
Data processing involves manipulating, analysing, and transforming data to extract
meaningful insights. Python provides powerful libraries like pandas, NumPy, and built-in
data structures for efficient data processing. Below are key data processing techniques with
examples.
1. Data Structures for Processing
Python’s built-in data structures (list, dict, set, tuple) are foundational for data processing.
Example:
# List processing
numbers = [1, 2, 3, 4, 5]
squared = [x**2 for x in numbers] # List comprehension
print(squared) # Output: [1, 4, 9, 16, 25]
# Dictionary processing
students = {"Alice": 85, "Bob": 90, "Charlie": 78}
passed = {name: score for name, score in students.items() if score >= 80}
print(passed) # Output: {'Alice': 85, 'Bob': 90}
2. File Handling
Reading from and writing to files is a common data processing task.
Example:
import csv
# Write to CSV
data = [["Name", "Age"], ["Alice", 25], ["Bob", 30]]
with open("people.csv", "w", newline="") as file:
writer = csv.writer(file)
writer.writerows(data)
# Read from CSV
with open("people.csv", "r") as file:
reader = csv.reader(file)
Simranjeet 24MAI10038
for row in reader:
print(row)
3. Data Manipulation with Pandas
pandas are a powerful library for data manipulation and analysis, ideal for tabular data.
Example:
import pandas as pd
# Create a DataFrame
data = {"Name": ["Alice", "Bob", "Charlie"], "Age": [25, 30, 22], "Score": [85, 90,
78]}
df = pd.DataFrame(data)
# Filter data
passed = df[df["Score"] >= 80]
print(passed)
# Group by and aggregate
avg_age = df.groupby("Score")["Age"].mean()
print(avg_age)
4. Numerical Processing with NumPy
NumPy is used for numerical computations, especially with arrays and matrices.
Example:
import numpy as np
# Create an array
array = np.array([1, 2, 3, 4, 5])
# Perform operations
mean = np.mean(array)
squared = array ** 2
print(mean)
print(squared)
# Matrix operations
matrix = np.array([[1, 2], [3, 4]])
inverse = np.linalg.inv(matrix)
print(inverse)
5. Data Cleaning
NumPy is used for numericalData cleaning involves handling missing values, duplicates,
and inconsistent data. computations, especially with arrays and matrices.
Simranjeet 24MAI10038
Example:
# Create DataFrame with missing values
data = {"Name": ["Alice", "Bob", None], "Age": [25, None, 22]}
df = pd.DataFrame(data)
# Handle missing values
df["Age"] = df["Age"].fillna(df["Age"].mean())
df["Name"] = df["Name"].fillna("Unknown")
print(df)
6. Data Visualization
Visualization is part of data processing to understand patterns. Libraries like matplotlib
and seaborn are commonly used.
Example:
import matplotlib.pyplot as plt
# Data
x = [1, 2, 3, 4]
y = [10, 20, 25, 30]
# Plot
plt.plot(x, y, marker="o")
plt.title("Simple Line Plot")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.show()
Combining OOP and Data Processing
OOP can be used to structure data processing tasks, encapsulating data and methods within
classes.
import pandas as pd
class DataProcessor:
def __init__(self, data):
self.df = pd.DataFrame(data)
def clean_data(self):
# Remove duplicates and fill missing values
Simranjeet 24MAI10038
self.df = self.df.drop_duplicates()
self.df = self.df.fillna(self.df.mean(numeric_only=True))
return self.df
def summarize(self):
# Return summary statistics
return self.df.describe()
# Usage
data = {"Name": ["Alice", "Bob", "Alice"], "Score": [85, None, 90]}
processor = DataProcessor(data)
print(processor.clean_data())
print(processor.summarize())
Q2. Write a Python implementable program to read, update, delete, calculate average
and handle exceptions of student's data of college.
Ans.
Student Class:
• Represents a student with student_id, name, and marks (dictionary: Math, Science,
English).
• __str__ method for readable output.
StudentManager Class:
• Manages Student objects, stores data in students.csv.
• Methods:
▪ load_data(): Reads from CSV.
▪ save_data(): Writes to CSV.
▪ add_student(): Adds student with validation (unique ID, marks 0–100).
▪ read_student(): Shows student details by ID.
▪ update_student(): Updates name/marks.
▪ delete_student(): Removes student by ID.
▪ calculate_average(): Computes average marks.
▪ display_all_students(): Lists all students.
Exception Handling:
• Catches file errors (FileNotFoundError, EmptyDataError).
Simranjeet 24MAI10038
• Validates inputs (non-empty ID/name, valid marks).
• Handles general exceptions to avoid crashes.
Main Function:
• Menu-driven CLI for user interaction.
• Supports add, read, update, delete, average, and display operations.
• Includes input validation.
CSV File:
• Columns: ID, Name, Math, Science, English.
• Created with headers if missing.
import pandas as pd
import os
from typing import Dict, List
Code:
class Student:
def __init__(self, student_id: str, name: str, marks: Dict[str, float]):
self.student_id = student_id
self.name = name
self.marks = marks # Dictionary of subject: mark
def __str__(self):
return f"ID: {self.student_id}, Name: {self.name}, Marks: {self.marks}"
class StudentManager:
def __init__(self, file_path: str = "students.csv"):
self.file_path = file_path
self.students: List[Student] = []
self.load_data()
def load_data(self):
"""Load student data from CSV file."""
try:
if os.path.exists(self.file_path):
df = pd.read_csv(self.file_path)
for _, row in df.iterrows():
marks = {
"Math": row["Math"],
"Science": row["Science"],
"English": row["English"]
}
student = Student(row["ID"], row["Name"], marks)
self.students.append(student)
Simranjeet 24MAI10038
else:
# Create empty CSV with headers if file doesn't exist
df = pd.DataFrame(columns=["ID", "Name", "Math", "Science", "English"])
df.to_csv(self.file_path, index=False)
except FileNotFoundError:
print("Error: File not found. Creating a new file.")
self.save_data()
except pd.errors.EmptyDataError:
print("Error: Empty CSV file. Initializing with headers.")
self.save_data()
except Exception as e:
print(f"Error loading data: {e}")
def save_data(self):
"""Save student data to CSV file."""
try:
data = []
for student in self.students:
data.append({
"ID": student.student_id,
"Name": student.name,
"Math": student.marks["Math"],
"Science": student.marks["Science"],
"English": student.marks["English"]
})
df = pd.DataFrame(data)
df.to_csv(self.file_path, index=False)
except Exception as e:
print(f"Error saving data: {e}")
def add_student(self, student_id: str, name: str, marks: Dict[str, float]):
"""Add a new student."""
try:
# Validate inputs
if not student_id or not name:
raise ValueError("Student ID and Name cannot be empty.")
if any(student.student_id == student_id for student in self.students):
raise ValueError(f"Student with ID {student_id} already exists.")
if not all(subject in marks for subject in ["Math", "Science", "English"]):
raise ValueError("Marks must include Math, Science, and English.")
if not all(0 <= marks[subject] <= 100 for subject in marks):
raise ValueError("Marks must be between 0 and 100.")
student = Student(student_id, name, marks)
self.students.append(student)
Simranjeet 24MAI10038
self.save_data()
print(f"Student {name} added successfully.")
except ValueError as e:
print(f"Error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
def read_student(self, student_id: str):
"""Read a student's data."""
try:
for student in self.students:
if student.student_id == student_id:
print(student)
return
print(f"Student with ID {student_id} not found.")
except Exception as e:
print(f"Error reading student: {e}")
def update_student(self, student_id: str, name: str = None, marks: Dict[str, float] = None):
"""Update a student's data."""
try:
for student in self.students:
if student.student_id == student_id:
if name:
student.name = name
if marks:
if not all(subject in marks for subject in ["Math", "Science", "English"]):
raise ValueError("Marks must include Math, Science, and English.")
if not all(0 <= marks[subject] <= 100 for subject in marks):
raise ValueError("Marks must be between 0 and 100.")
student.marks = marks
self.save_data()
print(f"Student {student_id} updated successfully.")
return
print(f"Student with ID {student_id} not found.")
except ValueError as e:
print(f"Error: {e}")
except Exception as e:
print(f"Error updating student: {e}")
def delete_student(self, student_id: str):
"""Delete a student."""
try:
for i, student in enumerate(self.students):
if student.student_id == student_id:
Simranjeet 24MAI10038
self.students.pop(i)
self.save_data()
print(f"Student {student_id} deleted successfully.")
return
print(f"Student with ID {student_id} not found.")
except Exception as e:
print(f"Error deleting student: {e}")
def calculate_average(self, student_id: str):
"""Calculate average marks for a student."""
try:
for student in self.students:
if student.student_id == student_id:
avg = sum(student.marks.values()) / len(student.marks)
print(f"Average marks for {student.name}: {avg:.2f}")
return
print(f"Student with ID {student_id} not found.")
except ZeroDivisionError:
print("Error: No marks available for calculation.")
except Exception as e:
print(f"Error calculating average: {e}")
def display_all_students(self):
"""Display all students."""
try:
if not self.students:
print("No students found.")
return
for student in self.students:
print(student)
except Exception as e:
print(f"Error displaying students: {e}")
def main():
manager = StudentManager()
while True:
print("\nStudent Management System")
print("1. Add Student")
print("2. Read Student")
print("3. Update Student")
print("4. Delete Student")
print("5. Calculate Average Marks")
print("6. Display All Students")
print("7. Exit")
Simranjeet 24MAI10038
choice = input("Enter choice (1-7): ")
try:
if choice == "1":
student_id = input("Enter Student ID: ")
name = input("Enter Name: ")
marks = {
"Math": float(input("Enter Math marks: ")),
"Science": float(input("Enter Science marks: ")),
"English": float(input("Enter English marks: "))
}
manager.add_student(student_id, name, marks)
elif choice == "2":
student_id = input("Enter Student ID: ")
manager.read_student(student_id)
elif choice == "3":
student_id = input("Enter Student ID: ")
name = input("Enter new Name (or press Enter to skip): ")
update_marks = input("Update marks? (y/n): ").lower() == "y"
marks = None
if update_marks:
marks = {
"Math": float(input("Enter new Math marks: ")),
"Science": float(input("Enter new Science marks: ")),
"English": float(input("Enter new English marks: "))
}
manager.update_student(student_id, name if name else None, marks)
elif choice == "4":
student_id = input("Enter Student ID: ")
manager.delete_student(student_id)
elif choice == "5":
student_id = input("Enter Student ID: ")
manager.calculate_average(student_id)
elif choice == "6":
manager.display_all_students()
elif choice == "7":
print("Exiting program.")
break
Simranjeet 24MAI10038
else:
print("Invalid choice. Please enter a number between 1 and 7.")
except ValueError as e:
print(f"Error: Invalid input. {e}")
except Exception as e:
print(f"Unexpected error: {e}")
if __name__ == "__main__":
main()
Simranjeet 24MAI10038