WhiteMask
WhiteMask

Reputation: 646

Python False Concatenate Error?

I can't seem to find my mistake. I'm trying to write a simple program that encrypts messages using the caesar shift method. However, I'm getting a funky error. Program is as follows:

alphabet = {"a":0,"b":1,"c":2,"d":3,"e":4,"f":5,"g":6,"h":7,"i":8,"j":9,"k":10,"l":11,"m":12,"n":13,"o":14,"p":15,"q":16,"r":17,"s":18,"t":19,"u":20,"v":21,"w":22,"x":23,"y":24,"z":25}

alpha2 = dict (zip(alphabet.values(),alphabet.keys()))

def key(n):
    code = alphabet

    for i in code:
        code[i] = (code[i] + n) % 26

    for i in code:
        code[i] = alpha2[code[i]] 

    return code

def encode(x,n):

    my_key = key(n)
    message = []
    for i in x:
        message.append(my_key[i])

print key(13)
print encode("Message",13)

I find this absurd, because after running my ./caesars.py the command line will return

{'a': 'n', 'c': 'p', 'b': 'o', 'e': 'r', 'd': 'q', 'g': 't', 'f': 's', 'i': 'v', 'h': 'u', 'k': 'x', 'j': 'w', 'm': 'z', 'l': 'y', 'o': 'b', 'n': 'a', 'q': 'd', 'p': 'c', 's': 'f', 'r': 'e', 'u': 'h', 't': 'g', 'w': 'j', 'v': 'i', 'y': 'l', 'x': 'k', 'z': 'm'}
Traceback (most recent call last):
  File "./caesars.py", line 56, in <module>
    print encode("Message",13)
  File "./caesars.py", line 27, in encode
    my_key = key(n)
  File "./caesars.py", line 15, in key
    code[i] = (code[i] + n) % 26
TypeError: cannot concatenate 'str' and 'int' objects

Which clearly means that the first run through of the key function was successful, but when the encode functions tries to call the key function a second time it decides to have issues? I have printed the types of n, and they come out as int. I'm sure this is an oversight in my code, but for the life of me I can't find it.

Upvotes: 0

Views: 46

Answers (1)

user2357112
user2357112

Reputation: 280500

You probably expected

code = alphabet

to copy the alphabet dict into code. That's not what happens. This line evaluates the alphabet variable, producing a reference to a dict, and then makes code refer to that same dict. Setting items of code will also change alphabet, because both variables are names for the same dict. In particular, after

for i in code:
    code[i] = alpha2[code[i]]

all the values of alphabet are strings.

If you want a copy, you can make a copy:

code = alphabet.copy()

though a copy of alphabet might not be the cleanest starting point to construct code.

Upvotes: 2

Related Questions