1import types
2import unittest
3
4from solution import *
5
6
7PLUGBOARD_POSITION = [{'a', 'c'}, {'t', 'z'}]
8ROTOR_POSITION = {'v': 'd', 'd': 'v', 'y': 'u', 'n': 'n', 'i': 'w', 'z': 'p',
9 's': 'e', 'x': 's', 'h': 'f', 'b': 'x', 'u': 'c', 'p': 'q',
10 'r': 'g', 'q': 'j', 'e': 't', 'l': 'y', 'o': 'z', 'g': 'o',
11 'k': 'b', 't': 'h', 'j': 'm', 'a': 'a', 'w': 'i', 'f': 'l',
12 'm': 'r', 'c': 'k'}
13
14
15class TestPlugboard(unittest.TestCase):
16 """Test the plugboard function."""
17
18 def test_sanity(self):
19 """Sanity test for the plugboard function."""
20 self.assertIsInstance(plugboard('enigma', PLUGBOARD_POSITION), str)
21
22
23class TestRotor(unittest.TestCase):
24 """Test the rotor function."""
25
26 def test_sanity(self):
27 """Sanity test for the rotor function."""
28 self.assertIsInstance(rotor('enigma', ROTOR_POSITION), str)
29
30
31class TestEncryptor(unittest.TestCase):
32 """Test the encryptor function."""
33
34 def test_sanity(self):
35 """Sanity test for the encryptor function."""
36 self.assertIsInstance(enigma_encrypt(PLUGBOARD_POSITION, ROTOR_POSITION), types.FunctionType)
37
38
39class TestDecryptor(unittest.TestCase):
40 """Test the decryptor function."""
41
42 def test_sanity(self):
43 """Sanity test for the decryptor function."""
44 self.assertIsInstance(enigma_decrypt(PLUGBOARD_POSITION, ROTOR_POSITION), types.FunctionType)
45
46
47if __name__ == '__main__':
48 unittest.main()
1import types
2import unittest
3from unittest.mock import Mock
4
5from solution import *
6
7
8"""
9Code for generating random rotor position
10import random
11
12all_letters = []
13for x in range(97, 97 + 26):
14 all_letters.append(chr(x))
15
16keys = all_letters[:]
17vals = all_letters[:]
18random.shuffle(vals)
19
20d = {}
21for k, v in zip(keys, vals):
22 d[k] = v
23
24print(d)
25"""
26
27
28TEST_FUN = lambda x: x
29
30
31class TestPlugboard(unittest.TestCase):
32 """Test the plugboard function."""
33
34 def test_empty(self):
35 """Test the plugboard function with empty input."""
36 self.assertEqual(plugboard('', []), '')
37
38 def test_no_mapping(self):
39 """Test the plugboard function with no mapping input."""
40 self.assertEqual(plugboard('enigma machine is working', []), 'enigma machine is working')
41
42 def test_normal_case(self):
43 """Test the plugboard function with normally expected input."""
44 plugboard_position = [{'a', 'z'}, {'e', 'y'}, {'t', 'i'}]
45 self.assertEqual(plugboard('this is a test input', plugboard_position), 'ihts ts z iysi tnpui')
46
47
48class TestRotor(unittest.TestCase):
49 """Test the rotor function."""
50
51 ROTOR_POSITION = {'a': 'c', 'b': 'a', 'c': 'i',
52 'd': 'm', 'e': 'd', 'f': 'g',
53 'g': 'h', 'h': 'b', 'i': 'j',
54 'j': 'x', 'k': 'w', 'l': 'r',
55 'm': 'f', 'n': 'y', 'o': 'z',
56 'p': 'l', 'q': 'n', 'r': 'u',
57 's': 'o', 't': 'k', 'u': 'q',
58 'v': 's', 'w': 'e', 'x': 'p',
59 'y': 't', 'z': 'v'}
60
61 def test_empty(self):
62 """Test the rotor function with empty input."""
63 self.assertEqual(rotor('', self.ROTOR_POSITION), '')
64
65 def test_normal_case(self):
66 """Test the rotor function with normally expected input."""
67 self.assertEqual(rotor('this is a test input', self.ROTOR_POSITION), 'kbjo jo c kdok jylqk')
68
69
70class TestEncryptor(unittest.TestCase):
71 """Test the encryptor function."""
72
73 PLUGBOARD_POSITION = [{'a', 'z'}, {'u', 'f'}, {'m', 'n'}, {'o', 'w'}]
74
75 ROTOR_POSITION = {'a': 'o', 'b': 'n', 'c': 's',
76 'd': 'e', 'e': 'g', 'f': 'a',
77 'g': 'w', 'h': 'j', 'i': 'v',
78 'j': 'h', 'k': 'k', 'l': 'i',
79 'm': 'y', 'n': 'u', 'o': 'f',
80 'p': 'l', 'q': 'c', 'r': 'r',
81 's': 'p', 't': 'm', 'u': 'z',
82 'v': 'x', 'w': 'q', 'x': 'd',
83 'y': 'b', 'z': 't'}
84
85 def test_full_letter_set(self):
86 """Test the encryptor function with all letters in the rotor."""
87 encryptor = enigma_encrypt(self.PLUGBOARD_POSITION, self.ROTOR_POSITION)
88 encrypted = encryptor(TEST_FUN)
89 self.assertEqual(encrypted('the quick brown fox jumps over the lazy dog'),
90 'mjg cavsk nrqfy zqd haulp qxgr mjg itob eqw')
91
92
93class TestDecryptor(unittest.TestCase):
94 """Test the decryptor function."""
95
96 PLUGBOARD_POSITION = [{'f', 'u'}, {'g', 'q'}, {'b', 'v'}, {'r', 's'}]
97
98 ROTOR_POSITION = {'a': 'z', 'b': 'i', 'c': 'e',
99 'd': 's', 'e': 'x', 'f': 'u',
100 'g': 'f', 'h': 'l', 'i': 'v',
101 'j': 'g', 'k': 'r', 'l': 'p',
102 'm': 'o', 'n': 'n', 'o': 'a',
103 'p': 'y', 'q': 't', 'r': 'q',
104 's': 'b', 't': 'm', 'u': 'j',
105 'v': 'c', 'w': 'k', 'x': 'd',
106 'y': 'w', 'z': 'h'}
107
108 def test_full_letter_set(self):
109 """Test the decryptor function with all letters in the rotor."""
110 decryptor = enigma_decrypt(self.PLUGBOARD_POSITION, self.ROTOR_POSITION)
111 decrypted = decryptor(TEST_FUN)
112 self.assertEqual(decrypted('mlx fuver cbakn jad guoyq aixb mlx pzhw sat'),
113 'the quick brown fox jumps over the lazy dog')
114
115
116class TestCombination(unittest.TestCase):
117 """Test decrypting an encrypted text."""
118
119 PLUGBOARD_POSITION = [{'a', 'b'}, {'c', 'd'}, {'e', 'f'}, {'g', 'h'},
120 {'i', 'j'}, {'k', 'l'}, {'m', 'n'}, {'o', 'p'},
121 {'q', 'r'}, {'s', 't'}, {'u', 'v'}, {'w', 'x'},
122 {'y', 'z'}]
123
124 ROTOR_POSITION = {'a': 'z', 'b': 'i', 'c': 'e',
125 'd': 's', 'e': 'x', 'f': 'u',
126 'g': 'f', 'h': 'l', 'i': 'v',
127 'j': 'g', 'k': 'r', 'l': 'p',
128 'm': 'o', 'n': 'n', 'o': 'a',
129 'p': 'y', 'q': 't', 'r': 'q',
130 's': 'b', 't': 'm', 'u': 'j',
131 'v': 'c', 'w': 'k', 'x': 'd',
132 'y': 'w', 'z': 'h'}
133
134 def test_full_letter_set(self):
135 """Test decrypting an encrypted text against itself."""
136 encryptor = enigma_encrypt(self.PLUGBOARD_POSITION, self.ROTOR_POSITION)
137 decryptor = enigma_decrypt(self.PLUGBOARD_POSITION, self.ROTOR_POSITION)
138 combined = decryptor(encryptor(TEST_FUN))
139 self.assertEqual(combined('i love python'), 'i love python')
140
141
142class TestDecorators(unittest.TestCase):
143 """Test decorators."""
144
145 PLUGBOARD_POSITION = [{'a', 'b'}, {'c', 'd'}, {'e', 'f'}, {'g', 'h'},
146 {'i', 'j'}, {'k', 'l'}, {'m', 'n'}, {'o', 'p'},
147 {'q', 'r'}, {'s', 't'}, {'u', 'v'}, {'w', 'x'},
148 {'y', 'z'}]
149
150 ROTOR_POSITION = {'a': 'z', 'b': 'i', 'c': 'e',
151 'd': 's', 'e': 'x', 'f': 'u',
152 'g': 'f', 'h': 'l', 'i': 'v',
153 'j': 'g', 'k': 'r', 'l': 'p',
154 'm': 'o', 'n': 'n', 'o': 'a',
155 'p': 'y', 'q': 't', 'r': 'q',
156 's': 'b', 't': 'm', 'u': 'j',
157 'v': 'c', 'w': 'k', 'x': 'd',
158 'y': 'w', 'z': 'h'}
159
160 def test_correct_decorator_order(self):
161 """Test whether the decorator is applying the functions in correct order."""
162 encryptor = enigma_encrypt(self.PLUGBOARD_POSITION, self.ROTOR_POSITION)
163 decryptor = enigma_decrypt(self.PLUGBOARD_POSITION, self.ROTOR_POSITION)
164 mock = Mock()
165 encryptor(mock)('test')
166 mock.assert_called_once_with('bumb')
167 mock = Mock()
168 decryptor(mock)('bumb')
169 mock.assert_called_once_with('test')
170
171
172if __name__ == '__main__':
173 unittest.main()
Георги Кунчев
31.10.2023 08:47@Веселина, при еднакви подадени стойности на `enigma_encrypt` и `enigma_decrypt`, и условието, че не можете да добавяте повече параметри от дефинираните на която и да било от функциите, в общи линии не ти остават много варианти, така че най-вероятно наистина трябва да "правим някакви магии в декоратора". Не е задължително да е така, но е валидно решение.
Хинтът е важен, за да ви подтикнем да "правите магии", а не да очаквате, че ние ще тестваме с различна стойност за енкриптора и декриптора.
Съдейки по прочетеното, правилно си разбрала условието.
|
Веселина Велкова
31.10.2023 01:06Здравейте, не разбирам тази част от хинта - "Не опитвайте да заобиколите проблема като подавате различни стойностите за rotor_position на enigma_encrypt и enigma_decrypt". Ако encryptor = enigma _ encrypt(plugboard _ position=plugboard _ position,
rotor _ position=rotor _ position) /
decryptor = enigma _ decrypt(plugboard _ position=plugboard _ position,
rotor _ position=rotor _ position)
тук сме подали едни и същи rotor _ position, е ок да си правим някакви магии в декоратора нали? Извинявам се, ако съм дала някаква подсказка на останалите, просто не съм сигурна как мога да си задам правилно въпроса :(
|
Георги Кунчев
30.10.2023 14:05@Даниел, конвертирането със сет не е обръвзано с ред. Която и да е буква от сета се конвертира в съседната си. Дефиниции като "първата" и "втората" буква от сета не са коректни.
|
Даниел Йорданов
30.10.2023 13:43Понеже знаем, че set не гарантира подредбата на данните, коректно ли е да го използваме за точно конвертиране от първата във втората буква от него?
|
Георги Кунчев
29.10.2023 10:05Съответните празни колекции ще свършат работа, но сори да нямаш стойности по подразбиране, те пак могат да се подадат като именувани.
|
Добромир Пеев
29.10.2023 09:56След като по условие аргументите в enigma_decrypt и enigme_encrypt са именувани в такъв случай какви стойности да им дадем по подразбиране ?
|
Георги Кунчев
26.10.2023 18:51@Николай, личи си кой не е ползвал `pytest`. Печелиш звезда.
|
Николай Николаев
26.10.2023 18:44И аз благодаря за обратната връзка! Тестовете действително са за pytest. Има автоматично откриване на тестовете, благодарение на имената на функциите, които започват с test. Вярно е, че изглеждат само като функции, но това е приятното на pytest - няма сложен синтаксис и при писане на pytest [името на файла с тестовете] в терминал пак се възползваме от благинките.
|
Георги Кунчев
26.10.2023 18:21@Александър, радвам се, че си намерил решение. Като цяло отговорът би бил не. Семантиката на функциите трябва да съвпада с това, което сме дефинирали в условието.
@Николай, благодаря за тестовете от името на колегите! Съветвам да се опиташ да използваш `unittest` или `pytest` за следващия път. Това са просто функции и не черпят от всички благинки, които библиотеките ти предлагат.
|
Николай Николаев
26.10.2023 16:38Това са мои unit тестове, използващи pytest. Дано са ви полезни :smile:
```
"""
This is a set of unit tests for homework 2 that uses PyTest. If you want
to use them to test your homework, install PyTest (pip install pytest in your
terminal). The tests are manually written and yield correct results with
my solution, but if you find any inconsistencies, feel free to comment below.
"""
from homework2 import plugboard, rotor, enigma_encrypt, enigma_decrypt
plugboard_position = [{'a', 'c'}, {'t', 'z'}]
rotor_position = {'v': 'd', 'd': 'v', 'y': 'u', 'n': 'n', 'i': 'w', 'z': 'p',
's': 'e', 'x': 's', 'h': 'f', 'b': 'x', 'u': 'c', 'p': 'q',
'r': 'g', 'q': 'j', 'e': 't', 'l': 'y', 'o': 'z', 'g': 'o',
'k': 'b', 't': 'h', 'j': 'm', 'a': 'a', 'w': 'i', 'f': 'l',
'm': 'r', 'c': 'k'}
@enigma_encrypt(plugboard_position, rotor_position)
def encrypt_decorated(text):
"""Helper to test the encryption decorator."""
return text
@enigma_decrypt(plugboard_position, rotor_position)
def decrypt_decorated(text):
"""Helper to test the decryption decorator."""
return text
def test_plugboard():
"""Tests the plugboard function."""
assert(plugboard("enigma", plugboard_position)) == "enigmc"
assert(plugboard("aarcetzot", plugboard_position)) == "ccraeztoz"
assert(plugboard("", plugboard_position)) == ""
assert(plugboard("t", plugboard_position)) == "z"
assert(plugboard("c", plugboard_position)) == "a"
assert(plugboard("tctatctzac", plugboard_position)) == "zazczaztca"
assert(plugboard("a t", plugboard_position)) == "c z"
assert(plugboard(" a t ", plugboard_position)) == " c z "
def test_rotor():
"""Tests the rotor function."""
assert(rotor("enigmc", rotor_position)) == "tnwork"
assert(rotor("e", rotor_position)) == "t"
assert(rotor("e c", rotor_position)) == "t k"
assert(rotor("", rotor_position)) == ""
assert(rotor("eeee", rotor_position)) == "tttt"
assert(rotor("abcdefghijklmopqrstuvwxyz", rotor_position)) == "axkvtlofwmbyrzqjgehcdisup"
def test_enigma_encrypt():
"""Tests the enigma_encrypt decorator."""
assert(encrypt_decorated("enigma")) == "tnwork"
assert(encrypt_decorated("abcdefghijklmopqrstuvwxyz")) == "kxavtlofwmbyrzqjgepcdisuh"
assert(encrypt_decorated("a")) == "k"
assert(encrypt_decorated("")) == ""
assert(encrypt_decorated("cat")) == "akp"
def test_enigma_decrypt():
"""Tests the enigma_decrypt decorator."""
assert(decrypt_decorated("tnwork")) == "enigma"
assert(decrypt_decorated("kxavtlofwmbyrzqjgepcdisuh")) == "abcdefghijklmopqrstuvwxyz"
assert(decrypt_decorated("k")) == "a"
assert(decrypt_decorated("")) == ""
assert(decrypt_decorated("akp")) == "cat"
```
|