Compare commits
10 Commits
f3106e28cd
...
a660cb793a
Author | SHA1 | Date |
---|---|---|
Claudio Maggioni | a660cb793a | |
Claudio Maggioni | 549b8859ff | |
Claudio Maggioni | c1b91104a3 | |
Claudio Maggioni | 6d44303c57 | |
Claudio Maggioni | 9d6315152e | |
Claudio Maggioni | f77c297ca0 | |
Claudio Maggioni | 967209b852 | |
Claudio Maggioni | f5f605c259 | |
Claudio Maggioni | 1153d5138a | |
Claudio Maggioni | a622cc5e27 |
72
README.md
72
README.md
|
@ -13,7 +13,7 @@ Note: Feel free to modify this file according to the project's necessities.
|
|||
|
||||
## Environment setup
|
||||
|
||||
To install the required dependencies the Python version manager `pyenv` must be installed and in `$PATH`.
|
||||
To install the required dependencies the Python version manager `pyenv` must be installed and in `$PATH`.
|
||||
|
||||
To set up a Python 3.11 virtualenv to execute parts 1, 2, and 3 of the project run:
|
||||
|
||||
|
@ -24,7 +24,7 @@ pyenv shell 3.11
|
|||
python3.11 -m venv env
|
||||
|
||||
source env/bin/activate
|
||||
pip3.11 install -r requirements.txt
|
||||
pip3.11 install -r requirements_3.11.txt
|
||||
```
|
||||
|
||||
To set up Python 3.7 (last version supported by `mut.py`) to execute part 4 of the project run:
|
||||
|
@ -34,18 +34,16 @@ deactivate || true # deactivate existing environment
|
|||
pyenv install -s 3.7
|
||||
pyenv shell 3.7
|
||||
python3.7 -m venv env37
|
||||
source env37/bin/activate
|
||||
|
||||
pip3.7 install MutPy==0.6.1
|
||||
pip3.7 install -r requirements.txt
|
||||
source env37/bin/activate
|
||||
pip3.7 install -r requirements_3.7.txt
|
||||
```
|
||||
|
||||
## Instrumentation (Part 1)
|
||||
|
||||
To generate the instrumented code for all the files in the benchmark run the command:
|
||||
To generate the instrumented code for all the files in the benchmark run the commands:
|
||||
|
||||
```shell
|
||||
# Reset Python to latest (system) version
|
||||
deactivate || true
|
||||
pyenv shell 3.11
|
||||
source env/bin/activate
|
||||
|
@ -56,12 +54,36 @@ python3.11 ./instrument.py
|
|||
The generated files are created in the directory `instrumented`. Each file name matches the file name of the
|
||||
corresponding source file in `benchmark`.
|
||||
|
||||
## Test case generation (Part 2 and Part 3)
|
||||
## Test case generation using the fuzzer (Part 2)
|
||||
|
||||
To generate test cases for all files in the benchmark run the command:
|
||||
To generate test cases for all files in the benchmark using the fuzzer run the commands:
|
||||
|
||||
```shell
|
||||
deactivate || true
|
||||
pyenv shell 3.11
|
||||
source env/bin/activate
|
||||
|
||||
python3.11 ./fuzzer.py
|
||||
```
|
||||
|
||||
The test suite is created in the directory `fuzzer_tests`. One test file is generated for each file present in the
|
||||
`benchmark` directory. Run the command with the `-h` options for more details on partial generation.
|
||||
|
||||
The test suite can be then executed over the benchmark code with the commands:
|
||||
|
||||
```shell
|
||||
deactivate || true
|
||||
pyenv shell 3.11
|
||||
source env/bin/activate
|
||||
|
||||
python3.11 -m unittest discover fuzzer_tests
|
||||
```
|
||||
|
||||
## Test case generation using the genetic algorithm (Part 3)
|
||||
|
||||
To generate test cases for all files in the benchmark using the genetic algorithm run the commands:
|
||||
|
||||
```shell
|
||||
# Reset Python to latest (system) version
|
||||
deactivate || true
|
||||
pyenv shell 3.11
|
||||
source env/bin/activate
|
||||
|
@ -69,13 +91,12 @@ source env/bin/activate
|
|||
python3.11 ./genetic.py
|
||||
```
|
||||
|
||||
The test suite is created in the directory `tests`. One test file is generated for each file present in the
|
||||
The test suite is created in the directory `tests`. One test file is generated for each file present in the
|
||||
`benchmark` directory. Run the command with the `-h` options for more details on partial generation.
|
||||
|
||||
The test suite can be then executed over the benchmark code with the command:
|
||||
The test suite can be then executed over the benchmark code with the commands:
|
||||
|
||||
```shell
|
||||
# Reset Python to latest (system) version
|
||||
deactivate || true
|
||||
pyenv shell 3.11
|
||||
source env/bin/activate
|
||||
|
@ -94,4 +115,27 @@ pyenv shell 3.7
|
|||
source env37/bin/activate
|
||||
|
||||
python3.7 muttest.py
|
||||
```
|
||||
```
|
||||
|
||||
The script will consider the tests in `fuzzer_tests` and `tests` and run mutation testing on them, collecting the
|
||||
mutation score for each run in `out/mutation_results_fuzzer.csv` and `out/mutation_results_genetic.csv` respectively.
|
||||
If either or both file exist, the p run for the matching test suite will be skipped and the saved values will be
|
||||
used.
|
||||
|
||||
The script additionally generates two plots for the distribution and average of mutation scores per kind of generation
|
||||
and benchmark file. These two plots are saved in `out/mutation_scores.png` and `out/mutation_scores_mean.png`
|
||||
respectively. `out/stats.csv` is also generated and will contain a statistical comparison between the mutation score
|
||||
distribution for the fuzzer-generated and genetic-generated test of each benchmark file, including the average score for
|
||||
both generations, the Wilcoxon paired test p-value, the Cohen's d effect size and its interpretation.
|
||||
|
||||
# Report
|
||||
|
||||
To compile the report run:
|
||||
|
||||
```shell
|
||||
cd report
|
||||
pdflatex -interaction=nonstopmode -output-directory=. main.tex
|
||||
pdflatex -interaction=nonstopmode -output-directory=. main.tex
|
||||
```
|
||||
|
||||
The report is then located in `report/main.pdf`.
|
|
@ -9,8 +9,6 @@ import operators
|
|||
class Archive:
|
||||
true_branches: Dict[int, any]
|
||||
false_branches: Dict[int, any]
|
||||
false_score: Dict[int, any]
|
||||
true_score: Dict[int, any]
|
||||
f_name: str
|
||||
|
||||
def __init__(self, f_name: str) -> None:
|
||||
|
@ -20,8 +18,6 @@ class Archive:
|
|||
def reset(self):
|
||||
self.true_branches = {}
|
||||
self.false_branches = {}
|
||||
self.true_score = {}
|
||||
self.false_score = {}
|
||||
|
||||
def branches_covered(self) -> int:
|
||||
return len(self.true_branches.keys()) + len(self.false_branches.keys())
|
||||
|
@ -67,7 +63,4 @@ class Archive:
|
|||
branch not in self.false_branches):
|
||||
branches.append((branch, False))
|
||||
|
||||
if len(branches) > 0:
|
||||
print(list(test_case.items()), branches)
|
||||
|
||||
return branches
|
||||
|
|
61
fuzzer.py
61
fuzzer.py
|
@ -1,6 +1,7 @@
|
|||
import argparse
|
||||
import os
|
||||
from random import randrange, choice, random, sample, seed
|
||||
from random import randrange, choice, random, seed
|
||||
from typing import Tuple, Dict, List, Set, Callable
|
||||
|
||||
from frozendict import frozendict
|
||||
from tqdm import tqdm
|
||||
|
@ -10,7 +11,6 @@ import operators
|
|||
from archive import Archive
|
||||
from instrument import (Arg, Params, invoke, call_statement, BranchTransformer,
|
||||
module_of, load_benchmark, get_benchmark, functions)
|
||||
from typing import Tuple, Dict, List, Set, Callable
|
||||
|
||||
Range = Tuple[int, int]
|
||||
|
||||
|
@ -18,7 +18,7 @@ INT_RANGE: Range = (-1000, 1000)
|
|||
STRING_LEN_RANGE: Range = (0, 10)
|
||||
STRING_CHAR_RANGE: Range = (32, 127)
|
||||
POOL_SIZE: int = 1000
|
||||
FUZZER_REPS: int = 1000
|
||||
FUZZER_REPS: int = 250
|
||||
|
||||
OUT_DIR = os.path.join(os.path.dirname(__file__), "fuzzer_tests")
|
||||
|
||||
|
@ -102,10 +102,11 @@ def add_to_pool(arguments: List[Arg], params: Params):
|
|||
param_list: List[any] = [None] * len(arg_names)
|
||||
for i, name in enumerate(arg_names):
|
||||
param_list[i] = params[name]
|
||||
|
||||
pools[arg_types].add(tuple(param_list))
|
||||
|
||||
|
||||
def get_pool(arguments: List[Arg]) -> List[Params]:
|
||||
def extract_from_pool(arguments: List[Arg]) -> Params:
|
||||
arg_types = tuple([arg_type for _, arg_type in arguments])
|
||||
arg_names = [arg_name for arg_name, _ in arguments]
|
||||
|
||||
|
@ -124,13 +125,22 @@ def get_pool(arguments: List[Arg]) -> List[Params]:
|
|||
|
||||
pools[arg_types] = new_pool
|
||||
|
||||
return [frozendict({arg_names[i]: p for i, p in enumerate(param)}) for param in pools[arg_types]]
|
||||
i = randrange(0, len(pools[arg_types]))
|
||||
|
||||
for e in pools[arg_types]:
|
||||
if i == 0:
|
||||
return frozendict({arg_names[i]: p for i, p in enumerate(e)})
|
||||
i -= 1
|
||||
|
||||
raise RuntimeError("unreachable statement")
|
||||
|
||||
|
||||
def mutate(test_case: Params, arguments: List[Arg]) -> Params:
|
||||
arg_name = choice(list(test_case.keys())) # choose name to mutate
|
||||
types: Dict[str, str] = {arg_name: arg_type for arg_name, arg_type in arguments}
|
||||
return test_case.set(arg_name, random_mutate(types[arg_name], test_case[arg_name]))
|
||||
mutated = test_case.set(arg_name, random_mutate(types[arg_name], test_case[arg_name]))
|
||||
add_to_pool(arguments, mutated)
|
||||
return mutated
|
||||
|
||||
|
||||
def crossover(chosen_test: Params, other_chosen_test: Params, arguments: List[Arg]) -> Tuple[Params, Params]:
|
||||
|
@ -149,31 +159,12 @@ def crossover(chosen_test: Params, other_chosen_test: Params, arguments: List[Ar
|
|||
t1 = chosen_test.set(arg_name, i1)
|
||||
t2 = other_chosen_test.set(arg_name, i2)
|
||||
|
||||
add_to_pool(arguments, t1)
|
||||
add_to_pool(arguments, t2)
|
||||
|
||||
return t1, t2
|
||||
|
||||
|
||||
def generate_test_case(f_name: str, arguments: List[Arg], archive: Archive, bias_unseen=True) -> Params:
|
||||
pool: List[Params] = get_pool(arguments)
|
||||
|
||||
attempts = 20 # attempts to generate a random test that satisfies a new branch
|
||||
|
||||
while True:
|
||||
test = sample(pool, 1)[0]
|
||||
is_new = [] if not bias_unseen else archive.satisfies_unseen_branches(test)
|
||||
|
||||
attempts -= 1
|
||||
|
||||
if bias_unseen and len(is_new) == 0 and attempts > 0:
|
||||
# print(f"Not new: {test}")
|
||||
continue
|
||||
|
||||
try:
|
||||
invoke(f_name, test)
|
||||
return test # return only test cases that satisfy assertions
|
||||
except AssertionError:
|
||||
pass
|
||||
|
||||
|
||||
def str_crossover(parent1: str, parent2: str):
|
||||
if len(parent1) > 1 and len(parent2) > 1:
|
||||
pos = randrange(1, len(parent1))
|
||||
|
@ -218,13 +209,13 @@ def get_test_class(orig_f_name: str, cases: Set[Params]) -> str:
|
|||
"\n")
|
||||
|
||||
|
||||
def generate_tests(files: List[str], seed_num: int, generation_fn: Callable[[str], Set[Params]]):
|
||||
load_benchmark(save_instrumented=False, files=files)
|
||||
def generate_tests(files: List[str], seed_num: int, generation_fn: Callable[[str], Set[Params]], out_dir: str):
|
||||
load_benchmark(save_instrumented=False, files_count=files)
|
||||
seed(seed_num) # init random seed
|
||||
|
||||
for file_name, f_names in tqdm(get_benchmark().items(), desc="Generating tests"):
|
||||
suite = [(name, generation_fn(name)) for name in f_names]
|
||||
with open(os.path.join(OUT_DIR, f"test_{file_name}.py"), "w") as f:
|
||||
with open(os.path.join(out_dir, f"test_{file_name}.py"), "w") as f:
|
||||
f.write(get_test_import_stmt(f_names))
|
||||
f.write("\n\n")
|
||||
f.write("\n\n".join([get_test_class(name, cases) for name, cases in suite]))
|
||||
|
@ -237,19 +228,17 @@ def fuzzer_generate(f_name: str) -> Set[Params]:
|
|||
archive = Archive(instrumented)
|
||||
|
||||
for _ in tqdm(range(FUZZER_REPS), desc=f"fuzzer [{f_name}]"):
|
||||
test = generate_test_case(instrumented, args, archive, bias_unseen=False)
|
||||
test = extract_from_pool(args)
|
||||
|
||||
alteration_choice = randrange(3)
|
||||
if alteration_choice == 1:
|
||||
test = mutate(test, args)
|
||||
elif alteration_choice == 2:
|
||||
test2 = generate_test_case(instrumented, args, archive, bias_unseen=False)
|
||||
test2 = extract_from_pool(args)
|
||||
test, test2 = crossover(test, test2, args)
|
||||
archive.consider_test(test2)
|
||||
add_to_pool(args, test2)
|
||||
|
||||
archive.consider_test(test)
|
||||
add_to_pool(args, test)
|
||||
|
||||
return archive.build_suite()
|
||||
|
||||
|
@ -264,7 +253,7 @@ def main():
|
|||
nargs="?", default=0)
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_tests(args.file, args.seed, fuzzer_generate)
|
||||
generate_tests(args.file, args.seed, fuzzer_generate, OUT_DIR)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
,file,score
|
||||
0,anagram_check,23.1
|
||||
1,anagram_check,23.1
|
||||
2,anagram_check,23.1
|
||||
3,anagram_check,23.1
|
||||
4,anagram_check,23.1
|
||||
5,anagram_check,23.1
|
||||
6,anagram_check,23.1
|
||||
7,anagram_check,23.1
|
||||
8,anagram_check,23.1
|
||||
9,anagram_check,23.1
|
||||
10,caesar_cipher,58.8
|
||||
11,caesar_cipher,58.8
|
||||
12,caesar_cipher,58.8
|
||||
13,caesar_cipher,58.8
|
||||
14,caesar_cipher,58.8
|
||||
15,caesar_cipher,58.8
|
||||
16,caesar_cipher,58.8
|
||||
17,caesar_cipher,58.8
|
||||
18,caesar_cipher,58.8
|
||||
19,caesar_cipher,58.8
|
||||
20,check_armstrong,90.3
|
||||
21,check_armstrong,90.3
|
||||
22,check_armstrong,90.3
|
||||
23,check_armstrong,90.3
|
||||
24,check_armstrong,90.3
|
||||
25,check_armstrong,90.3
|
||||
26,check_armstrong,90.3
|
||||
27,check_armstrong,90.3
|
||||
28,check_armstrong,90.3
|
||||
29,check_armstrong,90.3
|
||||
30,common_divisor_count,72.3
|
||||
31,common_divisor_count,72.3
|
||||
32,common_divisor_count,72.3
|
||||
33,common_divisor_count,72.3
|
||||
34,common_divisor_count,72.3
|
||||
35,common_divisor_count,72.3
|
||||
36,common_divisor_count,72.3
|
||||
37,common_divisor_count,72.3
|
||||
38,common_divisor_count,72.3
|
||||
39,common_divisor_count,72.3
|
||||
40,exponentiation,71.4
|
||||
41,exponentiation,71.4
|
||||
42,exponentiation,71.4
|
||||
43,exponentiation,71.4
|
||||
44,exponentiation,71.4
|
||||
45,exponentiation,71.4
|
||||
46,exponentiation,71.4
|
||||
47,exponentiation,71.4
|
||||
48,exponentiation,71.4
|
||||
49,exponentiation,71.4
|
||||
50,gcd,47.8
|
||||
51,gcd,47.8
|
||||
52,gcd,47.8
|
||||
53,gcd,47.8
|
||||
54,gcd,47.8
|
||||
55,gcd,47.8
|
||||
56,gcd,47.8
|
||||
57,gcd,47.8
|
||||
58,gcd,47.8
|
||||
59,gcd,47.8
|
||||
60,longest_substring,82.6
|
||||
61,longest_substring,82.6
|
||||
62,longest_substring,82.6
|
||||
63,longest_substring,82.6
|
||||
64,longest_substring,82.6
|
||||
65,longest_substring,82.6
|
||||
66,longest_substring,82.6
|
||||
67,longest_substring,82.6
|
||||
68,longest_substring,82.6
|
||||
69,longest_substring,82.6
|
||||
70,rabin_karp,64.9
|
||||
71,rabin_karp,64.9
|
||||
72,rabin_karp,64.9
|
||||
73,rabin_karp,64.9
|
||||
74,rabin_karp,64.9
|
||||
75,rabin_karp,64.9
|
||||
76,rabin_karp,64.9
|
||||
77,rabin_karp,64.9
|
||||
78,rabin_karp,64.9
|
||||
79,rabin_karp,64.9
|
||||
80,railfence_cipher,89.4
|
||||
81,railfence_cipher,89.4
|
||||
82,railfence_cipher,89.4
|
||||
83,railfence_cipher,89.4
|
||||
84,railfence_cipher,89.4
|
||||
85,railfence_cipher,89.4
|
||||
86,railfence_cipher,89.4
|
||||
87,railfence_cipher,89.4
|
||||
88,railfence_cipher,89.4
|
||||
89,railfence_cipher,89.4
|
||||
90,zellers_birthday,68.3
|
||||
91,zellers_birthday,68.3
|
||||
92,zellers_birthday,68.3
|
||||
93,zellers_birthday,68.3
|
||||
94,zellers_birthday,68.3
|
||||
95,zellers_birthday,68.3
|
||||
96,zellers_birthday,68.3
|
||||
97,zellers_birthday,68.3
|
||||
98,zellers_birthday,68.3
|
||||
99,zellers_birthday,68.3
|
|
|
@ -3,22 +3,17 @@ from benchmark.anagram_check import anagram_check
|
|||
|
||||
|
||||
class Test_anagram_check(TestCase):
|
||||
# distances_true = {1: [8], 3: [0]}
|
||||
# distances_false = {1: [0], 3: [7]}
|
||||
# distances_true = {1: [0], 2: [0]}
|
||||
# distances_false = {1: [1], 2: [1]}
|
||||
def test_anagram_check_1(self):
|
||||
assert anagram_check(s1='gU(@sp?!<', s2='^$') == False
|
||||
assert anagram_check(s1='2', s2='K') == False
|
||||
|
||||
# distances_true = {1: [1], 3: [0]}
|
||||
# distances_false = {1: [0], 3: [1]}
|
||||
def test_anagram_check_2(self):
|
||||
assert anagram_check(s1='NW', s2='^') == False
|
||||
|
||||
# distances_true = {1: [2], 3: [1], 4: [3]}
|
||||
# distances_false = {1: [0], 3: [0], 4: [0]}
|
||||
def test_anagram_check_2(self):
|
||||
assert anagram_check(s1='N9)', s2='%;r') == False
|
||||
|
||||
# distances_true = {1: [0], 2: [0]}
|
||||
# distances_false = {1: [1], 2: [1]}
|
||||
def test_anagram_check_3(self):
|
||||
assert anagram_check(s1='j', s2='7') == False
|
||||
|
||||
# distances_true = {1: [0], 2: [2], 3: [0]}
|
||||
# distances_false = {1: [1], 2: [0], 3: [2]}
|
||||
def test_anagram_check_4(self):
|
||||
assert anagram_check(s1='i', s2='E y') == False
|
||||
assert anagram_check(s1='I@N', s2='}*9') == False
|
||||
|
|
|
@ -4,14 +4,14 @@ from benchmark.caesar_cipher import decrypt
|
|||
|
||||
|
||||
class Test_encrypt(TestCase):
|
||||
# distances_true = {1: [0, 6, 0, 10, 0, 0, 0, 0]}
|
||||
# distances_false = {1: [48, 0, 60, 0, 57, 30, 25, 47]}
|
||||
# distances_true = {1: [24, 61, 0, 0, 48, 5]}
|
||||
# distances_false = {1: [0, 0, 12, 18, 0, 0]}
|
||||
def test_encrypt_1(self):
|
||||
assert encrypt(strng='_*k&hMH^', key=79) == 'Oy[uX=8N'
|
||||
assert encrypt(strng='P+sy8c', key=23) == 'gB+1Oz'
|
||||
|
||||
|
||||
class Test_decrypt(TestCase):
|
||||
# distances_true = {2: [0, 0, 32, 0]}
|
||||
# distances_false = {2: [1, 12, 0, 24]}
|
||||
# distances_true = {2: [9, 0, 43, 25, 0, 8, 42]}
|
||||
# distances_false = {2: [0, 8, 0, 0, 5, 0, 0]}
|
||||
def test_decrypt_1(self):
|
||||
assert decrypt(strng='\\Q|E', key=61) == '~s?g'
|
||||
assert decrypt(strng='VFxfIUw', key=46) == "(wJ8z'I"
|
||||
|
|
|
@ -3,22 +3,17 @@ from benchmark.check_armstrong import check_armstrong
|
|||
|
||||
|
||||
class Test_check_armstrong(TestCase):
|
||||
# distances_true = {1: [583], 2: [582], 3: [433], 4: [0, 0, 0, 1], 5: [81]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [583, 58, 5, 0], 5: [0]}
|
||||
# distances_true = {1: [1], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_check_armstrong_1(self):
|
||||
assert check_armstrong(n=583) == False
|
||||
assert check_armstrong(n=1) == True
|
||||
|
||||
# distances_true = {1: [0]}
|
||||
# distances_false = {1: [1]}
|
||||
# distances_true = {1: [135], 2: [134], 3: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [16]}
|
||||
def test_check_armstrong_2(self):
|
||||
assert check_armstrong(n=0) == True
|
||||
assert check_armstrong(n=135) == False
|
||||
|
||||
# distances_true = {1: [153], 2: [152], 3: [3], 4: [0, 0, 0, 1], 5: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [153, 15, 1, 0], 5: [1]}
|
||||
# distances_true = {1: [307], 2: [306], 3: [157], 4: [0, 0, 0, 1], 5: [63]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [307, 30, 3, 0], 5: [0]}
|
||||
def test_check_armstrong_3(self):
|
||||
assert check_armstrong(n=153) == True
|
||||
|
||||
# distances_true = {1: [5], 2: [4], 3: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [146]}
|
||||
def test_check_armstrong_4(self):
|
||||
assert check_armstrong(n=5) == False
|
||||
assert check_armstrong(n=307) == False
|
||||
|
|
|
@ -3,17 +3,32 @@ from benchmark.common_divisor_count import cd_count
|
|||
|
||||
|
||||
class Test_cd_count(TestCase):
|
||||
# distances_true = {1: [180], 2: [450], 3: [0], 4: [451], 5: [0, 0, 1], 6: [0, 0, 0, 2, 0, 0, 6, 2, 0], 7: [89, 43, 27, 13, 9, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [180], 4: [0], 5: [180, 90, 0], 6: [1, 1, 1, 0, 1, 1, 0, 0, 1], 7: [0, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [301], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_cd_count_1(self):
|
||||
assert cd_count(a=-180, b=450) == 12
|
||||
assert cd_count(a=301, b=0) == 2
|
||||
|
||||
# distances_true = {1: [524], 2: [858], 3: [525], 4: [0], 5: [0, 0, 0, 0, 0, 0, 0, 0, 1], 6: [0], 7: [1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [858], 5: [524, 334, 190, 144, 46, 6, 4, 2, 0], 6: [1], 7: [0]}
|
||||
# distances_true = {1: [28], 2: [7], 3: [29], 4: [8], 5: [0, 0, 1], 6: [0, 1], 7: [6]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [28, 7, 0], 6: [1, 0], 7: [0]}
|
||||
def test_cd_count_2(self):
|
||||
assert cd_count(a=524, b=-858) == 2
|
||||
assert cd_count(a=28, b=7) == 2
|
||||
|
||||
# distances_true = {1: [171], 2: [880], 3: [0], 4: [881], 5: [0, 0, 0, 0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [171], 4: [0], 5: [171, 25, 21, 4, 1, 0], 6: [1], 7: [1]}
|
||||
# distances_true = {1: [153], 2: [2], 3: [154], 4: [3], 5: [0, 0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [153, 2, 1, 0], 6: [1], 7: [1]}
|
||||
def test_cd_count_3(self):
|
||||
assert cd_count(a=-171, b=880) == 1
|
||||
assert cd_count(a=153, b=2) == 1
|
||||
|
||||
# distances_true = {1: [502], 2: [178], 3: [503], 4: [179], 5: [0, 0, 0, 0, 0, 0, 0, 0, 1], 6: [0], 7: [1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [502, 178, 146, 32, 18, 14, 4, 2, 0], 6: [1], 7: [0]}
|
||||
def test_cd_count_4(self):
|
||||
assert cd_count(a=502, b=178) == 2
|
||||
|
||||
# distances_true = {1: [0]}
|
||||
# distances_false = {1: [1]}
|
||||
def test_cd_count_5(self):
|
||||
assert cd_count(a=0, b=904) == 2
|
||||
|
||||
# distances_true = {1: [443], 2: [6], 3: [0], 4: [0], 5: [0, 0, 0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [443], 4: [6], 5: [443, 6, 5, 1, 0], 6: [1], 7: [1]}
|
||||
def test_cd_count_6(self):
|
||||
assert cd_count(a=-443, b=-6) == 1
|
||||
|
|
|
@ -3,7 +3,7 @@ from benchmark.exponentiation import exponentiation
|
|||
|
||||
|
||||
class Test_exponentiation(TestCase):
|
||||
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 2: [1, 1, 0, 0, 0, 1, 0, 0, 0]}
|
||||
# distances_false = {1: [630, 314, 156, 77, 38, 18, 8, 3, 1, 0], 3: [1], 2: [0, 0, 1, 1, 1, 0, 1, 1, 1]}
|
||||
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 2: [0, 1, 0, 1, 1, 1, 1, 1, 0]}
|
||||
# distances_false = {1: [832, 415, 207, 103, 51, 25, 12, 5, 2, 0], 3: [1], 2: [1, 0, 1, 0, 0, 0, 0, 0, 1]}
|
||||
def test_exponentiation_1(self):
|
||||
assert exponentiation(baseNumber=229, power=631) == 11381234101445775753511392015341744682588570986102224039390720285077899169674568038197326342940064901244177560842841924371421802587044521315773772186187547659830685455568537528049212994980159679816838690878596437635556336390603217974843590523706585633093363478766247718669151124253597924271460074695331123030002477672470888683820892451691712794240150714666068396254837851712428304279437706402840278841022427798845642299620119122197582242489041676042030717852031723255821528213497142055551145575663634990077305256845727132894737670148720272258452398194448015830799903170149287684706972565823541486622411136605841318617521051177682587295876588617192583199512651351936677507861660939730278101046178558162552821556410557719089125378645170386340572632243077354907575845913647147461310394166725741203050654294205855227960718731811784697401084780988753863828019215023964034022075473428520603004040086437560944507735374937837026821029527152268670187574842115160681136501433596553090081291095916580753660680615454664168228698567169031280782756475821551196582762941080904807113833394318850338264484961526692224500757025151325286773628959521989541968478235125022809094655704670640668124923174654970259046198975073787375738402994461267901157313580710146722768111601235186132446805107849024669181014876768249128669364324993951100257739165644330717095953945583658926347402457474225454535689578418160695265405822296417373349554757877558059686302770208714142534097327460841575601330771335995265872402591629
|
||||
assert exponentiation(baseNumber=-6, power=833) == -1584862427176646441032581448163502056522304714791688863077680763401594759422056202480618372145524894456151986289670118768654538337866053263611922000599918608949612484758034859452586327393651279190541552669586881048781584189639428134027926187502542805755360587303203758250141709609935145755270362171617090607605771330425353289800694836743426874185222171194524983577694492237864072603517346560417482797868100221342243559501229220749459182746246997902149679964895722044423357661248125544267360836746288616059898701793481334662209049986346281366837693465240393495058780389499730155312477987604559702499972667524745974854042821278371009362182850127855616
|
||||
|
|
|
@ -3,12 +3,27 @@ from benchmark.gcd import gcd
|
|||
|
||||
|
||||
class Test_gcd(TestCase):
|
||||
# distances_true = {1: [182], 2: [931], 3: [749], 4: [0], 5: [0, 0, 0, 0, 0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [749], 5: [183, 17, 13, 4, 1, 0]}
|
||||
# distances_true = {1: [0]}
|
||||
# distances_false = {1: [1]}
|
||||
def test_gcd_1(self):
|
||||
assert gcd(a=183, b=932) == 1
|
||||
assert gcd(a=1, b=751) == 1
|
||||
|
||||
# distances_true = {1: [720], 2: [503], 3: [217], 4: [218], 5: [0, 0, 0, 0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [504, 217, 70, 7, 0]}
|
||||
# distances_true = {1: [964], 2: [964], 3: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [1]}
|
||||
def test_gcd_2(self):
|
||||
assert gcd(a=721, b=504) == 7
|
||||
assert gcd(a=965, b=965) == 965
|
||||
|
||||
# distances_true = {1: [700], 2: [440], 3: [260], 4: [261], 5: [0, 0, 0, 0, 0, 0, 0, 0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [441, 260, 181, 79, 23, 10, 3, 1, 0]}
|
||||
def test_gcd_3(self):
|
||||
assert gcd(a=701, b=441) == 1
|
||||
|
||||
# distances_true = {1: [941], 2: [944], 3: [3], 4: [0], 5: [0, 0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [3], 5: [942, 3, 0]}
|
||||
def test_gcd_4(self):
|
||||
assert gcd(a=942, b=945) == 3
|
||||
|
||||
# distances_true = {1: [354], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_gcd_5(self):
|
||||
assert gcd(a=355, b=1) == 1
|
||||
|
|
|
@ -3,12 +3,7 @@ from benchmark.longest_substring import longest_sorted_substr
|
|||
|
||||
|
||||
class Test_longest_sorted_substr(TestCase):
|
||||
# distances_true = {1: [5, 0, 56, 0, 81, 0, 0], 2: [0, 1, 1, 0]}
|
||||
# distances_false = {1: [0, 38, 0, 86, 0, 5, 57], 2: [1, 0, 0, 1]}
|
||||
# distances_true = {1: [0, 17, 12, 17, 0, 47, 10, 0], 2: [0, 1, 1]}
|
||||
# distances_false = {1: [12, 0, 0, 0, 42, 0, 0, 3], 2: [1, 0, 0]}
|
||||
def test_longest_sorted_substr_1(self):
|
||||
assert longest_sorted_substr(s='<7\\$y(,d') == '(,d'
|
||||
|
||||
# distances_true = {1: [29, 2, 0, 50], 2: [0]}
|
||||
# distances_false = {1: [0, 0, 35, 0], 2: [1]}
|
||||
def test_longest_sorted_substr_2(self):
|
||||
assert longest_sorted_substr(s='Q42T"') == '2T'
|
||||
assert longest_sorted_substr(s='\\gVJ9b3)+') == '\\g'
|
||||
|
|
|
@ -3,22 +3,12 @@ from benchmark.rabin_karp import rabin_karp_search
|
|||
|
||||
|
||||
class Test_rabin_karp_search(TestCase):
|
||||
# distances_true = {1: [0, 70, 54, 65, 28, 51, 66], 3: [1], 4: [0, 0, 0, 0, 0, 0, 1], 5: [71, 55, 66, 29, 52, 67]}
|
||||
# distances_false = {1: [1, 0, 0, 0, 0, 0, 0], 3: [0], 4: [6, 5, 4, 3, 2, 1, 0], 5: [0, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [69, 86], 4: [0, 1], 5: [15]}
|
||||
# distances_false = {1: [0, 0], 4: [1, 0], 5: [0]}
|
||||
def test_rabin_karp_search_1(self):
|
||||
assert rabin_karp_search(pat='', txt=']vzK<k') == []
|
||||
assert rabin_karp_search(pat='Hi', txt=';Wd') == []
|
||||
|
||||
# distances_true = {1: [43, 0, 35, 7, 61], 4: [0, 0, 0, 0, 1], 5: [62, 27, 69, 1], 2: [0], 3: [2]}
|
||||
# distances_false = {1: [0, 1, 0, 0, 0], 4: [4, 3, 2, 1, 0], 5: [0, 0, 0, 0], 2: [53], 3: [0]}
|
||||
# distances_true = {1: [53, 0], 4: [0, 1], 5: [94], 2: [0], 3: [1]}
|
||||
# distances_false = {1: [0, 1], 4: [1, 0], 5: [0], 2: [47], 3: [0]}
|
||||
def test_rabin_karp_search_2(self):
|
||||
assert rabin_karp_search(pat='z+e', txt=':EQBa9M') == []
|
||||
|
||||
# distances_true = {1: [50, 61, 64, 66, 16, 14, 66], 4: [0, 0, 0, 0, 0, 0, 1], 5: [16, 13, 11, 93, 63, 11]}
|
||||
# distances_false = {1: [0, 0, 0, 0, 0, 0, 0], 4: [6, 5, 4, 3, 2, 1, 0], 5: [0, 0, 0, 0, 0, 0]}
|
||||
def test_rabin_karp_search_3(self):
|
||||
assert rabin_karp_search(pat='f)', txt='^E}QhXq_') == []
|
||||
|
||||
# distances_true = {1: [14, 24, 0, 29, 5, 70, 55], 4: [0, 0, 0, 0, 0, 0, 1], 5: [65, 89, 60, 84, 19, 34], 2: [1], 3: [0]}
|
||||
# distances_false = {1: [0, 0, 1, 0, 0, 0, 0], 4: [6, 5, 4, 3, 2, 1, 0], 5: [0, 0, 0, 0, 0, 0], 2: [0], 3: [1]}
|
||||
def test_rabin_karp_search_4(self):
|
||||
assert rabin_karp_search(pat='X', txt='J@X;Sw!') == [2]
|
||||
assert rabin_karp_search(pat='+g', txt='rZJ') == []
|
||||
|
|
|
@ -4,34 +4,24 @@ from benchmark.railfence_cipher import raildecrypt
|
|||
|
||||
|
||||
class Test_railencrypt(TestCase):
|
||||
# distances_true = {1: [0], 2: [944], 4: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
|
||||
# distances_false = {1: [1], 2: [0], 4: [125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [0, 0, 0, 0, 1, 1, 1, 0], 2: [3, 2, 1, 0, 2], 3: [2, 1, 0], 4: [0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1]}
|
||||
# distances_false = {1: [1, 1, 1, 1, 0, 0, 0, 1], 2: [0, 0, 0, 1, 0], 3: [0, 0, 1], 4: [106, 0, 0, 0, 0, 0, 38, 0, 0, 57, 0, 0, 0, 77, 0, 32, 0, 0, 41, 0, 108, 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 0]}
|
||||
def test_railencrypt_1(self):
|
||||
assert railencrypt(st='}', k=945) == '}'
|
||||
assert railencrypt(st='j9)wlM& ', k=4) == 'j&9M )lw'
|
||||
|
||||
# distances_true = {1: [0, 0, 0, 0, 1, 1, 1, 0, 0], 2: [3, 2, 1, 0, 2, 1], 3: [2, 1, 0], 4: [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1]}
|
||||
# distances_false = {1: [1, 1, 1, 1, 0, 0, 0, 1, 1], 2: [0, 0, 0, 1, 0, 0], 3: [0, 0, 1], 4: [45, 0, 0, 0, 0, 0, 71, 0, 0, 0, 66, 0, 0, 0, 104, 0, 70, 0, 0, 0, 61, 0, 54, 0, 0, 0, 36, 0, 0, 0, 57, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0], 2: [61, 60, 59, 58, 57, 56, 55, 54], 4: [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
|
||||
# distances_false = {1: [1, 1, 1, 1, 1, 1, 1, 1], 2: [0, 0, 0, 0, 0, 0, 0, 0], 4: [34, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
|
||||
def test_railencrypt_2(self):
|
||||
assert railencrypt(st='-B=96hGF$', k=4) == '-GBhF=6$9'
|
||||
|
||||
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 1], 2: [7, 6, 5, 4, 3, 2, 1, 0], 3: [6], 4: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1]}
|
||||
# distances_false = {1: [1, 1, 1, 1, 1, 1, 1, 1, 0], 2: [0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 4: [119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 122, 0, 0, 0, 0, 0, 0, 0, 72, 0]}
|
||||
def test_railencrypt_3(self):
|
||||
assert railencrypt(st='w[*]^=kHz', k=8) == 'w[*]^=kzH'
|
||||
assert railencrypt(st='"Q z <wC', k=62) == '"Q z <wC'
|
||||
|
||||
|
||||
class Test_raildecrypt(TestCase):
|
||||
# distances_true = {5: [0, 0, 0, 0, 0, 0, 0, 0, 0], 6: [43, 42, 41, 40, 39, 38, 37, 36, 35], 8: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 9: [0, 0, 0, 0, 0, 0, 0, 0, 0], 10: [9, 0, 0, 0, 0, 0, 0, 0, 0], 12: [0], 11: [42, 41, 40, 39, 38, 37, 36, 35]}
|
||||
# distances_false = {5: [1, 1, 1, 1, 1, 1, 1, 1, 1], 6: [0, 0, 0, 0, 0, 0, 0, 0, 0], 8: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 9: [73, 68, 91, 120, 37, 34, 41, 61, 107], 10: [0, 1, 1, 1, 1, 1, 1, 1, 1], 12: [1], 11: [0, 0, 0, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {5: [0, 0, 0, 1, 1, 0, 0], 6: [2, 1, 0, 1, 0], 7: [1, 0], 8: [0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0], 9: [0, 0, 0, 0, 0, 0, 0], 10: [7, 0, 0, 1, 1, 0, 0], 12: [0, 1, 0], 11: [1, 0, 1, 0]}
|
||||
# distances_false = {5: [1, 1, 1, 0, 0, 1, 1], 6: [0, 0, 1, 0, 1], 7: [0, 1], 8: [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], 9: [80, 119, 85, 119, 33, 102, 116], 10: [0, 1, 1, 0, 0, 1, 1], 12: [1, 0, 1], 11: [0, 1, 0, 1]}
|
||||
def test_raildecrypt_1(self):
|
||||
assert raildecrypt(st='ID[x%")=k', k=44) == 'ID[x%")=k'
|
||||
assert raildecrypt(st='P!wwfUt', k=3) == 'PwUw!ft'
|
||||
|
||||
# distances_true = {5: [0, 0, 0, 0, 1, 1, 1, 0, 0], 6: [3, 2, 1, 0, 2, 1], 7: [2, 1, 0], 8: [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1], 9: [0, 0, 0, 0, 0, 0, 0, 0, 0], 10: [9, 0, 0, 0, 1, 1, 1, 0, 0], 12: [0, 2, 1, 0], 11: [2, 1, 0, 2, 1]}
|
||||
# distances_false = {5: [1, 1, 1, 1, 0, 0, 0, 1, 1], 6: [0, 0, 0, 1, 0, 0], 7: [0, 0, 1], 8: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], 9: [45, 61, 104, 36, 71, 57, 66, 54, 70], 10: [0, 1, 1, 1, 0, 0, 0, 1, 1], 12: [1, 0, 0, 1], 11: [0, 0, 1, 0, 0]}
|
||||
# distances_true = {5: [0], 6: [365], 8: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 9: [0], 10: [1], 12: [0]}
|
||||
# distances_false = {5: [1], 6: [0], 8: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 9: [88], 10: [0], 12: [1]}
|
||||
def test_raildecrypt_2(self):
|
||||
assert raildecrypt(st='-B=96hGF$', k=4) == '-=h$G9B6F'
|
||||
|
||||
# distances_true = {5: [0, 0, 0, 0, 0, 0, 1, 1], 6: [5, 4, 3, 2, 1, 0], 7: [4, 3], 8: [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1], 9: [0, 0, 0, 0, 0, 0, 0, 0], 10: [8, 0, 0, 0, 0, 0, 1, 1], 12: [0, 4, 3], 11: [4, 3, 2, 1, 0]}
|
||||
# distances_false = {5: [1, 1, 1, 1, 1, 1, 0, 0], 6: [0, 0, 0, 0, 0, 1], 7: [0, 0], 8: [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], 9: [51, 99, 79, 96, 77, 65, 72, 104], 10: [0, 1, 1, 1, 1, 1, 0, 0], 12: [1, 0, 0], 11: [0, 0, 0, 0, 1]}
|
||||
def test_raildecrypt_3(self):
|
||||
assert raildecrypt(st='3cO`hMHA', k=6) == '3cO`MAHh'
|
||||
assert raildecrypt(st='X', k=366) == 'X'
|
||||
|
|
|
@ -3,22 +3,32 @@ from benchmark.zellers_birthday import zeller
|
|||
|
||||
|
||||
class Test_zeller(TestCase):
|
||||
# distances_true = {1: [6], 2: [0], 3: [0], 4: [7], 5: [0], 6: [0], 7: [0], 8: [2, 1, 0]}
|
||||
# distances_false = {1: [0], 2: [121], 3: [71], 4: [0], 5: [71], 6: [7], 7: [1], 8: [0, 0, 1]}
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1923], 7: [0], 8: [2, 1, 0]}
|
||||
# distances_false = {1: [214], 2: [49], 3: [78], 4: [1], 5: [0], 7: [1], 8: [0, 0, 1]}
|
||||
def test_zeller_1(self):
|
||||
assert zeller(d=-26, m=133, y=29) == 'Tuesday'
|
||||
assert zeller(d=245, m=-61, y=-22) == 'Tuesday'
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1904], 7: [3], 8: [6, 5, 4, 3, 2, 1, 0]}
|
||||
# distances_false = {1: [929], 2: [304], 3: [97], 4: [20], 5: [0], 7: [0], 8: [0, 0, 0, 0, 0, 0, 1]}
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1916], 7: [9], 8: [5, 4, 3, 2, 1, 0]}
|
||||
# distances_false = {1: [601], 2: [838], 3: [85], 4: [8], 5: [0], 7: [0], 8: [0, 0, 0, 0, 0, 1]}
|
||||
def test_zeller_2(self):
|
||||
assert zeller(d=960, m=-316, y=-3) == 'Saturday'
|
||||
assert zeller(d=-632, m=-850, y=15) == 'Friday'
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [74], 5: [0], 6: [0], 7: [0], 8: [3, 2, 1, 0]}
|
||||
# distances_false = {1: [932], 2: [552], 3: [4], 4: [0], 5: [4], 6: [74], 7: [2], 8: [0, 0, 0, 1]}
|
||||
# distances_true = {1: [5], 2: [0], 3: [0], 4: [9], 5: [0], 6: [0], 7: [10], 8: [0]}
|
||||
# distances_false = {1: [0], 2: [47], 3: [69], 4: [0], 5: [69], 6: [9], 7: [0], 8: [1]}
|
||||
def test_zeller_3(self):
|
||||
assert zeller(d=963, m=-564, y=96) == 'Wednesday'
|
||||
assert zeller(d=-27, m=-59, y=-31) == 'Sunday'
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [58], 5: [0], 6: [0], 7: [3], 8: [3, 2, 1, 0]}
|
||||
# distances_false = {1: [492], 2: [988], 3: [20], 4: [0], 5: [20], 6: [58], 7: [0], 8: [0, 0, 0, 1]}
|
||||
# distances_true = {1: [0], 2: [6], 3: [0], 4: [0], 5: [1915], 7: [5], 8: [5, 4, 3, 2, 1, 0]}
|
||||
# distances_false = {1: [885], 2: [0], 3: [86], 4: [9], 5: [0], 7: [0], 8: [0, 0, 0, 0, 0, 1]}
|
||||
def test_zeller_4(self):
|
||||
assert zeller(d=-523, m=-1000, y=80) == 'Wednesday'
|
||||
assert zeller(d=916, m=7, y=-14) == 'Friday'
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1923], 7: [8], 8: [0]}
|
||||
# distances_false = {1: [256], 2: [21], 3: [78], 4: [1], 5: [0], 7: [0], 8: [1]}
|
||||
def test_zeller_5(self):
|
||||
assert zeller(d=287, m=-33, y=-22) == 'Sunday'
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [5], 5: [0], 6: [0], 7: [4], 8: [0]}
|
||||
# distances_false = {1: [18], 2: [41], 3: [73], 4: [0], 5: [73], 6: [5], 7: [0], 8: [1]}
|
||||
def test_zeller_6(self):
|
||||
assert zeller(d=-49, m=-53, y=-27) == 'Sunday'
|
||||
|
|
31
genetic.py
31
genetic.py
|
@ -1,25 +1,22 @@
|
|||
import argparse
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
from functools import partial
|
||||
from typing import Tuple, List, Set
|
||||
from typing import Tuple, Set
|
||||
|
||||
import frozendict
|
||||
import tqdm
|
||||
from deap import creator, base, tools, algorithms
|
||||
|
||||
import fuzzer
|
||||
import instrument
|
||||
import operators
|
||||
from fuzzer import generate_test_case, get_test_class
|
||||
from archive import Archive
|
||||
|
||||
INDMUPROB = 0.05
|
||||
MUPROB = 0.33
|
||||
CXPROB = 0.33
|
||||
TOURNSIZE = 3
|
||||
NPOP = 1000
|
||||
NGEN = 200
|
||||
NPOP = 200
|
||||
NGEN = 20
|
||||
REPS = 10
|
||||
|
||||
OUT_DIR = os.path.join(os.path.dirname(__file__), "tests")
|
||||
|
@ -43,7 +40,7 @@ def generate(orig_name: str) -> Set[instrument.Params]:
|
|||
archive = Archive(f_name)
|
||||
|
||||
toolbox = base.Toolbox()
|
||||
toolbox.register("attr_test_case", lambda: list(generate_test_case(f_name, args, archive).items()))
|
||||
toolbox.register("attr_test_case", lambda: list(fuzzer.extract_from_pool(args).items()))
|
||||
toolbox.register("individual", tools.initIterate, creator.Individual, lambda: toolbox.attr_test_case())
|
||||
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
||||
toolbox.register("evaluate", partial(compute_fitness, f_name, archive))
|
||||
|
@ -52,12 +49,14 @@ def generate(orig_name: str) -> Set[instrument.Params]:
|
|||
t1, t2 = frozendict.frozendict(tc1), frozendict.frozendict(tc2)
|
||||
o1, o2 = fuzzer.crossover(t1, t2, args)
|
||||
i1, i2 = creator.Individual(o1.items()), creator.Individual(o2.items())
|
||||
# print("mate", tc1, tc2, i1, i2)
|
||||
return i1, i2
|
||||
|
||||
def mutate(tc):
|
||||
t = frozendict.frozendict(tc)
|
||||
o = fuzzer.mutate(t, args)
|
||||
i1 = creator.Individual(o.items())
|
||||
# print("mutate", tc, i1)
|
||||
return i1,
|
||||
|
||||
toolbox.register("mate", mate)
|
||||
|
@ -102,10 +101,11 @@ def compute_fitness(f_name: str, archive: Archive, individual: list) -> Tuple[fl
|
|||
try:
|
||||
out = instrument.invoke(f_name, x)
|
||||
except AssertionError:
|
||||
# print(f_name, x, "=", "[FAILS] fitness = 100.0")
|
||||
return 100.0,
|
||||
# print(f_name, x, "=", "[FAILS] fitness = inf")
|
||||
return math.inf,
|
||||
|
||||
fitness = 0.0
|
||||
no_branches_hit = True
|
||||
|
||||
# Sum up branch distances
|
||||
for branch in range(range_start, range_end):
|
||||
|
@ -113,14 +113,19 @@ def compute_fitness(f_name: str, archive: Archive, individual: list) -> Tuple[fl
|
|||
if branch not in archive.true_branches:
|
||||
fitness += normalize(operators.distances_true[branch])
|
||||
else:
|
||||
fitness += 10
|
||||
fitness += 2
|
||||
no_branches_hit = False
|
||||
|
||||
for branch in range(range_start, range_end):
|
||||
if branch in operators.distances_false:
|
||||
if branch not in archive.false_branches:
|
||||
fitness += normalize(operators.distances_false[branch])
|
||||
else:
|
||||
fitness += 10
|
||||
fitness += 2
|
||||
no_branches_hit = False
|
||||
|
||||
if no_branches_hit:
|
||||
fitness = 1000000
|
||||
|
||||
# print(f_name, x, "=", out, "fitness =", fitness)
|
||||
return fitness,
|
||||
|
@ -137,7 +142,7 @@ def main():
|
|||
args = parser.parse_args()
|
||||
|
||||
init_deap()
|
||||
fuzzer.generate_tests(args.file, args.seed, generate)
|
||||
fuzzer.generate_tests(args.file, args.seed, generate, OUT_DIR)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -6,6 +6,7 @@ from typing import Optional, Dict, DefaultDict, Tuple, List
|
|||
|
||||
import astunparse
|
||||
import frozendict
|
||||
import pandas as pd
|
||||
import tqdm
|
||||
|
||||
import operators
|
||||
|
@ -23,6 +24,7 @@ class BranchTransformer(ast.NodeTransformer):
|
|||
instrumented_name: Optional[str]
|
||||
in_assert: bool
|
||||
in_return: bool
|
||||
function_nodes: int
|
||||
|
||||
def __init__(self):
|
||||
self.branch_num = 0
|
||||
|
@ -30,6 +32,7 @@ class BranchTransformer(ast.NodeTransformer):
|
|||
self.in_assert = False
|
||||
self.in_return = False
|
||||
self.branches_range = {}
|
||||
self.function_nodes = 0
|
||||
|
||||
@staticmethod
|
||||
def to_instrumented_name(name: str):
|
||||
|
@ -53,6 +56,7 @@ class BranchTransformer(ast.NodeTransformer):
|
|||
return ast_node
|
||||
|
||||
def visit_FunctionDef(self, ast_node):
|
||||
self.function_nodes += 1
|
||||
self.instrumented_name = ast_node.name
|
||||
b_start = self.branch_num
|
||||
ast_node.name = BranchTransformer.to_instrumented_name(ast_node.name)
|
||||
|
@ -83,7 +87,7 @@ class BranchTransformer(ast.NodeTransformer):
|
|||
|
||||
ArgType = str
|
||||
Arg = Tuple[str, ArgType]
|
||||
Params = frozendict.frozendict[str, any]
|
||||
Params = 'frozendict.frozendict[str, any]'
|
||||
SignatureDict = Dict[str, List[Arg]]
|
||||
|
||||
n_of_branches: Dict[str, Tuple[int, int]] = {}
|
||||
|
@ -91,7 +95,7 @@ functions: SignatureDict = {}
|
|||
module_of: Dict[str, List[str]] = {}
|
||||
|
||||
|
||||
def instrument(source_path: str, target_path: str, save_instrumented=True):
|
||||
def instrument(source_path: str, target_path: str, save_instrumented=True) -> Tuple[int, int]:
|
||||
global functions, n_of_branches
|
||||
|
||||
with open(source_path, "r") as f:
|
||||
|
@ -102,6 +106,9 @@ def instrument(source_path: str, target_path: str, save_instrumented=True):
|
|||
b = BranchTransformer()
|
||||
b.visit(node)
|
||||
|
||||
functions_found = b.function_nodes
|
||||
conditions_found = b.branch_num - 1
|
||||
|
||||
for f_name, limits in b.branches_range.items():
|
||||
n_of_branches[f_name] = limits
|
||||
|
||||
|
@ -132,6 +139,8 @@ def instrument(source_path: str, target_path: str, save_instrumented=True):
|
|||
functions[f.name] = arg_types
|
||||
module_of[f.name] = os.path.splitext(os.path.normpath(os.path.relpath(source_path, ROOT_DIR)))[0].split("/")
|
||||
|
||||
return functions_found, conditions_found
|
||||
|
||||
|
||||
def invoke(f_name: str, f_args: Params) -> any:
|
||||
global functions
|
||||
|
@ -159,14 +168,24 @@ def find_py_files(search_dir: str):
|
|||
yield os.path.join(cwd, file)
|
||||
|
||||
|
||||
def load_benchmark(save_instrumented=True, files: List[str] = ()):
|
||||
to_load = set([os.path.splitext(os.path.basename(file))[0] + ".py" for file in files])
|
||||
def load_benchmark(save_instrumented=True, files_count: List[str] = ()) -> Tuple[int, int, int]:
|
||||
to_load = set([os.path.splitext(os.path.basename(file))[0] + ".py" for file in files_count])
|
||||
do_all = len(to_load) == 0
|
||||
|
||||
files_count = 0
|
||||
functions_count = 0
|
||||
conditions_count = 0
|
||||
|
||||
for file in tqdm.tqdm(find_py_files(IN_DIR), desc="Instrumenting"):
|
||||
filename = os.path.basename(file)
|
||||
if do_all or filename in to_load:
|
||||
instrument(file, os.path.join(OUT_DIR, filename), save_instrumented=save_instrumented)
|
||||
fs, cs = instrument(file, os.path.join(OUT_DIR, filename), save_instrumented=save_instrumented)
|
||||
|
||||
files_count += 1
|
||||
functions_count += fs
|
||||
conditions_count += cs
|
||||
|
||||
return files_count, functions_count, conditions_count
|
||||
|
||||
|
||||
def call_statement(f_name: str, f_args: Params) -> str:
|
||||
|
@ -191,5 +210,15 @@ def get_benchmark() -> Dict[str, List[str]]:
|
|||
return dict(names)
|
||||
|
||||
|
||||
def main():
|
||||
files_count, functions_count, conditions_count = load_benchmark(save_instrumented=True)
|
||||
df = pd.DataFrame.from_records([
|
||||
{'Type': 'Python Files', 'Number': files_count},
|
||||
{'Type': 'Function Nodes', 'Number': functions_count},
|
||||
{'Type': 'Comparison Nodes', 'Number': conditions_count},
|
||||
])
|
||||
print(df.to_latex(index=False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
load_benchmark(save_instrumented=True)
|
||||
main()
|
||||
|
|
123
muttest.py
123
muttest.py
|
@ -1,52 +1,147 @@
|
|||
import math
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import List, Dict
|
||||
from math import sqrt
|
||||
from statistics import mean, variance
|
||||
from typing import List, Dict, Callable, Set
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
import seaborn as sns
|
||||
from scipy.stats import wilcoxon
|
||||
from tqdm import tqdm
|
||||
|
||||
import genetic
|
||||
from fuzzer import generate_tests, fuzzer_generate
|
||||
from instrument import Params
|
||||
|
||||
ROOT_DIR = os.path.dirname(__file__)
|
||||
IN_SOURCE_DIR = os.path.join(ROOT_DIR, "benchmark")
|
||||
IN_TEST_DIR = os.path.join(ROOT_DIR, "tests")
|
||||
IN_FUZZER_TEST_DIR = os.path.join(ROOT_DIR, "fuzzer_tests")
|
||||
OUT_DIR = os.path.join(ROOT_DIR, "out")
|
||||
MUT_PY_PATH = os.path.join(ROOT_DIR, 'env37', 'bin', 'mut.py')
|
||||
REPS: int = 10
|
||||
|
||||
|
||||
def cohen_d(d1: List[float], d2: List[float]) -> float:
|
||||
pooled_sd = sqrt(((len(d1) - 1) * variance(d1) + (len(d2) - 1) * variance(d2)) /
|
||||
(len(d1) + len(d2) - 2))
|
||||
|
||||
if pooled_sd == 0:
|
||||
return math.inf
|
||||
|
||||
return (mean(d1) - mean(d2)) / pooled_sd
|
||||
|
||||
|
||||
def effect_size(eff: float) -> str:
|
||||
eff = abs(eff)
|
||||
if eff <= 0.01:
|
||||
return 'Very small'
|
||||
elif eff <= 0.2:
|
||||
return 'Small'
|
||||
elif eff <= 0.5:
|
||||
return 'Medium'
|
||||
elif eff <= 0.8:
|
||||
return 'Large'
|
||||
elif eff <= 1.2:
|
||||
return 'Very large'
|
||||
else:
|
||||
return 'Huge'
|
||||
|
||||
|
||||
def compute_stats(df_gen: pd.DataFrame, df_fuz: pd.DataFrame, output_file: str, avg_output_file: str, stat_csv: str):
|
||||
combined_df = pd.concat([df_gen, df_fuz], keys=["genetic", "fuzzer"]).reset_index()
|
||||
combined_df.columns = ['source', *combined_df.columns[1:]]
|
||||
del combined_df[combined_df.columns[1]]
|
||||
|
||||
combined_df = combined_df.sort_values(['source', 'file'])
|
||||
|
||||
plt.figure(figsize=(10, 6))
|
||||
sns.set(style="whitegrid")
|
||||
sns.boxplot(data=combined_df, x="file", y="score", hue="source")
|
||||
plt.yticks(range(0, 101, 10))
|
||||
plt.xticks(rotation=45)
|
||||
plt.tight_layout()
|
||||
plt.savefig(output_file)
|
||||
|
||||
plt.figure(figsize=(10, 6))
|
||||
df_avg = combined_df.groupby(['file', 'source']).mean().reset_index().sort_values(['source', 'file'])
|
||||
sns.set(style="whitegrid")
|
||||
sns.barplot(data=df_avg, x="file", y="score", hue="source")
|
||||
plt.yticks(range(0, 101, 10))
|
||||
plt.xticks(rotation=45)
|
||||
plt.tight_layout()
|
||||
plt.savefig(avg_output_file)
|
||||
|
||||
df_avg = df_avg.pivot(index='file', columns='source', values='score').rename_axis(None, axis=1)
|
||||
df_avg['cohen-d'] = [math.nan] * len(df_avg.index)
|
||||
df_avg['interpretation'] = [math.nan] * len(df_avg.index)
|
||||
df_avg['wilcoxon'] = [math.nan] * len(df_avg.index)
|
||||
|
||||
for f in combined_df['file'].drop_duplicates():
|
||||
list_gen = df_gen.loc[(df_gen.file == f), 'score'].tolist()
|
||||
list_fuz = df_fuz.loc[(df_fuz.file == f), 'score'].tolist()
|
||||
|
||||
df_avg.loc[f, 'cohen-d'] = cohen_d(list_gen, list_fuz)
|
||||
df_avg.loc[f, 'interpretation'] = effect_size(df_avg.loc[f, 'cohen-d'])
|
||||
df_avg.loc[f, 'wilcoxon'] = wilcoxon(list_gen, list_fuz, zero_method='zsplit').pvalue
|
||||
|
||||
df_avg.round(4).to_csv(stat_csv)
|
||||
|
||||
|
||||
def run_mutpy(test_path: str, source_path: str) -> float:
|
||||
output = subprocess.check_output(
|
||||
[sys.executable, MUT_PY_PATH, '-t', source_path, '-u', test_path]).decode('utf-8')
|
||||
[sys.executable,
|
||||
MUT_PY_PATH,
|
||||
'-t', source_path,
|
||||
'-u', test_path]).decode('utf-8')
|
||||
score = re.search('Mutation score \\[.*]: (\\d+\\.\\d+)%', output).group(1)
|
||||
return float(score)
|
||||
|
||||
|
||||
def mutate_suite(out_file: str, in_test_dir: str, to_test: List[str]):
|
||||
def mutate_suite(out_file: str, in_test_dir: str, to_test: List[str], seeds: List[int],
|
||||
generation_fn: Callable[[str], Set[Params]]):
|
||||
scores: List[Dict[str, any]] = []
|
||||
|
||||
if os.path.isfile(out_file): # do not re-generate if file exists
|
||||
return
|
||||
return pd.read_csv(out_file, index_col=0)
|
||||
|
||||
for filename in tqdm(to_test, desc=f"mut.py [{os.path.basename(out_file)}]"):
|
||||
source_path = os.path.join(IN_SOURCE_DIR, f"{filename}.py")
|
||||
test_path = os.path.join(in_test_dir, f"test_{filename}.py")
|
||||
scores.append({
|
||||
'file': filename,
|
||||
'score': run_mutpy(test_path, source_path)
|
||||
})
|
||||
for seed in tqdm(seeds, desc=f"generating with seeds"):
|
||||
generate_tests([], seed, generation_fn, in_test_dir)
|
||||
|
||||
for filename in tqdm(to_test, desc=f"mut.py [{os.path.basename(out_file)}]"):
|
||||
source_path = os.path.join(IN_SOURCE_DIR, f"{filename}.py")
|
||||
test_path = os.path.join(in_test_dir, f"test_{filename}.py")
|
||||
scores.append({
|
||||
'file': filename,
|
||||
'score': run_mutpy(test_path, source_path)
|
||||
})
|
||||
|
||||
df = pd.DataFrame.from_records(scores)
|
||||
df.to_csv(out_file)
|
||||
return df
|
||||
|
||||
|
||||
def main():
|
||||
files = [os.path.splitext(f) for f in os.listdir(IN_SOURCE_DIR)]
|
||||
to_test = [file[0] for file in files if file[1] == ".py"]
|
||||
to_test = [e for t in to_test for e in ([t] * REPS)]
|
||||
|
||||
mutate_suite(os.path.join(IN_TEST_DIR, 'mutation_results_genetic.csv'), IN_TEST_DIR, to_test)
|
||||
mutate_suite(os.path.join(IN_FUZZER_TEST_DIR, 'mutation_results_fuzzer.csv'), IN_FUZZER_TEST_DIR, to_test)
|
||||
seeds = [182, 81, 95, 16, 124, 166, 178, 22, 20, 54]
|
||||
|
||||
genetic.init_deap()
|
||||
|
||||
df_gen = mutate_suite(os.path.join(OUT_DIR, 'mutation_results_genetic.csv'), IN_TEST_DIR, to_test, seeds,
|
||||
genetic.generate)
|
||||
df_fuz = mutate_suite(os.path.join(OUT_DIR, 'mutation_results_fuzzer.csv'), IN_FUZZER_TEST_DIR, to_test, seeds,
|
||||
fuzzer_generate)
|
||||
|
||||
compute_stats(df_gen, df_fuz,
|
||||
os.path.join(OUT_DIR, "mutation_scores.png"),
|
||||
os.path.join(OUT_DIR, "mutation_scores_mean.png"),
|
||||
os.path.join(OUT_DIR, "stats.csv"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
,file,score
|
||||
0,anagram_check,23.1
|
||||
1,caesar_cipher,61.8
|
||||
2,check_armstrong,83.9
|
||||
3,common_divisor_count,74.5
|
||||
4,exponentiation,71.4
|
||||
5,gcd,60.9
|
||||
6,longest_substring,69.6
|
||||
7,rabin_karp,28.1
|
||||
8,railfence_cipher,88.3
|
||||
9,zellers_birthday,68.3
|
||||
10,anagram_check,23.1
|
||||
11,caesar_cipher,61.8
|
||||
12,check_armstrong,77.4
|
||||
13,common_divisor_count,78.7
|
||||
14,exponentiation,68.6
|
||||
15,gcd,65.2
|
||||
16,longest_substring,73.9
|
||||
17,rabin_karp,26.3
|
||||
18,railfence_cipher,89.4
|
||||
19,zellers_birthday,72.5
|
||||
20,anagram_check,23.1
|
||||
21,caesar_cipher,61.8
|
||||
22,check_armstrong,25.8
|
||||
23,common_divisor_count,76.6
|
||||
24,exponentiation,68.6
|
||||
25,gcd,56.5
|
||||
26,longest_substring,78.3
|
||||
27,rabin_karp,26.3
|
||||
28,railfence_cipher,88.3
|
||||
29,zellers_birthday,72.5
|
||||
30,anagram_check,23.1
|
||||
31,caesar_cipher,58.8
|
||||
32,check_armstrong,38.7
|
||||
33,common_divisor_count,76.6
|
||||
34,exponentiation,68.6
|
||||
35,gcd,60.9
|
||||
36,longest_substring,78.3
|
||||
37,rabin_karp,50.9
|
||||
38,railfence_cipher,87.2
|
||||
39,zellers_birthday,70.0
|
||||
40,anagram_check,23.1
|
||||
41,caesar_cipher,58.8
|
||||
42,check_armstrong,45.2
|
||||
43,common_divisor_count,74.5
|
||||
44,exponentiation,71.4
|
||||
45,gcd,60.9
|
||||
46,longest_substring,82.6
|
||||
47,rabin_karp,24.6
|
||||
48,railfence_cipher,89.4
|
||||
49,zellers_birthday,62.5
|
||||
50,anagram_check,23.1
|
||||
51,caesar_cipher,58.8
|
||||
52,check_armstrong,83.9
|
||||
53,common_divisor_count,78.7
|
||||
54,exponentiation,68.6
|
||||
55,gcd,43.5
|
||||
56,longest_substring,78.3
|
||||
57,rabin_karp,15.8
|
||||
58,railfence_cipher,87.2
|
||||
59,zellers_birthday,67.5
|
||||
60,anagram_check,23.1
|
||||
61,caesar_cipher,58.8
|
||||
62,check_armstrong,25.8
|
||||
63,common_divisor_count,74.5
|
||||
64,exponentiation,68.6
|
||||
65,gcd,60.9
|
||||
66,longest_substring,82.6
|
||||
67,rabin_karp,26.3
|
||||
68,railfence_cipher,89.4
|
||||
69,zellers_birthday,69.2
|
||||
70,anagram_check,23.1
|
||||
71,caesar_cipher,61.8
|
||||
72,check_armstrong,77.4
|
||||
73,common_divisor_count,78.7
|
||||
74,exponentiation,71.4
|
||||
75,gcd,60.9
|
||||
76,longest_substring,78.3
|
||||
77,rabin_karp,29.8
|
||||
78,railfence_cipher,89.4
|
||||
79,zellers_birthday,66.7
|
||||
80,anagram_check,23.1
|
||||
81,caesar_cipher,64.7
|
||||
82,check_armstrong,77.4
|
||||
83,common_divisor_count,72.3
|
||||
84,exponentiation,68.6
|
||||
85,gcd,60.9
|
||||
86,longest_substring,69.6
|
||||
87,rabin_karp,24.6
|
||||
88,railfence_cipher,87.2
|
||||
89,zellers_birthday,64.2
|
||||
90,anagram_check,23.1
|
||||
91,caesar_cipher,58.8
|
||||
92,check_armstrong,45.2
|
||||
93,common_divisor_count,76.6
|
||||
94,exponentiation,68.6
|
||||
95,gcd,60.9
|
||||
96,longest_substring,82.6
|
||||
97,rabin_karp,26.3
|
||||
98,railfence_cipher,88.3
|
||||
99,zellers_birthday,67.5
|
|
|
@ -0,0 +1,101 @@
|
|||
,file,score
|
||||
0,anagram_check,7.7
|
||||
1,caesar_cipher,61.8
|
||||
2,check_armstrong,93.5
|
||||
3,common_divisor_count,66.0
|
||||
4,exponentiation,71.4
|
||||
5,gcd,47.8
|
||||
6,longest_substring,78.3
|
||||
7,rabin_karp,45.6
|
||||
8,railfence_cipher,87.2
|
||||
9,zellers_birthday,70.0
|
||||
10,anagram_check,7.7
|
||||
11,caesar_cipher,61.8
|
||||
12,check_armstrong,93.5
|
||||
13,common_divisor_count,68.1
|
||||
14,exponentiation,71.4
|
||||
15,gcd,60.9
|
||||
16,longest_substring,78.3
|
||||
17,rabin_karp,50.9
|
||||
18,railfence_cipher,88.3
|
||||
19,zellers_birthday,71.7
|
||||
20,anagram_check,7.7
|
||||
21,caesar_cipher,61.8
|
||||
22,check_armstrong,93.5
|
||||
23,common_divisor_count,61.7
|
||||
24,exponentiation,68.6
|
||||
25,gcd,47.8
|
||||
26,longest_substring,69.6
|
||||
27,rabin_karp,50.9
|
||||
28,railfence_cipher,87.2
|
||||
29,zellers_birthday,75.0
|
||||
30,anagram_check,7.7
|
||||
31,caesar_cipher,61.8
|
||||
32,check_armstrong,93.5
|
||||
33,common_divisor_count,72.3
|
||||
34,exponentiation,68.6
|
||||
35,gcd,60.9
|
||||
36,longest_substring,82.6
|
||||
37,rabin_karp,50.9
|
||||
38,railfence_cipher,88.3
|
||||
39,zellers_birthday,73.3
|
||||
40,anagram_check,7.7
|
||||
41,caesar_cipher,61.8
|
||||
42,check_armstrong,93.5
|
||||
43,common_divisor_count,70.2
|
||||
44,exponentiation,71.4
|
||||
45,gcd,47.8
|
||||
46,longest_substring,78.3
|
||||
47,rabin_karp,50.9
|
||||
48,railfence_cipher,87.2
|
||||
49,zellers_birthday,71.7
|
||||
50,anagram_check,7.7
|
||||
51,caesar_cipher,58.8
|
||||
52,check_armstrong,93.5
|
||||
53,common_divisor_count,76.6
|
||||
54,exponentiation,68.6
|
||||
55,gcd,43.5
|
||||
56,longest_substring,69.6
|
||||
57,rabin_karp,50.9
|
||||
58,railfence_cipher,87.2
|
||||
59,zellers_birthday,70.8
|
||||
60,anagram_check,7.7
|
||||
61,caesar_cipher,58.8
|
||||
62,check_armstrong,93.5
|
||||
63,common_divisor_count,78.7
|
||||
64,exponentiation,68.6
|
||||
65,gcd,60.9
|
||||
66,longest_substring,69.6
|
||||
67,rabin_karp,50.9
|
||||
68,railfence_cipher,88.3
|
||||
69,zellers_birthday,70.8
|
||||
70,anagram_check,7.7
|
||||
71,caesar_cipher,61.8
|
||||
72,check_armstrong,93.5
|
||||
73,common_divisor_count,78.7
|
||||
74,exponentiation,71.4
|
||||
75,gcd,60.9
|
||||
76,longest_substring,73.9
|
||||
77,rabin_karp,49.1
|
||||
78,railfence_cipher,85.1
|
||||
79,zellers_birthday,71.7
|
||||
80,anagram_check,7.7
|
||||
81,caesar_cipher,61.8
|
||||
82,check_armstrong,93.5
|
||||
83,common_divisor_count,78.7
|
||||
84,exponentiation,71.4
|
||||
85,gcd,60.9
|
||||
86,longest_substring,87.0
|
||||
87,rabin_karp,49.1
|
||||
88,railfence_cipher,86.2
|
||||
89,zellers_birthday,70.8
|
||||
90,anagram_check,7.7
|
||||
91,caesar_cipher,61.8
|
||||
92,check_armstrong,93.5
|
||||
93,common_divisor_count,76.6
|
||||
94,exponentiation,40.0
|
||||
95,gcd,65.2
|
||||
96,longest_substring,82.6
|
||||
97,rabin_karp,26.3
|
||||
98,railfence_cipher,89.4
|
||||
99,zellers_birthday,71.7
|
|
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -0,0 +1,11 @@
|
|||
file,fuzzer,genetic,cohen-d,interpretation,wilcoxon
|
||||
anagram_check,23.1,7.7,inf,Huge,0.002
|
||||
caesar_cipher,60.59,61.2,0.3549,Medium,0.2955
|
||||
check_armstrong,58.07,93.5,2.0757,Huge,0.002
|
||||
common_divisor_count,76.17,72.76,-0.7471,Large,0.1258
|
||||
exponentiation,69.44,67.14,-0.3342,Medium,0.7108
|
||||
gcd,59.15,55.66,-0.5016,Large,0.1627
|
||||
longest_substring,77.41,76.98,-0.0771,Small,0.7589
|
||||
rabin_karp,27.9,47.55,2.3688,Huge,0.0078
|
||||
railfence_cipher,88.41,87.44,-0.8844,Very large,0.1011
|
||||
zellers_birthday,68.09,71.75,1.4701,Huge,0.0039
|
|
Binary file not shown.
|
@ -0,0 +1,196 @@
|
|||
%!TEX TS-program = pdflatexmk
|
||||
\documentclass{scrartcl}
|
||||
|
||||
\usepackage{algorithm}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{booktabs}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{microtype}
|
||||
\usepackage{rotating}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{paralist}
|
||||
\usepackage{tabularx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{multirow}
|
||||
\usepackage{pbox}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{colortbl}
|
||||
\usepackage{pifont}
|
||||
\usepackage{xspace}
|
||||
\usepackage{url}
|
||||
\usepackage{tikz}
|
||||
\usepackage{fontawesome}
|
||||
\usepackage{lscape}
|
||||
\usepackage{listings}
|
||||
\usepackage{color}
|
||||
\usepackage{anyfontsize}
|
||||
\usepackage{comment}
|
||||
\usepackage{soul}
|
||||
\usepackage{multibib}
|
||||
\usepackage{float}
|
||||
\usepackage{caption}
|
||||
\usepackage{subcaption}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{hyperref}
|
||||
\usepackage[margin=2.5cm]{geometry}
|
||||
\usepackage{changepage}
|
||||
|
||||
\title{Knowledge Search \& Extraction \\ Project 02: Python Test Generator}
|
||||
\author{Claudio Maggioni}
|
||||
\date{}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\maketitle
|
||||
|
||||
\begin{adjustwidth}{-4cm}{-4cm}
|
||||
\centering
|
||||
\begin{tabular}{cc}
|
||||
\toprule
|
||||
Repository URL & \url{https://github.com/kamclassroom2022/project-02-python-test-generator-maggicl} \\
|
||||
Commit ID & \texttt{549b8859ffaad5391da362ed9bbe9db82b2c5c0b} \\ \bottomrule
|
||||
\end{tabular}
|
||||
\end{adjustwidth}
|
||||
\vspace{1cm}
|
||||
|
||||
\subsection*{Section 1 - Instrumentation}
|
||||
|
||||
The script \textit{instrument.py} in the main directory of the project performs instrumentation to replace each
|
||||
condition node in the Python files present benchmark suite with a call to \texttt{evaluate\_condition}, which will
|
||||
preserve program behaviour but as a side effect will compute and store condition distance for each traversed branch.
|
||||
|
||||
Table~\ref{tab:count1} summarizes the number of Python files, function definition (\textit{FunctionDef}) nodes,
|
||||
and comparison nodes (\textit{Compare} nodes not in an \texttt{assert} or \texttt{return} statement) found by the
|
||||
instrumentation script.
|
||||
|
||||
\begin{table} [H]
|
||||
\centering
|
||||
\begin{tabular}{lr}
|
||||
\toprule
|
||||
\textbf{Type} & \textbf{Number} \\
|
||||
\midrule
|
||||
Python Files & 10 \\
|
||||
Function Nodes & 12 \\
|
||||
Comparison Nodes & 44 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Count of files and nodes found.}
|
||||
\label{tab:count1}
|
||||
\end{table}
|
||||
|
||||
\subsection*{Section 2: Fuzzer test generator}
|
||||
|
||||
The script \textit{fuzzer.py} loads the instrumented benchmark suite and generates tests at random to maximize branch
|
||||
coverage.
|
||||
|
||||
The implementation submitted with this report slightly improves on the specification required as it is
|
||||
able to deal with an arbitrary number of function parameters, which must be type-hinted as either \texttt{str} or
|
||||
\texttt{int}. The fuzzing process generates a pool of 1000 test case inputs according to the function signature,
|
||||
using randomly generated integers $\in [-1000, 1000]$, and randomly generated string of length $\in [0, 10]$ with
|
||||
ASCII characters with code $\in [32, 127]$. Note that test cases generated in the pool may not satisfy the
|
||||
preconditions (i.e.\ the \texttt{assert} statements on the inputs) for the given function.
|
||||
|
||||
250 test cases are extracted from the pool following this procedure. With equal probabilities (each with $p=1/3$):
|
||||
|
||||
\begin{itemize}
|
||||
\item The extracted test case may be kept as-is;
|
||||
\item The extracted test case may be randomly mutated using the \textit{mutate} function. An argument will be
|
||||
chosen at random, and if of type \texttt{str} a random position in the string will be replaced with a
|
||||
random character. If the argument is of type \texttt{int}, a random value $\in [-10, 10]$ will be added to
|
||||
the argument. If the resulting test case is not present in the pool, it will be added to the pool;
|
||||
\item The extracted test case may be randomly combined with another randomly extracted test using the
|
||||
\textit{crossover} function. The function will choose at random an argument, and if of type \texttt{int} it will
|
||||
swap the values assigned to the two tests. If the argument is of type \texttt{str}, the strings from the two test
|
||||
cases will be split in two substrings at random and they will be joined by combining the ``head'' substring from
|
||||
one test case with the ``tail'' substring from the other. If the two resulting test cases are new, they will be
|
||||
added to the pool.
|
||||
\end{itemize}
|
||||
|
||||
If the resulting test case (or test cases) satisfy the function precondition, and if their execution covers branches
|
||||
that have not been covered by other test cases, they will be added to the test suite. The resulting test suite is
|
||||
then saved as a \textit{unittest} file, comprising of one test class per function present in the benchmark test file.
|
||||
|
||||
\subsection*{Section 3: Genetic Algorithm test generator}
|
||||
|
||||
The script \textit{genetic.py} loads the instrumented benchmark suite and generates tests using a genetic algorithm
|
||||
to maximize branch coverage and minimize distance to condition boundary values.
|
||||
|
||||
The genetic algorithm is implemented via the library \textit{deap} using the \textit{eaSimple} procedure.
|
||||
The algorithm is initialized with 200 individuals extracted from a pool generated in the same way as the previous
|
||||
section. The algorithm runs for 20 generations, and it implements the \textit{mate} and \textit{mutate} operators
|
||||
using the \textit{crossover} and \textit{mutate} functions respectively as described in the previous section.
|
||||
|
||||
The fitness function used returns a value of $\infty$ if the test case does not satisfy the function precondition,
|
||||
a value of $1000000$ if the test case does not cover any new branches,
|
||||
or the sum of normalized ($1 / (x + 1)$) sum of distances for branches that are not yet covered by other test cases.
|
||||
A penalty of $2$ is summed to the fitness value for every branch that is already covered. The fitness function is
|
||||
minimized by the genetic algorithm.
|
||||
|
||||
The genetic algorithm is ran 10 times. At the end of each execution the best individuals (sorted by increasing
|
||||
fitness) are selected if they cover at least one branch that has not been covered. This is the only point in the
|
||||
procedure where the set of covered branches is updated\footnote{This differs from the reference implementation of
|
||||
\texttt{sb\_cgi\_decode.py}, which performs the update directly in the fitness function.}.
|
||||
|
||||
\subsection*{Section 4: Statistical comparison of test generators}
|
||||
|
||||
To compare the performance of the fuzzer and the genetic algorithm, the mutation testing tool \textit{mut.py} has
|
||||
been used to measure how robust the generated test suites hard. Both implementations have been executed for 10 times
|
||||
using different RNG seeds each time, and a statistical comparison of the resulting mutation score distributions has
|
||||
been performed to determine when one generation method is statistically more performant than the other.
|
||||
|
||||
\begin{figure}[t]
|
||||
\begin{center}
|
||||
\includegraphics[width=\linewidth]{../out/mutation_scores}
|
||||
\caption{Distributions of \textit{mut.py} mutation scores over the generated benchmark tests suites
|
||||
using the fuzzer and the genetic algorithm.}\label{fig:mutation-scores}
|
||||
\end{center}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[t]
|
||||
\begin{center}
|
||||
\includegraphics[width=\linewidth]{../out/mutation_scores_mean}
|
||||
\caption{\textit{mut.py} Mutation score average over the generated benchmark tests suites
|
||||
using the fuzzer and the genetic algorithm.}\label{fig:mutation-scores-mean}
|
||||
\end{center}
|
||||
\end{figure}
|
||||
|
||||
Figure~\ref{fig:mutation-scores} shows a boxplot of the mutation score distributions for each file in the benchmark
|
||||
suite, while figure~\ref{fig:mutation-scores-mean} shows the mean mutation scores.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\begin{tabular}{lrrp{3.5cm}r}
|
||||
\toprule
|
||||
\textbf{File} & \textbf{$E(\text{Fuzzer})$} & \textbf{$E(\text{Genetic})$} & \textbf{Cohen's $|d|$} & \textbf{Wilcoxon $p$} \\
|
||||
\midrule
|
||||
check\_armstrong & 58.07 & 93.50 & 2.0757 \hfill Huge & 0.0020 \\
|
||||
railfence\_cipher & 88.41 & 87.44 & 0.8844 \hfill Very large & 0.1011 \\
|
||||
longest\_substring & 77.41 & 76.98 & 0.0771 \hfill Small & 0.7589 \\
|
||||
common\_divisor\_count & 76.17 & 72.76 & 0.7471 \hfill Large & 0.1258 \\
|
||||
zellers\_birthday & 68.09 & 71.75 & 1.4701 \hfill Huge & 0.0039 \\
|
||||
exponentiation & 69.44 & 67.14 & 0.3342 \hfill Medium & 0.7108 \\
|
||||
caesar\_cipher & 60.59 & 61.20 & 0.3549 \hfill Medium & 0.2955 \\
|
||||
gcd & 59.15 & 55.66 & 0.5016 \hfill Large & 0.1627 \\
|
||||
rabin\_karp & 27.90 & 47.55 & 2.3688 \hfill Huge & 0.0078 \\
|
||||
anagram\_check & 23.10 & 7.70 & $\infty$ \hfill Huge & 0.0020 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Statistical comparison between fuzzer and genetic algorithm test case generation in terms of mutation
|
||||
score as reported by \textit{mut.py} over 10 runs, sorted by genetic mutation score. The table reports run
|
||||
means, the wilcoxon paired test p-value and the Cohen's $d$ effect size for each file in the
|
||||
benchmark.}\label{tab:stats}
|
||||
\end{table}
|
||||
|
||||
To perform a statistical comparison, the Wilcoxon paired test has been used with a p-value threshold of 0.05 has been
|
||||
used to check if there is there is a statistical difference between the distributions. Moreover, the Cohen's d
|
||||
effect-size has been used to measure the significance of the difference. Results of the statistical analysis are
|
||||
shown in table~\ref{tab:stats}.
|
||||
|
||||
Only 4 benchmark files out of 10 make the two script have statistical different performance. They are namely
|
||||
\textit{check\_armstrong}, \textit{zeller\_birthday}, \textit{rabin\_karp} and \textit{anagram\_check}.
|
||||
The first three show that the genetic algorithm performs significantly better than the fuzzer,
|
||||
while the last file shows the opposite.
|
||||
\end{document}
|
|
@ -3,4 +3,7 @@ deap==1.4.1
|
|||
astunparse==1.6.3
|
||||
frozendict==2.3.8
|
||||
tqdm==4.66.1
|
||||
pandas==1.3.5
|
||||
pandas==1.3.5
|
||||
matplotlib==3.8.2
|
||||
seaborn==0.12.2
|
||||
scipy==1.11.4
|
|
@ -0,0 +1,10 @@
|
|||
nltk==3.8.1
|
||||
deap==1.4.1
|
||||
astunparse==1.6.3
|
||||
frozendict==2.3.8
|
||||
tqdm==4.66.1
|
||||
pandas==1.3.5
|
||||
matplotlib==3.5.3
|
||||
seaborn==0.12.2
|
||||
scipy==1.7.3
|
||||
MutPy==0.6.1
|
|
@ -1,101 +0,0 @@
|
|||
,file,score
|
||||
0,anagram_check,38.5
|
||||
1,anagram_check,38.5
|
||||
2,anagram_check,38.5
|
||||
3,anagram_check,38.5
|
||||
4,anagram_check,38.5
|
||||
5,anagram_check,38.5
|
||||
6,anagram_check,38.5
|
||||
7,anagram_check,38.5
|
||||
8,anagram_check,38.5
|
||||
9,anagram_check,38.5
|
||||
10,caesar_cipher,64.7
|
||||
11,caesar_cipher,64.7
|
||||
12,caesar_cipher,64.7
|
||||
13,caesar_cipher,64.7
|
||||
14,caesar_cipher,64.7
|
||||
15,caesar_cipher,64.7
|
||||
16,caesar_cipher,64.7
|
||||
17,caesar_cipher,64.7
|
||||
18,caesar_cipher,64.7
|
||||
19,caesar_cipher,64.7
|
||||
20,check_armstrong,93.5
|
||||
21,check_armstrong,93.5
|
||||
22,check_armstrong,93.5
|
||||
23,check_armstrong,93.5
|
||||
24,check_armstrong,93.5
|
||||
25,check_armstrong,93.5
|
||||
26,check_armstrong,93.5
|
||||
27,check_armstrong,93.5
|
||||
28,check_armstrong,93.5
|
||||
29,check_armstrong,93.5
|
||||
30,common_divisor_count,80.9
|
||||
31,common_divisor_count,80.9
|
||||
32,common_divisor_count,80.9
|
||||
33,common_divisor_count,80.9
|
||||
34,common_divisor_count,80.9
|
||||
35,common_divisor_count,80.9
|
||||
36,common_divisor_count,80.9
|
||||
37,common_divisor_count,80.9
|
||||
38,common_divisor_count,80.9
|
||||
39,common_divisor_count,80.9
|
||||
40,exponentiation,71.4
|
||||
41,exponentiation,71.4
|
||||
42,exponentiation,71.4
|
||||
43,exponentiation,71.4
|
||||
44,exponentiation,71.4
|
||||
45,exponentiation,71.4
|
||||
46,exponentiation,71.4
|
||||
47,exponentiation,71.4
|
||||
48,exponentiation,71.4
|
||||
49,exponentiation,71.4
|
||||
50,gcd,60.9
|
||||
51,gcd,60.9
|
||||
52,gcd,60.9
|
||||
53,gcd,60.9
|
||||
54,gcd,60.9
|
||||
55,gcd,60.9
|
||||
56,gcd,60.9
|
||||
57,gcd,60.9
|
||||
58,gcd,60.9
|
||||
59,gcd,60.9
|
||||
60,longest_substring,69.6
|
||||
61,longest_substring,69.6
|
||||
62,longest_substring,69.6
|
||||
63,longest_substring,69.6
|
||||
64,longest_substring,69.6
|
||||
65,longest_substring,69.6
|
||||
66,longest_substring,69.6
|
||||
67,longest_substring,69.6
|
||||
68,longest_substring,69.6
|
||||
69,longest_substring,69.6
|
||||
70,rabin_karp,50.9
|
||||
71,rabin_karp,50.9
|
||||
72,rabin_karp,50.9
|
||||
73,rabin_karp,50.9
|
||||
74,rabin_karp,50.9
|
||||
75,rabin_karp,50.9
|
||||
76,rabin_karp,50.9
|
||||
77,rabin_karp,50.9
|
||||
78,rabin_karp,50.9
|
||||
79,rabin_karp,50.9
|
||||
80,railfence_cipher,86.2
|
||||
81,railfence_cipher,86.2
|
||||
82,railfence_cipher,86.2
|
||||
83,railfence_cipher,86.2
|
||||
84,railfence_cipher,86.2
|
||||
85,railfence_cipher,86.2
|
||||
86,railfence_cipher,86.2
|
||||
87,railfence_cipher,86.2
|
||||
88,railfence_cipher,86.2
|
||||
89,railfence_cipher,86.2
|
||||
90,zellers_birthday,65.0
|
||||
91,zellers_birthday,65.0
|
||||
92,zellers_birthday,65.0
|
||||
93,zellers_birthday,65.0
|
||||
94,zellers_birthday,65.0
|
||||
95,zellers_birthday,65.0
|
||||
96,zellers_birthday,65.0
|
||||
97,zellers_birthday,65.0
|
||||
98,zellers_birthday,65.0
|
||||
99,zellers_birthday,65.0
|
|
|
@ -3,17 +3,12 @@ from benchmark.anagram_check import anagram_check
|
|||
|
||||
|
||||
class Test_anagram_check(TestCase):
|
||||
# distances_true = {1: [0], 2: [0]}
|
||||
# distances_false = {1: [1], 2: [1]}
|
||||
def test_anagram_check_1(self):
|
||||
assert anagram_check(s1='/', s2='6') == False
|
||||
|
||||
# distances_true = {1: [1], 3: [1], 4: [0]}
|
||||
# distances_false = {1: [0], 3: [0], 4: [1]}
|
||||
def test_anagram_check_2(self):
|
||||
assert anagram_check(s1='', s2='') == True
|
||||
|
||||
# distances_true = {1: [1], 3: [0]}
|
||||
# distances_false = {1: [0], 3: [1]}
|
||||
def test_anagram_check_3(self):
|
||||
assert anagram_check(s1='md', s2='p') == False
|
||||
def test_anagram_check_1(self):
|
||||
assert anagram_check(s1='Oi', s2='p') == False
|
||||
|
||||
# distances_true = {1: [0], 2: [0]}
|
||||
# distances_false = {1: [1], 2: [1]}
|
||||
def test_anagram_check_2(self):
|
||||
assert anagram_check(s1='_', s2='T') == False
|
||||
|
|
|
@ -4,14 +4,14 @@ from benchmark.caesar_cipher import decrypt
|
|||
|
||||
|
||||
class Test_encrypt(TestCase):
|
||||
# distances_true = {1: [0, 0, 0, 0, 40, 0, 31, 22]}
|
||||
# distances_false = {1: [33, 14, 23, 29, 0, 28, 0, 0]}
|
||||
# distances_true = {1: [3, 47, 0, 0, 46, 0, 22]}
|
||||
# distances_false = {1: [0, 0, 31, 19, 0, 8, 0]}
|
||||
def test_encrypt_1(self):
|
||||
assert encrypt(strng='vclr.q7@', key=41) == '@-6<W;`i'
|
||||
assert encrypt(strng='V*wk+`C', key=38) == "|P>2Q'i"
|
||||
|
||||
|
||||
class Test_decrypt(TestCase):
|
||||
# distances_true = {2: [0, 0, 1, 0, 0, 3, 1, 18, 48]}
|
||||
# distances_false = {2: [1, 3, 0, 15, 6, 0, 0, 0, 0]}
|
||||
# distances_true = {2: [0, 215, 203, 206, 217, 13]}
|
||||
# distances_false = {2: [21, 0, 0, 0, 0, 0]}
|
||||
def test_decrypt_1(self):
|
||||
assert decrypt(strng='203$-53Db', key=19) == '~| py" 1O'
|
||||
assert decrypt(strng='C."%0d', key=56) == 'jöêíø,'
|
||||
|
|
|
@ -3,27 +3,27 @@ from benchmark.check_armstrong import check_armstrong
|
|||
|
||||
|
||||
class Test_check_armstrong(TestCase):
|
||||
# distances_true = {1: [2], 2: [1], 3: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [149]}
|
||||
# distances_true = {1: [1], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_check_armstrong_1(self):
|
||||
assert check_armstrong(n=2) == False
|
||||
assert check_armstrong(n=1) == True
|
||||
|
||||
# distances_true = {1: [0]}
|
||||
# distances_false = {1: [1]}
|
||||
def test_check_armstrong_2(self):
|
||||
assert check_armstrong(n=0) == True
|
||||
|
||||
# distances_true = {1: [380], 2: [379], 3: [230], 4: [0, 0, 0, 1], 5: [159]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [380, 38, 3, 0], 5: [0]}
|
||||
# distances_true = {1: [161], 2: [160], 3: [11], 4: [0, 0, 0, 1], 5: [57]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [161, 16, 1, 0], 5: [0]}
|
||||
def test_check_armstrong_3(self):
|
||||
assert check_armstrong(n=380) == False
|
||||
assert check_armstrong(n=161) == False
|
||||
|
||||
# distances_true = {1: [153], 2: [152], 3: [3], 4: [0, 0, 0, 1], 5: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [153, 15, 1, 0], 5: [1]}
|
||||
def test_check_armstrong_4(self):
|
||||
assert check_armstrong(n=153) == True
|
||||
|
||||
# distances_true = {1: [1], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
# distances_true = {1: [3], 2: [2], 3: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [148]}
|
||||
def test_check_armstrong_5(self):
|
||||
assert check_armstrong(n=1) == True
|
||||
assert check_armstrong(n=3) == False
|
||||
|
|
|
@ -3,32 +3,32 @@ from benchmark.common_divisor_count import cd_count
|
|||
|
||||
|
||||
class Test_cd_count(TestCase):
|
||||
# distances_true = {1: [5], 2: [618], 3: [6], 4: [619], 5: [0, 0, 0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [5, 3, 2, 1, 0], 6: [1], 7: [1]}
|
||||
# distances_true = {1: [5], 2: [621], 3: [0], 4: [622], 5: [0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [5], 4: [0], 5: [5, 1, 0], 6: [1], 7: [1]}
|
||||
def test_cd_count_1(self):
|
||||
assert cd_count(a=5, b=618) == 1
|
||||
assert cd_count(a=-5, b=621) == 1
|
||||
|
||||
# distances_true = {1: [0]}
|
||||
# distances_false = {1: [1]}
|
||||
def test_cd_count_2(self):
|
||||
assert cd_count(a=0, b=-49) == 2
|
||||
assert cd_count(a=0, b=621) == 2
|
||||
|
||||
# distances_true = {1: [4], 2: [101], 3: [5], 4: [0], 5: [0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [101], 5: [4, 1, 0], 6: [1], 7: [1]}
|
||||
# distances_true = {1: [2], 2: [616], 3: [3], 4: [617], 5: [0, 1], 6: [0], 7: [1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [2, 0], 6: [1], 7: [0]}
|
||||
def test_cd_count_3(self):
|
||||
assert cd_count(a=4, b=-101) == 1
|
||||
assert cd_count(a=2, b=616) == 2
|
||||
|
||||
# distances_true = {1: [10], 2: [52], 3: [0], 4: [0], 5: [0, 0, 1], 6: [0], 7: [1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [10], 4: [52], 5: [10, 2, 0], 6: [1], 7: [0]}
|
||||
# distances_true = {1: [7], 2: [630], 3: [0], 4: [631], 5: [0, 1], 6: [0, 1], 7: [6]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [7], 4: [0], 5: [7, 0], 6: [1, 0], 7: [0]}
|
||||
def test_cd_count_4(self):
|
||||
assert cd_count(a=-10, b=-52) == 2
|
||||
assert cd_count(a=-7, b=630) == 2
|
||||
|
||||
# distances_true = {1: [9], 2: [0]}
|
||||
# distances_true = {1: [624], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_cd_count_5(self):
|
||||
assert cd_count(a=9, b=0) == 2
|
||||
assert cd_count(a=-624, b=0) == 2
|
||||
|
||||
# distances_true = {1: [10], 2: [150], 3: [0], 4: [0], 5: [0, 1], 6: [0, 0, 1], 7: [9, 3]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [10], 4: [150], 5: [10, 0], 6: [1, 1, 0], 7: [0, 0]}
|
||||
# distances_true = {1: [637], 2: [6], 3: [0], 4: [0], 5: [0, 0, 0, 1], 6: [0], 7: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [637], 4: [6], 5: [637, 6, 1, 0], 6: [1], 7: [1]}
|
||||
def test_cd_count_6(self):
|
||||
assert cd_count(a=-10, b=-150) == 4
|
||||
assert cd_count(a=-637, b=-6) == 1
|
||||
|
|
|
@ -3,7 +3,7 @@ from benchmark.exponentiation import exponentiation
|
|||
|
||||
|
||||
class Test_exponentiation(TestCase):
|
||||
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 2: [1, 1, 0, 1, 0, 1, 1, 1, 1]}
|
||||
# distances_false = {1: [591, 295, 147, 73, 36, 17, 8, 3, 1, 0], 3: [1], 2: [0, 0, 1, 0, 1, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 2: [0, 1, 1, 1, 1, 1, 0, 0, 1]}
|
||||
# distances_false = {1: [773, 386, 192, 95, 47, 23, 11, 5, 2, 0], 3: [1], 2: [1, 0, 0, 0, 0, 0, 1, 1, 0]}
|
||||
def test_exponentiation_1(self):
|
||||
assert exponentiation(baseNumber=748, power=592) == 2237411859567305228712820969577177889399507688925863669623492970046756800811752671771192642266754818786206883016528099952656873068236573570940727536208482507787576742117892529716174302439216500172363521344994812494798736599216689085381729125165667408413134378577619291662064250215391547791138001022452137862778730264821893010999654434708983063321061487758219131875157534566833176981850918287964729665626846138477133321680757074668758491790945198601054224199588300081988215907925870651530562786845054260705838873377721118111382749970684115994163428904242940249188932413043444079730697574946438556722431973692672316117631662669780447322962255376036216266360170992797300680863608151678208837497803629559832285706122751678247068182933676547879825690946817522731921058001762116141626296741021042361970731691972888241818460142317141771780073548156492405406490981515425290002128649234461825789947573119368985161153262332388808724131879060867880473096842000650483632521058294479344879944564436266652927131107918428149402925778007533423162302903655859402260228366219008304205413113994847339399353552421491921433679173463981507810853240889014970942564956030433528528976883729747234323037570498652835167034147294039927751837932259353682824119565000780453933743514380393121666554146174425347788804096581718436380869076273595714279596282320033858652789005508958162362572551844879419089353500606113442189427958545044465106509994666028492893004614086892576645413919934301813479926994631172622364458500761310743512340332065554689760340750349754142540650730287762939301975905339162897423087384712675419496189151357961520127467940210297313531487397450555066413386239184330770939775155310643870407646031104489325011664896
|
||||
assert exponentiation(baseNumber=-1, power=774) == 1
|
||||
|
|
|
@ -3,22 +3,27 @@ from benchmark.gcd import gcd
|
|||
|
||||
|
||||
class Test_gcd(TestCase):
|
||||
# distances_true = {1: [97], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_gcd_1(self):
|
||||
assert gcd(a=98, b=1) == 1
|
||||
|
||||
# distances_true = {1: [97], 2: [1], 3: [96], 4: [97], 5: [0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [2, 0]}
|
||||
def test_gcd_2(self):
|
||||
assert gcd(a=98, b=2) == 2
|
||||
|
||||
# distances_true = {1: [9], 2: [9], 3: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [1]}
|
||||
def test_gcd_3(self):
|
||||
assert gcd(a=10, b=10) == 10
|
||||
|
||||
# distances_true = {1: [7], 2: [943], 3: [936], 4: [0], 5: [0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [936], 5: [8, 0]}
|
||||
def test_gcd_4(self):
|
||||
assert gcd(a=8, b=944) == 8
|
||||
|
||||
# distances_true = {1: [0]}
|
||||
# distances_false = {1: [1]}
|
||||
def test_gcd_1(self):
|
||||
assert gcd(a=1, b=376) == 1
|
||||
|
||||
# distances_true = {1: [3], 2: [309], 3: [306], 4: [0], 5: [0, 0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [306], 5: [4, 2, 0]}
|
||||
def test_gcd_2(self):
|
||||
assert gcd(a=4, b=310) == 2
|
||||
|
||||
# distances_true = {1: [930], 2: [8], 3: [922], 4: [923], 5: [0, 0, 0, 1]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [9, 4, 1, 0]}
|
||||
def test_gcd_3(self):
|
||||
assert gcd(a=931, b=9) == 1
|
||||
|
||||
# distances_true = {1: [698], 2: [0]}
|
||||
# distances_false = {1: [0], 2: [1]}
|
||||
def test_gcd_4(self):
|
||||
assert gcd(a=699, b=1) == 1
|
||||
def test_gcd_5(self):
|
||||
assert gcd(a=1, b=933) == 1
|
||||
|
|
|
@ -3,7 +3,7 @@ from benchmark.longest_substring import longest_sorted_substr
|
|||
|
||||
|
||||
class Test_longest_sorted_substr(TestCase):
|
||||
# distances_true = {1: [45, 0, 14, 0, 15, 0, 0], 2: [0, 1, 1, 0]}
|
||||
# distances_false = {1: [0, 43, 0, 13, 0, 30, 3], 2: [1, 0, 0, 1]}
|
||||
# distances_true = {1: [0, 8, 0, 27, 53, 0, 11], 2: [0, 1, 1]}
|
||||
# distances_false = {1: [11, 0, 82, 0, 0, 71, 0], 2: [1, 0, 0]}
|
||||
def test_longest_sorted_substr_1(self):
|
||||
assert longest_sorted_substr(s='b5_Q]Nkm') == 'Nkm'
|
||||
assert longest_sorted_substr(s="$.&w\\'mb") == '$.'
|
||||
|
|
|
@ -3,17 +3,17 @@ from benchmark.rabin_karp import rabin_karp_search
|
|||
|
||||
|
||||
class Test_rabin_karp_search(TestCase):
|
||||
# distances_true = {1: [0], 2: [1], 3: [0], 4: [1]}
|
||||
# distances_false = {1: [1], 2: [0], 3: [1], 4: [0]}
|
||||
# distances_true = {1: [0], 2: [1, 0], 3: [1], 4: [1]}
|
||||
# distances_false = {1: [1], 2: [0, 4], 3: [0], 4: [0]}
|
||||
def test_rabin_karp_search_1(self):
|
||||
assert rabin_karp_search(pat='z', txt='z') == [0]
|
||||
assert rabin_karp_search(pat='A@@', txt='A<g') == []
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [3], 4: [1]}
|
||||
# distances_false = {1: [1], 2: [23], 3: [0], 4: [0]}
|
||||
# distances_true = {1: [28], 4: [1]}
|
||||
# distances_false = {1: [0], 4: [0]}
|
||||
def test_rabin_karp_search_2(self):
|
||||
assert rabin_karp_search(pat='b&k<', txt='K@qO') == []
|
||||
assert rabin_karp_search(pat='RC)', txt='][`') == []
|
||||
|
||||
# distances_true = {1: [0, 0, 61, 51, 81, 82, 87, 98], 3: [1, 2], 4: [0, 0, 0, 0, 0, 0, 0, 1], 5: [1, 62, 52, 82, 83, 88, 99]}
|
||||
# distances_false = {1: [1, 1, 0, 0, 0, 0, 0, 0], 3: [0, 0], 4: [7, 6, 5, 4, 3, 2, 1, 0], 5: [0, 0, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [0], 2: [0], 3: [2], 4: [1]}
|
||||
# distances_false = {1: [1], 2: [25], 3: [0], 4: [0]}
|
||||
def test_rabin_karp_search_3(self):
|
||||
assert rabin_karp_search(pat='', txt='ex[>NC6') == []
|
||||
assert rabin_karp_search(pat='*3~', txt='C9`') == []
|
||||
|
|
|
@ -4,14 +4,14 @@ from benchmark.railfence_cipher import raildecrypt
|
|||
|
||||
|
||||
class Test_railencrypt(TestCase):
|
||||
# distances_true = {1: [0, 0, 0, 0, 1, 1, 1, 0, 0], 2: [3, 2, 1, 0, 2, 1], 3: [2, 1, 0], 4: [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1]}
|
||||
# distances_false = {1: [1, 1, 1, 1, 0, 0, 0, 1, 1], 2: [0, 0, 0, 1, 0, 0], 3: [0, 0, 1], 4: [102, 0, 0, 0, 0, 0, 112, 0, 0, 0, 110, 0, 0, 0, 122, 0, 52, 0, 0, 0, 124, 0, 50, 0, 0, 0, 48, 0, 0, 0, 38, 0, 0, 0, 0, 0]}
|
||||
# distances_true = {1: [0, 0, 0, 1, 1, 0, 0, 1], 2: [2, 1, 0, 1, 0], 3: [1, 0, 1], 4: [0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1]}
|
||||
# distances_false = {1: [1, 1, 1, 0, 0, 1, 1, 0], 2: [0, 0, 1, 0, 1], 3: [0, 1, 0], 4: [126, 0, 0, 0, 110, 0, 0, 0, 0, 117, 0, 52, 0, 50, 0, 67, 0, 0, 32, 0, 0, 0, 104, 0]}
|
||||
def test_railencrypt_1(self):
|
||||
assert railencrypt(st='fn|&2zp40', k=4) == 'fpnz4|20&'
|
||||
assert railencrypt(st='~u 4n2hC', k=3) == '~nu42C h'
|
||||
|
||||
|
||||
class Test_raildecrypt(TestCase):
|
||||
# distances_true = {5: [0, 0, 0, 0, 1, 1, 1], 6: [3, 2, 1, 0], 7: [2, 1, 0], 8: [0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1], 9: [0, 0, 0, 0, 0, 0, 0], 10: [7, 0, 0, 0, 1, 1, 1], 12: [0, 2, 1, 0], 11: [2, 1, 0]}
|
||||
# distances_false = {5: [1, 1, 1, 1, 0, 0, 0], 6: [0, 0, 0, 1], 7: [0, 0, 1], 8: [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], 9: [125, 79, 95, 32, 85, 109, 46], 10: [0, 1, 1, 1, 0, 0, 0], 12: [1, 0, 0, 1], 11: [0, 0, 1]}
|
||||
# distances_true = {5: [0, 0, 0, 1, 1, 0, 0, 1], 6: [2, 1, 0, 1, 0], 7: [1, 0, 1], 8: [0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1], 9: [0, 0, 0, 0, 0, 0, 0, 0], 10: [8, 0, 0, 1, 1, 0, 0, 1], 12: [0, 1, 0, 1], 11: [1, 0, 1, 0]}
|
||||
# distances_false = {5: [1, 1, 1, 0, 0, 1, 1, 0], 6: [0, 0, 1, 0, 1], 7: [0, 1, 0], 8: [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0], 9: [58, 96, 58, 124, 48, 73, 82, 79], 10: [0, 1, 1, 0, 0, 1, 1, 0], 12: [1, 0, 1, 0], 11: [0, 1, 0, 1]}
|
||||
def test_raildecrypt_1(self):
|
||||
assert raildecrypt(st='}.Om_U ', k=4) == '}O_ Um.'
|
||||
assert raildecrypt(st=':0`|IO:R', k=3) == ':`:|0IRO'
|
||||
|
|
|
@ -6,14 +6,19 @@ class Test_zeller(TestCase):
|
|||
# distances_true = {1: [1], 2: [6], 3: [0], 4: [0], 5: [1923], 7: [5], 8: [0]}
|
||||
# distances_false = {1: [0], 2: [0], 3: [78], 4: [1], 5: [0], 7: [0], 8: [1]}
|
||||
def test_zeller_1(self):
|
||||
assert zeller(d=31, m=7, y=-22) == 'Sunday'
|
||||
assert zeller(d=-31, m=-7, y=-22) == 'Sunday'
|
||||
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1923], 7: [0], 8: [3, 2, 1, 0]}
|
||||
# distances_false = {1: [1], 2: [1], 3: [78], 4: [1], 5: [0], 7: [1], 8: [0, 0, 0, 1]}
|
||||
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1923], 7: [0], 8: [6, 5, 4, 3, 2, 1, 0]}
|
||||
# distances_false = {1: [4], 2: [1], 3: [78], 4: [1], 5: [0], 7: [1], 8: [0, 0, 0, 0, 0, 0, 1]}
|
||||
def test_zeller_2(self):
|
||||
assert zeller(d=32, m=13, y=-22) == 'Wednesday'
|
||||
assert zeller(d=-35, m=-13, y=-22) == 'Saturday'
|
||||
|
||||
# distances_true = {1: [1], 2: [0], 3: [0], 4: [8], 5: [0], 6: [0], 7: [0], 8: [1, 0]}
|
||||
# distances_false = {1: [0], 2: [1], 3: [70], 4: [0], 5: [70], 6: [8], 7: [1], 8: [0, 1]}
|
||||
# distances_true = {1: [1], 2: [0], 3: [0], 4: [7], 5: [0], 6: [0], 7: [0], 8: [0]}
|
||||
# distances_false = {1: [0], 2: [1], 3: [71], 4: [0], 5: [71], 6: [7], 7: [1], 8: [1]}
|
||||
def test_zeller_3(self):
|
||||
assert zeller(d=31, m=13, y=-30) == 'Monday'
|
||||
assert zeller(d=-31, m=-13, y=-29) == 'Sunday'
|
||||
|
||||
# distances_true = {1: [1], 2: [0], 3: [0], 4: [0], 5: [1923], 7: [1], 8: [4, 3, 2, 1, 0]}
|
||||
# distances_false = {1: [0], 2: [2], 3: [78], 4: [1], 5: [0], 7: [0], 8: [0, 0, 0, 0, 1]}
|
||||
def test_zeller_4(self):
|
||||
assert zeller(d=-31, m=-14, y=-22) == 'Thursday'
|
||||
|
|
Loading…
Reference in New Issue