As part of the CS50 Harvard programming course, which I'm currently attending, I'm doing an exercise called "Vigenere".
The Cipher of Vigenere is supposed to have a key as input, for example "abcd". This will encode any plaintext, according to each character in the key, where a = 0 and b = 1 etc. So a key "abcd" with plaintext "aa!aa" would give "ab!cd". if the plaintext is longer than the key, the key is supposed to loop back to [0] and start over until plaintext has all been encoded. Non alphabetic letters are supposed to printed out normally however.
My program is doing everything right (it's going line by line and the expected behavior is met) except when I receive input that starts with an uppercase letter followed by a lowercase letter my program prints a different letter with the lowercase key then it should give me. EX: key: "Baz". Plaintext: "aaa". Result: "bgz" where it should return "baz".
Have been googling, debugging but just can't figure it out. Have tried doing it in a lot of other different ways too but I just can't get it to work. (sorry for kind of copy paste, as you might notice I've already posted a similar problem, however that was in C (this is python) and it was a different kind of bug)
Code:
import sys
if len(sys.argv) != 2 or not sys.argv[1].isalpha():
print("usage: python vigenere.py keyword")
sys.exit()
cipher = sys.argv[1]
plaintext = input("plaintext: ")
j = 0
def code(j):
for key in cipher:
if key.islower():
return ord(cipher[j]) - 97
if key.isupper():
return ord(cipher[j]) - 65
print("ciphertext: ", end="")
for letters in plaintext:
if letters.islower():
print(chr(((ord(letters) - 97 + code(j)) % 26) + 97), end="")
j += 1
if letters.isupper():
print(chr(((ord(letters) - 65 + code(j)) % 26) + 65), end="")
j += 1
if j == len(cipher):
j = 0
if not letters.isalpha():
print(letters, end="")
print("")