I wrote my first project in Python and I would like to know if this is correct. I prepared some guidelines I want to ask. (I know that I don't have any documentation yet). In the future I want to extend my project about new algorithms such as search, crypto, machine learning, hashes, graphs and so on. Also, I would like to add some data structures. For easier review I can share my files if needed.
- Is my code compatible with PEP8?
- Is my code compatible with ZenOfPython?
- Is my code compatible with OOP?
- Is my code easy to expand? (Extended with new algorithms and classes)
- Is my code readable?
- Are my subclasses easy to build for testcases?
- Are my unit tests correct (don't really know what I should ask about)?
- Should I use some design patterns in such a project?
initiate.py
from dsal.algorithm_list import algorithms
class Initiate:
def __init__(self, algorithm_name, **kwargs):
self.algorithm_name = algorithm_name
self.result = {}
self.args = kwargs
@staticmethod
def get_algorithm(name):
algorithm = None
for key, alg in algorithms.items():
if name in key:
algorithm = alg
break
if algorithm is None:
raise TypeError('Algorithm not defined !')
return algorithm
def set_params(self, name):
algorithm, params = Initiate.get_algorithm(name), dict()
for k, v in algorithm.check_params(self).items():
val = self.args.get(k, None)
if val is not None and v(val):
params[k] = val
return algorithm(**params)
def run(self):
algorithm = self.set_params(self.algorithm_name)
return algorithm.run()
def run_time(self):
algorithm = self.set_params(self.algorithm_name)
return algorithm.time_task()
algorithm_list.py
from dsal.algorithms.sorting.simple_sort.bubble_sort import bubble_sort
algorithms = {"BubbleSortV1": bubble_sort.BubbleSortV1,
"BubbleSortV2": bubble_sort.BubbleSortV2}
allgorithms\sorting\simple_sort\bubble_sort\bubble_sort.py
from dsal.core.algorithms.sorting.simple_sort import SimpleSort
class BubbleSortV1(SimpleSort):
def run_task(self):
# setting up variables
length = len(self.container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if self.container[i] > self.container[i + 1]:
self.container[i], self.container[i + 1] = self.container[i + 1], self.container[i]
changed = True
length -= 1
return self.container
class BubbleSortV2(SimpleSort):
def run_task(self):
# setting up variables
length = len(self.container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if self.container[i - 1] > self.container[i]:
self.container[i - 1], self.container[i] = self.container[i], self.container[i - 1]
changed_times = i
length = changed_times
return self.container
core\algorithms\algorithm.py
import time
class Algorithm:
def __init__(self, **kwargs):
self.set_params(**kwargs)
def set_params(self, **kwargs):
pass
def check_params(self, **kwargs):
pass
def run_task(self):
return None
def time_task(self):
t1 = time.time()
self.run_task()
t2 = time.time()
return (t2 - t1) * 1000
def run(self):
return self.run_task()
core\algorithms\simple_sort\simple_sort.py
from dsal.core.algorithms.algorithm import Algorithm
class SimpleSort(Algorithm):
def set_params(self, **kwargs):
self.container = kwargs["container"]
def check_params(self):
return {
'container': lambda x: isinstance(x, list)
}
def run_task(self):
return None
tests\run_tests.py
import unittest
if __name__ == '__main__':
testsuite = unittest.TestLoader().discover('./algorithms')
for test in testsuite:
unittest.TextTestRunner(verbosity=3).run(test)
tests\algorithms\test.py
from unittest import TestCase
from dsal.core.algorithms.algorithm import Algorithm
class AlgorithmBaseTestCase(TestCase):
def setUp(self):
self.algorithm = Algorithm()
def test_run(self):
self.assertEqual(self.algorithm.run(), None)
def test_run_task(self):
self.assertEqual(self.algorithm.run_task(), None)
def test_time_task(self):
self.assertEqual(self.algorithm.time_task(), 0.0)
def test_set_params(self):
self.assertEqual(self.algorithm.set_params(), None)
self.assertEqual(self.algorithm.set_params(container=[1, 2, 3, 4]), None)
def test_check_params(self):
self.assertEqual(self.algorithm.set_params(), None)
self.assertEqual(self.algorithm.set_params(container=[1, 2, 3, 4]), None)
class AlgorithmTestCase(TestCase):
def algorithm_run_test(self, algorithm):
return algorithm.run()
tests\algorithm\sorting\test.py
from tests.algorithms.test import AlgorithmTestCase
class SortTestCase(AlgorithmTestCase):
def setUp(self):
super(AlgorithmTestCase, self).setUp()
def _test_sort_single_func(self, input_list, **kwargs):
expected_list = sorted(input_list)
result = AlgorithmTestCase.algorithm_run_test(self, self.function_name(**kwargs))
self.assertEqual(result, expected_list)
tests\algorithms\sorting\simple_sort\tests.py
from dsal.algorithms.sorting.simple_sort.bubble_sort.bubble_sort import BubbleSortV1
from tests.algorithms.sorting.test import SortTestCase
class SimpleSortTestCase(SortTestCase):
def setUp(self):
self.function_name = BubbleSortV1
super(SortTestCase, self).setUp()
def test_sort_empty_list(self):
input_list = []
self._test_sort_single_func(input_list, container = sorted(input_list))
def test_sort_one_element(self):
input_list = [0]
self.container = input_list
self._test_sort_single_func(input_list, container = sorted(input_list))
def test_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self.container = input_list
self._test_sort_single_func(input_list, container = sorted(input_list))
def test_sort_already_sorted(self):
input_list = [1, 2, 3, 4]
self.container = input_list
self._test_sort_single_func(input_list, container = sorted(input_list))
def test_sort_reversed(self):
input_list = [4, 3, 2, 1]
self.container = input_list
self._test_sort_single_func(input_list, container = sorted(input_list))
def test_sort_disorder_with_repetitions(self):
input_list = [3, 5, 3, 2, 4, 2, 1, 1]
self.container = input_list
self._test_sort_single_func(input_list, container = sorted(input_list))
tests\algorithms\sorting\simple_sort\bubble_sort
from dsal.algorithms.sorting.simple_sort.bubble_sort.bubble_sort import BubbleSortV1, BubbleSortV2
from tests.algorithms.sorting.simple_sort.test import SimpleSortTestCase
class BubbleSortV1TestCase(SimpleSortTestCase):
def test_bubble_sort_v1(self):
self.function_name = BubbleSortV1
super(SimpleSortTestCase, self).setUp()
class BubbleSortV2TestCase(SimpleSortTestCase):
def test_bubble_sort_v2(self):
self.function_name = BubbleSortV2
super(SimpleSortTestCase, self).setUp()