Debug an ISBN Validator - Debug an ISBN Validator

Tell us what’s happening:

Hi,
i can´t get Test 8 to pass. All other Test pass.
I dont understand why Test 14 passes but Test 8 doesnt. Can you please help me to understand this?

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]):
                print("Invalid character was found.")
                return
            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 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0

Challenge Information:

Debug an ISBN Validator - Debug an ISBN Validator

There seem to be some cases getting the wrong output. Ie. I tried: 978153005ll20,10 and 978153005ll20231,13 (notice two L-s near the end of isbn), and got back Length should be 10 or 13. and Length must be a number. respectively.

1 Like

I only checked if the last digit was an number if a string in the isbn was detected. So for example aaaaaaaaaa,10 would go pass this check.
But i found a solution that passed all checks

thanks now i have an idea

The clue is in the variable names: if “given_check_digit” is the last digit in the isbn number, then “main_digits” must be the isbn number without that last digit. Otherwise, there is no point in slicing isbn to get main_digits. So, the line where you slice isbn to get main_digits should be:

main_digits = isbn[0 : length - 1]

with this, you do not need to change line 8 in the original source. All that is needed is to catch the ValueError raised by “int(digit)” in line 8 when “digit” is non-numeric. The final check_digit can also be handled by raising an exception if it’s non-numeric and not X. With this solution, you won’t need the regex tests in main(), and you should get the correct output for all test cases, as well as the correct output for the two inputs mentioned in the previous solution.

i.e., both 978153005ll20,10 and 978153005ll20231,13 will yield:

ISBN-10 code should be 10 digits long, and
ISBN-10 code should be 13 digits long, respectively.