Project: Debugging a Student Grading App
Project: Debugging a Student Grading App
In this capstone project, we will apply the debugging and diagnostic techniques mastered throughout this chapter—Structured Logging, Logging Levels, Exception Traceback Capture, and Invariant Assertions—to diagnose and resolve logical and runtime bugs in an enterprise Student Grading & Analytics Application.
1. The Scenario & Buggy Application
Imagine inheriting a legacy grading script that crashes unexpectedly on certain student batches and produces incorrect honors classifications.
The Buggy Code (Before Debugging):
2. Implementing Diagnostic Logging Architecture
Instead of blindly adding print() statements, we establish a robust dual-channel logging architecture:
- 1Console Handler: Emits
INFOand higher messages for general application feedback. - 2File Handler (
grading_audit.log): Emits fine-grainedDEBUGlogs containing exact numerical calculations, variable types, and captured tracebacks.
3. The Refactored, Bug-Free Grading Engine
Here is the fully instrumented, defensively programmed grading engine incorporating validations and assertions:
4. Execution Output & Audit Verification
Console Output:
Log File Output (grading_audit.log):
Multiple Choice Questions
1. In our refactored grading application, why do we configure two separate handlers (console and file)?
A. Because Python requires at least two handlers to run B. To allow high-level summaries on the console (INFO) while storing detailed diagnostic traces (DEBUG) in a file C. To prevent threads from colliding D. To encrypt the student records Answer: B Explanation: Multi-handler logging enables separation of concerns: users see clean high-level output on stdout, while complete granular diagnostics are saved to log files for debugging.
2. How did the refactored code handle string scores like "95" without crashing?
A. By deleting the student from the dictionary B. By attempting to cast each item to float inside a try/except (ValueError, TypeError) block C. By using eval() D. Strings cannot be converted to floats in Python Answer: B Explanation: Wrapping the float(item) conversion in a try-except block safely converts numeric strings while catching non-numeric values like "invalid".
3. What prevents the ZeroDivisionError when a student has submitted zero scores?
A. Python automatically sets 0 / 0 = 0 B. Checking if not sanitized: before performing the division and logging a warning C. Adding 1 to the denominator D. The assert statement Answer: B Explanation: Checking if the list is empty before dividing prevents ZeroDivisionError and allows handling incomplete records gracefully.
4. What is the role of assert 0.0 <= avg <= 100.0 in compute_student_performance()?
A. To parse student names B. To serve as an internal sanity invariant ensuring calculation logic never produces an impossible average C. To validate command line arguments D. To terminate the database connection Answer: B Explanation: Assertions verify internal algorithm correctness; an average outside 0-100 would indicate an internal mathematical defect.
5. Why is logger.exception() preferred over logger.error() inside the pipeline's top-level catch-all block?
A. It runs faster B. It automatically records the complete stack traceback to the log file along with the error message C. It deletes previous log files D. It sends an email alert automatically Answer: B Explanation: logger.exception() automatically captures and appends the active traceback, preserving essential debugging context.
Math and Random Module
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Assertions | Math and Random Module |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.