Skip to content

Instantly share code, notes, and snippets.

@ShardulJunagade
Last active May 7, 2026 10:05
Show Gist options
  • Select an option

  • Save ShardulJunagade/e8bfe861dd663fa34c843d32bd9d8ef3 to your computer and use it in GitHub Desktop.

Select an option

Save ShardulJunagade/e8bfe861dd663fa34c843d32bd9d8ef3 to your computer and use it in GitHub Desktop.
CPI and P/F Calculator
# Description: This program calculates the Cumulative Performance Index (CPI) of a student based on their grades and credits.
# Author: Shardul Junagade
# Date: 24-12-2024
class Course:
def __init__(self, name, course_code, grade, credit, pass_fail=False):
if grade < 0 or credit < 0:
raise ValueError("Grade and credits must be non-negative.")
self.name = name
self.course_code = course_code
self.grade = grade
self.credit = credit
self.pass_fail = pass_fail # New attribute
def weighted_score(self):
return 0 if self.pass_fail else self.grade * self.credit
class Semester:
def __init__(self, semester_number):
self.semester_number = semester_number
self.courses = []
def add_course(self, course):
self.courses.append(course)
def calculate_spi(self):
total_weighted_score = sum(course.weighted_score() for course in self.courses if not course.pass_fail)
total_credits = sum(course.credit for course in self.courses if not course.pass_fail)
return round(total_weighted_score / total_credits, 2) if total_credits > 0 else 0
def total_score(self):
return sum(course.weighted_score() for course in self.courses if not course.pass_fail)
def total_credits(self):
return sum(course.credit for course in self.courses if not course.pass_fail)
class Student:
def __init__(self, name):
self.name = name
self.semesters = []
self.total_score = 0
self.total_credits = 0
self.cpi = 0
def add_semester(self, semester):
self.semesters.append(semester)
self.total_score += semester.total_score()
self.total_credits += semester.total_credits()
def calculate_cpi(self):
self.total_score = sum(sem.total_score() for sem in self.semesters)
self.total_credits = sum(sem.total_credits() for sem in self.semesters)
self.cpi = round(self.total_score / self.total_credits, 2) if self.total_credits > 0 else 0
return self.cpi
def get_spi_history(self):
return {sem.semester_number: sem.calculate_spi() for sem in self.semesters}
def convert_to_pass_fail(self, course_code, show_message=True):
for sem in self.semesters:
for course in sem.courses:
if course.course_code == course_code:
course.pass_fail = True
if show_message:
print(f"Converted {course.name} ({course.course_code}) to pass/fail.")
self.calculate_cpi()
return
if show_message:
print(f"Course with code {course_code} not found.")
def convert_to_grade(self, course_code):
for sem in self.semesters:
for course in sem.courses:
if course.course_code == course_code:
course.pass_fail = False
print(f"Converted {course.name} ({course.course_code}) to graded.")
self.calculate_cpi()
return
print(f"Course with code {course_code} not found.")
def print_student_summary(student):
print(f"\n{'='*40}")
print(f"Student Name: {student.name}")
# print(f"{'='*40}")
# print(f"Total Credits Completed: {student.total_credits}")
print(f"{'='*40}")
print(f"{'Semester':<10} {'Credits':<10} {'SPI':<10}")
print(f"{'-'*40}")
for sem in student.semesters:
print(f"{sem.semester_number:<10} {sem.total_credits():<10} {sem.calculate_spi():<10.2f}")
print(f"{'-'*40}")
cpi = student.calculate_cpi()
# show the CPI with 2 decimal places and total number of credits
print(f"{'Total':<10} {student.total_credits:<10} CPI: {cpi:<10.2f}")
print(f"{'='*40}")
# List current pass/fail courses and their credits
pf_courses = []
for sem in student.semesters:
for course in sem.courses:
if course.pass_fail:
pf_courses.append((course.name, course.course_code, course.credit, sem.semester_number))
if pf_courses:
print("Current Pass/Fail Courses:")
print(f"{'Semester':<10} {'Course Name':<40} {'Code':<12} {'Credits':<7}")
print(f"{'-'*75}")
for name, code, credit, semnum in pf_courses:
print(f"{semnum:<10} {name:<40} {code:<12} {credit:<7}")
print(f"{'-'*75}")
print(f"Credits in Pass/Fail Courses: {sum(credit for _, _, credit, _ in pf_courses)}")
print(f"Total Credits including Pass/Fail: {student.total_credits + sum(credit for _, _, credit, _ in pf_courses)}")
if cpi >= 9:
print("Good Job!\n")
else:
print("Keep Improving!\n")
def suggest_courses_to_maximize_cpi(student):
print("\nSuggesting courses to convert to pass/fail to maximize CPI...")
original_cpi = student.calculate_cpi()
best_cpi = original_cpi
best_combination = []
# Collect all courses that are not already pass/fail
all_courses = [
(course, sem)
for sem in student.semesters
for course in sem.courses
if not course.pass_fail
]
# Check the effect of converting each course individually
for course, sem in all_courses:
# Temporarily mark the course as pass/fail
course.pass_fail = True
student.calculate_cpi() # Recalculate CPI
# Check if this improves the CPI
if student.cpi > best_cpi:
best_cpi = student.cpi
best_combination = [(course.name, course.course_code)]
# Revert the course to its original state
course.pass_fail = False
# Check the effect of converting pairs of courses
for i in range(len(all_courses)):
for j in range(i + 1, len(all_courses)):
course1, sem1 = all_courses[i]
course2, sem2 = all_courses[j]
# Temporarily mark both courses as pass/fail
course1.pass_fail = True
course2.pass_fail = True
student.calculate_cpi() # Recalculate CPI
# Check if this combination improves the CPI
if student.cpi > best_cpi:
best_cpi = student.cpi
best_combination = [
(course1.name, course1.course_code),
(course2.name, course2.course_code),
]
# Revert the courses to their original state
course1.pass_fail = False
course2.pass_fail = False
# Print and return the best result
print(f"Original CPI: {original_cpi:.2f}")
print("Suggested courses to convert to pass/fail to maximize CPI:")
for course in best_combination:
print(f" Course: {course[0]} (Code: {course[1]})")
print(f"Improved CPI: {best_cpi:.2f}")
return best_combination, best_cpi
# Example Usage
student = Student("Shardul Junagade")
# Semester 1
sem1 = Semester(1)
sem1.add_course(Course("Foundation Programme", "FP 100", 10, 4))
sem1.add_course(Course("Engineering Graphics", "ES 101", 10, 3))
sem1.add_course(Course("Computing", "ES 112", 10, 3))
sem1.add_course(Course("The World of Engineering", "ES 117", 10, 2))
sem1.add_course(Course("Materials for the Future", "ES 118", 10, 3))
sem1.add_course(Course("Introduction to Writing I", "HS 191", 10, 2))
sem1.add_course(Course("Calculus of Single Variable and Linear Algebra", "MA 103", 10, 4))
sem1.add_course(Course("World Civilizations and Cultures", "HS 201", 9, 4))
student.add_semester(sem1)
student.convert_to_pass_fail("FP 100", show_message=False)
# Semester 2
sem2 = Semester(2)
sem2.add_course(Course("Ordinary Differential Equations", "MA 104", 10, 2))
sem2.add_course(Course("Data-Centric Computing", "ES 113", 9, 3))
sem2.add_course(Course("Probability, Statistics, and Data Visualization", "ES 114", 8, 3))
sem2.add_course(Course("Design, Innovation, and Prototyping", "ES 115", 8, 5))
sem2.add_course(Course("Principles and Applications of Electrical Engineering", "ES 116", 9, 5))
sem2.add_course(Course("Undergraduate Science Laboratory", "BS 192", 9, 3))
sem2.add_course(Course("Introduction to Writing II", "HS 192", 9, 2))
sem2.add_course(Course("General Education I", "GE 101", 10, 2))
student.add_semester(sem2)
student.convert_to_pass_fail("GE 101", show_message=False)
# Semester 3
sem3 = Semester(3)
sem3.add_course(Course("Machine Learning", "ES 335", 10, 4))
sem3.add_course(Course("Data Structures and Algorithms I", "ES 242(N)", 10, 4))
sem3.add_course(Course("Biology for Engineers", "ES 243", 8, 4))
sem3.add_course(Course("Introduction to Philosophy", "HS 221", 9, 4))
sem3.add_course(Course("Calculus of Several Variables", "MA 205", 9, 2))
sem3.add_course(Course("Discrete Mathematics", "ES 214", 9, 4))
sem3.add_course(Course("Introduction to Partial Differential Equations", "MA 204", 9, 2))
sem3.add_course(Course("General Education II", "GE 102", 10, 2))
student.add_semester(sem3)
student.convert_to_pass_fail("GE 102", show_message=False)
# Semester 4
sem4 = Semester(4)
sem4.add_course(Course("Theory of Computing", "CS 201", 8, 4))
sem4.add_course(Course("Digital Systems", "ES 204", 8, 4))
sem4.add_course(Course("Numerical Methods", "MA 203", 10, 2))
sem4.add_course(Course("Data Structures and Algorithms II", "ES 301", 8, 4))
sem4.add_course(Course("Introduction to Data Science", "ES 328", 7, 4))
sem4.add_course(Course("Project Course", "CS 299", 9, 4))
# sem4.add_course(Course("Online ML Course - Coursera", "Online ML", 10, 5))
student.add_semester(sem4)
# student.convert_to_pass_fail("Online ML", show_message=False)
# Semester 5
sem5 = Semester(5)
sem5.add_course(Course("Operating Systems", "CS 330", 10, 4))
sem5.add_course(Course("Computer Networks", "CS 331", 6, 4))
sem5.add_course(Course("Computer Vision", "EE 666", 8, 4))
sem5.add_course(Course("Deep Learning", "ES 667", 8, 4))
sem5.add_course(Course("STT CSE", "CS 202", 10, 4))
sem5.add_course(Course("Foundations of AI", "CS 329", 8, 4))
sem5.add_course(Course("Economics", "HS 151", 7, 4))
student.add_semester(sem5)
# Semester 6
sem6 = Semester(6)
sem6.add_course(Course("Computer Organization and Architecture", "ES 215", 6, 4))
sem6.add_course(Course("Compilers", "CS 327", 10, 5))
sem6.add_course(Course("Databases", "CS 433", 9, 4))
sem6.add_course(Course("Biodiversity Conservation and Sustainable Development", "EH 608", 7, 4))
sem6.add_course(Course("Ocean and Global Change", "EH 612", 9, 4))
sem6.add_course(Course("History of Computing and its Applications to Domains", "ES 670", 7, 2))
student.add_semester(sem6)
# Semester 7
# sem7 = Semester(7)
# sem7.add_course(Course("Modelling of Earth Systems", "EH 605", int(input("Modelling of Earth Systems: ")), 4))
# sem7.add_course(Course("Natural Language Processing", "CS 613", int(input("Natural Language Processing: ")), 4))
# Convert some courses to pass/fail
# student.convert_to_pass_fail("CS 331")
# student.convert_to_pass_fail("ES 215")
# Print the student summary
print_student_summary(student)
# Suggest courses to convert to pass/fail to maximize CPI
suggest_courses_to_maximize_cpi(student)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment