Home > Software design >  Why can't the for-loop skip to the next if condition I have set if it does not meet the first o
Why can't the for-loop skip to the next if condition I have set if it does not meet the first o

Time:10-30

I'm trying to have a function use the autokey cipher to encrypt a message. The function has an if statement telling it whether to use the uppercase ASCII letters or lower case. I do not understand why that if statement is not working. If the letter getting ciphered is lowercase, it should use the lowercase list, but that is not the case and it keeps using the upper case list to try to cipher it, which gives me an error since the letter is not an element in the list.

import string
# This is the variable that will hold the list of the alphabet
alphau = list(string.ascii_uppercase)
alphal = list(string.ascii_lowercase)
punctuation=list(string.punctuation)

# This is the encryption function
def encrypt(plaintext,key):
    enc = ''
    i = 0
    for letter in plaintext:
        if letter == ' ':
            enc  = ' '
        elif letter =='\n':
            enc  = '\n'
        else:
            if letter in alphal:
                x = (alphal.index(letter) alphal.index(key[i]))&
                i  = 1 
                enc  = alphal[x]
                x = ''
            if letter in alphau:
                x = (alphau.index(letter) alphau.index(key[i]))&
                i  = 1 
                enc  = alphau[x]
                x = ''
            if letter not in alphal or alphau:
                enc  = letter
    return enc

msg=encrypt("MyNameIsMhegazy","jMiXMyNameIsMahm")
print(msg)
Traceback (most recent call last):
  File "c:\Users\User\Documents\GitHub\Coursework-1\encrypt.py", line 41, in <module>
    msg=encrypt("MyNameIsMahmoud",key1)
  File "c:\Users\User\Documents\GitHub\Coursework-1\encrypt.py", line 25, in encrypt
    x = (alphau.index(letter) alphau.index(key[i]))&
ValueError: 'j' is not in list

I have tried using the lists in other if statements and they are working fine. Also tried putting strings and having a for loop separate upper from lower case letters using the lists and that has also worked fine. I am not sure what the problem is with the code posted above. Thanks For Your Help!

CodePudding user response:

Nothing wrong with the if statement, its your algorithm that needs a little tweaking. Take a look at this statement for example:

(alphau.index(letter) alphau.index(key[i]))&

as per your input

plaintext = "MyNameIsMhegazy"
key = "jMiXMyNameIsMahm"

on the first iteration, the letter is "M", i = 0, so key[i] = "j". Now you are trying to lookup the value of "j" in alphau which raises a ValueError.

What you can do is check further where the value of key[i] lies in, then use that list for lookup.

CodePudding user response:

You only want one clause to match, so this needs to be a series of if/elif/elif clauses, like this:

def encrypt(plaintext,key):
    enc = ''
    i = 0
    for letter in plaintext:
        if letter == ' ':
            enc  = ' '
        elif letter =='\n':
            enc  = '\n'
        elif letter in alphal:
            x = (alphal.index(letter) alphal.index(key[i]))&
            i  = 1 
            enc  = alphal[x]
        elif letter in alphau:
            x = (alphau.index(letter) alphau.index(key[i]))&
            i  = 1 
            enc  = alphau[x]
        else:
            enc  = letter
    return enc

You can skip the index call by just converting the letter to its ASCII equivalent.

def encrypt(plaintext,key):
    enc = ''
    i = 0
    for letter in plaintext:
        if key[i] < 'a':
            keyidx = ord(key[i])-'A'
        else:
            keyidx = ord(key[i])-'a' 
        if letter == ' ':
            enc  = ' '
        elif letter =='\n':
            enc  = '\n'
        elif letter in alphal:
            x = (ord(letter) - ord('a')   keyidx) % 26
            i  = 1 
            enc  = alphal[x]
        elif letter in alphau:
            x = (ord(letter) - ord('A')   keyidx) % 26
            i  = 1 
            enc  = alphau[x]
        else:
            enc  = letter
    return enc
  • Related