From 21c228ce002276492d3b13615162471e0c187414 Mon Sep 17 00:00:00 2001 From: Obed-727 Date: Wed, 23 Sep 2026 20:30:41 +0000 Subject: [PATCH 1/4] Now patience_sort.py can receive integers, floats, and strings. The previous code was only able to receive integers but crashes when you included string and float. Now the new changes receives strings, floats, and integers without crashing. --- sorts/patience_sort.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sorts/patience_sort.py b/sorts/patience_sort.py index 63c2c8ffe99c..49bcac4f2910 100644 --- a/sorts/patience_sort.py +++ b/sorts/patience_sort.py @@ -1,5 +1,4 @@ from __future__ import annotations - from bisect import bisect_left from functools import total_ordering from heapq import merge @@ -18,7 +17,6 @@ python3 patience_sort.py """ - @total_ordering class Stack(list): def __lt__(self, other): @@ -59,8 +57,17 @@ def patience_sort(collection: list) -> list: collection[:] = merge(*(reversed(stack) for stack in stacks)) return collection +def convert_item(item): + item = item.strip() + try: + return int(item) + except ValueError: + try: + return float(item) + except ValueError: + return item if __name__ == "__main__": user_input = input("Enter numbers separated by a comma:\n").strip() - unsorted = [int(item) for item in user_input.split(",")] - print(patience_sort(unsorted)) + unsorted = [convert_item(item) for item in user_input.split(",")] + print(unsorted) From 1447b36136ca6069ad6b3830867e8f0dd1f5e1c3 Mon Sep 17 00:00:00 2001 From: Obed-727 Date: Thu, 24 Sep 2026 02:01:54 +0000 Subject: [PATCH 2/4] Now patience_sort.py receives integers, floats, and strings and the sort them. The code receives integers, strings, and floats. After that it sort them in this order: 1. Numbers are sorted first, followed by alphabets. 2. Integers and floats are sorted according to their magnitude. 3. Strings are sorted in alphabetical order. --- sorts/patience_sort.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/sorts/patience_sort.py b/sorts/patience_sort.py index 49bcac4f2910..f3f63bacb2e0 100644 --- a/sorts/patience_sort.py +++ b/sorts/patience_sort.py @@ -25,7 +25,6 @@ def __lt__(self, other): def __eq__(self, other): return self[-1] == other[-1] - def patience_sort(collection: list) -> list: """A pure implementation of patience sort algorithm in Python @@ -52,10 +51,36 @@ def patience_sort(collection: list) -> list: stacks[i].append(element) else: stacks.append(new_stacks) - + # use a heap-based merge to merge stack efficiently collection[:] = merge(*(reversed(stack) for stack in stacks)) return collection + +def mixed_patience_sort(collection: list) -> list: + """ + With this block of code, numbers are sorted according to their + magnitude, the strings are arranged in alphbetical order. And the numbers + are arranged before the alphabets. + """ + + number_items = [] + string_items = [] + + for element in collection: + if isinstance(element, (int, float)): + number_items.append(element) + elif isinstance(element, str): + string_items.append(element) + else: + print("Only integers, floats, and strings are allowed.") + + # The user input is sort by using the patience sort algorithm + sorted_numbers = patience_sort(number_items) + sorted_strings = patience_sort(string_items) + + # use a heap-based merge to merge stack efficiently + collection[:] = sorted_numbers + sorted_strings + return collection def convert_item(item): item = item.strip() @@ -70,4 +95,4 @@ def convert_item(item): if __name__ == "__main__": user_input = input("Enter numbers separated by a comma:\n").strip() unsorted = [convert_item(item) for item in user_input.split(",")] - print(unsorted) + print(mixed_patience_sort(unsorted)) From f8f777332386cf9306f14ac3a7958d426fc24915 Mon Sep 17 00:00:00 2001 From: Obed-727 Date: Fri, 2 Oct 2026 02:05:14 +0000 Subject: [PATCH 3/4] 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. --- sorts/patience_sort.py | 110 ++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 33 deletions(-) diff --git a/sorts/patience_sort.py b/sorts/patience_sort.py index f3f63bacb2e0..f5c8fd4e7aee 100644 --- a/sorts/patience_sort.py +++ b/sorts/patience_sort.py @@ -1,22 +1,27 @@ from __future__ import annotations + from bisect import bisect_left from functools import total_ordering from heapq import merge """ -A pure Python implementation of the patience sort algorithm +A pure Python implementation of the patience sort algorithm. For more information: https://en.wikipedia.org/wiki/Patience_sorting -This algorithm is based on the card game patience +This algorithm is based on the card game patience. + +This version can sort integers, floats, and strings using +mixed_patience_sort(). -For doctests run following command: +For doctests run the following command: python3 -m doctest -v patience_sort.py For manual testing run: python3 patience_sort.py """ + @total_ordering class Stack(list): def __lt__(self, other): @@ -25,13 +30,11 @@ def __lt__(self, other): def __eq__(self, other): return self[-1] == other[-1] -def patience_sort(collection: list) -> list: - """A pure implementation of patience sort algorithm in Python - - :param collection: some mutable ordered collection with heterogeneous - comparable items inside - :return: the same collection ordered by ascending +def patience_sort(collection: list) -> list: + """Sort a collection using the patience sort algorithm. + :param collection: A mutable ordered collection containing comparable items. + :return: The same collection ordered in ascending order. Examples: >>> patience_sort([1, 9, 5, 21, 17, 6]) [1, 5, 6, 9, 17, 21] @@ -43,28 +46,53 @@ def patience_sort(collection: list) -> list: [-48, -17, -3] """ stacks: list[Stack] = [] - # sort into stacks + + # Place each element on the first suitable stack, following + # the rules of the patience sort algorithm. for element in collection: - new_stacks = Stack([element]) - i = bisect_left(stacks, new_stacks) - if i != len(stacks): - stacks[i].append(element) + new_stack: list = Stack([element]) + stack_index: list = bisect_left(stacks, new_stack) + + if stack_index != len(stacks): + stacks[stack_index].append(element) else: - stacks.append(new_stacks) - - # use a heap-based merge to merge stack efficiently + stacks.append(new_stack) + + # Merge the stacks to produce the final sorted collection. collection[:] = merge(*(reversed(stack) for stack in stacks)) return collection - + + def mixed_patience_sort(collection: list) -> list: - """ - With this block of code, numbers are sorted according to their - magnitude, the strings are arranged in alphbetical order. And the numbers - are arranged before the alphabets. - """ + """Sort integers, floats, and strings using patience sort. + + Numbers are sorted by magnitude and placed before strings. + Strings are sorted alphabetically according to Python's + standard string ordering. - number_items = [] - string_items = [] + :param collection: A mutable collection containing integers, + floats, and strings. + :return: The same collection with numbers followed by strings. + + Examples: + >>> mixed_patience_sort([1, 9, 3.64, "Apple", "letter", 23.65]) + [1, 3.64, 9, 23.65, 'Apple', 'letter'] + + >>> mixed_patience_sort(["banana", "Apple", "letter"]) + ['Apple', 'banana', 'letter'] + + >>> mixed_patience_sort([3.5, 1, 8.2]) + [1, 3.5, 8.2] + + >>> mixed_patience_sort([]) + [] + + >>> mixed_patience_sort([1, {"name": "Obed"}]) + Traceback (most recent call last): + ValueError: Only integers, floats, and strings are allowed. + """ + number_items: list[int | float] = [] + string_items: list[str] = [] for element in collection: if isinstance(element, (int, float)): @@ -72,18 +100,33 @@ def mixed_patience_sort(collection: list) -> list: elif isinstance(element, str): string_items.append(element) else: - print("Only integers, floats, and strings are allowed.") + raise ValueError("Only integers, floats, and strings are allowed.") - # The user input is sort by using the patience sort algorithm - sorted_numbers = patience_sort(number_items) - sorted_strings = patience_sort(string_items) + sorted_numbers: int = patience_sort(number_items) + sorted_strings: str = patience_sort(string_items) - # use a heap-based merge to merge stack efficiently collection[:] = sorted_numbers + sorted_strings return collection -def convert_item(item): + +def convert_item(item: str) -> int | float | str: + """Convert a string into an integer, float, or string. + + :param item: The input string to convert. + :return: An integer, float, or the original string. + + Examples: + >>> convert_item("25") + 25 + + >>> convert_item("3.14") + 3.14 + + >>> convert_item("Apple") + 'Apple' + """ item = item.strip() + try: return int(item) except ValueError: @@ -92,7 +135,8 @@ def convert_item(item): except ValueError: return item + if __name__ == "__main__": - user_input = input("Enter numbers separated by a comma:\n").strip() - unsorted = [convert_item(item) for item in user_input.split(",")] + user_input: str| int|float = input("Enter integers, floats, and strings separated by commas:\n").strip() + unsorted: str| int|float = [convert_item(item) for item in user_input.split(",")] print(mixed_patience_sort(unsorted)) From 478c3b9b30826b7d6449e9a9615b29b0932839a8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 2 Oct 2026 03:41:46 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sorts/patience_sort.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/sorts/patience_sort.py b/sorts/patience_sort.py index 93fdc28f7b35..faee1d9040c0 100644 --- a/sorts/patience_sort.py +++ b/sorts/patience_sort.py @@ -68,8 +68,8 @@ def patience_sort(collection: list) -> list: # Place each element on the first suitable stack, following # the rules of the patience sort algorithm. for element in collection: - new_stack: list = Stack([element]) - stack_index: list = bisect_left(stacks, new_stack) + new_stack: list = Stack([element]) + stack_index: list = bisect_left(stacks, new_stack) if stack_index != len(stacks): stacks[stack_index].append(element) @@ -113,15 +113,16 @@ def mixed_patience_sort(collection: list) -> list: string_items: list[str] = [] for element in collection: - if isinstance(element, (int, float)): - number_items.append(element) - elif isinstance(element, str): - string_items.append(element) - else: - raise ValueError("Only integers, floats, and strings are allowed.") + match element: + case int() | float(): + number_items.append(element) + case str(): + string_items.append(element) + case _: + raise ValueError("Only integers, floats, and strings are allowed.") - sorted_numbers: int = patience_sort(number_items) - sorted_strings: str = patience_sort(string_items) + sorted_numbers: int = patience_sort(number_items) + sorted_strings: str = patience_sort(string_items) collection[:] = sorted_numbers + sorted_strings return collection @@ -155,6 +156,8 @@ def convert_item(item: str) -> int | float | str: if __name__ == "__main__": - user_input: str| int|float = input("Enter integers, floats, and strings separated by commas:\n").strip() - unsorted: str| int|float = [convert_item(item) for item in user_input.split(",")] + user_input: str | int | float = input( + "Enter integers, floats, and strings separated by commas:\n" + ).strip() + unsorted: str | int | float = [convert_item(item) for item in user_input.split(",")] print(mixed_patience_sort(unsorted))