Instructions
Requirements and Specifications
Source Code
CLASSES
class Course:
"""
The following class will be used to represent a Course.
It will contain information about the id, name and pre-requisites
"""
def __init__(self, id, name):
self.id = id
self.name = name
self.prereqs = []
def add_prereq(self, course):
self.prereqs.append(course)
def __str__(self):
ret = f"{self.id} - {self.name}. Prereqs: ["
for i in range(len(self.prereqs)):
ret += str(self.prereqs[i])
if i < len(self.prereqs) -1:
ret += ", "
ret += "]"
return ret
class Program:
"""
The following class will be used to represent a Program.
It will contain information about its name and the courses in it
"""
def __init__(self, name):
self.name = name
self.courses = []
def add_course(self, course: Course):
if not course in self.courses:
self.courses.append(course)
def __str__(self):
ret = f"{self.name}\n"
ret += "["
for i in range(len(self.courses)):
ret += str(self.courses[i])
if i < len(self.courses) -1:
ret += ", "
ret += "]"
return ret
class Student:
"""
This class will store the name and a dictionary with the courses and their grades for each student
"""
def __init__(self, name):
self.name = name
self.courses = dict()
def add_course(self, id, grade):
if not id in self.courses:
self.courses[id] = []
self.courses[id].append(grade)
def __str__(self):
ret = f"Name: {self.name}\n"
ret += "Grades: " + str(self.courses)
return ret
MAIN
import os
from Classes import *
def get_folder() -> str:
"""
This function will repeatedly prompt user for a folder name.
If the entered folder is not valid, the program will display and error message and then
re-prompt the uer until he/she enters a valid folder
:return: full path of folder (str)
"""
while True:
# ask for folder
folder_name = input("Please enter the name of the sub-folder with files: ")
# Build full path
full_path = os.path.join(os.getcwd(), folder_name)
# Check if path exists
if os.path.exists(full_path):
return full_path
else:
print("This folder does not exists in the current working directory.")
def load_programs(full_path: str) -> list:
"""
Load the programs' files from the folder
:param full_path: str containing the path
:return: list of programs
"""
# List to store programs
programs = []
# First, read the prereqs into a dictionary where the key is the id of the course
# and the value is a list with the prerequisites of that course
prereqs = {}
# Check if there is a file named 'prereqs.txt' in the folder
if os.path.exists(full_path + "\\prereqs.txt"):
with open(full_path + "\\prereqs.txt", 'r') as file:
lines = file.readlines()
for line in lines:
row = line.split(":")
parent_course = row[0].strip()
child_courses = row[1].strip().split(" ")
prereqs[parent_course] = child_courses
# List all files in folder
for f in os.listdir(full_path):
# Check if the name of the file contains then word 'program'
if "program" in f:
# Read file
file_path = full_path + "\\" + f
with open(file_path, 'r') as file:
lines = file.readlines()
program_name = lines[0].strip()
program = Program(program_name)
# Read courses
for i in range(1, len(lines)):
course_data = lines[i].strip().split(" ")
course = Course(int(course_data[0]), course_data[1])
# Check if this course has prerequisites
if course.id in prereqs:
course.prereqs += prereqs[course.id]
# Add course to program
program.add_course(course)
# Finally, save the program into the list
programs.append(program)
return programs
def load_students(full_path: str) -> list:
"""
This function will iterate through all grades files in the folder
and get the name of each student with the grade for that course
:param full_path: str
:return: List of students
"""
# List to store students
students = []
# List all files in folder
for f in os.listdir(full_path):
# Check if the name of the file does not contains 'program' or 'prereqs'
if not "program" in f and not "prereqs" in f:
# Read file
file_path = full_path + "\\" + f
with open(file_path, 'r') as file:
lines = file.readlines()
# Get course name and id from first line
course_name = lines[0].strip()
course_id = int(course_name[1:]) # Ignore first chat which is a 'c'
# iterate through students
for i in range(1, len(lines)):
row = lines[i].strip().split(" ")
student_name = row[0].strip()
grade = float(row[1].strip())
# Check if student is already in the list
student = None
found = False
for st in students:
if st.name == student_name:
student = st
found = True
break
if student is None: # student is not in the list
student = Student(student_name)
student.add_course(course_id, grade)
if not found:
students.append(student)
return students
def get_approved_students(program, students):
"""
Given the program and the students list, get all students that are elegibel for a degree in the current program
:param program: Program
:param students: list of Student
:return: list of approved students
"""
approved_students = []
# Loop through students
program_courses_required = set([x.id for x in program.courses])
for student in students:
# Loop through all student's courses
approved = set() # Store here all approved courses by student
for course_id in student.courses:
if course_id in program_courses_required: # The course approved by student is in the program's requirements
approved.add(course_id)
# Finally, check if both sets are equal
if approved == program_courses_required:
approved_students.append(student)
return approved_students
if __name__ == '__main__':
# Get folder name
full_path = get_folder()
# Load programs
programs = load_programs(full_path)
# Load students
students = load_students(full_path)
# Begin with program and re-prompt user until s/he press enters
while True:
program_name = input("Enter program name or press enter to stop: ")
# If the input is empty, it means user pressed enter to exist
if len(program_name) == 0:
print("Bye!")
break
# Get the program
program = None
for p in programs:
if p.name == program_name:
program = p
break
# If program is still None, it means the user entered a program name that does not exists
if program != None:
approved = get_approved_students(program, students)
print(f"{len(approved)} students are elegible for degree in {program_name}")
for st in approved:
print(st.name)
else:
print("There is no program with that name.")