Joseph Nolan
Joseph Nolan

Reputation: 23

Dictionary call into a variable during for loop

I need to create a function that takes a 13 digit sequence and uses the last number as a check using modulo 10. ie BAF189D234EA2 entry check = 2.

Using the values of A-F (see weight dict below) instead of ord(char). So as my loop iterates I need char to pull the corresponding weight dict if it is a string value. I simply cannot figure out how to make it call from that dictionary based on the value of char.

Thanks in advance for any help.

weight={
'A' : '10',
'B' : '11',
'C' : '12',
'D' : '13',
'E' : '14',
'F' : '15',
}

def validater(value):
    global userEntry
    valSum = 0
    i = 0
    for char in userEntry:
        if i == 12:
            break
        try:
            if char >=0 and char <= 9:
                valSum += char * i
                i +=1
        except TypeError:  
            valSum += weight[char] * i
            i += 1

Error:

Traceback (most recent call last):
    line 93, in <module>
    if validater(userEntry) ==True:
    line 74, in validater
    valSum += weight[char] * i
TypeError: unsupported operand type(s) for +=: 'int' and 'str'

Edit: Thanks, I changed the dictionary by dropping the quotes around my ints. Now I get a Key Error 1

Upvotes: 2

Views: 61

Answers (3)

Serge
Serge

Reputation: 3765

1) remove quotation from weights

2) cast char as int, right after try

3) the remainder from division (modulo) is % btw

Upvotes: 1

Ralf
Ralf

Reputation: 16505

Short version:

>>> is_ok = lambda x: sum(i * int(c, 16) for i, c in enumerate(x[:-1])) % 10 == int(x[-1], 16)
>>> is_ok('BAF189D234EA2')
True
>>> is_ok('BAF189D234EA3')
False

When using the build-in int() you can specify a base. Looking at this answer, you can convert you chars directly.

>>> int('a', 16)
10
>>> int('1a', 16)
26

So try this code:

def validate(value):
    assert len(value) == 13

    value_sum = sum(
        int(c, 16) * i
        for i, c in enumerate(value[:-1]))

    last_digit = int(value[-1], 16)

    assert value_sum % 10 == last_digit

I get the correct result when testing with your example:

>>> validate('BAF189D234EA2')

And it fails with an assertion error when I change a char:

>>> validate('BAF189D234EA3')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 10, in validate
AssertionError

Also raises error when input is not 13 chars long

>>> validate('BAF189D234EA23')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 2, in validate
AssertionError

Upvotes: 2

Sayse
Sayse

Reputation: 43300

Your error is due to your dictionary values all being strings instead of integers, so changing them to integers would solve your issues, but since all you're mapping is hexadecimal numbers to base 10, you may as well just do the conversion yourself

valSum += int(char, 16) * i

Upvotes: 2

Related Questions