Debug an ISBN Validator - Debug an ISBN Validator

Tell us what’s happening:

Struggling to pass tests 8 and 14. Everything else worked fine, but I have no clue what I’m doing wrong. Any help is appreciated! Thank you!

Your code so far

import re
def validate_isbn(isbn, length):
    if len(isbn) != length:
        print(f'ISBN-{length} code should be {length} digits long.')
        return
    main_digits = isbn[0:length]
    given_check_digit = isbn[length-1]
    main_digits_list = [int(digit) for digit in main_digits[:length-1]]
    # Calculate the check digit from other digits
    if length == 10:
        expected_check_digit = calculate_check_digit_10(main_digits_list)
    else:
        expected_check_digit = calculate_check_digit_13(main_digits_list)
    # Check if the given check digit matches with the calculated check digit
    if given_check_digit == expected_check_digit:
        print('Valid ISBN Code.')
    else:
        print('Invalid ISBN Code.')
def calculate_check_digit_10(main_digits_list):
    # Note: You don't have to fully understand the logic in this function.
    digits_sum = 0
    # Multiply each of the first 9 digits by its corresponding weight (10 to 2) and sum up the results
    for index, digit in enumerate(main_digits_list):
        digits_sum += digit * (10 - index)
    # Find the remainder of dividing the sum by 11, then subtract it from 11
    result = 11 - digits_sum % 11
    # The calculation result can range from 1 to 11.
    # If the result is 11, use 0.
    # If the result is 10, use upper case X.
    # Use the value as it is for other numbers.
    if result == 11:
        expected_check_digit = '0'
    elif result == 10:
        expected_check_digit = 'X'
    else:
        expected_check_digit = str(result)
    return expected_check_digit
def calculate_check_digit_13(main_digits_list):
    # Note: You don't have to fully understand the logic in this function.
    digits_sum = 0
    # Multiply each of the first 12 digits by 1 and 3 alternately (starting with 1), and sum up the results
    for index, digit in enumerate(main_digits_list):
        if index % 2 == 0:
            digits_sum += digit * 1
        else:
            digits_sum += digit * 3
    # Find the remainder of dividing the sum by 10, then subtract it from 10
    result = 10 - digits_sum % 10
    # The calculation result can range from 1 to 10.
    # If the result is 10, use 0.
    # Use the value as it is for other numbers.
    if result == 10:
        expected_check_digit = '0'
    else:
        expected_check_digit = str(result)
    return expected_check_digit
def main():
    user_input = input('Enter ISBN and length: ')
    try:
        values = user_input.split(',')
        isbn = values[0]
        length = int(values[1])
        if not re.fullmatch(r"\d+", isbn):
            if re.match(r"\d", isbn[length-1]):
                return "Invalid character was found."
            
            else:
                pass
        print(length)
        if length == 10 or length == 13:
            validate_isbn(isbn, length)
        else:
            print('Length should be 10 or 13.')
    except (IndexError):
        print("Enter comma-separated values.")
    except (ValueError):
        print("Length must be a number.")
   

#main()

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36

Challenge Information:

Debug an ISBN Validator - Debug an ISBN Validator

  1. When the user enters an incorrect ISBN code with characters other than numbers, you should see the message Invalid character was found. in the console.

What happens when you test this? What output does your app give?

You can uncomment main() to enable input

Which part? You say uncomment main, but I’m not sure which one? At the bottom? I tried that, and it made steps 1, 8, and 14 give an error:

The console says:

// running tests
1. You should comment out the call to the main function to allow for the rest of the tests to work properly.
8. When the user enters an incorrect ISBN code with characters other than numbers, you should see the message Invalid character was found. in the console.
14. When the user enters 15-0051126,10, you should see the message Invalid character was found..
// tests completed
// console output
Enter comma-separated values.

Yes. Don’t run the tests. This is so you can type input into your program in the console to test it and answer the question:

What happens when you test this? What output does your app give?

