Skip to main content

46. The Code Rescue Mission

1. Introduction

Welcome to your mid-way revision! At DHNair, we believe that reading and fixing code is just as important as writing it from scratch.

Below is a prototype script meant to process student records and calculate their grades. However, the previous developer left it in a messy, broken state. The script crashes, loops infinitely, and gives the wrong grades.

Your mission is to rescue this script. You will tackle this in three phases, applying everything you have learned in Chapters 17 through 45.


2. The Broken Script (tracker.py)

Run this code in your environment or trace it mentally to see what goes wrong.

# tracker.py - DHNair Student Record Processor

student_name = "Deepak Nair"
student_age = "25"
contact_info = ("deepak@example.com", "555-1234")
enrolled_courses = ["Python", "Linux", "AIX", "Python", "Linux"]
scores = [45, 88, 92, 78, 60]

# --- PHASE 2 BUGS (Data Types & Structures) ---
print("Calculating age next year...")
age_next_year = student_age + 1 # CRASH 1

print("Updating contact info...")
contact_info[0] = "deepak@dhnair.in" # CRASH 2

# We need a collection of unique courses, but lists allow duplicates.
unique_courses = enrolled_courses # LOGIC BUG 1

# --- PHASE 3 BUGS (Control Flow) ---
print("Processing records...")
processing = True
count = 0
while processing:
print("Saving to database...")
if count == 3:
pass # CRASH 3 (Infinite Loop!)

# Calculate average grade
average_score = sum(scores) / len(scores)

# Assign Letter Grade
if average_score >= 50:
letter_grade = "C"
elif average_score >= 75:
letter_grade = "B"
elif average_score >= 90:
letter_grade = "A"
else:
letter_grade = "F"
# LOGIC BUG 2: Deepak's average is 72.6, but an 80 would also get a "C"!

# Find passing scores (greater than 70)
passing_scores = []
for s in scores:
if s > 70:
passing_scores.append(s)

print(f"Student: {student_name}, Grade: {letter_grade}")
print(f"Passing Scores: {passing_scores}")

3. Task 1: The Data Fix (Phase 2 Review)

Your first goal is to stop the script from throwing TypeErrors and Data Structure errors. Review Chapters 17-26 to complete these fixes.

  • Fix CRASH 1: The script fails to calculate age_next_year. Cast the variable to the correct data type before doing the math.
  • Fix CRASH 2: We are trying to update an email address inside a tuple. Change the contact_info structure to a more appropriate data type (like a List or a Dictionary) so it can be updated.
  • Fix LOGIC BUG 1: enrolled_courses contains duplicate entries. Convert this list into a data structure that automatically removes duplicates, then convert it back to a list.

4. Task 2: The Flow Fix (Phase 3 Review)

Now that the data is stable, the script gets stuck or makes bad decisions. Review Chapters 27-36 to complete these fixes.

  • Fix CRASH 3: The while loop runs forever. You need to do two things: replace pass with the correct loop control statement, and ensure count increments on each loop iteration.
  • Fix LOGIC BUG 2: The if/elif chain is evaluating out of order. A student with an average of 95 will get a "C" because 95 >= 50 is evaluated first. Reorder this logic so grades are assigned correctly.
  • Refactor the for Loop: The passing_scores loop works, but it takes 4 lines of code. Rewrite this logic into a single List Comprehension.

5. Task 3: The Refactor (Phase 4 Review)

The script works now, but it is one long block of spaghetti code living in the global scope. Let's make it modular and professional. Review Chapters 37-45 to complete this phase.

  • Step 1: Create a new file called dhnair_utils.py.
  • Step 2: Move your fixed if/elif grading logic into a function inside dhnair_utils.py called calculate_letter_grade(score). It should return the letter grade.
  • Step 3: Back in tracker.py, import your new module.
  • Step 4: Wrap the rest of the student processing logic inside a function called process_student(**kwargs). It should accept keyword arguments (like name="Deepak", age=25, scores=[45, 88...]) and print the final report.
  • Step 5: Set up a Virtual Environment for this project, activate it, and generate a requirements.txt file (even if it's currently empty of external packages).