Skip to content

Commit 94d7867

Browse files
committed
types(reverse_selection): constrain items to Comparable
Bind reverse_selection_sort's element type to a Comparable Protocol so the signature says "a list of items that can be compared with each other" instead of a bare list, and keep the element type in the return. reverse_subarray only swaps elements and never compares them, so its TypeVar stays unbounded. Also adds doctests for a comparable non-int type (strings, floats) and for the failure mode: mixing non-comparable items must raise TypeError rather than silently mis-sort. The test battery picks the sort up for the shared cases and for the rejection check.
1 parent db6bf8a commit 94d7867

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

‎sorts/reverse_selection.py‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44
This algorithm progressively sorts the array by reversing subarrays
55
66
For doctests run following command:
7-
python3 -m doctest -v reverse_selection_sort.py
7+
python3 -m doctest -v reverse_selection.py
88
99
For manual testing run:
10-
python3 reverse_selection_sort.py
10+
python3 reverse_selection.py
1111
"""
1212

13+
from typing import Any, Protocol
1314

14-
def reverse_subarray(arr: list, start: int, end: int) -> None:
15+
16+
class Comparable(Protocol):
17+
def __lt__(self, other: Any, /) -> bool: ...
18+
19+
20+
def reverse_subarray[T](arr: list[T], start: int, end: int) -> None:
1521
"""
1622
Reverse a subarray in-place.
1723
@@ -41,7 +47,7 @@ def reverse_subarray(arr: list, start: int, end: int) -> None:
4147
end -= 1
4248

4349

44-
def reverse_selection_sort(collection: list) -> list:
50+
def reverse_selection_sort[T: Comparable](collection: list[T]) -> list[T]:
4551
"""
4652
A pure implementation of reverse selection sort algorithm in Python
4753
@@ -64,6 +70,17 @@ def reverse_selection_sort(collection: list) -> list:
6470
6571
>>> reverse_selection_sort([5, 4, 3, 2, 1])
6672
[1, 2, 3, 4, 5]
73+
74+
>>> reverse_selection_sort(["banana", "apple", "cherry"])
75+
['apple', 'banana', 'cherry']
76+
77+
>>> reverse_selection_sort([3.14, 1.5, 2.7])
78+
[1.5, 2.7, 3.14]
79+
80+
>>> reverse_selection_sort([1, "a"]) # doctest: +ELLIPSIS
81+
Traceback (most recent call last):
82+
...
83+
TypeError: ...
6784
"""
6885
n = len(collection)
6986
for i in range(n - 1):

‎tests/test_sorts.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
from sorts.quick_sort import quick_sort
4444
from sorts.recursive_insertion_sort import rec_insertion_sort
4545
from sorts.recursive_mergesort_array import merge
46+
from sorts.reverse_selection import reverse_selection_sort
4647
from sorts.reversort import reversort
4748
from sorts.selection_sort import selection_sort
4849
from sorts.shell_sort import shell_sort
@@ -79,6 +80,7 @@ def test_heap_sort() -> None:
7980
pancake_sort,
8081
patience_sort,
8182
quick_sort,
83+
reverse_selection_sort,
8284
reversort,
8385
selection_sort,
8486
shell_sort,
@@ -149,6 +151,7 @@ def test_rec_insertion_sort(case) -> None:
149151
odd_even_sort,
150152
odd_even_transposition,
151153
pancake_sort,
154+
reverse_selection_sort,
152155
reversort,
153156
selection_sort,
154157
shrink_shell_sort,

0 commit comments

Comments
 (0)