Welcome to Day 17 of the #80DaysOfChallenges journey! Today’s
challenge was a polished take on a classic: converting numeric grades to letter grades, emphasizing clean input handling, modern conditional logic, and Python 3.10+ match-case. This beginner-to-intermediate task gave me a solid workout in validation, control flow, and user-friendly program design. It felt like building a tiny, reliable grading assistant.
💡 Key Takeaways from Day 17: Robust Grade Converter
This challenge accepts both integer and decimal grades (like 89.5), validates input thoroughly, and uses match-case to map values to A–F letters. The output is simple, but the strength lies in the input loop, data cleaning, and readable branching. Let’s break down the essentials: robust input, match-case for clarity, and smooth user flow.
1. Robust Input: Ensuring a Valid Grade Every Time
The get_valid_grade function is the gatekeeper. It uses a while True loop to force a valid float between 0 and 100, handling both whole numbers and decimals:
while True:
raw_input_value = input("Enter your grade (0–100): ").strip()
try:
grade = float(raw_input_value)
except ValueError:
print("That doesn't look like a number. Please enter a valid numeric grade.")
continue
if not (0 <= grade <= 100):
print("Grade must be between 0 and 100. Try again.")
continue
return grade
I loved how resilient this is; strip() removes stray spaces, float() accepts 85 or 89.5 equally well. If the user types "abc" or "-5", it responds with a clear message and loops again, no crashes, no nonsense. This kind of input handling turns a fragile script into something you can actually trust.
2. match-case: Modern, Readable Conditional Branching
The convert_to_letter_grade function uses Python 3.10+ match-case with guard clauses to define grade ranges cleanly, replacing long if-elif chains:
match grade:
case grade if 90 <= grade <= 100:
return "A"
case grade if 80 <= grade < 90:
return "B"
case grade if 70 <= grade < 80:
return "C"
case grade if 60 <= grade < 70:
return "D"
case grade if 0 <= grade < 60:
return "F"
case _:
return None # Signal invalid value
Each case is explicit and scannable. For example, 92 → "A", 79.9 → "C". The wildcard case _ acts as a safety net (though input validation already prevents invalid ranges). It’s like reading a grading policy in code form, clear, maintainable, and elegant.
3. Program Flow: A Friendly, Interactive Experience
The main loop lets users convert multiple grades and exit gracefully:
while True:
grade_value = get_valid_grade()
letter = convert_to_letter_grade(grade_value)
print(f"Your letter grade is {letter}")
again = input("Would you like to enter another grade? (y/n): ").strip().lower()
if again != "y":
print("Thanks for using the grade converter! Goodbye.")
break
Small touches like emojis (Checkmark, Graduation cap), consistent formatting, and case-insensitive input ("Y", "yes", " y ") make it feel polished. The user isn’t just running code, they’re having a conversation with it.
🎯 Summary and Reflections
This challenge showed that even a simple conversion can teach big lessons in code quality. It made me focus on:
- Input resilience: Loop + try/except + validation = unbreakable user entry.
-
Modern syntax:
match-casefor multi-condition logic that reads like a table. - User experience: Clear feedback, flexibility, and a touch of warmth turn functionality into delight.
The surprise? How much cleaner match-case made the logic feel. It’s like the code grew up. For extensions, I could add plus/minus grades (A-, B+), or read from a CSV to process an entire class.
Advanced Alternatives: Use dataclasses to bundle grade data, or build a GUI with tkinter for visual input. How do you handle grading logic in Python? Drop your approaches below!
🚀 Next Steps and Resources
Day 17 grounded me in robust input and modern control flow, setting up for more interactive challenges. If you're on the #80DaysOfChallenges train, how did you handle validation? Any match-case tips or UX tweaks? Share in the comments!
- Source Code for Challenge #17: scripts/grade_converter.py
- Main Repository: 80-days-of-challenges
- Daily Updates: Twitter/X (@Shahrouzlogs)
Onward to Day 18, ready for the next coding adventure!
Top comments (0)