Acknowledgement: This debugging journal’s structure was inspired by a format shared by Alexandra Berdashkevich, with permission from the teaching team.
Status: Resolved
File(s) Affected: Student.py
Commit (Noticed): Update #1 - Student.py file (107aaed)
Commit (Resolved): Update #2 - Student.py file (8aa89bb)
There wasn’t an actual error thrown, but while writing the enrol() method I realised a student could end up enrolling in the same course more than once, or even re-enrol in a course they’d already completed — which shouldn't happen.
Expected:
- Student should only be allowed to enrol in a course once, and not if they’ve completed it already.
Actual (if not fixed):
- The same course could be added again to the
enrolled_courseslist with no checks, which messes up the logic and could cause issues later.
- I added two checks before adding the course to
__enrolled_courses- One for already being enrolled
- One for already completed
- Used simple
ifstatements and addedreturnafter each one to stop the function early - Added print messages for each case so the user gets feedback
- Tested it with dummy course objects and it worked as expected
Status: Resolved
File(s) Affected: Student.py
Commit (Noticed): Update #1 - Student.py file (107aaed)
Commit (Resolved): Update #2 - Student.py file (8aa89bb)
No error occurred, but I wanted to make sure the drop() method handled all possible situations — especially:
- Trying to drop a course that the student isn’t enrolled in
- Trying to drop a course that’s already been completed (which shouldn’t be possible)
Expected:
- Student should only be able to drop a course if they are currently enrolled in it.
- Should get clear feedback if they try to drop something invalid.
Resolution Log:
- Added
if course in enrolled_coursesto handle valid case - Used
eliffor checking if the course was already completed (blocked it) - Used
elseto handle the case where they were never enrolled in the course at all - Each condition includes a
returnand a print statement for feedback - Ran some tests with fake courses and it responded correctly
Status: Resolved
File(s) Affected: Course.py
Commit (Noticed): Update #1 - Course.py file (2e2f84e)
Commit (Resolved): Update #1 - Course.py file (2e2f84e)
No error came up, but while writing the __init__() method for the Course class, I wasn’t sure how to safely handle the enrolled_students list. At first I considered using enrolled_students=[] as a default parameter, but I remembered this can cause problems in Python if that same list ends up being shared across different course instances.
Expected:
- Each course should have its own separate list of enrolled students.
Actual (if not fixed):
- If the default list was shared, multiple course objects might end up with the same
enrolled_studentslist, which would break logic later and make debugging harder.
- First tried using
enrolled_students=[]as a default value - Realised it could lead to shared state between course instances
- Considered using
Noneand then assigning the list inside__init__, but it felt a bit overcomplicated for what I needed - In the end, I removed
enrolled_studentsfrom the parameter list entirely and just wroteself.__enrolled_students = []directly in the constructor - It was simpler, safer, and avoids the risk of unexpected behaviour
Status: Resolved
File(s) Affected: Student.py
Commit (Noticed): Update #2 - Student.py file (8aa89bb)
Commit (Resolved): Update #5 - Student.py file (d4bdd8f)
No runtime error, but I realised there was no way to track course completions in the system. We had __completed_courses defined in __init__(), but nothing added to it. This meant there was no clear way for a course to move from "enrolled" to "completed."
Expected:
- There should be a method that allows the system to mark a course as completed and update the lists properly.
Actual (if not handled):
- Courses would remain in
enrolled_coursesindefinitely unless manually moved, andcompleted_courseswould stay empty.
- Created a new method called
complete_course(course) - Added a check to see if the course is currently in
enrolled_courses - If yes, it removes the course from enrolled and appends it to completed
- If not, it shows a message saying the student can't complete a course they’re not enrolled in
- Added a print statement for feedback
- Also added a
TODOcomment inside the method to remind myself that in a real system, there should be a grade/pass check before marking a course as completed - This method now works as a basic manual way to track completed courses for the moment
Status: Resolved
File(s) Affected: Course.py
Commit (Noticed): Update #1 - Course.py file (2e2f84e)
Commit (Resolved): Update #5 - Course.py file (d4bdd8f)
No error came up during testing, but I wanted to make sure the course enrolment logic included a check for the maximum number of students allowed. The assignment brief says a course should have a maximum of 10 students, and any enrolments after that should be rejected.
Expected:
- Prevent students from being enrolled in a course once it reaches its maximum capacity.
Actual (if not handled):
- Without a check, students could keep being added to the list and break the course limit requirement.
- Declared a class-level constant called
MAX_CAPACITY = 10 - In the
enrol_student()method, added a condition to check the length of__enrolled_students - Used
>=instead of==to ensure defensive programming — just in case someone adds directly to the list outside the method - If the list is at or above capacity, it prints a message and exits the function
- If there’s space, it adds the student and gives a success message
- Manually tested by enrolling more than 10 students — method correctly blocked enrolment when full
Status: Resolved
File(s) Affected: Course.py, Student.py
Commit (Noticed): Update #4 - Course.py, Student.py (ecb8868)
Commit (Resolved): Update #5 - Course.py, Student.py (d4bdd8f)
No runtime errors, but some of the output from print() statements looked awkward. Specifically:
- When enrolling or dropping a student from a course, the output used
__str__()before updating their status, resulting in messages like:Anush De Costa (ID: S123456) - Enrolled Courses: None has been successfully enrolled... - The course
__str__()method printed all details on one line, which made the output harder to read.
Expected:
- Print messages should clearly show student actions using their name
- Course string output should list the instructor on a new line
Actual:
- Student summaries were printed mid-update, making them confusing
- Course string was cluttered and not easy to scan
- Added a
get_full_name()method toStudent.pyfor cleaner use in print messages - Replaced uses of
str(student)in course methods withstudent.get_full_name()to avoid mid-state print issues - Updated the
__str__()method inCourse.pyto include a\nso instructor appears on a separate line - Output is now clear, user-friendly, and easier to read in the console
Status: Resolved
File(s) Affected: Staff.py
Commit (Noticed): Update #6 - Staff.py file (db6e596)
Commit (Resolved): Update #7 - Staff.py file (e92cafa)
There was no actual error, but while implementing the assign_course() method, I realised it needed to enforce the assignment rule from the brief:
Instructors can only manage 5 courses at once.
Additionally, this was the first implementation of key Staff methods and required careful logic to align with how Student and Course were built.
Expected:
- Prevent assigning more than 5 courses to a staff member
- Provide meaningful feedback when assigning/removing courses
Actual (if not handled):
- Staff could be assigned unlimited courses
- Output messages would be unclear and not consistent with
Student.py
- Declared a class-level constant
MAX_COURSES = 5inStaff.py - Implemented
assign_course()with duplicate check and enrolment cap - Implemented
remove_course()to safely drop courses with feedback - Added
list_assigned_courses()to show assigned courses or 'None' - Used
get_full_name()in print messages for clarity - Updated
__str__()to include full name, ID, and department - Manually tested with >5 courses — sixth assignment correctly blocked.
Status: Resolved
File(s) Affected: Student.py, Course.py, Staff.py
Commit (Noticed): Update #5 - Course.py, Student.py (d4bdd8f)
Commit (Resolved): Update #8 - Student.py, Course.py, Staff.py (8dbeb98)
During testing in main.py, I noticed several user feedback messages used vague references like "You have been enrolled..." or "You have been removed...". This became confusing when working with multiple students or staff members in output logs — it was unclear who "You" was referring to.
Expected:
- All output messages should use either the student or staff member’s full name for clarity and consistency
Actual (if not fixed):
"You"messages appeared in all three classes, which could lead to ambiguous console output when running batch operations or debugging
- In
Student.py, replaced all"You"references withself.get_full_name()inenrol(),drop(), andcomplete_course() - In
Course.py, updatedenrol_student()anddrop_student()to usestudent.get_full_name()instead of generic"You" - In
Staff.py, updatedassign_course()andremove_course()to useself.get_full_name()in all print statements - Output is now unambiguous and consistent across all three core classes
- Manually tested using
main.pywith multiple objects — messages now correctly identify the actor involved
Status: Resolved
File(s) Affected: Student.py, Course.py, Staff.py
Commit (Noticed): Update #6 - Staff.py file (db6e596)
Commit (Resolved):
- Update #9 - Student.py (
22bb2c3) - Update #10 - Course.py (
b51c26c) - Update #11 - Staff.py (
12de847)
No runtime error occurred, but as I began planning the School class, I realised that external access would be required to several private attributes in the Student, Course, and Staff classes — especially for logic such as:
- Checking which student is enrolled in which course
- Verifying course assignment limits for staff
- Tracking completed courses for a student
- Matching students or staff by ID
Expected:
- Other classes (like School) should be able to access necessary data without breaking encapsulation
- External logic should go through well-named getters
Actual (if not handled):
- Other modules would either:
- Access private variables directly (bad practice)
- Duplicate logic or violate OOP design principles
- Be harder to scale and maintain
- Reviewed each class and identified only the necessary attributes that required external access
- Implemented minimal, purposeful getters:
- Student.py:
get_student_id(),get_enrolled_courses(),get_completed_courses() - Course.py:
get_course_id(),get_course_name(),get_instructor(),set_instructor(),get_enrolled_students() - Staff.py:
get_employee_id(),get_assigned_courses()
- Student.py:
- Ensured all getters are documented and no unnecessary setters were added
- Committed these changes across Updates #9, #10, and #11
Status: Resolved
File(s) Affected: School.py
Commit (Noticed): Update #12 - Created School class skeleton (32a238c)
Commit (Resolved): Update #13 - Implemented add/remove logic (9fe3761)
No error occurred, but while implementing the add_ and remove_ methods for students, staff, and courses in School.py, I realised using direct object comparison (if student in self.__students) could lead to false negatives when objects are logically equal but not the same instance in memory.
Expected:
- Avoid duplicates when adding students/staff/courses based on their ID, not memory reference.
- Allow proper removal even if the object passed in is a copy with the same ID.
Actual (if not fixed):
- Duplicate records could be added unintentionally.
- The system might fail to remove a record if the passed object wasn't the same reference.
- Used
get_student_id(),get_employee_id(), andget_course_id()in all comparisons - Looped through each internal list to compare objects by ID
- Ensured that
remove_methods safely delete the correct object - Output messages were updated to give user-friendly feedback
- Fully tested through
main.pyto confirm reliable add/remove behaviour
Status: Resolved
File(s) Affected: Staff.py, Course.py, Student.py
Commit (Noticed): Update #8 – Student.py, Course.py & Staff.py (8dbeb98)
Commit (Resolved): Update #14 – Refactor Student.py, Course.py & Staff.py (45e2869)
Course.__str__was callingstr(instructor)(i.e.,Staff.__str__), so course prints pulled in “Assigned Courses: …”.Course.enrol_student()/drop_student()contained internalprint()calls, leading to duplicate output when invoked fromStudent.enrol()/drop().Student.enrol()anddrop()mixed calls tostr(course)with custom prints, causing multi-line or confusing messages.Staff.assign_course()/remove_course()printed the fullCourse.__str__instead of a concise “course name (term)”.
- Course.py
- Removed all
print()calls fromenrol_student()anddrop_student(). - Rewrote
__str__()to include only<course_name> (<term>)andInstructor: <name> (ID: <eid>)via getters.
- Removed all
- Student.py
- Consolidated user-facing prints into
enrol()anddrop(). - Updated messages to use
course.get_course_name()andcourse.get_term(). - Ensured bi-directional updates by calling
course.enrol_student(self)/course.drop_student(self)without internal prints.
- Consolidated user-facing prints into
- Staff.py
- Refactored
assign_course()andremove_course()to explicitly print course name and term without callingstr(course). - Updated
__str__()to list assigned courses (or “None”) instead of department.
- Refactored
- All files
- Tidied up extra blank lines and normalized spacing project-wide.