如何修复CS50 Credit作业中Python代码的回溯错误?
CS50 Credit作业Python实现的回溯错误修复
正在完成CS50的Credit编程作业,用Python实现并通过正则表达式处理卡号格式。在编写Luhn算法部分前一切正常,但现在出现回溯错误,check50测试中所有预期输出为INVALID的用例都触发相同错误:
Traceback (most recent call last): File "/tmp/tmph_wbo0m4/test9/credit.py", line 43, in <module> main() File "/tmp/tmph_wbo0m4/test9/credit.py", line 7, in main validate(card) File "/tmp/tmph_wbo0m4/test9/credit.py", line 21, in validate ...
问题代码
import re def main(): card = int(input("Card number: ")) validate(card) def validate(card): if re.search(r"^(34|37)\d{13}$", str(card)): print("AMEX\n") elif re.search(r"^(51|52|53|54|55)\d{14}$", str(card)): print("MASTERCARD\n") elif re.search(r"^[4](\d{12}|\d{15})$", str(card)): print("VISA\n") sum = 0 productSum = 0 # Reversing the str with [::-1] for i in range(len(card[::-1])): if i % 2 == 0: sum += int(card[::-1][i]) * 2 if sum > 9: # Using modulus operator to get the second digit of a product (second digit is the remainder) n = sum % 10 # Using integer division to get the first digit of a product (disregarding the remainder) m = sum // 10 productSum = n + m sum += productSum for j in range(len(card[::-1])): if j % 2 == 0: sum += int(card[::-1][j]) if sum % 10 != 0: print("INVALID\n") if __name__ == "__main__": main()
核心错误及修复建议
类型错误触发回溯
main里把输入转成int传入validate,但后续直接对card用[::-1]切片——整数不支持切片操作,这是回溯的直接原因。
修复:在validate开头先把card转成字符串并保存,避免重复转换:def validate(card): card_str = str(card) # 后续所有操作改用card_str,比如card_str[::-1]Luhn算法逻辑混乱
当前两次循环重复计算,且数值处理逻辑错误。正确的Luhn步骤是:- 反转卡号字符串
- 遍历每个数字,反转后索引为奇数的数字乘2,若结果大于9则拆成单个数字相加
- 反转后索引为偶数的数字直接相加
- 总和模10等于0则有效
修正后的计算部分:
total = 0 reversed_card = card_str[::-1] for idx, char in enumerate(reversed_card): num = int(char) if idx % 2 == 1: # 处理反转后的第2、4...位(原卡号倒数第2、4...位) doubled = num * 2 total += doubled // 10 + doubled % 10 else: # 反转后的第1、3...位直接累加 total += num流程逻辑错误
当前匹配到卡种后直接打印但不终止函数,会继续执行Luhn检查,可能导致有效卡号也输出INVALID。需在打印卡种后加return,或调整顺序:先做Luhn有效性验证,再判断卡种格式。
完整修正代码示例
import re def main(): card = input("Card number: ") validate(card) def validate(card): # 先执行Luhn有效性验证 total = 0 reversed_card = card[::-1] for idx, char in enumerate(reversed_card): num = int(char) if idx % 2 == 1: doubled = num * 2 total += doubled // 10 + doubled % 10 else: total += num if total % 10 != 0: print("INVALID") return # 再验证卡种格式 if re.search(r"^(34|37)\d{13}$", card): print("AMEX") elif re.search(r"^(51|52|53|54|55)\d{14}$", card): print("MASTERCARD") elif re.search(r"^4\d{12}(?:\d{3})?$", card): print("VISA") else: print("INVALID") if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者Jötunn
相关产品推荐
相关产品推荐

