1

I wrote a program that shifts letters in a string and returns a dictionary. It works, unless the letter 'w' is within the string. Does anyone know why this happens? This is my code:

def buildCoder(shift):
    import string
    impStr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    resultDict = {}

    lowerValues = dict()
    for index, letter in enumerate(string.ascii_lowercase):
        lowerValues[letter] = index + 1

    upperValues = dict()
    for index, letter in enumerate(string.ascii_uppercase):
        upperValues[letter] = index + 1

    inv_lowerValues = {v:k for k, v in lowerValues.items()}

    inv_upperValues = {v:k for k, v in upperValues.items()}

    for char in impStr:
        if char in string.ascii_lowercase:
            value = lowerValues[char]
            value += shift
            if value <= 25:
                resultDict[char] = inv_lowerValues[value]
            else:
                value = abs(26-value)
                resultDict[char] = inv_lowerValues[value]
        elif char in string.ascii_uppercase:
            value = upperValues[char]
            value += shift
            if value <= 25:
                resultDict[char] = inv_upperValues[value]
            else:
                value = abs(26-value)
                resultDict[char] = inv_upperValues[value]
    return resultDict

This is the error I get (if 'w' is included in impStr):

KeyError                                  Traceback (most recent call last)
<ipython-input-117-0f4ac72e3c63> in <module>()
----> 1 buildCoder(3)

/var/folders/CV/CVkEwo3TGuu4+2cStWCRyE+++TQ/-Tmp-/tmpMr_sV1.py in buildCoder(shift)

KeyError: 0 

I also saw this error:

Traceback (most recent call last):
  File "submission.py", line 24, in buildCoder
    resultDict[char] = inv_lowerValues[value]
KeyError: 0

*** ERROR: Expected to find a dictionary in the line:
Traceback (most recent call last):
  File "submission.py", line 24, in buildCoder
    resultDict[char] = inv_lowerValues[value]
KeyError: 0

 ***
2
  • It's trying to look up 0, not w. My guess is value = abs(26-value) gets triggered if value == 26, which means it's checking inv_lowerValues[0] which doesn't exist. Commented Jul 30, 2014 at 18:25
  • Looks like M.I.T 6.00X? Commented Jul 30, 2014 at 18:41

3 Answers 3

2

Let's use a bit of introspection on your code:

lowerValues['w'] == 23
inv_lowerValues[23] == 'w'

# presumably shift == 3

for char in impStr: # when char==w
    if char in string.ascii_lowercase: # it is
        value += shift # 23 + 3 == 26
        if values <= 25 # it's not
        else:
            value = abs(26-value)
            # abs( 26 - 26 ) == 0
            resultDict[char] = inv_lowerValues[value]
            # resultDict['w'] = inv_lowerValues[0]; KeyError

It sounds like you just want to be sure that your shift wraps around the alphabet. That's not abs(26-value), that's (value % 25)+1.

Sign up to request clarification or add additional context in comments.

Comments

1

I think, you want to write

value = abs(value-25)

instead of

value = abs(26-value)

otherwise you would get 0 as value.

3 Comments

Absolute values are always positive...except when it's zero.
Aren't we wrapping, here? Why abs(26-value) instead of (value % 25)+1 (and, better question, why are we not using 0 as a key anyway?
a better point is that the code does not return what it should even with this fix
0

A more concise version of what you are doing:

import string

def buildCoder(shift):
    alpha = string.ascii_lowercase
    ALPHA = string.ascii_uppercase
    if 0 <= shift < 26:
        unshifted_letters = ALPHA + alpha
        shifted_letters = ALPHA[shift:] + ALPHA[:shift] + alpha[shift:] + alpha[:shift]
        return dict(zip(unshifted_letters, shifted_letters))

Comments

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.