Skip to content

Commit 3f98cc9

Browse files
TjstretchalotOmkarPathak
authored andcommitted
Improve sorting tests (#96)
This verifies that sorting algorithms are either entirely inplace or do not modify the list and return a copy. Furthermore, this standardizes how they handle empty lists.
1 parent 953c2d4 commit 3f98cc9

File tree

4 files changed

+173
-134
lines changed

4 files changed

+173
-134
lines changed

pygorithm/sorting/bucket_sort.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@
1414
def sort(_list, bucket_size=5):
1515
"""
1616
bucket sort algorithm
17-
17+
1818
:param _list: list of values to sort
1919
:param bucket_size: Size of the bucket
2020
:return: sorted values
2121
"""
2222
string = False
2323

2424
if len(_list) == 0:
25-
# print("You don\'t have any elements in array!")
26-
raise ValueError("Array can not be empty.")
27-
25+
return []
26+
2827
elif all(isinstance(element, str) for element in _list):
2928
string = True
3029
_list = [ord(element) for element in _list]

pygorithm/sorting/merge_sort.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
Created On: 31st July 2017
44
55
- Best = Average = Worst = O(n log(n))
6-
6+
77
"""
88
import inspect
99

1010

1111
def merge(a, b):
1212
"""
13-
Function to merge
13+
Function to merge
1414
two arrays / separated lists
15-
15+
1616
:param a: Array 1
1717
:param b: Array 2
1818
:return: merged arrays
@@ -34,14 +34,14 @@ def merge(a, b):
3434

3535
def sort(_list):
3636
"""
37-
Function to sort an array
38-
using merge sort algorithm
39-
37+
Function to sort an array
38+
using merge sort algorithm
39+
4040
:param _list: list of values to sort
4141
:return: sorted
4242
"""
4343
if len(_list) == 0 or len(_list) == 1:
44-
return _list
44+
return list(_list)
4545
else:
4646
middle = len(_list)//2
4747
a = sort(_list[:middle])
@@ -61,7 +61,7 @@ def time_complexities():
6161

6262
def get_code():
6363
"""
64-
easily retrieve the source code
64+
easily retrieve the source code
6565
of the sort function
6666
6767
:return: source code

pygorithm/sorting/quick_sort.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def sort(_list):
1616
:return: sorted list
1717
"""
1818
if len(_list) <= 1:
19-
return _list
19+
return list(_list)
2020
pivot = _list[len(_list) // 2]
2121
left = [x for x in _list if x < pivot]
2222
middle = [x for x in _list if x == pivot]

tests/test_sorting.py

Lines changed: 161 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,161 @@
1-
import unittest
2-
import random
3-
4-
from pygorithm.sorting import (
5-
bubble_sort,
6-
insertion_sort,
7-
selection_sort,
8-
merge_sort,
9-
quick_sort,
10-
counting_sort,
11-
bucket_sort,
12-
shell_sort,
13-
heap_sort,
14-
radix_sort)
15-
16-
17-
class TestSortingAlgorithm(unittest.TestCase):
18-
def setUp(self):
19-
# to test numeric numbers
20-
self.array = list(range(15))
21-
random.shuffle(self.array)
22-
self.sorted_array = list(range(15))
23-
24-
# to test alphabets
25-
string = 'pythonisawesome'
26-
self.alphaArray = list(string)
27-
random.shuffle(self.alphaArray)
28-
self.sorted_alpha_array = sorted(string)
29-
30-
31-
class TestBubbleSort(TestSortingAlgorithm):
32-
def test_bubble_sort(self):
33-
self.result = bubble_sort.sort(self.array)
34-
self.assertEqual(self.result, self.sorted_array)
35-
36-
self.alphaResult = bubble_sort.sort(self.alphaArray)
37-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
38-
39-
40-
class TestInsertionSort(TestSortingAlgorithm):
41-
def test_insertion_sort(self):
42-
self.result = insertion_sort.sort(self.array)
43-
self.assertEqual(self.result, self.sorted_array)
44-
45-
self.alphaResult = insertion_sort.sort(self.alphaArray)
46-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
47-
48-
49-
class TestSelectionSort(TestSortingAlgorithm):
50-
def test_selection_sort(self):
51-
self.result = selection_sort.sort(self.array)
52-
self.assertEqual(self.result, self.sorted_array)
53-
54-
self.alphaResult = selection_sort.sort(self.alphaArray)
55-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
56-
57-
58-
class TestMergeSort(TestSortingAlgorithm):
59-
def test_merge_sort(self):
60-
self.result = merge_sort.sort(self.array)
61-
self.assertEqual(self.result, self.sorted_array)
62-
63-
self.alphaResult = merge_sort.sort(self.alphaArray)
64-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
65-
66-
67-
class TestQuickSort(TestSortingAlgorithm):
68-
def test_quick_sort(self):
69-
self.result = quick_sort.sort(self.array)
70-
self.assertEqual(self.result, self.sorted_array)
71-
72-
self.alphaResult = quick_sort.sort(self.alphaArray)
73-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
74-
75-
76-
class TestCountingSort(TestSortingAlgorithm):
77-
def test_counting_sort(self):
78-
# counting sort is an integer based sort
79-
self.result = counting_sort.sort(self.array)
80-
self.assertEqual(self.result, self.sorted_array)
81-
82-
83-
class TestBucketSort(TestSortingAlgorithm):
84-
def test_bucket_sort(self):
85-
self.result = bucket_sort.sort(self.array)
86-
self.assertEqual(self.result, self.sorted_array)
87-
88-
self.alphaResult = bucket_sort.sort(self.alphaArray)
89-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
90-
91-
92-
class TestShellSort(TestSortingAlgorithm):
93-
def test_shell_sort(self):
94-
self.result = shell_sort.sort(self.array)
95-
self.assertEqual(self.result, self.sorted_array)
96-
97-
self.alphaResult = shell_sort.sort(self.alphaArray)
98-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
99-
100-
101-
class TestHeapSort(TestSortingAlgorithm):
102-
def test_heap_sort(self):
103-
self.result = heap_sort.sort(self.array)
104-
self.assertEqual(self.result, self.sorted_array)
105-
106-
self.alphaResult = heap_sort.sort(self.alphaArray)
107-
self.assertEqual(self.alphaResult, self.sorted_alpha_array)
108-
109-
110-
class TestRadixSort(TestSortingAlgorithm):
111-
def test_radix_sort(self):
112-
self.result = radix_sort.sort(self.array)
113-
self.assertEqual(self.result, self.sorted_array)
114-
115-
# TODO: Fix radix sort to sort alphabetically
116-
# self.alphaResult = radix_sort.sort(self.alphaArray)
117-
# self.assertEqual(self.alphaResult, self.sorted_alpha_array)
118-
119-
120-
if __name__ == '__main__':
121-
unittest.main()
1+
import unittest
2+
import random
3+
4+
from pygorithm.sorting import (
5+
bubble_sort,
6+
insertion_sort,
7+
selection_sort,
8+
merge_sort,
9+
quick_sort,
10+
counting_sort,
11+
bucket_sort,
12+
shell_sort,
13+
heap_sort)
14+
15+
16+
class TestSortingAlgorithm:
17+
def test_test_setup(self):
18+
self.assertIsNotNone(getattr(self, 'sort', None))
19+
self.assertIsNotNone(getattr(self, 'inplace', None))
20+
self.assertIsNotNone(getattr(self, 'alph_support', None))
21+
22+
def _check_sort_list(self, arr, expected):
23+
cp_arr = list(arr)
24+
sarr = self.sort(cp_arr)
25+
26+
self.assertTrue(
27+
isinstance(sarr, list), 'weird result type: ' + str(type(sarr)))
28+
self.assertEqual(len(sarr), len(arr))
29+
self.assertEqual(sarr, expected)
30+
if self.inplace:
31+
self.assertTrue(cp_arr is sarr, 'was not inplace')
32+
else:
33+
self.assertTrue(cp_arr is not sarr, 'was inplace')
34+
self.assertEqual(cp_arr, arr, 'inplace modified list')
35+
36+
def _check_sort_alph(self, inp, expected):
37+
if not self.alph_support:
38+
return
39+
40+
self._check_sort_list(list(inp), list(expected))
41+
42+
def test_sort_empty(self):
43+
self._check_sort_list([], [])
44+
45+
def test_sort_single(self):
46+
self._check_sort_list([5], [5])
47+
48+
def test_sort_single_alph(self):
49+
self._check_sort_alph('a', 'a')
50+
51+
def test_sort_two_inorder(self):
52+
self._check_sort_list([1, 2], [1, 2])
53+
54+
def test_sort_two_outoforder(self):
55+
self._check_sort_list([2, 1], [1, 2])
56+
57+
def test_sort_5_random_numeric(self):
58+
arr = list(range(5))
59+
random.shuffle(arr)
60+
self._check_sort_list(arr, list(range(5)))
61+
62+
def test_sort_15_random_numeric(self):
63+
arr = list(range(15))
64+
random.shuffle(arr)
65+
self._check_sort_list(arr, list(range(15)))
66+
67+
def test_sort_5_random_alph(self):
68+
arr = ['a', 'b', 'c', 'd', 'e']
69+
random.shuffle(arr)
70+
self._check_sort_alph(''.join(arr), 'abcde')
71+
72+
def test_sort_15_random_alph(self):
73+
arr = [chr(ord('a') + i) for i in range(15)]
74+
exp = ''.join(arr)
75+
random.shuffle(arr)
76+
self._check_sort_alph(''.join(arr), exp)
77+
78+
79+
class TestBubbleSort(unittest.TestCase, TestSortingAlgorithm):
80+
inplace = True
81+
alph_support = True
82+
83+
@staticmethod
84+
def sort(arr):
85+
return bubble_sort.sort(arr)
86+
87+
88+
class TestInsertionSort(unittest.TestCase, TestSortingAlgorithm):
89+
inplace = True
90+
alph_support = True
91+
92+
@staticmethod
93+
def sort(arr):
94+
return insertion_sort.sort(arr)
95+
96+
97+
class TestSelectionSort(unittest.TestCase, TestSortingAlgorithm):
98+
inplace = True
99+
alph_support = True
100+
101+
@staticmethod
102+
def sort(arr):
103+
return selection_sort.sort(arr)
104+
105+
106+
class TestMergeSort(unittest.TestCase, TestSortingAlgorithm):
107+
inplace = False
108+
alph_support = True
109+
110+
@staticmethod
111+
def sort(arr):
112+
return merge_sort.sort(arr)
113+
114+
115+
class TestQuickSort(unittest.TestCase, TestSortingAlgorithm):
116+
inplace = False
117+
alph_support = True
118+
119+
@staticmethod
120+
def sort(arr):
121+
return quick_sort.sort(arr)
122+
123+
124+
class TestCountingSort(unittest.TestCase, TestSortingAlgorithm):
125+
inplace = True
126+
alph_support = False
127+
128+
@staticmethod
129+
def sort(arr):
130+
return counting_sort.sort(arr)
131+
132+
133+
class TestBucketSort(unittest.TestCase, TestSortingAlgorithm):
134+
inplace = False
135+
alph_support = True
136+
137+
@staticmethod
138+
def sort(arr):
139+
return bucket_sort.sort(arr)
140+
141+
142+
class TestShellSort(unittest.TestCase, TestSortingAlgorithm):
143+
inplace = True
144+
alph_support = True
145+
146+
@staticmethod
147+
def sort(arr):
148+
return shell_sort.sort(arr)
149+
150+
151+
class TestHeapSort(unittest.TestCase, TestSortingAlgorithm):
152+
inplace = True
153+
alph_support = True
154+
155+
@staticmethod
156+
def sort(arr):
157+
return heap_sort.sort(arr)
158+
159+
160+
if __name__ == '__main__':
161+
unittest.main()

0 commit comments

Comments
 (0)