【问题标题】:Find odd and even digits for credit card validation查找信用卡验证的奇数和偶数
【发布时间】:2023-03-18 11:50:01
【问题描述】:

我参加了 CS50 课程,这是我第一次使用 Python。我正在处理问题集 6 - 信用卡。这是我的代码:

from cs50 import get_string
from itertools import chain
import re

def main():
    # get credit card number from user
    credit_card = get_string("Number: ")

    # take odd and even number from Credit Card and then store it in reversed
    # 4003600000000014 || even = 10000604 || count from last-to-second

    even =''.join(reversed (re.findall("\w",credit_card[::2])))
    odd =''.join(reversed (re.findall("\w",credit_card[1::2])))

    # convert strings to integer
    even = [int(i) for i in even]
    odd = [int(i) for i in odd]

    
    # add each number in the list
    # BUT for SUM_EVEN number, multiply each digit by 2. and there will be the case the result is greater than 9
    # ex : 6 * 2 = 12 || so we need to seperate it (12 = 1 + 2)
    
    sum_even = sum([int(((2 * x) % 10) + ((2 * x)) / 10) for x in even])
    sum_odd = sum(odd)
    checksum = sum_even + sum_odd
    

    # FIND first digit and first two digit
    first_digit = int(credit_card[0:1])
    first_two_digit = int(credit_card[0:2])
    

    # VALIDATE the credit card and check which company by its structure
    if checksum % 10 == 0:
        if first_digit == 4 and (len(credit_card) == 13 or len(credit_card) == 16):
            print("VISA")
        elif (first_two_digit == 34 or first_two_digit == 37) and len(credit_card) == 15:
            print("AMEX")
        elif (first_two_digit >= 51 and first_two_digit <= 55) and len(credit_card) == 16:
            print("MASTERCARD")
        else:
            print("INVALID")
    else:
        print("INVALID")


main()

4003600000000014

因此,我们需要获取信用卡上的倒数第二个数字(或者我们可以称之为偶数),然后将每个数字乘以 2。然后我们与奇数相加。

问题是,我的代码几乎成功了。它成功打印了VISA和MASTERCARD信用卡。但是对于AMEX,它总是无效的。后来我发现AMEX信用卡使用的是15位数字。 MASTERCARD 使用 16 位数字。 VISA 使用 13 位或 16 位数字。

对于奇数位(13 或 15),我的代码没有像偶数位(16)那样采用奇数和偶数。

for example: 

VISA : 4003600000000014
even: [1, 0, 0, 0, 0, 6, 0, 4]
odd: [4, 0, 0, 0, 0, 0, 3, 0]

but for AMEX: 378282246310005
even: [5, 0, 1, 6, 2, 8, 8, 3]
odd: [0, 0, 3, 4, 2, 2, 7]

你能看到吗?美国运通的“偶数”不像VISA那样从倒数第二个数字开始。事实上,偶数和奇数互换了。

所以,我知道我自己发现的这段代码有一个错误:

even =''.join(reversed (re.findall("\w",credit_card[::2])))
odd =''.join(reversed (re.findall("\w",credit_card[1::2])))

我需要更改代码以处理数字是 13、15 还是 16。或者我的代码错误,我需要使用另一个代码来查找信用卡上的偶数和奇数卡。

【问题讨论】:

  • re.findall() 调用似乎没有必要(假设credit_card 变量只包含数字)。只需 even = credit_card[::2] 会给出偶数位,odd = credit_card[1::2] 会给出奇数位。
  • 原始问题陈述是否在某处可用?很难说你的程序应该做什么。
  • 这是完整的解释,但是对于 C:cs50.harvard.edu/x/2020/psets/1/credit --- 这是针对 Python 的。这是没有解释:cs50.harvard.edu/x/2020/psets/6/credit
  • @Kevinkun 你能确认我的回答能解决你的问题吗?当我尝试使用您的代码时,它似乎对我有用。

标签: python string slice


【解决方案1】:

问题说明您必须从倒数第二个数字开始每隔一个数字进行输入。但是正如您所发现的,这与简单地取数字的奇数位和偶数位不同,因为对于奇数或偶数长度的数字,它会给出不同的结果。解决方法是把数字取反,然后取其奇数位和偶数位:

# reverse the digits
cc_reversed = credit_card[::-1]
print(cc_reversed)

# convert to integers
even = [int(i) for i in cc_reversed[1::2]]
odd = [int(i) for i in cc_reversed[::2]]
print(even)
print(odd)

对于 4003600000000014 (VISA),打印:

4100000000063004
[1, 0, 0, 0, 0, 6, 0, 4]
[4, 0, 0, 0, 0, 0, 3, 0]

对于 378282246310005 (AMEX),它会打印:

500013642282873
[0, 0, 3, 4, 2, 2, 7]
[5, 0, 1, 6, 2, 8, 8, 3]

所以现在偶数列表将始终从原始号码的倒数第二个数字开始(即在上面的示例中,1 用于 VISA,0 用于 AMEX)。

更新

为了澄清,这里有一个更简单的例子:

>>> '0010'[::2] # even digits
'01'
>>> '0010'[::2][::-1] # even digits, reversed
'10'

对于偶数长度的数字,取偶数将始终以倒数第二个数字结束(这是我们想要的)。但这对于奇数长度永远不会起作用,因为它总是在 最后一个数字结束:

>>> '00010'[::2] # even digits
'000'

我们需要做的是取其他每个数字从第二个到最后一个数字开始。这可以通过先反转数字来保证:

>>> '0010'[::-1] # reversed
'0100'
>>> '0010'[::-1][1::2] # reversed, every other digit
'10'
>>> '00010'[::-1] # reversed
'01000'
>>> '00010'[::-1][1::2] # reversed, every other digit
'10'

谈论奇数和偶数实际上是一种误导。真正重要的是确保您始终从同一个地方开始

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    相关资源
    最近更新 更多