Ошибка IndexError: string index out of range в шифровальщике

Пишу шифровальщик на python3.x задумка такая: в каждом слове каждую букву на случайное количество. Программа выдает нам ключ по которому можно будет расшифровать послание. Возникает ошибка:

Введите сообщене:msg
m
Обработка1
s
Обработка2
g
Обработка3
Traceback (most recent call last):
  File "/home/ilia/1.py", line 41, in <module>
    a.encrypt(msg)
  File "/home/ilia/1.py", line 20, in encrypt
    letter = msg[index]
IndexError: string index out of range

Код:

import random


class Kriptograf:
    def __init__(self,msg) :
        self.msg = msg

#Зашифровать сообщение
#list(msg) - позволяет разбить сообщение по буквам
#len(list(msg)) - позволяет узнать количество символов в сообщение
#random.randint(0,33) - генерирует случайное число от 1 до 33
    def encrypt(msg):
        key=[]
        new_msg=[]
        alphabet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
        index = 0
        while index<=len(list(msg)):
            rannd=random.randint(0,52)
            key.append(rannd)
            letter = msg[index]
            print(letter)
            alphabet.index(letter)
            alphabet[(alphabet.index('Z') + rannd) % len(alphabet)]
            new_msg.append(letter)
            index+=1
            print("Обработка" + str(index))
        print ("Зашифрованное сообщение:")
        print(new_msg)
        print('Коюч:')
        print(key)


    def decipher(msg):
        pass

msg = input("Введите сообщене:")
a = Kriptograf
a.encrypt(msg) 

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

Автор решения: finally

раз уж я тут, проведем небольшой Code Review:

  1. нет никакого смысла вычислять длину строки как len(list('string')), строка и так хранит в себе свою длинy - len('string').

  2. тут действительно было бы предпочтительнее использовать цикл for. не надо будет хранить индекс. и тем более его инкрементировать:

for i in range(len('string')):
    i тут и будет вашим индексом.
  1. старайтесь не занимать имена встроенных функций, вроде index, это плохой тон и уменьшает читабельность кода.

  2. если функция находится в классе, она всегда принимает первым аргументом self. это даже не best practise, это канон языка. в вашем случае нет ошибки на этой почве, потому что вы не создаете экземпляр класса - Kriptograf(), вы записываете в переменную сам объект Kriptograf и от него вызываете функцию. если вы этого и хотите, сделайте метод статичным, иначе вы ломаете логику языка:

@staticmethod
def function(arg):
    pass
  1. ошибка сама тут довольно проста - вы проверяете индекс на меньше либо равенство длине сообщения, вот только индексация идет с 0, и получается что на последней итерации вы берете индекс равный длине, что не возможно. исправьте на index < len('string'), а еще лучше воспользуйтесь пунктом 2
→ Ссылка