简体   繁体   中英

How to iterate backwards through a string using “for in range”? (application is to validate UPC codes)

I'm trying to create a program that checks the validity of a UPC code of any length (although most are 12 digits) based on a string of numbers entered by the user. My current approach is first storing the string into a list and then iterating through the list using "for in range."

The guidelines I am using for how UPC code validation algorithms work is as follows: (The UPC codes are designed this way in part to prevent cashiers making a typo at checkout, as one wrong digit will likely make the code invalid)

  1. The validation process runs from RIGHT to LEFT.

  2. For digits in even positions, there are no changes.

  3. For digits in odd positions, multiply the digit by 3.

  4. Sum the results.

  5. For a valid UPC number, this sum will be a multiple of 10.

I have been able to get everything running as I have hoped with the exception of guideline 1, that the validation process occurs from right to left across the string of numbers in the UPC code. My current method goes from left to right. This will prove to be an issue if a user-entered UPC code was an odd number of digits long, as it would throw off the algorithm.

The input code in def upc_check(code): below is the UPC code the user enters to see if the UPC code is valid.

def upc_check(code):
    ODD_DIGIT_MULTIPLIER = 3
    UPC_VALIDITY_DIVISOR = 10
    digits = []
    for num in code:
        digits.append(int(num))
    print(digits)
    check_sum = 0
    for i in range(0, len(code)):
        if (i + 1) % 2 != 0:
            check_sum += (ODD_DIGIT_MULTIPLIER * digits[i])
        else:
            check_sum += (digits[i])
    if check_sum % UPC_VALIDITY_DIVISOR == 0:
        return "Valid UPC code."
    else:
        return "Invalid UPC code."

Currently, the output is as I expect it (ie a valid UPC code shows up as valid and an invalid UPC code shows up as invalid) but the algorithm is going from left to right through the string of numbers.

To go from right to left, I would expect that I could make the following replacement and achieve the same results:

for i in range(0, len(code)):

with

for i in range(-1, -len(code), -1):

This would make the code read as follows:

def upc_check(code):
    ODD_DIGIT_MULTIPLIER = 3
    UPC_VALIDITY_DIVISOR = 10
    digits = []
    for num in code:
        digits.append(int(num))
    print(digits)
    check_sum = 0
    for i in range(-1, -len(code), -1):
        if (i + 1) % 2 != 0:
            check_sum += (ODD_DIGIT_MULTIPLIER * digits[i])
        else:
            check_sum += (digits[i])
    if check_sum % UPC_VALIDITY_DIVISOR == 0:
        return "Valid UPC code."
    else:
        return "Invalid UPC code."

However, when I make this change all my valid UPC codes now return the value invalid, and I am unsure why. I would expect the output to be the same. Does anyone have any suggestions? Thank you for any help!

If it is helpful for checking, the following are valid UPC codes:

096619363148

017082886026

381370036005

Here are some invalid UPC codes (Intentional typos from codes above):

096619363149

017082786026

381370036015

What you need here is a little complicated. range by default doesn't go the full way.

for i in range(len(code)-1,-1,-1):

etc. will work but doesn't strike me as very neet. I don't know of another way, perhaps someone else does?

If the code is working as you expect from left to right, a quick way to keep most of the code as it is would be to reverse your digits list before the for loop.

So digits = digits.reverse() and the first line of your for loop can remain as it was

for i in range(0, len(code)):

Ill test this and update my answer shortly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM