I am porting caesar.c to python and am having a problem. The code below works for uppercase characters, for example 'A' outputs 'B' with a shift of 1. But lowercase characters, like 'a' with the same shift of 1 is outputting 'H' instead of 'b'. Fiddling around with my code before posting here I noticed if I remove the c.isupper condition, it prints the correct output for lowercase characters.

import sys
from cs50 import get_string

def main():

    if len(sys.argv) is not 2:
        print("Invalid arguments")

    k = sys.argv[1]

    plaintext = get_string("plaintext: ")

    for c in plaintext:
        if c.isupper:
            c = ord(c) - ord("A")
            c = c + int(k)
            c = c % 26
            c = chr(c + ord("A"))
        elif c.islower:
            c = ord(c) - ord("a")
            c = c + int(k)
            c = c % 26
            c = chr(c + ord("a"))

if __name__ == "__main__":

1 Answer 1


The solution is simple, you are calling the isupper and islower functions without parenthesis, the correct way is:

 if c.isupper():

 if c.islower():
  • Thanks, first day using Python :P It's kinda strange if I only use c.islower or c.isupper as a condition, it works just fine without parenthesis. But checking both conditions in my for loop breaks it. I'm curious as to the reason that is, but oh well.
    – JohnWick
    Mar 12, 2018 at 0:09
  • 1
    I did not want to obscure the answer with theoretical dissertations that perhaps you do not know yet, I use the word attribute for anything after a point; for example, in the expression z.real, real is an attribute of the z object, so it is not incorrectly syntactically. But forget it, suffice it to say that a function must always carry parentheses, and syntax errors are frequent when you are learning a language, and it is the first thing we should look for when we find an error.
    – MARS
    Mar 12, 2018 at 19:44

You must log in to answer this question.

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