We’re on Day 11 of the #80DaysOfChallenges journey, and today’s challenge was a delightful return to the fundamentals: printing all numbers divisible by 8 up to a user-defined limit. This beginner-level task was a great way to sharpen my skills in loops, list comprehension, and input validation in Python. It’s amazing how much you can learn from a seemingly simple problem, let’s dive into what made this challenge both fun and insightful.
💡 Key Takeaways from Day 11: Divisible by 8
The goal was to ask the user for a positive integer and print all numbers from 1 to that integer that are divisible by 8. The challenge emphasized three core concepts: iteration, conditional logic, and input validation. It also gave me a chance to play with list comprehension, which felt like a little Python magic trick.
1. Iteration and Conditional Logic: The Core of Divisibility
The heart of the challenge lies in the print_divisible_by_eight
function, which finds and prints numbers divisible by 8 within a given range. A number is divisible by 8 if it leaves no remainder when divided by 8 (i.e., num % 8 == 0
). The function uses a list comprehension to handle this elegantly:
def print_divisible_by_eight(limit: int) -> None:
divisible_numbers = [num for num in range(1, limit + 1) if num % 8 == 0]
print(f"Numbers from 1 to {limit} divisible by 8: {divisible_numbers}")
What I loved about this was the simplicity of the modulo operator (%
). It’s like a gatekeeper that checks if a number fits the divisibility rule. The list comprehension was a game-changer; it condenses what could’ve been a verbose for
loop into a single, readable line. For example, if the user enters 20
, the output is [8, 16]
, since those are the only numbers from 1 to 20 divisible by 8.
I initially considered using a traditional for
loop to build the list, like this:
divisible_numbers = []
for num in range(1, limit + 1):
if num % 8 == 0:
divisible_numbers.append(num)
While this works, the list comprehension felt more Pythonic and concise. It was a small but satisfying moment of realizing how Python’s syntax can make code both efficient and expressive.
2. Input Validation: Making the Program Bulletproof
The get_positive_integer
function handles user input, ensuring it’s a positive integer. This part was a great reminder of how important it is to anticipate user errors. Here’s the code:
def get_positive_integer() -> int:
while True:
try:
value = int(input("Enter a positive integer: "))
if value > 0:
return value
print("The number must be positive. Try again.")
except ValueError:
print("Invalid input. Enter a valid integer.")
This function does two critical checks:
-
Type validation: The
try-except
block catches non-integer inputs (like letters or decimals) and prompts the user to try again. -
Value validation: It ensures the input is positive (
value > 0
), since negative or zero limits wouldn’t make sense for this task.
I appreciated how the while True
loop creates a persistent but polite prompt, looping until the user provides a valid input. For example, entering "abc"
triggers “Invalid input. Enter a valid integer.”, while entering -5
prompts “The number must be positive. Try again.” It’s like teaching the program to be patient with the user, which feels surprisingly human.
One lesson here was the importance of clear error messages. Vague messages like “Error!” could frustrate users, but specific feedback guides them to fix their input. It’s a small detail, but it makes the program feel polished.
3. Function Design: Keeping It Modular
The challenge splits the logic into two functions: get_positive_integer
for input and print_divisible_by_eight
for processing. This modularity makes the code clean and reusable. For instance, I could easily adapt print_divisible_by_eight
to find numbers divisible by any other number (say, 7 or 10) by tweaking the modulo condition.
The output formatting was straightforward but effective:
print(f"Numbers from 1 to {limit} divisible by 8: {divisible_numbers}")
Using an f-string keeps the output readable, like Numbers from 1 to 20 divisible by 8: [8, 16]
. I briefly considered printing each number on a new line, but the list format felt more concise and visually clear, especially for larger ranges where the output could get long.
🎯 Summary and Reflections
This challenge was a perfect blend of simplicity and depth. It reinforced:
- List Comprehension: A concise way to filter numbers based on a condition, making code elegant and efficient.
- Input Validation: Building a robust program that handles user errors gracefully is as important as the core logic.
- Modularity: Separating input and processing into functions makes the code reusable and maintainable.
What surprised me was how much fun I had with list comprehension. It felt like solving a puzzle in one line instead of several. I also realized how much thought goes into user interaction, even a simple prompt can make or break the experience.
Advanced Alternatives: You could extend this by allowing the user to choose the divisor (not just 8) or return the count of divisible numbers instead of listing them. Another idea is using a generator expression for memory efficiency with large ranges. What’s your favorite way to handle loops or input validation in Python? Share your thoughts below!
🚀 Next Steps and Resources
Day 11 was a grounding exercise in core programming concepts, reminding me that even “simple” challenges can sharpen your skills. If you’re following along with the #80DaysOfChallenges, how did you tackle this one? Got any clever tricks for list comprehension or input handling? Drop them in the comments!
- Source Code for Challenge #11: scripts/divisible_by_eight.py
- Main Repository: 80-days-of-challenges
- Daily Updates: Twitter/X (@Shahrouzlogs)
Top comments (0)