-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path01-lists_extra.py
More file actions
157 lines (145 loc) · 10.2 KB
/
01-lists_extra.py
File metadata and controls
157 lines (145 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Дополнительное задание к уроку "Понятие списков"
# Задача: создать алгоритм преобразования введённого пользователем
# текста в шрифт Цезаря (сдвиг символов вперёд в алфавитном порядке)
# В коде применены обработки исключений и основы ООП
# Создан класс-родитель для шифрования строки,
# и классы шифровальщик и дешифратор, наследуемые от него
# Создаём списки с заглавными и маленькими буквами
# русского и английского алфавита, кодировать будем только их,
# числа, символы и специфичные буквы других алфавитов останутся прежними
up_ru = "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я".split()
down_ru = "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я".split()
up_en = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z".split()
down_en = "a b c d e f g h i j k l m n o p q r s t u v w x y z".split()
# Создаём класс, который не будет ничего шифровать,
# но именно в нём будет заложен алгоритм шифрования строки по символам.
# Потом наследуем шифровальщик и дешифратор от него.
class Cryptor:
# Инициализируем поля для исходного текста
# (который будет введён пользователем), и для зашифрованного
# Значения не вводим, пишем None
textIn = None
encrypted = None
# В конструкторе класса ничего не делаем
def __init__(self):
pass
# Та самая функция, которой будут отличаться шифровальщик и дешифратор.
# Ничего здесь не делаем, возвращаем NOTFOUND
def encryptCharFrom(self, ch, letterArr):
return "NOTFOUND"
# Прошлая функция должна для шифрования брать список букв
# Эта функция просто повторяет прошлую,
# но сразу для четырёх наших списков с буквами.
# Если от той функции получаем NOTFOUND, здесь возвращаем
# введённый символ неизменным.
# Таким образом, мы понимаем, почему мы сможем кодировать только буквы из наших списков,
# а также почему этот класс-родитель не будет никак изменять введённый текст.
def encryptChar(self, ch):
# Инициализируем наши списки с ключевым словом global, иначе ошибка
global up_ru, down_ru, up_en, down_en
for i in [up_ru, down_ru, up_en, down_en]:
# Получаем зашифрованную функцией выше букву
enc = self.encryptCharFrom(ch, i)
# Если функция вернула не NOTFOUND,
# возвращаем шифр здесь
if(enc != "NOTFOUND"):
return enc
# Если не удалось зашифровать символ, используя наши списки,
# возвращаем его неизменным
return ch
# Ну и та функция, которая будет шифровать целую строку
# по символам поочерёдно, без аргументов, ввёденный пользователем текст
# будем брать из поля класса textIn
def encrypt(self):
# Получаем и создаём список всех символов строки методом list
textArr = list(self.textIn)
# Создаём список зашифрованных символов
encr = []
# Делаем пробег по символам, шифруем их функцией и добавляем в список шифра
for item in textArr:
encr.append(self.encryptChar(item))
# Преобразуем список зашифрованных символов в строку функцией join от пустой строки,
# и записываем полученную строку в поле
self.encrypted = "".join(encr)
# Функция для вывода введённого и зашифрованного текстов в консоль
def print(self):
# Берём текст от пользователя
self.textIn = input("Введите текст: ")
# Шифруем
self.encrypt()
# Выводим
print("Вы ввели: " + self.textIn)
print("Шифр: " + self.encrypted)
# Создаём класс шифровальщик, наследуем его от основы,
# которую мы написали ранее
class CaesarEncryptor(Cryptor):
# Изменяем только самую первую функцию, использующую один список букв
def encryptCharFrom(self, ch, letterArr):
# Ищем данный символ в данном списке букв, но если его там нет,
# вылезет исключение ValueError. Делаем его обработку.
try:
# Получаем индекс символа
ench = letterArr.index(ch)
# Берём индекс на 3 позиции вперёд, вычисляем остаток
# от деления на длину списка, в случае если индекс получится больше длины
index = (ench + 3) % len(letterArr)
# Возвращаем элемент списка с полученным ранее индексом
return letterArr[index]
# Если вылезает, возвращаем тот самый NOTFOUND,
# в случае возвращения которого следующая функция
# либо вызовет эту на следующий список букв, либо
# вернёт неизменённый символ, если в списках его не нашлось
except ValueError:
return "NOTFOUND"
# Создаём класс дешифратор
class CaesarDecryptor(Cryptor):
# Абсолютно так же само изменяем самую первую функцию,
# но здесь берём индекс на 3 позиции НАЗАД
def encryptCharFrom(self, ch, letterArr):
try:
ench = letterArr.index(ch)
index = (ench - 3) % len(letterArr)
return letterArr[index]
except ValueError:
return "NOTFOUND"
# Наконец пишем работу нашей программы при запуске скрипта
if __name__ == "__main__":
print("Вас приветствует программа для работы со шрифтом Цезаря")
# Создаём функцию, которая будет использовать шифровальщик или дешифратор,
# а потом либо завершаться, либо вызываться заново, в зависимости от решения пользователя
def summonDialog():
# Внутри создаём функцию, которая будет выводить в консоль вопрос пользователю
# с возможными ответами 0 и 1, и будет вызывать сама себя ещё раз в случае неправильно введённых данных
def summonChoice(question):
choice = None
try:
choice = int(input(question))
if choice == 0 or choice == 1:
pass
else:
print("Некорректно введённые данные! Можно ввести только число 0 или 1! Попробуйте ещё раз!")
summonChoice(question)
except ValueError:
print("Некорректно введённые данные! Можно ввести только целое число 0 или 1! Попробуйте ещё раз!")
summonChoice(question)
return choice
# Вызываем вопрос
tasktype = summonChoice("Будем шифровать (0) или расшифровывать (1)? ")
# И в зависимости от выбора пользователя создаём шифровальщик или дешифратор
cryptor = None
if tasktype == 0:
cryptor = CaesarEncryptor()
else:
cryptor = CaesarDecryptor()
# Выводим в консоль результат шифрования
cryptor.print()
# Наконец спрашиваем у пользателя, продолжить ли работу
# Если да, вызываем диалог ещё раз, если нет, завершаем работу программы
toContinue = True if summonChoice("Продолжить (0) или завершить работу (1)? ") == 0 else False
if toContinue:
summonDialog()
else:
print("Спасибо за пользование этой программой! До новых встреч!")
# Вызываем один диалог в программе
summonDialog()
# Спасибо за внимание)))