the call to main() only needs to be commented out when you run the tests, but it needs to be uncommented to test in the preview window.

// running tests
1. You should comment out the call to the main function to allow for the rest of the tests to work properly.
8. When the user enters an incorrect ISBN code with characters other than numbers, you should see the message Invalid character was found. in the console.
14. When the user enters 15-0051126,10, you should see the message Invalid character was found..
// tests completed
// console output
Enter comma-separated values.

how are you testing? you should not run the tests when you have main() uncommented as they are not going to work

instead type the ISBN in the terminal

It’s not uncommented anymore.

import re

def validate_isbn(isbn, length):

if len(isbn) != length:

print(f'ISBN-{length} code should be {length} digits long.')

return

    main_digits = isbn[0:length]

    given_check_digit = isbn[length-1]

    main_digits_list = [int(digit) for digit in main_digits[:length-1]]

# Calculate the check digit from other digits

if length == 10:

        expected_check_digit = calculate_check_digit_10(main_digits_list)

else:

        expected_check_digit = calculate_check_digit_13(main_digits_list)

# Check if the given check digit matches with the calculated check digit

if given_check_digit == expected_check_digit:

print('Valid ISBN Code.')

else:

print('Invalid ISBN Code.')

def calculate_check_digit_10(main_digits_list):

# Note: You don't have to fully understand the logic in this function.

    digits_sum = 0

# Multiply each of the first 9 digits by its corresponding weight (10 to 2) and sum up the results

for index, digit in enumerate(main_digits_list):

        digits_sum += digit * (10 - index)

# Find the remainder of dividing the sum by 11, then subtract it from 11

    result = 11 - digits_sum % 11

# The calculation result can range from 1 to 11.

# If the result is 11, use 0.

# If the result is 10, use upper case X.

# Use the value as it is for other numbers.

if result == 11:

        expected_check_digit = '0'

elif result == 10:

        expected_check_digit = 'X'

else:

        expected_check_digit = str(result)

return expected_check_digit

def calculate_check_digit_13(main_digits_list):

# Note: You don't have to fully understand the logic in this function.

    digits_sum = 0

# Multiply each of the first 12 digits by 1 and 3 alternately (starting with 1), and sum up the results

for index, digit in enumerate(main_digits_list):

if index % 2 == 0:

            digits_sum += digit * 1

else:

            digits_sum += digit * 3

# Find the remainder of dividing the sum by 10, then subtract it from 10

    result = 10 - digits_sum % 10

# The calculation result can range from 1 to 10.

# If the result is 10, use 0.

# Use the value as it is for other numbers.

if result == 10:

        expected_check_digit = '0'

else:

        expected_check_digit = str(result)

return expected_check_digit

def main():

    user_input = input('Enter ISBN and length: ')

try:

        values = user_input.split(',')

        isbn = values[0]

        length = int(values[1])

if not re.fullmatch(r"\d+", isbn):

if re.match(r"\d", isbn[length-1]):

return "Invalid character was found."

else:

pass

print(length)

if length == 10 or length == 13:

            validate_isbn(isbn, length)

else:

print('Length should be 10 or 13.')

except (IndexError):

print("Enter comma-separated values.")

except (ValueError):

print("Length must be a number.")




main()

are you able to see in the terminal where it say Enter ISBN and length: ? It may be visible only in night mode at this time. You should write the ISBN there

you can also use a different environment, like for example this one Python Tutor code visualizer: Visualize code in Python, JavaScript, C, C++, and Java where you can see the execution of your code line by line

I can see it. Thank you! I’m also trying the different environment you recommended, but still unable to figure out where to put anything. I feel I’m making some form of progress, but at the same time, not really.

If you can see the output, then you don’t need to try the other environment.

Did you try typing a test into the input on the console?

I don’t know what I did, but I fixed it somehow. Now I’m trying to figure out 19, and I have this:

