pythoncs50

How do I fix a traceback error in a CS50 Credit Pset in Python?


Been working on a Credit Pset in python. Decided to use regular expressions. Everything was fine before I got to the Lunh's algorithm part. Now I get traceback errors and don't know what to do with them.

Here is the code:

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()

The check50 errors are the same for every expected "INVALID" output:

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
 ...

The rubber duck only tells me that the problem is in validate() function. Thank you.


Solution

  • There are several small errors in your code. The first two are from the comments above:

    1. In main(), you convert the input to an integer, then try to use the value as a string in validate().
    2. The Luhn digit calculation is incorrect. It returns INVALID for "David's VISA card": 4003600000000014.

    Another thing I noticed:

    1. Your regular expression checks all the expected CC #s but doesn't have an else statement for #s that don't match (for example, it won't catch 1234567890).

    Issues with the Luhn digit calculation:

    1. You are only supposed to sum the product digits for the digits multiplied by 2. You are summing the products and the product digits.
    2. When looping over the digits to multiply, use all 3 arguments of the range() function: (start, stop, step): start=-2 starts at the next to last digit; step=-2 increments the value by -2; stop should be the length of the card string +1. When you do this, you can eliminate the test for i % 2 == 0. It's also a lot easier to check the calculation. :-)
    3. The same idea about range() applies when you are summing the digits that weren’t multiplied by 2 (using start=-1).

    My version with the modifications described above passes check50.