As the title suggests, when I tried to run my current code for Caesar.py, I got the error message "TypeError: 'str' object does not support item assignment" from the interpreter.

My code is like this:

import cs50
import sys

if len(sys.argv) == 1 or len(sys.argv) > 2:
    print("Usage: python caesar.py <key>")

print("plaintext: ", end="")
plaintext = cs50.get_string()
key = int(sys.argv[1])
size = len(plaintext)
ciphertext = str(len(plaintext))

if key >= pow(2, 31) - 26 or key <= 0:
    print("The value for the key is invalid!")
    if key > 26:
        key %= 26
    for i in range(size):
        if plaintext.isalpha():
            c = plaintext[i] + key
            if plaintext[i].isupper() > 'Z':
                c -= 26
            ciphertext[i] = c
            ciphertext[i] = plaintext[i]

print("ciphertext: {}".format(ciphertext))

If I can't do the ciphertext[i] = plaintext[i] thing in Python, what would be the correct equivalent of it from C?

Any help would be appreciated.


You set ciphertext to a string representation of the string length (not clear to me what the length does there). Strings are immutable. You could instead create it as a list using

ciphertext = []

and later when returning use not ciphertext, but "".join(ciphertext), which returns a string built from the list elements.

Please follow the links provided in the hints: ord, chr

  • I did ciphertext = [str(len(plaintext))] (wonder if this would work) and then inside the loop, in the else, I have these two lines: ciphertext[i] = plaintext[i] and "".join(ciphertext). The Python interpreter is telling me that my list assignment index is out of range. Feb 20 '17 at 10:47
  • Could you give me a hint about where to use ord and chr if that's okay, though? I could do something like ciphertext[i] = ord(plaintext[i]) + key and then subtract 26 if the Unicode number is outside the range of 'A' through 'Z'? If I can get my assignment into the ciphertext list to work. Feb 20 '17 at 10:53
  • Why would you put the length inside the ciphertext? Based on your code above, you could try c = ord(plaintext[i]) + k and ciphertext.append(chr(c)). The "".join(ciphertext) is meant for the return line only.
    – Blauelf
    Feb 20 '17 at 12:19
  • I tried it like in this paste: pastebin.com/fpQZE3H9. I got the string to print, but right now it's not shifting the letters at all. It prints the same "ciphertext" as the plaintext. Feb 20 '17 at 13:17
  • Would have to be if plaintext[i].isalpha():, and you could remove the ciphertext[i] = c and else:, and move the ciphertext.append(chr(c)) one indentation level to the left, so you'd take some c, if it's alphabetic then shift it, then in any case append the letter for that c to the list.
    – Blauelf
    Feb 20 '17 at 13:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .