0

i have a program that is supposed to read a string with alphabets and number and then return a checksum. Everything runs smooth till I add these lines of codes.

if((length_alphabet == 2) and (length_nums == 1)):
            #Obtain first alphabet
            first_alphabet = obtain_alphabet[0:1]
            #Obtain 2nd alphabet 
            second_alphabet = obtain_alphabet[1:] 
            #First alphabet value
            alphabet_value_1 = alphabet_dictionary.get(first_alphabet)
            #Second alphabet value
            alphabet_value_2 = alphabet_dictionary.get(second_alphabet)

            #Actual Alphabet
            product_first_alphabet = int(alphabet_value_1) * fixed_numbers_list[0]
            product_second_alphabet = int(alphabet_value_2) * fixed_numbers_list[1]

            #If there is only 1 digit in Numerical series
            # we can safely assume that, the 000 will be infront of the digit
            # this will result in a product of zero each therefore the code below
            prod_next_three_num = 0
            fourth_digit = obtain_nums[3:]

            #product_first_digit = int(first_digit) * fixed_numbers_list[2]
            #product_second_digit = int(second_digit) * fixed_numbers_list[3]
            #product_second_last_num = int(third_digit) * fixed_numbers_list[4]
            product_last_num = int(fourth_digit) * fixed_numbers_list[5]
            sum_of_all_products = product_first_alphabet + product_second_alphabet + prod_next_three_num + product_last_num
            #Getting remainder for sum of products divided by 19
            remainder = sum_of_all_products % divide_num
            check_sum = second_dictionary.get(remainder)
        
   
    return(check_sum)

The error is

    Traceback (most recent call last):
  File "c:/Users/nic97/Downloads/MikailNicholasWongLiangEe_6648769_a3 (1).py", line 486, in <module>
    main()
  File "c:/Users/nic97/Downloads/MikailNicholasWongLiangEe_6648769_a3 (1).py", line 479, in main
    print(sing.car_plate_checksum("EG2"))
  File "c:/Users/nic97/Downloads/MikailNicholasWongLiangEe_6648769_a3 (1).py", line 325, in car_plate_checksum
 product_second_last_num = int(first_digit) * fixed_numbers_list[4]
ValueError: invalid literal for int() with base 10: 'G'

This is line 325, which the terminal says there's a problem

 product_second_last_num = int(first_digit) * fixed_numbers_list[4]

This is the whole Code

class SingaporeNumbers():
    
#Class Constructor
def __init__(self,registration_number):
    self.registration_number = registration_number

