现在,当我运行这段代码时,我得到一个错误提示"4不在列表中“,因为if (numberList.index(digit)-1) % 2 == 0:行不确定我哪里出错了,但如果有任何提示我们将不胜感激。它从倒数第二个字母开始,if语句通过.index(digit) % 2 == 0检查它是否每隔一个字母
def credit():
cardType = ""
mastercard = ["51", "52", "53", "54", "55"]
american_express = ["34", "37"]
total = 0
while True:
number = input("Enter Valid Credit Card Number: ")
if " " in str(number):
print("INVALID")
continue
number = int(number)
if len(str(number)) == 15 and str(number)[0:2] in american_express:
cardType = "American Express"
break
elif len(str(number)) == 16:
if str(number)[0] == "4":
cardType = "Visa"
elif str(number)[0:2] in mastercard:
cardType = "Mastercard"
break
elif len(str(number)) == 13:
cardType = "Visa"
break
else:
print("INVALID CARD")
continue
numberList = []
for n in str(number):
numberList.append(n)
for digit in numberList[::-2]:
digit = int(digit)
if numberList.index(digit) % 2 == 0:
if (digit*2) >= 10:
total += ((digit*2) / 10)
total += ((digit*2) % 10)
elif (digit*2) < 10:
total += digit
else:
if digit > 10:
total += (digit / 10)
total += (digit % 10)
elif digit < 9:
total += digit
if (total % 10) == 0:
print(cardType)
else:
print("INVALID CARD")
print(total)
credit()发布于 2021-03-13 02:34:16
这是因为您已将该字符转换为int:
for digit in numberList[::-2]:
digit = int(digit)
if numberList.index(digit) % 2 == 0:numberList是单个字符的列表。但是字符不同于整数:"9" != 9,所以index找不到这个整数。
因此,要么执行numberList.index(str(digit)),要么将语句digit = int(digit)推迟到执行完if条件之后。然后,您需要将该语句放入if和else块中。
您可以通过将numberList设置为整数(而不是字符)列表来完全避免这种情况:
替换为:
numberList = []
for n in str(number):
numberList.append(n)通过以下方式:
numberList = list(map(int, s))现在,您不需要语句digit = int(digit)。
发布于 2021-03-13 03:29:04
@trincot指出了一个索引错误。另一种是numberList.index(str(digit))将返回匹配的第一个数字的索引,例如,如果它们是两个4,那么它将为这两个数字提供相同的索引。
下面是一个有效的算法:
def card_type(number):
cardType = ""
mastercard = '51','52','53','54','55'
american_express = '34','37'
digits = len(number)
if digits == 15 and number[:2] in american_express:
return 'American Express'
elif digits == 16 and number[0] == '4' or digits == 13:
return 'Visa'
elif number[:2] in mastercard:
return 'Mastercard'
else:
return 'Unknown'
def credit(number):
# https://en.wikipedia.org/wiki/Luhn_algorithm
total = 0
for digit in number[-2::-2]: # every other digit from right starting 2nd-to-last
value = int(digit) * 2
total += value if value < 10 else value - 9 # value-9 same as sum of two digits, e.g. 16 => 1+6 = 16-9 = 7
for digit in number[-1::-2]: # every other digit from right starting from last
total += int(digit)
if total % 10 == 0:
return card_type(number)
return 'Invalid'
print(credit('4123456789123450')) # Visa
print(credit('341234567891232')) # AmEx
print(credit('5112345678912349')) # Mastercard
print(credit('1234567891233')) # Visa
print(credit('123')) # bad check
print(credit('125')) # valid but unrecognizedVisa
American Express
Mastercard
Visa
Invalid
Unknown发布于 2021-03-13 03:48:46
你的for digit in numberList[::-2]:只处理每隔一个数字,完全跳过中间的数字。然后,假设您正在遍历所有数字,您将找到一个数字在字符串中的位置,如果代码中有重复的数字,该位置将不会给出正确的值。除此之外,即使代码中没有重复的数字,.index()也会从开头查找位置,因此如果代码中有偶数个位置,您所做的奇/偶测试将给出错误的答案。
要正确执行Luhn测试,必须在开始之前反转代码。然后,一切都变得更简单,可以按顺序执行(例如,使用总和和理解)。
例如:
def luhnTest(code):
digits = [*map(int,code[::-1])]
cd = sum(digits) + sum(d - (d>4)*9 for d in digits[1::2])
return not cd % 10 将每个数字(包括校验位)相加一次,以验证校验位。奇数位置的数字(在反码中)被再次相加(即,加倍),但是,如果加倍> 10,则将加倍的值的数字相加,这相当于减去9(即- (d>4)*9)。
# test set from https://en.wikipedia.org/wiki/Luhn_algorithm
tests = [79927398710, 79927398711, 79927398712, 79927398713, 79927398714,
79927398715, 79927398716, 79927398717, 79927398718, 7992739871]
for t in tests: print(t,luhnTest(str(t))
79927398710 False
79927398711 False
79927398712 False
79927398713 True
79927398714 False
79927398715 False
79927398716 False
79927398717 False
79927398718 False
7992739871 False只需稍加修改,您就可以将其分解为一个单独的理解:
return 1>sum(d+(i%2)*(d-(d>4)*9) for i,d in enumerate(map(int,code[::-1])))%10https://stackoverflow.com/questions/66605252
复制相似问题