Зашифровывая текст с помощью cesar cipher, str.replace дает TypeError: Невозможно неявно преобразовать объект 'NoneType' в str - PullRequest
0 голосов
/ 18 сентября 2018

cipher.py:

import argparse

def parse_command_line():  
    parser=argparse.ArgumentParser()
    parser.add_argument("infile",type=str,help="input file to be encrypted or decrypted")

    parser.add_argument("-o outfile_path","--outfile outfile_path",type=str,help="output file")
    parser.add_argument("-k KEY","--key KEY",type=int,default=1,help="encryption/decryption key (must be positive) (default= 1)")
    parser.add_argument("-d","--decrypt",action="store_true",help="decrypt the input file")
    parser.add_argument("-a","--all",action="store_false",help="decrypt using all keys [1, 25], save outputs in different files. (useful in case the key is lost orunknown)")
    parser.add_argument("-v","--verbose",action="store_true",help="Verbose mode")

    args=parser.parse_args()
    return args 
    pass



def transform(message, key, decrypt):

    #TODO: Your code goes here
    if decrypt:
        for i in message:
            temp=shift(i,key)
            transformed_message=message.replace(i,temp,1)
            message=transformed_message
    return transformed_message
    pass
def shift(char, key):     
    # ordered lower case alphabet
    alphabet = "abcdefghijklmnopqrstuvwxyz"

    # will contain shifted lower case alphabet
    shifted_alphabet = ''
    for i in range(len(alphabet)):
        shifted_alphabet = shifted_alphabet + alphabet[(i + key) % 26]

    if char.isalpha():
        char_index = alphabet.index(char.lower())
        shifted_char = shifted_alphabet[char_index]

        # keep char's case (upper or lower)
        if char.isupper():
            return shifted_char.upper()
        else:
            return shifted_char

def main():
    # parse command line arguments
    args = parse_command_line()

    # key is specified
    if not args.all:
        # encrypt/decrypt content of infile
        outstring = transform(instring, args.key, args.decrypt)

        # write content of outstring to outfile
        write_file(outstring, args.outfile)

    # key is not specified, try all keys from 1 to 25 to decrypt infile
    else:
        for k in range(1, 26):
            # decrypt content of infile
            outstring = transform(instring, k, True)

            # write content of outstring to outfile
            write_file(outstring, "decrypted_by_" + str(k) + ".txt")

if __name__ == '__main__':
    main()

Я запускаю это с:

$ python3 cipher.py plain_message.txt -k 23 -v -o cipher_message.txt

и файл:

Software is a great combination between artistry and engineering.

--Bill Gates

, но это даетвместо этого следуя трассировке:

Traceback (most recent call last):
  File "cipher.py", line 231, in <module>
    main()
  File "cipher.py", line 218, in main
    outstring = transform(instring, k, True)
  File "cipher.py", line 141, in transform
    transformed_message=message.replace(i,temp,1)
TypeError: Can't convert 'NoneType' object to str implicitly

Я пытался запустить transform(message,key, decrypt) отдельно, он без проблем возвращает строки.

Пожалуйста, отметьте только parse_command_line() и transform(message,key, decrypt), как shift()и main() написаны заранее, и они должны работать без проблем.

1 Ответ

0 голосов
/ 18 сентября 2018

Ваша ошибка связана с вашей функцией shift() при обнаружении последней строки вашего файла в первой строке текста: 'Software is a great combination between artistry and engineering.'

. - это не isalpha(), поэтому функция shift () делаетне возвращает явно ничего, что означает, что оно неявно возвращает None.

Ваш метод преобразования не обрабатывает None изящно:

def transform(message, key, decrypt):
    if decrypt:
        for i in message:
            temp=shift(i,key)
            transformed_message=message.replace(i,temp,1) # does not work if temp == None
            message=transformed_message
    return transformed_message
    pass

Вы можете избежать ошибки, не заменяя, если temp is None:

def transform(message, key, decrypt): 
    if decrypt:
        for i in message:
            temp=shift(i,key)
            if temp: # check if not Falsy - None is falsy, "if temp is not None:" works too
                transformed_message=message.replace(i,temp,1)

             # assigning something to message does nothing, so removed it
    return transformed_message

Если выразрешено изменять саму функцию shift (), я бы, вероятно, просто возвратил (неизмененный) не отображенный символ, который также работал бы.

...