forked from MIT-Emerging-Talent/ET6-practice-code-review
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Finished writing solution and test files for sort colors,ready for co…
…de review
- Loading branch information
1 parent
5c3b7cc
commit 28022aa
Showing
2 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
""" | ||
A module for sorting a list of numbers based on their colors. | ||
Module contents: | ||
- sort_colors: sorts a list of integers representing colors (0, 1, 2) in ascending order. | ||
Dependencies: | ||
- typing: Used for type annotations (List). | ||
Notes: | ||
- Does not use built-in sorting functions or libraries such as `sorted()` or `sort()`. | ||
- Implements an in-place counting sort approach. | ||
- Time complexity: O(n) | ||
- Space complexity: O(1) (in-place). | ||
Created on 26 12 2024 | ||
@author: Mohamed Elnageeb | ||
""" | ||
|
||
from typing import List # Importing List for type annotations | ||
|
||
|
||
def sort_colors(nums: List[int]) -> None: | ||
""" | ||
Sorts a given list of integers representing colors (0, 1, 2) in-place. | ||
This function implements sorting logic manually using a counting sort approach and does not use | ||
any built-in sorting functions or libraries, such as `sorted()` or `sort()`. | ||
Time Complexity: | ||
O(n): Iterates through the list once to count occurrences and again to modify it in-place. | ||
Space Complexity: | ||
O(1): Uses a fixed-size counter array of size 3. No additional space is used. | ||
Parameters: | ||
nums: List[int] | ||
A list of integers where each integer is 0, 1, or 2. Modified in-place. | ||
Returns: | ||
None | ||
Raises: | ||
AssertionError: if the input is not a list or contains invalid elements. | ||
Examples: | ||
>>> nums = [0, 2, 1] | ||
>>> sort_colors(nums) | ||
>>> nums | ||
[0, 1, 2] | ||
>>> nums = [1] | ||
>>> sort_colors(nums) | ||
>>> nums | ||
[1] | ||
>>> nums = [2, 1, 1, 0, 2] | ||
>>> sort_colors(nums) | ||
>>> nums | ||
[0, 1, 1, 2, 2] | ||
""" | ||
# Validate input | ||
assert isinstance(nums, list), "Input must be a list." | ||
assert all(0 <= number <= 2 for number in nums), "All elements must be 0, 1, or 2." | ||
|
||
# Create a counter array to store the count of each number | ||
counter_array = [0] * 3 | ||
|
||
# Count occurrences of each number | ||
for number in nums: | ||
counter_array[number] += 1 | ||
|
||
# Rebuild the nums array in-place | ||
index = 0 | ||
for number in range(3): | ||
for _ in range(counter_array[number]): | ||
nums[index] = number | ||
index += 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Created on 26 10 2024 | ||
@author: Mohamed Elnageeb | ||
""" | ||
|
||
import random | ||
import unittest | ||
|
||
# Import the function to be tested | ||
from ..sort_colors import sort_colors | ||
|
||
|
||
class TestSortColors(unittest.TestCase): | ||
"""Test the sort_colors function""" | ||
|
||
def test_empty_list(self): | ||
"""It should handle an empty list""" | ||
nums = [] | ||
sort_colors(nums) | ||
self.assertEqual(nums, []) | ||
|
||
def test_single_element(self): | ||
"""It should handle a list with one element""" | ||
nums = [1] | ||
sort_colors(nums) | ||
self.assertEqual(nums, [1]) | ||
|
||
def test_all_same_elements(self): | ||
"""It should handle a list with all elements being the same""" | ||
nums = [2, 2, 2] | ||
sort_colors(nums) | ||
self.assertEqual(nums, [2, 2, 2]) | ||
|
||
def test_already_sorted(self): | ||
"""It should not modify an already sorted list""" | ||
nums = [0, 0, 1, 1, 2, 2] | ||
sort_colors(nums) | ||
self.assertEqual(nums, [0, 0, 1, 1, 2, 2]) # Fixed expected output | ||
|
||
def test_unsorted_list(self): | ||
"""It should sort an unsorted list""" | ||
nums = [2, 0, 2, 1, 1, 0] | ||
sort_colors(nums) | ||
self.assertEqual(nums, [0, 0, 1, 1, 2, 2]) | ||
|
||
def test_large_list(self): | ||
"""It should handle a large list""" | ||
nums = [0, 2, 1] * 100000 | ||
sort_colors(nums) | ||
self.assertEqual(nums, [0] * 100000 + [1] * 100000 + [2] * 100000) | ||
|
||
def test_not_a_list(self): | ||
"""It should raise an assertion error if the input is not a list""" | ||
with self.assertRaises(AssertionError): | ||
sort_colors("not a list") | ||
|
||
def test_invalid_elements(self): | ||
"""It should raise an assertion error for invalid elements""" | ||
nums = [0, 1, 3] # Invalid element 3 | ||
with self.assertRaises(AssertionError): | ||
sort_colors(nums) | ||
|
||
def test_randomly_generated_list(self): | ||
"""It should sort an unsorted list""" | ||
nums = [random.randint(0, 2) for i in range(1000)] | ||
expected = list(sorted(nums)) | ||
sort_colors(nums) | ||
self.assertEqual(nums, expected) |