Потрібно зашифрувати текст підстановкою символів. Для кожної букви алфавіту є відповідна буква шифрованого алфавіту. Наприклад, букви
replace_from = "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя' "
потрібно перетворити у відповідні символи:
replace_to = "he*vd%qa ptkmj+gfx'rylzi@!ubwsc$=no"
Великі букви перетворити у маленькі, потім зробити заміну букв, а якщо якихось символів немає в першому списку, просто проігнорувати їх.
Приклад перетворення:
Щурячий бугай із їжаком-харцизом в'ючись підписали ґешефт у єнах.
=>
siy=btjoeivhjokpom h+'f!hyutp'fo*n$btlcork%rtlhgtodqwq@zoioaxh!
Оскільки дефісу і крапки немає в коді шифрування, результат став на 2 символи коротшим.
За допомогою великої кількості elif letter == '...':
перебрати всі варіанти букв:
replace_from = "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя' "
replace_to = "he*vd%qa ptkmj+gfx'rylzi@!ubwsc$=no"
def encode_1(message):
message = message.lower() # по завданню треба перетворити у маленькі букви
result = ""
for letter in message:
if letter == 'а':
result += 'h'
elif letter == 'б':
result += 'e'
elif letter == 'в':
result += '*'
elif ...
return result
Цей спосіб буде працювати, якщо повністю записати всю таблицю. Але це дуже і дуже довго.
Можна автоматизувати пошук відповідників за допомогою .index
:
replace_from = "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя' "
replace_to = "he*vd%qa ptkmj+gfx'rylzi@!ubwsc$=no"
def encode_2(message):
message = message.lower() # по завданню треба перетворити у маленькі букви
result = ""
for letter in message:
# якщо буква недоступна для шифру, то ігноруємо її
if letter not in replace_from:
#print(f'Ignoring letter {letter}')
continue
# дістати індекс букви з списку шифрування
index = replace_from.index(letter)
# дістати відповідний шифрований символ
symbol = replace_to[index]
result += symbol
return result
Це уже кращий варіант, бо не треба перебирати всі варіанти. Але можна зробити ще краще.
В Пайтоні є тип даних "словник", який дозволяє записувати пари "ключ"-"значення", і робити пошук значення по ключу. Словник записується в фігурних дужках ({ }
), схоже як список записується в квадратних дужках ([ ]
).
replace_dict = {
'а': 'h', 'б': 'e', 'в': '*', 'г': 'v', 'ґ': 'd',
'д': '%', 'е': 'q', 'є': 'a', 'ж': ' ', 'з': 'p',
'и': 't', 'і': 'k', 'ї': 'm', 'й': 'j', 'к': '+',
'л': 'g', 'м': 'f', 'н': 'x', 'о': "'", 'п': 'r',
'р': 'y', 'с': 'l', 'т': 'z', 'у': 'i', 'ф': '@',
'х': '!', 'ц': 'u', 'ч': 'b', 'ш': 'w', 'щ': 's',
'ь': 'c', 'ю': '$', 'я': '=', "'": 'n', ' ': 'o'
}
Пари ключ-значення треба записувати через двокрапку і розділяти комами.
Після цього можна взнати значення по ключу через replace_dict.get()
:
symb = replace_dict.get('й')
print(symb) # виведе j
Якщо символа немає серед ключів, повернеться "нічого"
symb = replace_dict.get('A') # такого ключа немає
print(symb) # виведе None
Другий аргумент у replace_dict.get
дозволяє задати дефолтне значення:
symb = replace_dict.get('A', "NO") # такого ключа немає
print(symb) # виведе "NO"
Все це разом дозволяє зробити ще одну версію шифрувальної машини:
def encode_3(message):
message = message.lower()
result = ""
for letter in message:
symbol = replace_dict.get(letter, "")
result += symbol
return result
Розкодуйте шифрограму xqo hyzijzqoekgcwqory'ohe'ei
, використавши словник дешифрування:
decode_dict = {
'h': 'а', 'e': 'б', '*': 'в', 'v': 'г', 'd': 'ґ',
'%': 'д', 'q': 'е', 'a': 'є', ' ': 'ж', 'p': 'з', 't': 'и',
'k': 'і', 'm': 'ї', 'j': 'й', '+': 'к', 'g': 'л', 'f': 'м',
'x': 'н', "'": 'о', 'r': 'п', 'y': 'р', 'l': 'с', 'z': 'т',
'i': 'у', '@': 'ф', '!': 'х', 'u': 'ц', 'b': 'ч', 'w': 'ш',
's': 'щ', 'c': 'ь', '$': 'ю', '=': 'я', 'n': "'", 'o': ' '
}
plato = {
"name": "Plato",
"country": "Ancient Greece",
"born": -427,
"teacher": "Socrates",
"student": "Aristotle"
}
Коли народився Платон?
Значення словника можна змінювати, і можна додавати/видаляти ключі.
plato["importance"] = 2 # додати новий ключ. Значення по 5-бальній шкалі
plato["born"] = -428 # змінити значення ключа
del plato["student"] # видалити ключ-значення
Це додасть нову пару ключ-значення в слоник plato
.
Замініть ім'я у Платона на "Kanye", додайте прізвище "West", замініть країну на USA, рік народження на 1977, видаліть вчителя і студентів. Додайте ключ "importance" і придумайте йому значення.
Вивести словник гарно на екран. Наприклад, словник { 'a': 10, 'b': 20, 'c': 30 }
при виводі повинен виглядати як:
a -- 10
b -- 20
c -- 30
Для цього доведеться "пройтись" по всім парам ключ-значення в словнику. Це можна зробити так:
my_dict = { ... }
for key, value in my_dict.items():
# key та value -- це тепер відповідні ключ та значення
print(key)
...
Зробити консоль адміна. В консолі можна додавати нових юзверів в систему.
Спочатку програма питає: "хочеш додати ще одного юзвера?". Якщо адмін відповідає "так", то програма питає окремо логін юзвера, пароль юзвера і записує його у словник.
При запису у словник потрібно в якості ключа вказати логін, а в якості значення –- пароль.
Якщо адмін відповідає "ні", то програма виводить словник юзверів на екран, красиво.
Гравці на сервері Майнкрафту зберігаються в одному великому словнику. Ключем є ID гравця, а значенням – об'єкт гравця. Ось приклад об'єктів у цьому словнику:
class Player:
pass
# id 1
player1 = Player()
player1.name = "vasia"
player1.is_banned = False
# id 2
player2 = Player()
player2.name = "petia"
player2.is_banned = True
player2.ban_reason = "мати, гріф"
player2.ban_till = 1619540031
# id 3
player3 = Player()
player3.name = "ksiusha"
player3.is_banned = True
player3.ban_reason = "чітер, волхацкер"
player3.ban_till = 1619531049
users = {
1: player1,
2: player2,
3: player3,
}
Потрібно написати функцію def send_msg(user_id, msg)
, яка робить прінт повідомлення на екран, але тільки якщо юзер не забанений. Якщо юзер забанений, написати скільки лишилось часу до розбану.
Як взнати скільки лишилось часу? Потрібно взнати поточний час (time.time()
з бібліотеки time
), і відняти його від параметру player.ban_till
(доколи забанено). Якщо результат додатній, значить юзер ще в бані, якщо від'ємний, то бан треба знімати і повідомлення можна прінтити.
Маючи два рядки replace_from
та replace_to
зробити словник заміни replace_dict
. Алгоритм такий:
replace_dict
Нехай є текст:
big_text = """
Class for timing execution speed of small code snippets.
The constructor takes a statement to be timed, an additional statement used for setup, and a timer function. Both statements default to 'pass'; the timer function is platform-dependent (see the module doc string). stmt and setup may also contain multiple statements separated by ; or newlines, as long as they don’t contain multi-line string literals. The statement will by default be executed within timeit’s namespace; this behavior can be controlled by passing a namespace to globals.
To measure the execution time of the first statement, use the timeit() method. The repeat() and autorange() methods are convenience methods to call timeit() multiple times.
The execution time of setup is excluded from the overall timed execution run.
The stmt and setup parameters can also take objects that are callable without arguments. This will embed calls to them in a timer function that will then be executed by timeit(). Note that the timing overhead is a little larger in this case because of the extra function calls.
"""
Потрібно порахувати скільки разів яка буква зустрічається. Алгоритм:
Маючи словник частот (наприклад, з попереднього завдання) порахувати суму всіх значень. (Для перевірки: вона повинна дорівнювати довжині ориганільного тексту)
Якщо у нас є словник заміни, як розкодувати шифроване повідомлення? Потрібно зробити аналогічний словник і зробити "шифрування", але тепер іншим словником.
Потрібно словник:
replace_dict = {
'а': 'h',
'б': 'e',
'в': '*',
'г': 'v',
...
}
перетворити у
reverse_dict = {
'h': 'а',
'e': 'б',
'*': 'в',
'v': 'г',
...
}
Зробити функцію decode
і дешифрувати за її допомогою повідомлення.
Мода –- це ключ, у якого найбільше значення у словнику частот. Окрім моди, зручно також знати топ-5, або топ-10 з цього словника.
Нехай є словник частот (наприклад, з попередніх завдань). Потрібно:
Маючи словник частот, потрібно знайти топ-50% –- мінімальний набір ключів, чиї значення в сумі дають 50% всіх значень таблиці.