#static method car_plate_checksum
@staticmethod
def car_plate_checksum(registration_number):
    #Declare variables
    length_count = 0
    #product_first_num = 0
    newstring1 = ""
    divide_num = 19 

    #Dictionary storing Alphabets A - Z followed by their values
    alphabet_dictionary = {
        "A": "1",
        "B": "2",
        "C": "3",
        "D": "4",
        "E": "5",
        "F": "6",
        "G": "7",
        "H": "8",
        "I": "9",
        "J": "10",
        "K": "11",
        "L": "12",
        "M": "13",
        "N": "14",
        "O": "15",
        "P": "16",
        "Q": "17",
        "R": "18",
        "S": "19",
        "T": "20",
        "U": "21",
        "V": "22",
        "W": "23",
        "X": "24",
        "Y": "25",
        "Z": "26"
    }

    #2nd Dictionary with jumbled alphabets as well as
    second_dictionary = {
        0: "A",
        1: "Z",
        2: "Y",
        3: "X",
        4: "U",
        5: "T",
        6: "S",
        7: "R",
        8: "P",
        9: "M",
        10: "L",
        11: "K",
        12: "J",
        13: "H",
        14: "G",
        15: "E",
        16: "D",
        17: "C",
        18: "B"
    }


    # List storing the six values that will be used for multiplication
    fixed_numbers_list = [9,4,5,4,3,2]

        
    for a in registration_number:
        #try:
            #if(registration_number.isdigit() == True):
                #raise ValueError(("Wrong format given!")) 
        if(a.isalpha() == True):
            length_count = length_count + 1
            newstring1 = newstring1 + a
            startAlphabet_pos = registration_number.find(newstring1)
            last_pos_alpha = length_count

                #For alphabets!!
            length_string1 = len(registration_number) #length of alphabets (Exclusively)
            last_pos_string = length_string1 -1 #Last Position of alphabet

                #Get numbers part
        obtain_nums = registration_number[last_pos_alpha:]
        obtain_alphabet = registration_number[startAlphabet_pos:last_pos_alpha]

                #Length of Digits & Alphabets
        length_nums = len(obtain_nums)
        length_alphabet = len(obtain_alphabet)
                #If there is only one alphabet in  "registration number"
             
                #If there is only one alphabet prefix
                # and one digit in the vehicle registration numbers
                # E.g For this scenario p1
        if((length_alphabet == 1) and (length_nums == 1)): 
            alphabet_value = alphabet_dictionary.get(obtain_alphabet)
            product_first_num = 0 * fixed_numbers_list[0]
            product_sec_num = int(alphabet_value) * fixed_numbers_list[1]
            #If there is only 1 digit in Numerical series
            # we can safely assume that, the 000 will be infront of the digit
            # this will result in a product of zero each therefore the code below
            sum_next_three_num = 0
            product_last_num = int(obtain_nums) * fixed_numbers_list[5]
            sum_of_all_products = product_first_num + product_sec_num + sum_next_three_num + product_last_num
            #Getting remainder for sum of products divided by 19
            remainder = sum_of_all_products % divide_num
            check_sum = second_dictionary.get(remainder)

        # 1 alphabet and 2 digits
        # E.g.E22
        #050022
        elif((length_alphabet == 1) and (length_nums == 2)): 
            alphabet_value = alphabet_dictionary.get(obtain_alphabet)
            #0 placed in front of alphabet
            product_first_num = 0 * fixed_numbers_list[0]
            #Actual Alphabet
            product_sec_num = int(alphabet_value) * fixed_numbers_list[1]

            #If there is only 1 digit in Numerical series
            # we can safely assume that, the 000 will be infront of the digit
            # this will result in a product of zero each therefore the code below
            sum_next_two_num = 0
            first_digit = obtain_nums[0:1]
            second_digit = obtain_nums[1:]
            product_second_last_num = int(first_digit) * fixed_numbers_list[4]
            product_last_num = int(second_digit) * fixed_numbers_list[5]
            sum_of_all_products = product_first_num + product_sec_num + sum_next_two_num + product_second_last_num + product_last_num
            #Getting remainder for sum of products divided by 19
            remainder = sum_of_all_products % divide_num
            check_sum = second_dictionary.get(remainder)
        
        # 1 alphabet and 3 digits
        # E.g.E223
        #050223
        elif((length_alphabet == 1) and (length_nums == 3)): 
            alphabet_value = alphabet_dictionary.get(obtain_alphabet)
            #0 placed in front of alphabet
            product_first_num = 0 * fixed_numbers_list[0]
            #Actual Alphabet
            product_sec_num = int(alphabet_value) * fixed_numbers_list[1]

            #If there is only 1 digit in Numerical series
            # we can safely assume that, the 000 will be infront of the digit
            # this will result in a product of zero each therefore the code below
            prod_next_num = 0
            first_digit = obtain_nums[0:1]
            second_digit = obtain_nums[1:2]
            third_digit = obtain_nums[2:]
            product_first_digit = int(first_digit) * fixed_numbers_list[3]
            product_second_last_num = int(second_digit) * fixed_numbers_list[4]
            product_last_num = int(third_digit) * fixed_numbers_list[5]
            sum_of_all_products = product_first_num + product_sec_num + prod_next_num +product_first_digit \
                                + product_second_last_num + product_last_num
            #Getting remainder for sum of products divided by 19
            remainder = sum_of_all_products % divide_num
            check_sum = second_dictionary.get(remainder)
                                                                   
        #except ValueError as e:
            #print(e)   

        # 1 alphabet and 4 digits
        # E.g.E223
        #051223    
        if((length_alphabet == 1) and (length_nums == 4)): 
            alphabet_value = alphabet_dictionary.get(obtain_alphabet)
            #0 placed in front of alphabet
            product_first_num = 0 * fixed_numbers_list[0]
            #Actual Alphabet
            product_sec_num = int(alphabet_value) * fixed_numbers_list[1]

            #If there is only 1 digit in Numerical series
            # we can safely assume that, the 000 will be infront of the digit
            # this will result in a product of zero each therefore the code below
            
            first_digit = obtain_nums[0:1]
            second_digit = obtain_nums[1:2]
            third_digit = obtain_nums[2:3]
            fourth_digit = obtain_nums[3:]

            product_first_digit = int(first_digit) * fixed_numbers_list[2]
            product_second_digit = int(second_digit) * fixed_numbers_list[3]
            product_second_last_num = int(third_digit) * fixed_numbers_list[4]
            product_last_num = int(fourth_digit) * fixed_numbers_list[5]
            sum_of_all_products = product_first_num + product_sec_num + product_first_digit +product_second_digit \
                                + product_second_last_num + product_last_num
            #Getting remainder for sum of products divided by 19
            remainder = sum_of_all_products % divide_num
            check_sum = second_dictionary.get(remainder)

        # 2 Alphabets and 1 digits
        #E.g. AB1
        #120001
        
        if((length_alphabet == 2) and (length_nums == 1)):
            #Obtain first alphabet
            first_alphabet = obtain_alphabet[0:1]
            #Obtain 2nd alphabet 
            second_alphabet = obtain_alphabet[1:] 
            #First alphabet value
            alphabet_value_1 = alphabet_dictionary.get(first_alphabet)
            #Second alphabet value
            alphabet_value_2 = alphabet_dictionary.get(second_alphabet)

            #Actual Alphabet
            product_first_alphabet = int(alphabet_value_1) * fixed_numbers_list[0]
            product_second_alphabet = int(alphabet_value_2) * fixed_numbers_list[1]

            #If there is only 1 digit in Numerical series
            # we can safely assume that, the 000 will be infront of the digit
            # this will result in a product of zero each therefore the code below
            prod_next_three_num = 0
            fourth_digit = obtain_nums[3:]

            #product_first_digit = int(first_digit) * fixed_numbers_list[2]
            #product_second_digit = int(second_digit) * fixed_numbers_list[3]
            #product_second_last_num = int(third_digit) * fixed_numbers_list[4]
            product_last_num = int(fourth_digit) * fixed_numbers_list[5]
            sum_of_all_products = product_first_alphabet + product_second_alphabet + prod_next_three_num + product_last_num
            #Getting remainder for sum of products divided by 19
            remainder = sum_of_all_products % divide_num
            check_sum = second_dictionary.get(remainder)
        
   
    return(check_sum)enter code here

