Skip to content

Commit f8f7773

Browse files
authored
fix: I revised previous changes to meet contributing.md guidelines
I reviewed and revised the changes from the previous commits and made sure that they follow the CONTRIBUTING.md guidelines. The revisions I made include: 1.Correcting and expanding doctests. 2. Adding missing type hints and docstrings. 3. Handling invalid input with ValueError. 4. Improving variable naming and code readability. 5. Cleaning up formatting and spacing. 6. Maintaining the original patience sort implementation and the added mixed integer, float, and string functionality.
1 parent 1447b36 commit f8f7773

1 file changed

Lines changed: 77 additions & 33 deletions

File tree

‎sorts/patience_sort.py‎

Lines changed: 77 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
from __future__ import annotations
2+
23
from bisect import bisect_left
34
from functools import total_ordering
45
from heapq import merge
56

67
"""
7-
A pure Python implementation of the patience sort algorithm
8+
A pure Python implementation of the patience sort algorithm.
89
910
For more information: https://en.wikipedia.org/wiki/Patience_sorting
1011
11-
This algorithm is based on the card game patience
12+
This algorithm is based on the card game patience.
13+
14+
This version can sort integers, floats, and strings using
15+
mixed_patience_sort().
1216
13-
For doctests run following command:
17+
For doctests run the following command:
1418
python3 -m doctest -v patience_sort.py
1519
1620
For manual testing run:
1721
python3 patience_sort.py
1822
"""
1923

24+
2025
@total_ordering
2126
class Stack(list):
2227
def __lt__(self, other):
@@ -25,13 +30,11 @@ def __lt__(self, other):
2530
def __eq__(self, other):
2631
return self[-1] == other[-1]
2732

28-
def patience_sort(collection: list) -> list:
29-
"""A pure implementation of patience sort algorithm in Python
30-
31-
:param collection: some mutable ordered collection with heterogeneous
32-
comparable items inside
33-
:return: the same collection ordered by ascending
3433

34+
def patience_sort(collection: list) -> list:
35+
"""Sort a collection using the patience sort algorithm.
36+
:param collection: A mutable ordered collection containing comparable items.
37+
:return: The same collection ordered in ascending order.
3538
Examples:
3639
>>> patience_sort([1, 9, 5, 21, 17, 6])
3740
[1, 5, 6, 9, 17, 21]
@@ -43,47 +46,87 @@ def patience_sort(collection: list) -> list:
4346
[-48, -17, -3]
4447
"""
4548
stacks: list[Stack] = []
46-
# sort into stacks
49+
50+
# Place each element on the first suitable stack, following
51+
# the rules of the patience sort algorithm.
4752
for element in collection:
48-
new_stacks = Stack([element])
49-
i = bisect_left(stacks, new_stacks)
50-
if i != len(stacks):
51-
stacks[i].append(element)
53+
new_stack: list = Stack([element])
54+
stack_index: list = bisect_left(stacks, new_stack)
55+
56+
if stack_index != len(stacks):
57+
stacks[stack_index].append(element)
5258
else:
53-
stacks.append(new_stacks)
54-
55-
# use a heap-based merge to merge stack efficiently
59+
stacks.append(new_stack)
60+
61+
# Merge the stacks to produce the final sorted collection.
5662
collection[:] = merge(*(reversed(stack) for stack in stacks))
5763
return collection
58-
64+
65+
5966
def mixed_patience_sort(collection: list) -> list:
60-
"""
61-
With this block of code, numbers are sorted according to their
62-
magnitude, the strings are arranged in alphbetical order. And the numbers
63-
are arranged before the alphabets.
64-
"""
67+
"""Sort integers, floats, and strings using patience sort.
68+
69+
Numbers are sorted by magnitude and placed before strings.
70+
Strings are sorted alphabetically according to Python's
71+
standard string ordering.
6572
66-
number_items = []
67-
string_items = []
73+
:param collection: A mutable collection containing integers,
74+
floats, and strings.
75+
:return: The same collection with numbers followed by strings.
76+
77+
Examples:
78+
>>> mixed_patience_sort([1, 9, 3.64, "Apple", "letter", 23.65])
79+
[1, 3.64, 9, 23.65, 'Apple', 'letter']
80+
81+
>>> mixed_patience_sort(["banana", "Apple", "letter"])
82+
['Apple', 'banana', 'letter']
83+
84+
>>> mixed_patience_sort([3.5, 1, 8.2])
85+
[1, 3.5, 8.2]
86+
87+
>>> mixed_patience_sort([])
88+
[]
89+
90+
>>> mixed_patience_sort([1, {"name": "Obed"}])
91+
Traceback (most recent call last):
92+
ValueError: Only integers, floats, and strings are allowed.
93+
"""
94+
number_items: list[int | float] = []
95+
string_items: list[str] = []
6896

6997
for element in collection:
7098
if isinstance(element, (int, float)):
7199
number_items.append(element)
72100
elif isinstance(element, str):
73101
string_items.append(element)
74102
else:
75-
print("Only integers, floats, and strings are allowed.")
103+
raise ValueError("Only integers, floats, and strings are allowed.")
76104

77-
# The user input is sort by using the patience sort algorithm
78-
sorted_numbers = patience_sort(number_items)
79-
sorted_strings = patience_sort(string_items)
105+
sorted_numbers: int = patience_sort(number_items)
106+
sorted_strings: str = patience_sort(string_items)
80107

81-
# use a heap-based merge to merge stack efficiently
82108
collection[:] = sorted_numbers + sorted_strings
83109
return collection
84110

85-
def convert_item(item):
111+
112+
def convert_item(item: str) -> int | float | str:
113+
"""Convert a string into an integer, float, or string.
114+
115+
:param item: The input string to convert.
116+
:return: An integer, float, or the original string.
117+
118+
Examples:
119+
>>> convert_item("25")
120+
25
121+
122+
>>> convert_item("3.14")
123+
3.14
124+
125+
>>> convert_item("Apple")
126+
'Apple'
127+
"""
86128
item = item.strip()
129+
87130
try:
88131
return int(item)
89132
except ValueError:
@@ -92,7 +135,8 @@ def convert_item(item):
92135
except ValueError:
93136
return item
94137

138+
95139
if __name__ == "__main__":
96-
user_input = input("Enter numbers separated by a comma:\n").strip()
97-
unsorted = [convert_item(item) for item in user_input.split(",")]
140+
user_input: str| int|float = input("Enter integers, floats, and strings separated by commas:\n").strip()
141+
unsorted: str| int|float = [convert_item(item) for item in user_input.split(",")]
98142
print(mixed_patience_sort(unsorted))

0 commit comments

Comments
 (0)