программа не выполняется корректно

Шифр Цезаря заключается в замене каждого символа входной строки на символ, находящийся на несколько позиций левее или правее его в алфавите.

Для всех символов сдвиг один и тот же. Сдвиг циклический, т.е. если к последнему символу алфавита применить единичный сдвиг, то он заменится на первый символ, и наоборот.

Используемый алфавит — пробел и малые символы латинского алфавита:
' abcdefghijklmnopqrstuvwxyz'.

Есть вот такая идея, но она не совсем корректно выводит данные. Помогите испровить.

def caesar(n:int, str1:str):
    s =" abcdefghijklmnopqrstuvwxyz"
    s = [i for i in s]
    sett = {i for i in str1}
    for i in sett:
        str1=str1.replace(i, s[(s.index(i)+n)%len(s)])
    print(f'Result: "{str1}"')

caesar(int(input()),input())

Ответы (2 шт):

Автор решения: Sergei Kirjanov

Заменять нужно все буквы одновременно.

С re.sub можно использовать заменячщий callback.


Один из самых частых типов ошибок: ошибка случается, если читать-из и менять что-либо одно попеременно (в цикле, рекурсии). Легко запутаться. Старайтесь читать одну структуру, а формировать другую. Для меня переприсвоение переменной -- уже повод насторожиться.


def caesar(n:int, str1:str):
    s =" abcdefghijklmnopqrstuvwxyz"
    def repl(match):
        i = match.group(0)
        return s[(s.index(i)+n) % len(s)]
    return re.sub(r".", repl, str1)
→ Ссылка
Автор решения: MarianD

Я сделал только минимальные изменения в вашей программе, потому что основа вашей программы — выражение s[(s.index(i)+n) % len(s)] — правильная:

def caesar(n:int, str1:str):
    s =" abcdefghijklmnopqrstuvwxyz"
    result = ""
    for i in str1:
        result += s[(s.index(i)+n) % len(s)]
    print(f'Result: "{result}"')

caesar(int(input()), input())

Вместо изменения заданной строки я в цикле построил другую.

Я удалил лишние строки (не надо использовать списки / множества):

s = [i for i in s]
sett = {i for i in str1}

Строку

for i in sett:

изменил на

for i in str1:

и перед ней добавил

result = ""
→ Ссылка