def validate_isbn(isbn, length):
    if len(isbn) != length:
        print(f'ISBN-{length} code should be {length} digits long.')
        return

    main_digits = isbn[0:length]
    given_check_digit = length
     
    main_digits_list = [int(digit) for digit in main_digits]
   
    # Calculate the check digit from other digits
    if length == 10:
        expected_check_digit = calculate_check_digit_10(main_digits_list)
        print(expected_check_digit)
    else:
        expected_check_digit = calculate_check_digit_13(main_digits_list)
    # Check if the given check digit matches with the calculated check digit
    if expected_check_digit == '0':
        print('Valid ISBN Code.')
    else:
        print('Invalid ISBN Code.')

def calculate_check_digit_10(main_digits_list):
    # Note: You don't have to fully understand the logic in this function.
    digits_sum = 0
    # Multiply each of the first 9 digits by its corresponding weight (10 to 2) and sum up the results
    for index, digit in enumerate(main_digits_list):
        digits_sum += digit * (10 - index)
        print(digits_sum)
    # Find the remainder of dividing the sum by 11, then subtract it from 11
    result = 11 - digits_sum % 11
    # The calculation result can range from 1 to 11.
    # If the result is 11, use 0.
    # If the result is 10, use upper case X.
    # Use the value as it is for other numbers.
    if result == 11:
        expected_check_digit = '0'
    elif result == 10:
        expected_check_digit = 'X'
    else:
        expected_check_digit = str(result)
    return expected_check_digit

def calculate_check_digit_13(main_digits_list):
    # Note: You don't have to fully understand the logic in this function.
    digits_sum = 0
    # Multiply each of the first 12 digits by 1 and 3 alternately (starting with 1), and sum up the results
    for index, digit in enumerate(main_digits_list):
        if index % 2 == 0:
            digits_sum += digit * 1
        else:
            digits_sum += digit * 3
    # Find the remainder of dividing the sum by 10, then subtract it from 10
    result = 10 - digits_sum % 10
    # The calculation result can range from 1 to 10.
    # If the result is 10, use 0.
    # Use the value as it is for other numbers.
    if result == 10:
        expected_check_digit = '0'
    else:
        expected_check_digit = str(result)
    return expected_check_digit

def main():
    user_input = input('Enter ISBN and length: ')
    if user_input.find(',') == -1:
        print('Enter comma-separated values.')
        return

    values = user_input.split(',')

    isbn = values[0]
    if isbn.find('X') != -1:
        print('Detected an X in input. Continuing...') 
        pass
    else:
        print('Turning ISBN into an intger...')
        try:
            isbn = (int(isbn))
            print('Successfully turned into an intger!')
        except ValueError: 
            print("Invalid character was found.")
            return
    try:
        length = int(values[1])
    except ValueError:
        print('Length must be a number.')
        return
    
    if length == 10 or length == 13:
        validate_isbn(str(isbn), length)
    else:
        print('Length should be 10 or 13.')

main()

I put in 080442957X,10 into the terminal, but it gave me this:

Enter ISBN and length: 
080442957X,10
Detected an X in input. Continuing...
Traceback (most recent call last):
  File "main.py", line 95, in <module>
  File "main.py", line 91, in main
  File "main.py", line 9, in validate_isbn
  File "main.py", line 9, in <listcomp>
ValueError: invalid literal for int() with base 10: 'X'

Ok what does this tell you?

Can you locate line 9 and try to understand what the error is telling you?

Line 9: main_digits_list = [int(digit) for digit in main_digits]

I think I get it but I can’t figure it out entirely

What do you mean?

What does this line do? Why do you think it generates that error?

It’s talking about the X, but other than it not being an integer, I can’t figure out what to do.

What does this line of code do?

converts a collection of string digits (or characters) into a list of integers

Can Python convert a character into an integer?

Try some small tests if you need to.

print(int('1'))
print(int('B'))

Yes it can, but I don’t know where I’m supposed to put that in the code for any of it