Python生日星期推算程序开发:当前代码疑似陷入循环问题
Hey there! I get that you're building a Python program to calculate the weekday of a given birthday, using Arthur Benjamin's neat modulo-7 trick from Think Like A Math Genius (2006)—such a fun application of calendar math! Let's dig into why your code might be stuck in a loop, and walk through a working version of the logic.
Common Causes of the Infinite Loop
First, let's rule out the usual suspects that trap code in loops:
- A
whileloop with a condition that never becomesFalse(e.g., forgetting to increment/decrement a counter variable) - Input handling that repeatedly prompts without accepting valid input (e.g., missing a
breakor not updating an input flag) - Buggy date calculation logic (like a broken leap year check that loops indefinitely)
Working Implementation of Benjamin's Method
Here's a clean, loop-free implementation that follows the core math from the book, with comments explaining each step:
def get_weekday(birth_year, birth_month, birth_day): # Step 1: Define weekday labels (matches Benjamin's numbering) weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] # Step 2: Month code (from Benjamin's trick) month_codes = { 1: 6, 2: 2, 3: 2, 4: 5, 5: 0, 6: 3, 7: 5, 8: 1, 9: 4, 10: 6, 11: 2, 12: 4 } # Step 3: Adjust month code for leap years (only affects Jan/Feb) def is_leap(year): if year % 4 != 0: return False elif year % 100 != 0: return True else: return year % 400 == 0 if is_leap(birth_year) and birth_month in (1, 2): month_code = month_codes[birth_month] - 1 else: month_code = month_codes[birth_month] # Step 4: Year code calculation (Benjamin's formula) last_two_digits = birth_year % 100 year_code = (last_two_digits + (last_two_digits // 4)) % 7 # Step 5: Century code (for Gregorian calendar) century = birth_year // 100 century_codes = {17: 4, 18: 2, 19: 0, 20: 6, 21: 4} # Extend as needed for future centuries century_code = century_codes.get(century, 0) # Default fallback # Step 6: Total sum modulo 7 to get weekday index total = (month_code + birth_day + year_code + century_code) % 7 return weekdays[total] # Example usage (no infinite loops here!) if __name__ == "__main__": try: year = int(input("Enter birth year (YYYY): ")) month = int(input("Enter birth month (1-12): ")) day = int(input("Enter birth day (1-31): ")) weekday = get_weekday(year, month, day) print(f"Your birthday falls on a {weekday}!") except ValueError: print("Please enter valid numeric values for year, month, and day.")
Key Fixes to Avoid Loops
- We replaced any potential looping logic with direct calculations (no
whileloops are needed for the core calendar math) - Input handling uses a single
try/exceptblock to catch invalid inputs without looping indefinitely - All calendar rules (leap years, month/century codes) are implemented with straightforward lookups and arithmetic—no recursive or looping checks that could get stuck
If your original code had a loop for input validation or date parsing, make sure you include a clear exit condition—for example, breaking the loop once valid input is received, or limiting the number of retries.
内容的提问来源于stack exchange,提问作者dd110110