I hope someone can help me out, thanks!

2
  • The code you added has neither the line causing the error (product_second_last_num = int(first_digit) * fixed_numbers_list[4]), nor does it have the definition of first_digit, which is probably 'G' at the time the error occurs. In general though it looks like your code has an awful lot of repetition and inefficiency, you may want to fix that before fixing particular issues (which may just be the result of bad copypasta code) Commented Nov 16, 2020 at 4:59
  • Please read ericlippert.com/2014/03/05/how-to-debug-small-programs and try to trace through an example calculation and make sure that everything has the value you expect it to have. Commented Nov 16, 2020 at 5:08

1 Answer 1

1

I looked up wikipedia for Singapore license plate checksum. Found out how they computed it and wrote the code for you. It should work correctly. Tested it with a few reasonable inputs.

def car_plate_checksum(registration_number: str):

    prefixLength = 0

    registration_values = []

    # compute the numerical equivalent for all letters in the plate number
    for c in registration_number:
        if c.isalpha():
            registration_values.append(ord(c) - 65 + 1)
        else:
            registration_values.append(int(c))

    # find the prefix length
    for c in registration_number:
        if c.isalpha():
            prefixLength += 1
        else:
            break
    
    # get the prefix part and numerical part
    prefix_values = registration_values[:prefixLength]
    numeral_values = registration_values[prefixLength:]

    # correct prefix to length of 2
    if prefixLength == 3:
        
        prefix_values = prefix_values[1:]

    elif prefixLength == 1:
        
        prefix_values = [0] + prefix_values

    # combine together
    registration_values = prefix_values + \
        [0] * (4 - len(numeral_values)) + numeral_values

    # pre defined values
    checksum_values = [9, 4, 5, 4, 3, 2]
    
    # compute checksum
    checksum = 0

    for (v, c) in zip(registration_values, checksum_values):

        checksum += v*c

    checksum_letters = ["A", "Z", "Y", "X", "U", "T", "S", "R",
                        "P", "M", "L", "K", "J", "H", "G", "E", "D", "C", "B"]

    return checksum_letters[checksum % 19]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks alot David! I really appreciate you taking your time out, I've been slugging this out for the last several hours. It works!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.