Задача: Тексты, состоящие из цифр и латинских букв, зашифрованные различными способами, Вариант 135 (9, 10)
- Шифрование заменой символов (указатель на массив пар: [текущий символ, замещающий символ]; зашифрованный текст – строка символов)
- Шифрование циклическим сдвигом кода каждого символа на n (целое число, определяющее сдвиг; зашифрованный текст – строка символов)
- Шифрование заменой символов на числа (пары: текущий символ, целое число – подстановка при шифровании кода символа в виде короткого целого; зашифрованный текст – целочисленный массив)
- Открытый текст – строка символов
- Частное от деления суммы кодов незашифрованной строки на число символов в этой строке (действительное число)
После размещения данных в контейнер необходимо осуществить их обработку в соответствии с вариантом задания. Обработанные данные после этого заносятся в отдельный файл результатов. Упорядочить элементы контейнера по возрастанию используя сортировку с помощью прямого включения (Straight Insertion). В качестве ключей для сортировки и других действий используются результаты функции, общей для всех альтернатив.
Программа написана на Python 3 в объектно-ориентированном стиле.
Точка входа: main.py
Запуск программы:
1.
Ввод данных из файла python main.py input <input file> <output file>
2. Для рандомного
заполенения python main.py rnd <count elements> <output file>
. Основная реализация расположена в директории "src"
Тесты находятся в директории tests. Входные данные в поддиректории "input", а выходные данные в "output". В случае
некорректных данных, поступающих в программу, в выходной файл поступает сообщение об ошибке. Также есть файл time.txt, в котором записано время тестов программы.
В первой строке задается размер контейнера. Следующие строки описывают элементы контейнера: в начале каждой строки задан
тип шифра, через пробел текст в двойных кавычках, параметр шифрования(определяет, например, количество сдвигов),далее
идут пары вида char-char(заменяемый-заменяющий).
Пример ввода:
6
3 "" 3 a-1 b-2 c-3
3 "2345" 3 2-4 4-9 3-5
3 "10" 2 1-0 0-1
1 "ACS+HUmexUrk!" 3 +- U-o x-w
2 "" 1
3 "12345" 5 1-10 2-20 3-30 4-40 5-50
Пример вывода:
There are 6 elements in container
1. "", Hash=0; Count of replacements: 3 ; Symbols: a <-> 1 b <-> 2 c <-> 3 ; Result: [ ]
2. "2345", Hash=52; Count of replacements: 3 ; Symbols: 2 <-> 4 4 <-> 9 3 <-> 5 ; Result: [ 4 5 9 5 ]
3. "10", Hash=48; Count of replacements: 2 ; Symbols: 1 <-> 0 0 <-> 1 ; Result: [ 0 1 ]
4. "ACS+HUmexUrk!", Hash=83; Count of replacements: 3 ; Symbols: + <-> U <-> o x <-> w ; Result: ACS Homework!
5. "", Hash=0; ReplaceShift: 1; Result: ""
6. "12345", Hash=51; Count of replacements: 5 ; Symbols: 1 <-> 10 2 <-> 20 3 <-> 30 4 <-> 40 5 <-> 50 ; Result: [ 10 20 30 40 50 ]
-----Straight Insertion-----
There are 6 elements in container
1. "", Hash=0; Count of replacements: 3 ; Symbols: a <-> 1 b <-> 2 c <-> 3 ; Result: [ ]
2. "", Hash=0; ReplaceShift: 1; Result: ""
3. "10", Hash=48; Count of replacements: 2 ; Symbols: 1 <-> 0 0 <-> 1 ; Result: [ 0 1 ]
4. "12345", Hash=51; Count of replacements: 5 ; Symbols: 1 <-> 10 2 <-> 20 3 <-> 30 4 <-> 40 5 <-> 50 ; Result: [ 10 20 30 40 50 ]
5. "2345", Hash=52; Count of replacements: 3 ; Symbols: 2 <-> 4 4 <-> 9 3 <-> 5 ; Result: [ 4 5 9 5 ]
6. "ACS+HUmexUrk!", Hash=83; Count of replacements: 3 ; Symbols: + <-> U <-> o x <-> w ; Result: ACS Homework!
⠀ | HW02-OoStaticLangArch | HW03-DynamicLangArch |
---|---|---|
Число интерфейсных модулей | 5 | - |
Число модулей реализации | 5 | 8 |
Общий размер исходных текстов | 14 848 байт | 13 326 байт |
Размер исполняемого файла | 33 336 байт | 15 273 байт (_pycache_) |
Тест | Время работы теста (сек.) | |
1-9 | ≈0 | 0.000664 - 0.000996 |
10 | ≈0 | 0.001181 |
20 случайных элементов | ≈0 | 0.002091 |
1000 случайных элементов | 0.015625 | 0.050444 |
10000 случайных элементов | 0.0625 | 0.516384 |
По сравнению с предыдущей работой увеличилось число модулей реализации (из-за запрета циклических зависимостей требуется бóльшая модульность), несколько уменьшился размер исходных текстов, исчез исполняемый файл (вместо него интерпретатор генерирует во время исполнения более компактный байт-код), и в разы упала производительность. С одной стороны, Python в какой-то степени упрощает программирование и обеспечивает компактность и кроссплатформенность программ. С другой стороны, Python как интерпретируемый язык с динамической типизацией сильно проигрывает в производительности компилируемым языкам со статической типизацией.
Таблица классов | Таблица имен | Описания |
---|---|---|
Container | _init_ | def __init__(self, array: List[Text]) -> None |
from_file | def from_file(cls, input_file: TextIO) |
|
random_symbols | def random_symbols(cls, length: int) |
|
_len_ | def __len__(self) -> int |
|
insertion_sort | def insertion_sort(self) |
|
output | def output(self, output_file: TextIO) -> None |
|
Text | Key | class Key(IntEnum) |
_init_ | def __init__(self, text: str) -> None |
|
_len_ | def __len__(self) -> object |
|
from_file | def from_file(cls, text: str, input_file: TextIO) |
|
hash | def hash(self) |
|
random_encryption | def random_encryption(cls, text: str) |
|
encrypted_text | def encrypted_text(self) -> str |
|
output | def output(self, output_file: TextIO) -> None |
|
CharEncryption | _init_ | def __init__(self, text: str, replacements: List[Tuple[str, Union[int, str]]], to_int: bool) -> None |
from_file | def from_file(cls, text: str, input_file: TextIO) -> Text |
|
file_to_int | def from_file__to_int(cls, text: str, input_file: TextIO, to_int: bool) -> Text |
|
random_to_int | def random_encryption__to_int(cls, text: str, to_int: bool) -> Text |
|
check_validation | def valid_replacements(self) -> bool |
|
replacement_string | def replacement_string(self, index: int) -> str |
|
encrypted_text | def encrypted_text(self) -> str |
|
random_encryption | def random_encryption(cls, text: str) -> Text |
|
output | def output(self, output_file: TextIO) -> None |
|
ShiftEncryption | _init_ | def __init__(self, text: str, shift: int) |
from_file | def from_file(cls, text: str, input_file: TextIO) -> Text |
|
encrypted_text | def encrypted_text(self) -> str |
|
random_encryption | def random_encryption(cls, text: str) -> Text |
|
output | def output(self, output_file: TextIO) -> None |
Память программы | Таблица имен | Память данных |
---|---|---|
main.py | _name_ | str |
src.main.main | args | Tuple[str] |
file | bool | |
input_file | TextIO | |
count_random | int | |
output_file | TextIO | |
start | float | |
container | Container | |
exception | Exception | |
src.checkErrors.not_space | input_file | TextIO |
following | str | |
src.checkErrors.read_char | input_file | TextIO |
following | str | |
src.checkErrors.read_until_space | input_file | TextIO |
content | List[str] | |
following | str | |
src.container.Container._init_ | array | List[Text] |
src.container.Container.from_file | input_file | TextIO |
length | int | |
src.container.Container.random_symbols | length | int |
src.container.Container.insertion_sort | key | float |
tmp | str | |
i | int | |
j | int | |
src.container.Container.output | output_file | TextIO |
index | int | |
src.replaceShift.ShiftEncryption._init_ | text | str |
shift | int | |
src.replaceShift.ShiftEncryption.from_file | text | str |
input_file | TextIO | |
shift | int | |
src.replaceShift.ShiftEncryption.random_encryption | text | str |
src.replaceShift.ShiftEncryption.output | output_file | TextIO |
src.replaceShift.ShiftEncryption.encrypted_text | begin | int |
end | int | |
symbol | str | |
src.replaceChar.CharEncryption._init_ | text | str |
replacements | List[Tuple[str, Union[int, str]]] | |
to_int | bool | |
src.replaceChar.CharEncryption.from_file | text | str |
input_file | TextIO | |
src.replaceChar.CharEncryption.file_to_int | text | str |
input_file | TextIO | |
to_int | bool | |
count_replaces | int | |
arr | List[Tuple[str, Union[int, str]]] | |
from_symbol | str | |
to_symbol | Union[int, str] | |
space | str | |
text_object | CharEncryption | |
src.replaceChar.CharEncryption.random_encryption | text | str |
src.replaceChar.CharEncryption.random_to_int | text | str |
to_int | bool | |
rnd | int | |
pos | set | |
pos1 | Union[List[bool], set] | |
arr | List[Tuple[str, Union[int, str]]] | |
from_symbol | str | |
to_symbol | Union[int, str] | |
src.replaceChar.CharEncryption.replacement_string | index | int |
src.replaceChar.CharEncryption.output | output_file | TextIO |
index | int | |
src.replaceChar.CharEncryption.encrypted_text | pair_map | Dict[str, Union[int, str]] |
couple | Tuple[str, Union[int, str]] | |
encrypted | List[Union[int, str]] | |
symbol | str | |
src.replaceChar.CharEncryption.check_validation | pair | Tuple[str, Union[int, str]] |
src.text.Text._init_ | text | str |
src.text.Text.output | output_file | TextIO |
hash_string | str | |
src.text_factory.input_text | input_file | TextIO |
key | int | |
arr | List[str] | |
current_symbol | str | |
content | str | |
text | Text | |
src.text_factory.random_symbols | content | str |
key | int | |
text | Text |
⠀ | Статическая типизация (HW2) | Динамическая типизация (HW3) |
---|---|---|
Тесты | Время работы теста (сек.) | |
2 | <0.001 сек | 0.0007089 сек |
4 | <0.001 сек | 0.0012162 сек |
10 | <0.0015 сек | 0.0016475 сек |
50 | 0.0015625 сек | 0.0131493 сек |
100 | 0.00625 сек | 0.0175105 сек |
Очевидно, что из-за использования динамической типизации программа работает в разы медленнее. Поэтому для больших проектов лучше использовать языки с статической типизацией. Но также можно сказать, что инамическая типизация концептуально проще, чем статическая, а также приводит к созданию более компактных программ, поскольку она является более гибкой и не требует указания типов. Преимущества статической типизации более заметны для больших и сложных программ.