I've pretty much gotten my program to work 90% successfully! But, it does not produce the correct outcome for mix case or spaces/symbols. I've tried a number of different methods to no avail. At the moment, when I have mix case I get a blank ciphertext output. In any instance of space/symbols, my last print statement produces something such as this:

~/workspace/pset6/ $ python caesar.py 12
plaintext: why not
ciphertext: wwhwhywhy why nwhy nowhy not

Here is my current code:

from cs50 import get_string
import cs50
import sys
import string

while True:
# convert string into integer
key = int(sys.argv[1])

# if index is greater than 0 and has 2 arguments move to the next step
if key > 0 and len(sys.argv) == 2:
# print error if not
    print("Error-- must have 2 arguments and sys.argv[1] must be a positive integer")

# get plaintext input from user
print("plaintext: ", end="")

plaintext = cs50.get_string()
i = 0
c = ""

print("ciphertext: ", end="")

for i in plaintext:

n = ord(i) + key

if plaintext.isupper():

    c = ((n -65) % 26 + 65)
    print(chr(c), end="")

elif plaintext.islower():
     c = ((n -97) % 26 + 97)
     print(chr(c), end="")

    c = c + i
    print(c, end="")


Multiple things.

if plaintext.isupper():

you meant i.isupper(). plaintext.isupper() would check whether the whole string is upper-case, which it is not, but it also isn't completely lower-case, so the else path triggers.

i is a bad choice for a variable name, and if it is used as such, it usually means an integer, not a string as in your code. For a string of a single character, I sometimes use ch, but only use one or two character variable names if the code section is very short and it is clear what the variable means (like ch for the only character-holding variable in a short loop). Here, you have two character-containing variables, one for the plaintext character, one for the "encrypted", or ciphertext character. If you have those, I would expect the two variable names to show this distinction in some way.


    c = c + i
    print(c, end="")

so c is either the empty string, or whatever was printed last. And now you concatenate i, printing again whatever was in c (and already got printed), because of the first mistake this is what you are experiencing all the time. Just print the character in i, without any concatenation.

  • Thank you so much for this thorough explanation! My program now works perfectly. This definitely helped my understanding of the root of my problem and improved my program. I'll keep in mind to name my variables better as well. It is more helpful and I have a more accurate representation of what it is.
    – Beyn18
    Jan 9 '19 at 22:39

You must log in to answer this question.

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