Basic Python (JC) Recap Quiz - NRIC Check Digit
The structure of the Singapore NRIC/FIN number is one initial letter (S,T,F,G) followed by seven digits and one letter behind. E.g. S1234567D
The last letter is obtained from the 7 digits using the modulus eleven method. The steps to obtain the last letter are as below:
- Multiply each digit in the NRIC/FIN number by its weight (refer to table below).
- Add together the above products.
- If the first digit is G or T, add 4 to the sum obtained.
- Obtain the number to add to this sum such that the total will be divisible by 11. This is done by:
- Divide the resulting sum by 11 to obtain the remainder.
- If the remainder is 0, that is the check digit
- If the remainder is not 0, subtract remainder from 11 to obtain the check digit.
- Check the check digit against the tables below to obtain the last letter.
The following table shows the weight for each digit:
| 2 | 7 | 6 | 5 | 4 | 3 | 2 |
The following tables are used to check the check digit corresponding letter.
If the first digit is S or T:
| Check Digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| Last Letter | J | A | B | C | D | E | F | G | H | I | Z |
If the first digit is G or F:
| Check Digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| Last Letter | X | K | L | M | N | P | Q | R | T | U | W |
source: https://userapps.support.sap.com/sap/support/knowledge/en/2572734
Task 1.1
Fill in the following function to calculate the check digit given the initial letter and 7 numerical digits (provided as a string)
# nric will be provided as a string, containing initial letter + 7 digits, e.g. 'S1234567'
def calculate_check_digit(nric):
# TODO: if the length of the nric string is NOT 8 characters, return the string 'Error'
if len(nric) != 8:
return 'Error'
# TODO: if the first digit (i.e. index 0) is NOT either 'S', T', 'F' or 'G', return the string 'Error'
if nric[0] not in ['S', 'T', 'F', 'G']:
return 'Error'
# TODO: if the subsequent 7 digits (2nd to 8th digits, i.e. index 1 to index 7) are NOT numerical, return the string 'Error'
# hint: use <str>.isdigit()
if not nric[1:8].isdigit():
return 'Error'
# TODO: fill in this weight table according to info given above
weight = [2, 7, 6, 5, 4, 3, 2]
# TODO: fill in these check digits tables (stored as strings) according to info given above
digits_S_T = 'JABCDEFGHIZ' # this is done for you, all digits according to the sequence given above, in a single string
digits_G_F = 'XKLMNPQRTUW' # fill this in, all digits according to the sequence given above, in a single string
# TODO: write a loop to calculated the weighted sum of the nric digits, saving it into variable total
# based on steps 1 & 2 above
total = 0
for i in range(1,8):
total += int(nric[i])*weight[i-1]
# TODO: handle if NRIC starts with G or T
# based on step 3 above
if nric[0] in ['G', 'T']:
total += 4
# TODO: calculate and return the check digit
# based on steps 4 & 5 above
remainder = total % 11
if remainder == 0:
check_digit = remainder
else:
check_digit = 11-remainder
if nric[0] in ['S', 'T']:
last_digit = digits_S_T[check_digit]
return last_digit # i asked chatgpt for this idk why we need to return here
if nric[0] in ['G', 'F']:
last_digit = digits_G_F[check_digit]
return last_digit
Task 1.2
Test your code from Task 1.1 with the following test cases.
- S1234567 (should return ‘D’)
- T1122334 (should return ‘B’)
- G7654321 (should return ‘L’)
- A1111111 (should return ‘Error’)
The first one has been written for you.
print(calculate_check_digit('S1234567') == 'D')# should print True
print(calculate_check_digit('T1122334'))
print(calculate_check_digit('G7654321'))
print(calculate_check_digit('A1111111'))Task 1.3
Fill in the following function to check if a given full nric string is valid or not
# nric will be provided as a string, containing initial letter + 7 digits + check digit, e.g. 'S1234567D'
def check_valid(nric):
# TODO: if the length of the nric string is NOT 9 characters, return boolean value False
if len(nric) != 9:
return False
# TODO: if the first digit (i.e. index 0) is NOT either 'S', T', 'F' or 'G', return boolean value False
if nric[0] not in ['S', 'T', 'F', 'G']:
return False
# TODO: if the subsequent 7 digits (2nd to 8th digits, i.e. index 1 to index 7) are NOT numerical, return boolean value False
# hint: use <str>.isdigit()
if not nric[1:8].isdigit():
return False
# TODO: if the last digit (9th digit, i.e. index 8) is NOT a letter, return boolean value False
# hint: use <str>.isalpha()
if not nric[8].isalpha():
return False
# TODO: fill in the code to obtain the check digit from the function written in Task 1.1
# hint: extract the first 8 digits from nric (excluding the check digit) and pass it into the function from Task 1.1
calculated_check_digit = calculate_check_digit(nric[0:8])
# TODO: fill in the code to check if the calculated check digit matches the last digit from the provided nric string
if calculated_check_digit == nric[8]:
return True
else:
return False
Task 1.4
Test your code from Task 1.3 with the following test cases.
- S1234567D (should return True)
- T1122334C (should return False)
- G7654321L (should return True)
- F1111111 (should return False)
The first one has been written for you.
print(check_valid('S1234567D') == True) # should print True
print(check_valid('T1122334C') == True)
print(check_valid('G7654321L') == True)
print(check_valid('F1111111') == True)Task 1.5
Fill in the following procedure to print out n number of randomly generated NRIC numbers
import random
def generate_nric(n): # n is given as an integer; represents how many to generate
# TODO: write a loop to repeat for n times
for i in range(n):
nric = '' # empty string that will be filled in later with the generated NRIC
alphabets = ['S', 'T', 'F', 'G']
# TODO: add a random alphabet from the above list into the nric string
nric += random.choice(alphabets)
# TODO: write a loop to repeat for 7 times
for i in range(7):
# TODO: generate a random number between 0 to 9
random_num = random.choice('1234567890')
# TODO: add the string version of this random number to the nric string
nric += random_num
# TODO: use the function written in Task 1.1 to generate the check digit
check_digit = calculate_check_digit(nric)
# add the generated check digit to the nric string
nric += check_digit
# TODO: print the final nric string
print(nric)
Task 1.6
Test your code from Task 1.5 by printing 10 randomly generated NRIC numbers.
generate_nric(10)