Bubble sort algorithms and unittest in Python
up vote
4
down vote
favorite
I am quite new in Python and I am starting my journey with sorting algorithms, PEP8 and the Zen of Python. So far i wrote a post BubbleSort and I drew conclusions and followed the advices. I implemented two methods with optimatization from Wikipedia. I would ask for information about the current code, tests and directories.
- Is it possible to write tests more succinctly?
- Should i make a docummentation with tests? ( or the specific name of the function is enough )
- Is the code compatible with PEP8 and Zen of Python?
- Is the code compatible with Python-style coding?
- What should i change to avoid future problems with my code?
- Should i add more options to functions for example: reverse, default options, exceptions? ( or its unnecessary in algorithms )
- Should i add comparator? Should it be a class then? Can you give some advice?
- Is my directory layout correct?
- If you found something else in the text, try to give me this information.
My directory looks like:
Python:.
│
├───algorithms
│ └───sorting
│ bubble_sort.py
│ __init__.py
│
└───tests
└───algorithms
└───sorting
bubble_sort_test.py
__init__.py
bubble_sort.py
import copy
def bubble_sort_v_one(container: object) -> object:
"""
Bubble sort with first optimization.
Description
----------
From wikipedia: inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if container[i] > container[i + 1]:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container: object) -> object:
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if container[i - 1] > container[i]:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort_v_one as bubble_one
from Algorithms.Sorting.bubble_sort import bubble_sort_v_two as bubble_two
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_one([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_one([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_one([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_one([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_one(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_two([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_two([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_two([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_two([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_two(), )
if __name__ == '__main__':
unittest.main()
Should i add bubble_sort
function so user can choose which version want to run easier?
def bubble_sort(container: object, version : int = 1) -> object:
if version == 1:
bubble_sort_v_one(container)
elif version == 2:
bubble_sort_v_two(container)
else:
raise ValueError
What do you think about comparator and editing the function head to:
def comparator(a: object, b: object) -> object:
return a - b
def bubble_sort_v_one(container: object, comparator=comparator) -> object:
and for sure the line for comparating the 2 variables should like like that:
if comparator(container[i] , container[i + 1]) > 0:
Of course, the questions are not only about this code. I would like to know if this methodology in the future will help me write correct and clean code and will increase its functionality.
So my bubble_sort.py
will look like:
import copy
def comparator(a, b):
return a - b
def bubble_sort(container, version: int = 1, cmp=comparator):
if version == 1:
return bubble_sort_v_one(container, cmp)
elif version == 2:
return bubble_sort_v_two(container, cmp)
else:
raise ValueError
def bubble_sort_v_one(container, cmp):
"""
Bubble sort with first optimization.
Description
----------
From wikipedia : inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if cmp(container[i], container[i + 1]) > 0:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container, cmp):
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if cmp(container[i - 1], container[i]) > 0:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
and bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5],
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], version=2),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2,
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2,
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
version=2, cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1], version=2), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(, version=2), )
if __name__ == '__main__':
unittest.main()
Which one is better and why? Of course I will accept all the imperfections on the chest.
python beginner sorting unit-testing comparative-review
add a comment |
up vote
4
down vote
favorite
I am quite new in Python and I am starting my journey with sorting algorithms, PEP8 and the Zen of Python. So far i wrote a post BubbleSort and I drew conclusions and followed the advices. I implemented two methods with optimatization from Wikipedia. I would ask for information about the current code, tests and directories.
- Is it possible to write tests more succinctly?
- Should i make a docummentation with tests? ( or the specific name of the function is enough )
- Is the code compatible with PEP8 and Zen of Python?
- Is the code compatible with Python-style coding?
- What should i change to avoid future problems with my code?
- Should i add more options to functions for example: reverse, default options, exceptions? ( or its unnecessary in algorithms )
- Should i add comparator? Should it be a class then? Can you give some advice?
- Is my directory layout correct?
- If you found something else in the text, try to give me this information.
My directory looks like:
Python:.
│
├───algorithms
│ └───sorting
│ bubble_sort.py
│ __init__.py
│
└───tests
└───algorithms
└───sorting
bubble_sort_test.py
__init__.py
bubble_sort.py
import copy
def bubble_sort_v_one(container: object) -> object:
"""
Bubble sort with first optimization.
Description
----------
From wikipedia: inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if container[i] > container[i + 1]:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container: object) -> object:
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if container[i - 1] > container[i]:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort_v_one as bubble_one
from Algorithms.Sorting.bubble_sort import bubble_sort_v_two as bubble_two
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_one([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_one([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_one([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_one([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_one(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_two([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_two([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_two([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_two([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_two(), )
if __name__ == '__main__':
unittest.main()
Should i add bubble_sort
function so user can choose which version want to run easier?
def bubble_sort(container: object, version : int = 1) -> object:
if version == 1:
bubble_sort_v_one(container)
elif version == 2:
bubble_sort_v_two(container)
else:
raise ValueError
What do you think about comparator and editing the function head to:
def comparator(a: object, b: object) -> object:
return a - b
def bubble_sort_v_one(container: object, comparator=comparator) -> object:
and for sure the line for comparating the 2 variables should like like that:
if comparator(container[i] , container[i + 1]) > 0:
Of course, the questions are not only about this code. I would like to know if this methodology in the future will help me write correct and clean code and will increase its functionality.
So my bubble_sort.py
will look like:
import copy
def comparator(a, b):
return a - b
def bubble_sort(container, version: int = 1, cmp=comparator):
if version == 1:
return bubble_sort_v_one(container, cmp)
elif version == 2:
return bubble_sort_v_two(container, cmp)
else:
raise ValueError
def bubble_sort_v_one(container, cmp):
"""
Bubble sort with first optimization.
Description
----------
From wikipedia : inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if cmp(container[i], container[i + 1]) > 0:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container, cmp):
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if cmp(container[i - 1], container[i]) > 0:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
and bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5],
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], version=2),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2,
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2,
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
version=2, cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1], version=2), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(, version=2), )
if __name__ == '__main__':
unittest.main()
Which one is better and why? Of course I will accept all the imperfections on the chest.
python beginner sorting unit-testing comparative-review
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I am quite new in Python and I am starting my journey with sorting algorithms, PEP8 and the Zen of Python. So far i wrote a post BubbleSort and I drew conclusions and followed the advices. I implemented two methods with optimatization from Wikipedia. I would ask for information about the current code, tests and directories.
- Is it possible to write tests more succinctly?
- Should i make a docummentation with tests? ( or the specific name of the function is enough )
- Is the code compatible with PEP8 and Zen of Python?
- Is the code compatible with Python-style coding?
- What should i change to avoid future problems with my code?
- Should i add more options to functions for example: reverse, default options, exceptions? ( or its unnecessary in algorithms )
- Should i add comparator? Should it be a class then? Can you give some advice?
- Is my directory layout correct?
- If you found something else in the text, try to give me this information.
My directory looks like:
Python:.
│
├───algorithms
│ └───sorting
│ bubble_sort.py
│ __init__.py
│
└───tests
└───algorithms
└───sorting
bubble_sort_test.py
__init__.py
bubble_sort.py
import copy
def bubble_sort_v_one(container: object) -> object:
"""
Bubble sort with first optimization.
Description
----------
From wikipedia: inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if container[i] > container[i + 1]:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container: object) -> object:
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if container[i - 1] > container[i]:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort_v_one as bubble_one
from Algorithms.Sorting.bubble_sort import bubble_sort_v_two as bubble_two
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_one([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_one([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_one([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_one([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_one(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_two([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_two([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_two([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_two([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_two(), )
if __name__ == '__main__':
unittest.main()
Should i add bubble_sort
function so user can choose which version want to run easier?
def bubble_sort(container: object, version : int = 1) -> object:
if version == 1:
bubble_sort_v_one(container)
elif version == 2:
bubble_sort_v_two(container)
else:
raise ValueError
What do you think about comparator and editing the function head to:
def comparator(a: object, b: object) -> object:
return a - b
def bubble_sort_v_one(container: object, comparator=comparator) -> object:
and for sure the line for comparating the 2 variables should like like that:
if comparator(container[i] , container[i + 1]) > 0:
Of course, the questions are not only about this code. I would like to know if this methodology in the future will help me write correct and clean code and will increase its functionality.
So my bubble_sort.py
will look like:
import copy
def comparator(a, b):
return a - b
def bubble_sort(container, version: int = 1, cmp=comparator):
if version == 1:
return bubble_sort_v_one(container, cmp)
elif version == 2:
return bubble_sort_v_two(container, cmp)
else:
raise ValueError
def bubble_sort_v_one(container, cmp):
"""
Bubble sort with first optimization.
Description
----------
From wikipedia : inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if cmp(container[i], container[i + 1]) > 0:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container, cmp):
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if cmp(container[i - 1], container[i]) > 0:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
and bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5],
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], version=2),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2,
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2,
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
version=2, cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1], version=2), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(, version=2), )
if __name__ == '__main__':
unittest.main()
Which one is better and why? Of course I will accept all the imperfections on the chest.
python beginner sorting unit-testing comparative-review
I am quite new in Python and I am starting my journey with sorting algorithms, PEP8 and the Zen of Python. So far i wrote a post BubbleSort and I drew conclusions and followed the advices. I implemented two methods with optimatization from Wikipedia. I would ask for information about the current code, tests and directories.
- Is it possible to write tests more succinctly?
- Should i make a docummentation with tests? ( or the specific name of the function is enough )
- Is the code compatible with PEP8 and Zen of Python?
- Is the code compatible with Python-style coding?
- What should i change to avoid future problems with my code?
- Should i add more options to functions for example: reverse, default options, exceptions? ( or its unnecessary in algorithms )
- Should i add comparator? Should it be a class then? Can you give some advice?
- Is my directory layout correct?
- If you found something else in the text, try to give me this information.
My directory looks like:
Python:.
│
├───algorithms
│ └───sorting
│ bubble_sort.py
│ __init__.py
│
└───tests
└───algorithms
└───sorting
bubble_sort_test.py
__init__.py
bubble_sort.py
import copy
def bubble_sort_v_one(container: object) -> object:
"""
Bubble sort with first optimization.
Description
----------
From wikipedia: inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if container[i] > container[i + 1]:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container: object) -> object:
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best case : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
Returns
-------
container : Sorted container
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if container[i - 1] > container[i]:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort_v_one as bubble_one
from Algorithms.Sorting.bubble_sort import bubble_sort_v_two as bubble_two
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_one([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_one([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_one([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_one([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_one(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_two([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_two([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_two([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_two([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_two(), )
if __name__ == '__main__':
unittest.main()
Should i add bubble_sort
function so user can choose which version want to run easier?
def bubble_sort(container: object, version : int = 1) -> object:
if version == 1:
bubble_sort_v_one(container)
elif version == 2:
bubble_sort_v_two(container)
else:
raise ValueError
What do you think about comparator and editing the function head to:
def comparator(a: object, b: object) -> object:
return a - b
def bubble_sort_v_one(container: object, comparator=comparator) -> object:
and for sure the line for comparating the 2 variables should like like that:
if comparator(container[i] , container[i + 1]) > 0:
Of course, the questions are not only about this code. I would like to know if this methodology in the future will help me write correct and clean code and will increase its functionality.
So my bubble_sort.py
will look like:
import copy
def comparator(a, b):
return a - b
def bubble_sort(container, version: int = 1, cmp=comparator):
if version == 1:
return bubble_sort_v_one(container, cmp)
elif version == 2:
return bubble_sort_v_two(container, cmp)
else:
raise ValueError
def bubble_sort_v_one(container, cmp):
"""
Bubble sort with first optimization.
Description
----------
From wikipedia : inner loop can avoid looking
at the last (length − 1) items when running for the n-th time.
Performance cases:
Worst : O(n^2)
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_one([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_one(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
changed = True
while changed:
changed = False
for i in range(length - 1):
if cmp(container[i], container[i + 1]) > 0:
container[i], container[i + 1] = container[i + 1], container[i]
changed = True
length -= 1
return container
def bubble_sort_v_two(container, cmp):
"""
Bubble sort with second optimization.
Description
----------
From wikipedia: This allows us to skip over a lot of the elements,
resulting in about a worst case 50% improvement in comparison count.
Performance cases:
Worst : O(n^2) - 50%
Average : O(n^2)
Best : O(n)
Parameters
----------
container : Mutable container with comparable objects and structure
which has implemented __len__, __getitem__ and __setitem__.
cmp : Comparator default a - b > 0
Returns
-------
container : New sorted container,
Examples
----------
>>> bubble_sort_v_two([7,1,2,6,4,2,3])
[1, 2, 2, 3, 4, 6, 7]
>>> bubble_sort_v_two(['a', 'c', 'b'])
['a', 'b', 'c']
"""
# setting up variables
container = copy.copy(container)
length = len(container)
while length >= 1:
changed_times = 0
for i in range(1, length):
if cmp(container[i - 1], container[i]) > 0:
container[i - 1], container[i] = container[i], container[i - 1]
changed_times = i
length = changed_times
return container
and bubble_sort_test.py
import unittest
from Algorithms.Sorting.bubble_sort import bubble_sort
class TestBubbleSortVOneAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1]),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5]),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5],
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1]), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(), )
class TestBubbleSortVTwoAlgorithm(unittest.TestCase):
def test_bubble_sort_with_positive_numbers(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2),
[1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_negative_numbers_only(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2),
[-9, -7, -5, -5, -3, -1])
def test_bubble_sort_with_negative_and_positive_numbers(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], version=2),
[-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_with_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([5, 5, 7, 8, 2, 4, 1], version=2,
cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1])
def test_bubble_sort_negative_numbers_only_reverse(self):
self.assertEqual(bubble_sort([-1, -3, -5, -7, -9, -5], version=2,
cmp=lambda x, y: y - x),
[-1, -3, -5, -5, -7, -9])
def test_bubble_sort_with_negative_and_positive_numbers_reverse(self):
self.assertEqual(bubble_sort([-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1],
version=2, cmp=lambda x, y: y - x),
[8, 7, 5, 5, 4, 2, 1, 0, -4, -5, -6])
def test_bubble_sort_same_numbers(self):
self.assertEqual(bubble_sort([1, 1, 1, 1], version=2), [1, 1, 1, 1])
def test_bubble_sort_empty_list(self):
self.assertEqual(bubble_sort(, version=2), )
if __name__ == '__main__':
unittest.main()
Which one is better and why? Of course I will accept all the imperfections on the chest.
python beginner sorting unit-testing comparative-review
python beginner sorting unit-testing comparative-review
edited Dec 11 at 10:56
asked Dec 10 at 19:38
Michael Ogorkovyi
263
263
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Various things with no precise order:
Function names
Numbers are accepted in identifier such as function names. Instead of having my_func_v_one
, you could go for my_func_v1
.
Less verbose tests
These comments are to be taken with a pinch of salt: some prefer their unit test to be as simple as possible, some prefer to consider them as code and apply the usual principles such as Don't repeat yourself.
In order to make the tests more concise and easier to write, you could consider adding an helper method.
Also, you could have a single class like this:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list, expected_list):
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_v1_with_positive_numbers(self):
self._test_sort(bubble_sort_v1, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_negative_numbers_only(self):
self._test_sort(bubble_sort_v1, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v1_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v1, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_same_numbers(self):
self._test_sort(bubble_sort_v1, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v1_empty_list(self):
self._test_sort(bubble_sort_v1, , )
def test_bubble_sort_v2_with_positive_numbers(self):
self._test_sort(bubble_sort_v2, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_negative_numbers_only(self):
self._test_sort(bubble_sort_v2, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v2_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v2, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_same_numbers(self):
self._test_sort(bubble_sort_v2, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v2_empty_list(self):
self._test_sort(bubble_sort_v2, , )
Then you can use the fact that we have a sorting function we can trust to use it as a Test Oracle.
Then you can write something like:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
Or even:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
Also, as for the tests themselves, I wouldn't base my tests on type of numbers you have (positive, negative, etc) other criteria. For instance, I'd write the following tests:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
def test_bubble_sort_one_element(self):
input_list = [0]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_already_sorted(self):
input_list = [1, 2, 3, 4]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_reversed(self):
input_list = [4, 3, 2, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_disorder_with_repetitions(self):
input_list = [3, 5, 3, 2, 4, 2, 1, 1]
self._test_sort_all_funcs(input_list)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209387%2fbubble-sort-algorithms-and-unittest-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Various things with no precise order:
Function names
Numbers are accepted in identifier such as function names. Instead of having my_func_v_one
, you could go for my_func_v1
.
Less verbose tests
These comments are to be taken with a pinch of salt: some prefer their unit test to be as simple as possible, some prefer to consider them as code and apply the usual principles such as Don't repeat yourself.
In order to make the tests more concise and easier to write, you could consider adding an helper method.
Also, you could have a single class like this:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list, expected_list):
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_v1_with_positive_numbers(self):
self._test_sort(bubble_sort_v1, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_negative_numbers_only(self):
self._test_sort(bubble_sort_v1, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v1_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v1, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_same_numbers(self):
self._test_sort(bubble_sort_v1, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v1_empty_list(self):
self._test_sort(bubble_sort_v1, , )
def test_bubble_sort_v2_with_positive_numbers(self):
self._test_sort(bubble_sort_v2, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_negative_numbers_only(self):
self._test_sort(bubble_sort_v2, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v2_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v2, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_same_numbers(self):
self._test_sort(bubble_sort_v2, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v2_empty_list(self):
self._test_sort(bubble_sort_v2, , )
Then you can use the fact that we have a sorting function we can trust to use it as a Test Oracle.
Then you can write something like:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
Or even:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
Also, as for the tests themselves, I wouldn't base my tests on type of numbers you have (positive, negative, etc) other criteria. For instance, I'd write the following tests:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
def test_bubble_sort_one_element(self):
input_list = [0]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_already_sorted(self):
input_list = [1, 2, 3, 4]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_reversed(self):
input_list = [4, 3, 2, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_disorder_with_repetitions(self):
input_list = [3, 5, 3, 2, 4, 2, 1, 1]
self._test_sort_all_funcs(input_list)
add a comment |
up vote
0
down vote
Various things with no precise order:
Function names
Numbers are accepted in identifier such as function names. Instead of having my_func_v_one
, you could go for my_func_v1
.
Less verbose tests
These comments are to be taken with a pinch of salt: some prefer their unit test to be as simple as possible, some prefer to consider them as code and apply the usual principles such as Don't repeat yourself.
In order to make the tests more concise and easier to write, you could consider adding an helper method.
Also, you could have a single class like this:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list, expected_list):
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_v1_with_positive_numbers(self):
self._test_sort(bubble_sort_v1, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_negative_numbers_only(self):
self._test_sort(bubble_sort_v1, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v1_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v1, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_same_numbers(self):
self._test_sort(bubble_sort_v1, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v1_empty_list(self):
self._test_sort(bubble_sort_v1, , )
def test_bubble_sort_v2_with_positive_numbers(self):
self._test_sort(bubble_sort_v2, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_negative_numbers_only(self):
self._test_sort(bubble_sort_v2, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v2_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v2, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_same_numbers(self):
self._test_sort(bubble_sort_v2, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v2_empty_list(self):
self._test_sort(bubble_sort_v2, , )
Then you can use the fact that we have a sorting function we can trust to use it as a Test Oracle.
Then you can write something like:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
Or even:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
Also, as for the tests themselves, I wouldn't base my tests on type of numbers you have (positive, negative, etc) other criteria. For instance, I'd write the following tests:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
def test_bubble_sort_one_element(self):
input_list = [0]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_already_sorted(self):
input_list = [1, 2, 3, 4]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_reversed(self):
input_list = [4, 3, 2, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_disorder_with_repetitions(self):
input_list = [3, 5, 3, 2, 4, 2, 1, 1]
self._test_sort_all_funcs(input_list)
add a comment |
up vote
0
down vote
up vote
0
down vote
Various things with no precise order:
Function names
Numbers are accepted in identifier such as function names. Instead of having my_func_v_one
, you could go for my_func_v1
.
Less verbose tests
These comments are to be taken with a pinch of salt: some prefer their unit test to be as simple as possible, some prefer to consider them as code and apply the usual principles such as Don't repeat yourself.
In order to make the tests more concise and easier to write, you could consider adding an helper method.
Also, you could have a single class like this:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list, expected_list):
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_v1_with_positive_numbers(self):
self._test_sort(bubble_sort_v1, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_negative_numbers_only(self):
self._test_sort(bubble_sort_v1, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v1_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v1, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_same_numbers(self):
self._test_sort(bubble_sort_v1, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v1_empty_list(self):
self._test_sort(bubble_sort_v1, , )
def test_bubble_sort_v2_with_positive_numbers(self):
self._test_sort(bubble_sort_v2, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_negative_numbers_only(self):
self._test_sort(bubble_sort_v2, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v2_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v2, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_same_numbers(self):
self._test_sort(bubble_sort_v2, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v2_empty_list(self):
self._test_sort(bubble_sort_v2, , )
Then you can use the fact that we have a sorting function we can trust to use it as a Test Oracle.
Then you can write something like:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
Or even:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
Also, as for the tests themselves, I wouldn't base my tests on type of numbers you have (positive, negative, etc) other criteria. For instance, I'd write the following tests:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
def test_bubble_sort_one_element(self):
input_list = [0]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_already_sorted(self):
input_list = [1, 2, 3, 4]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_reversed(self):
input_list = [4, 3, 2, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_disorder_with_repetitions(self):
input_list = [3, 5, 3, 2, 4, 2, 1, 1]
self._test_sort_all_funcs(input_list)
Various things with no precise order:
Function names
Numbers are accepted in identifier such as function names. Instead of having my_func_v_one
, you could go for my_func_v1
.
Less verbose tests
These comments are to be taken with a pinch of salt: some prefer their unit test to be as simple as possible, some prefer to consider them as code and apply the usual principles such as Don't repeat yourself.
In order to make the tests more concise and easier to write, you could consider adding an helper method.
Also, you could have a single class like this:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list, expected_list):
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_v1_with_positive_numbers(self):
self._test_sort(bubble_sort_v1, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_negative_numbers_only(self):
self._test_sort(bubble_sort_v1, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v1_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v1, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v1_same_numbers(self):
self._test_sort(bubble_sort_v1, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v1_empty_list(self):
self._test_sort(bubble_sort_v1, , )
def test_bubble_sort_v2_with_positive_numbers(self):
self._test_sort(bubble_sort_v2, [5, 5, 7, 8, 2, 4, 1], [1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_negative_numbers_only(self):
self._test_sort(bubble_sort_v2, [-1, -3, -5, -7, -9, -5], [-9, -7, -5, -5, -3, -1])
def test_bubble_sort_v2_with_negative_and_positive_numbers(self):
self._test_sort(bubble_sort_v2, [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1], [-6, -5, -4, 0, 1, 2, 4, 5, 5, 7, 8])
def test_bubble_sort_v2_same_numbers(self):
self._test_sort(bubble_sort_v2, [1, 1, 1, 1], [1, 1, 1, 1])
def test_bubble_sort_v2_empty_list(self):
self._test_sort(bubble_sort_v2, , )
Then you can use the fact that we have a sorting function we can trust to use it as a Test Oracle.
Then you can write something like:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort(bubble_sort_v1, input_list)
self._test_sort(bubble_sort_v2, input_list)
Or even:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_with_positive_numbers(self):
input_list = [5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_negative_numbers_only(self):
input_list = [-1, -3, -5, -7, -9, -5]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_with_negative_and_positive_numbers(self):
input_list = [-6, -5, -4, 0, 5, 5, 7, 8, 2, 4, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
Also, as for the tests themselves, I wouldn't base my tests on type of numbers you have (positive, negative, etc) other criteria. For instance, I'd write the following tests:
class TestBubbleSortAlgorithm(unittest.TestCase):
def _test_sort_single_func(self, sorting_func, input_list):
expected_list = sorted(input_list)
self.assertEqual(sorting_func(input_list), expected_list)
def _test_sort_all_funcs(self, input_list):
self._test_sort_single_func(bubble_sort_v1, input_list)
self._test_sort_single_func(bubble_sort_v2, input_list)
def test_bubble_sort_empty_list(self):
input_list =
self._test_sort_all_funcs(input_list)
def test_bubble_sort_one_element(self):
input_list = [0]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_same_numbers(self):
input_list = [1, 1, 1, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_already_sorted(self):
input_list = [1, 2, 3, 4]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_reversed(self):
input_list = [4, 3, 2, 1]
self._test_sort_all_funcs(input_list)
def test_bubble_sort_disorder_with_repetitions(self):
input_list = [3, 5, 3, 2, 4, 2, 1, 1]
self._test_sort_all_funcs(input_list)
answered Dec 12 at 14:14
Josay
24.8k13784
24.8k13784
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209387%2fbubble-sort-algorithms-and-unittest-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown