Найти - Пользователи
Полная версия: Код цезаря. Ошибка "IndexError: string index out of range"
Начало » Центр помощи » Код цезаря. Ошибка "IndexError: string index out of range"
1
coffe4wolf
Доброго времени суток
Листая одну замечательную книгу столкнулся с ошибкой
Код
 import pyperclip
message = "Xqp whh ahoa kb pda sknhz swo ejreoexha."
key = 22
mode = 'decrypt'
translated = ''
num = 0
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
message = message.upper()
for symbol in message:
     if symbol in LETTERS:
         num = LETTERS.find(symbol)
         if mode == 'encrypt':
             num = num + key
         elif mode == 'decrypt':
             num = num - key
         if num >= len(LETTERS):
            num = num - len(LETTERS)
         elif num <= 0:
            num = num + len(LETTERS)
         translated = translated + LETTERS[num]
     else:
         translated = translated + symbol
print(translated)
pyperclip.copy(translated)

Ошибка
 Traceback (most recent call last):
  File "C:\python\caesar.py", line 22, in <module>
    translated = translated + LETTERS[num]
IndexError: string index out of range
С ключами меньше 22 компилятор ошибок не выдаёт. С ключами больше - выдаёт ту же ошибку.
Не пойму где конкретно возбуждается проблема :с
Насколько я понял идёт обращение к несуществующему индексу строки LETTERS (в смысле к тому индексу, в котором нет никакого значения), а конкретно к 26му. По крайней мере в консоли после исполнения модуля значение num = 26.
Так как строка с сообщение в данном случае достаточно короткая, num=26 только в случае если к этому моменту
          if num >= len(LETTERS):
            num = num - len(LETTERS)
         elif num <= 0:
            num = num + len(LETTERS)
у нас num был равен 0 и к нему прибавили длину строки LETTERS
noob_saibot
 LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
print list(enumerate(LETTERS))
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'), (4, 'E'), (5, 'F'), (6, 'G'), (7, 'H'), (8, 'I'), (9, 'J'), (10, 'K'), (11, 'L'), (12, 'M'), (13, 'N'), (14, 'O'), (15, 'P'), (16, 'Q'), (17, 'R'), (18, 'S'), (19, 'T'), (20, 'U'), (21, 'V'), (22, 'W'), (23, 'X'), (24, 'Y'), (25, 'Z')]
Индекса 26 попросту нет.

PS. Я вообщем последнюю часть ваших выкладок не понял. Вы вроде сами нашли проблему, вы её решить не можете или что?
coffe4wolf
noob_saibot
Да уже решил х) какое-то время не мог понять откуда у меня этот индекс появляется.
Добавил условие - если num = 0, то таким его и оставлять. Правда выглядит не очень красиво. Можно реализовать данное условие как то по-лучше?
 import pyperclip
message = "'This is still a silly example.'"
key = 0
mode = 'decrypt'
translated = ''
num = 0
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
message = message.upper()
for symbol in message:
     if symbol in LETTERS:
         num = LETTERS.find(symbol)
         if mode == 'encrypt':
             num = num + key
         elif mode == 'decrypt':
             num = num - key
         if num >= len(LETTERS):
            num = num - len(LETTERS)
         elif num < 0:
            num = num + len(LETTERS)
         elif num == 0:
            num = 0
         translated = translated + LETTERS[num]
     else:
         translated = translated + symbol
print(translated)
pyperclip.copy(translated)                    
noob_saibot
coffe4wolf
noob_saibotДа уже решил х) какое-то время не мог понять откуда у меня этот индекс появляется.Добавил условие - если num = 0, то таким его и оставлять. Правда выглядит не очень красиво. Можно реализовать данное условие как то по-лучше?
Так а чего вот этот блок просто не убрать?
 elif num == 0:
            num = 0
Shaman
Подумайте, как будут кодироваться A и Z.
coffe4wolf
Shaman
В смысле как индексироваться?
А как LETTERS
Z как LETTERS либо LETTERS
coffe4wolf
noob_saibot
Вай, точно х) спасибище
Shaman
coffe4wolf, у вас день ВДВ чтоль?
 >>> LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> LETTERS.index('A') - 1
-1
>>> LETTERS.index('Z') + 1
26
>>> len(LETTERS)
26
>>> 
marvellik
циклическое получение индекса буквы алфавита
 index=(LETTERS.find(symbol)+key)%len(LETTERS)
мой вариант шифра цезаря c сохранением регистра букв

def CaesarCipherChar(c, k):
c = list(c)
alfavit = ''.join(chr(x) for x in range(ord('a'),ord('z')+1))
for i in range (len(c)):
if c[i].isalpha():
index = (alfavit.find(c[i].lower())+k)%len(alfavit)
c[i] = alfavit[index] if c[i] == c[i].lower() else alfavit[index].upper()
return ''.join(c)

message = input()
key = int(input())
print(CaesarCipherChar(message, key))
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB